parent
fb4d563804
commit
54dc8a2556
|
@ -51,8 +51,8 @@
|
||||||
"repositoryURL": "https://github.com/passepartoutvpn/tunnelkit",
|
"repositoryURL": "https://github.com/passepartoutvpn/tunnelkit",
|
||||||
"state": {
|
"state": {
|
||||||
"branch": null,
|
"branch": null,
|
||||||
"revision": "ca378c4999f2040565b9ec944746b684ab19c347",
|
"revision": "3a54295ed9d2b71057fdeef752144beea66e31f2",
|
||||||
"version": "5.0.0"
|
"version": null
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
|
@ -90,13 +90,15 @@ class CoreContext {
|
||||||
)
|
)
|
||||||
|
|
||||||
#if targetEnvironment(simulator)
|
#if targetEnvironment(simulator)
|
||||||
let strategy = MockVPNManagerStrategy()
|
let vpn = MockVPN()
|
||||||
#else
|
#else
|
||||||
|
let vpn = NetworkExtensionVPN()
|
||||||
|
#endif
|
||||||
let strategy = TunnelKitVPNManagerStrategy(
|
let strategy = TunnelKitVPNManagerStrategy(
|
||||||
appGroup: Constants.App.appGroupId,
|
appGroup: Constants.App.appGroupId,
|
||||||
tunnelBundleIdentifier: Constants.App.tunnelBundleId
|
tunnelBundleIdentifier: Constants.App.tunnelBundleId,
|
||||||
|
vpn: vpn
|
||||||
)
|
)
|
||||||
#endif
|
|
||||||
vpnManager = VPNManager(
|
vpnManager = VPNManager(
|
||||||
appGroup: Constants.App.appGroupId,
|
appGroup: Constants.App.appGroupId,
|
||||||
store: store,
|
store: store,
|
||||||
|
|
|
@ -23,8 +23,8 @@ let package = Package(
|
||||||
dependencies: [
|
dependencies: [
|
||||||
// Dependencies declare other packages that this package depends on.
|
// Dependencies declare other packages that this package depends on.
|
||||||
// .package(url: /* package url */, from: "1.0.0"),
|
// .package(url: /* package url */, from: "1.0.0"),
|
||||||
.package(name: "TunnelKit", url: "https://github.com/passepartoutvpn/tunnelkit", from: "5.0.0"),
|
// .package(name: "TunnelKit", url: "https://github.com/passepartoutvpn/tunnelkit", from: "5.0.0"),
|
||||||
// .package(name: "TunnelKit", url: "https://github.com/passepartoutvpn/tunnelkit", .revision("000fde0aa2f028575e811a984ef1972cb9afeb36")),
|
.package(name: "TunnelKit", url: "https://github.com/passepartoutvpn/tunnelkit", .revision("3a54295ed9d2b71057fdeef752144beea66e31f2")),
|
||||||
// .package(name: "TunnelKit", path: "../../tunnelkit"),
|
// .package(name: "TunnelKit", path: "../../tunnelkit"),
|
||||||
.package(url: "https://github.com/zoul/generic-json-swift", from: "2.0.0"),
|
.package(url: "https://github.com/zoul/generic-json-swift", from: "2.0.0"),
|
||||||
.package(url: "https://github.com/SwiftyBeaver/SwiftyBeaver", from: "1.9.0")
|
.package(url: "https://github.com/SwiftyBeaver/SwiftyBeaver", from: "1.9.0")
|
||||||
|
|
|
@ -1,126 +0,0 @@
|
||||||
//
|
|
||||||
// MockVPNManagerStrategy.swift
|
|
||||||
// Passepartout
|
|
||||||
//
|
|
||||||
// Created by Davide De Rosa on 2/9/22.
|
|
||||||
// Copyright (c) 2022 Davide De Rosa. All rights reserved.
|
|
||||||
//
|
|
||||||
// https://github.com/passepartoutvpn
|
|
||||||
//
|
|
||||||
// This file is part of Passepartout.
|
|
||||||
//
|
|
||||||
// Passepartout is free software: you can redistribute it and/or modify
|
|
||||||
// it under the terms of the GNU General Public License as published by
|
|
||||||
// the Free Software Foundation, either version 3 of the License, or
|
|
||||||
// (at your option) any later version.
|
|
||||||
//
|
|
||||||
// Passepartout is distributed in the hope that it will be useful,
|
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
// GNU General Public License for more details.
|
|
||||||
//
|
|
||||||
// You should have received a copy of the GNU General Public License
|
|
||||||
// along with Passepartout. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
//
|
|
||||||
|
|
||||||
import Foundation
|
|
||||||
import Combine
|
|
||||||
import TunnelKitCore
|
|
||||||
import PassepartoutCore
|
|
||||||
|
|
||||||
// XXX: mock connect/disconnect tasks overlap, should cancel other pending task
|
|
||||||
|
|
||||||
public class MockVPNManagerStrategy: VPNManagerStrategy {
|
|
||||||
private var currentState: ObservableVPNState?
|
|
||||||
|
|
||||||
private var dataCountTimer: AnyCancellable?
|
|
||||||
|
|
||||||
public init() {
|
|
||||||
}
|
|
||||||
|
|
||||||
public func observe(into state: ObservableVPNState) {
|
|
||||||
currentState = state
|
|
||||||
}
|
|
||||||
|
|
||||||
public func reinstate(configuration: VPNConfiguration) {
|
|
||||||
}
|
|
||||||
|
|
||||||
@MainActor
|
|
||||||
public func connect(configuration: VPNConfiguration) {
|
|
||||||
guard currentState?.vpnStatus != .connected else {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
Task {
|
|
||||||
currentState?.isEnabled = true
|
|
||||||
currentState?.vpnStatus = .connecting
|
|
||||||
await Task.maybeWait(forMilliseconds: 1000)
|
|
||||||
currentState?.vpnStatus = .connected
|
|
||||||
startCountingData()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@MainActor
|
|
||||||
public func reconnect() async {
|
|
||||||
guard currentState?.vpnStatus == .connected else {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
Task {
|
|
||||||
currentState?.vpnStatus = .disconnecting
|
|
||||||
await Task.maybeWait(forMilliseconds: 1000)
|
|
||||||
currentState?.vpnStatus = .disconnected
|
|
||||||
await Task.maybeWait(forMilliseconds: 1000)
|
|
||||||
currentState?.vpnStatus = .connecting
|
|
||||||
await Task.maybeWait(forMilliseconds: 1000)
|
|
||||||
currentState?.vpnStatus = .connected
|
|
||||||
currentState?.dataCount = nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@MainActor
|
|
||||||
public func disconnect() {
|
|
||||||
stopCountingData()
|
|
||||||
guard currentState?.vpnStatus != .disconnected else {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
Task {
|
|
||||||
currentState?.isEnabled = false
|
|
||||||
currentState?.vpnStatus = .disconnecting
|
|
||||||
await Task.maybeWait(forMilliseconds: 1000)
|
|
||||||
currentState?.vpnStatus = .disconnected
|
|
||||||
currentState?.dataCount = nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private func startCountingData() {
|
|
||||||
guard currentState?.vpnStatus == .connected else {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
guard dataCountTimer == nil else {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
dataCountTimer = Timer.TimerPublisher(interval: 2.0, runLoop: .main, mode: .common)
|
|
||||||
.autoconnect()
|
|
||||||
.sink(receiveValue: { _ in
|
|
||||||
let previous = self.currentState?.dataCount ?? DataCount(0, 0)
|
|
||||||
self.currentState?.dataCount = DataCount(previous.received + 4000, previous.sent + 2000)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
private func stopCountingData() {
|
|
||||||
dataCountTimer?.cancel()
|
|
||||||
dataCountTimer = nil
|
|
||||||
}
|
|
||||||
|
|
||||||
@MainActor
|
|
||||||
public func removeConfigurations() {
|
|
||||||
disconnect()
|
|
||||||
}
|
|
||||||
|
|
||||||
public func serverConfiguration(forProtocol vpnProtocol: VPNProtocolType) -> Any? {
|
|
||||||
nil
|
|
||||||
}
|
|
||||||
|
|
||||||
public func debugLogURL(forProtocol vpnProtocol: VPNProtocolType) -> URL? {
|
|
||||||
nil
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -32,7 +32,7 @@ import TunnelKitOpenVPNCore
|
||||||
import PassepartoutCore
|
import PassepartoutCore
|
||||||
import PassepartoutUtils
|
import PassepartoutUtils
|
||||||
|
|
||||||
public class TunnelKitVPNManagerStrategy: VPNManagerStrategy {
|
public class TunnelKitVPNManagerStrategy<VPNType: VPN>: VPNManagerStrategy where VPNType.Configuration == NetworkExtensionConfiguration, VPNType.Extra == NetworkExtensionExtra {
|
||||||
private struct AtomicState: Equatable {
|
private struct AtomicState: Equatable {
|
||||||
let isEnabled: Bool
|
let isEnabled: Bool
|
||||||
|
|
||||||
|
@ -44,7 +44,7 @@ public class TunnelKitVPNManagerStrategy: VPNManagerStrategy {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static let reconnectionSeconds = 2
|
private let reconnectionSeconds = 2
|
||||||
|
|
||||||
private let appGroup: String
|
private let appGroup: String
|
||||||
|
|
||||||
|
@ -52,7 +52,7 @@ public class TunnelKitVPNManagerStrategy: VPNManagerStrategy {
|
||||||
|
|
||||||
private let defaults: UserDefaults
|
private let defaults: UserDefaults
|
||||||
|
|
||||||
private let vpn: NetworkExtensionVPN
|
private let vpn: VPNType
|
||||||
|
|
||||||
private let dataCountInterval: TimeInterval
|
private let dataCountInterval: TimeInterval
|
||||||
|
|
||||||
|
@ -71,14 +71,19 @@ public class TunnelKitVPNManagerStrategy: VPNManagerStrategy {
|
||||||
private var currentBundleIdentifier: String?
|
private var currentBundleIdentifier: String?
|
||||||
|
|
||||||
@MainActor
|
@MainActor
|
||||||
public init(appGroup: String, tunnelBundleIdentifier: @escaping (VPNProtocolType) -> String, dataCountInterval: TimeInterval = 3.0) {
|
public init(
|
||||||
|
appGroup: String,
|
||||||
|
tunnelBundleIdentifier: @escaping (VPNProtocolType) -> String,
|
||||||
|
vpn: VPNType,
|
||||||
|
dataCountInterval: TimeInterval = 3.0
|
||||||
|
) {
|
||||||
self.appGroup = appGroup
|
self.appGroup = appGroup
|
||||||
self.tunnelBundleIdentifier = tunnelBundleIdentifier
|
self.tunnelBundleIdentifier = tunnelBundleIdentifier
|
||||||
guard let defaults = UserDefaults(suiteName: appGroup) else {
|
guard let defaults = UserDefaults(suiteName: appGroup) else {
|
||||||
fatalError("No entitlements for group '\(appGroup)'")
|
fatalError("No entitlements for group '\(appGroup)'")
|
||||||
}
|
}
|
||||||
self.defaults = defaults
|
self.defaults = defaults
|
||||||
vpn = NetworkExtensionVPN()
|
self.vpn = vpn
|
||||||
self.dataCountInterval = dataCountInterval
|
self.dataCountInterval = dataCountInterval
|
||||||
|
|
||||||
registerNotification(withName: VPNNotification.didReinstall) {
|
registerNotification(withName: VPNNotification.didReinstall) {
|
||||||
|
@ -151,7 +156,7 @@ public class TunnelKitVPNManagerStrategy: VPNManagerStrategy {
|
||||||
bundleIdentifier,
|
bundleIdentifier,
|
||||||
configuration: configuration.neConfiguration,
|
configuration: configuration.neConfiguration,
|
||||||
extra: configuration.neExtra,
|
extra: configuration.neExtra,
|
||||||
after: .seconds(Self.reconnectionSeconds)
|
after: .seconds(reconnectionSeconds)
|
||||||
)
|
)
|
||||||
} catch {
|
} catch {
|
||||||
pp_log.error("Unable to connect: \(error)")
|
pp_log.error("Unable to connect: \(error)")
|
||||||
|
@ -160,7 +165,7 @@ public class TunnelKitVPNManagerStrategy: VPNManagerStrategy {
|
||||||
|
|
||||||
public func reconnect() async {
|
public func reconnect() async {
|
||||||
try? await vpn.reconnect(
|
try? await vpn.reconnect(
|
||||||
after: .seconds(Self.reconnectionSeconds)
|
after: .seconds(reconnectionSeconds)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue