Reconnect VPN without disabling it

Retain on-demand flag to avoid leaks during reconnection.
This commit is contained in:
Davide De Rosa 2022-07-23 10:06:03 +02:00
parent 1c64253a1f
commit 92ffc382cb
7 changed files with 39 additions and 4 deletions

View File

@ -51,7 +51,7 @@
"repositoryURL": "https://github.com/passepartoutvpn/tunnelkit", "repositoryURL": "https://github.com/passepartoutvpn/tunnelkit",
"state": { "state": {
"branch": null, "branch": null,
"revision": "36ed23ccc4e6083d671b6b823f50787b018f2844", "revision": "e2aaffc06f1d59a96e55e77d2a70d15c7f58b585",
"version": null "version": null
} }
}, },

View File

@ -24,7 +24,7 @@ let package = Package(
// 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: "4.1.0"), // .package(name: "TunnelKit", url: "https://github.com/passepartoutvpn/tunnelkit", from: "4.1.0"),
.package(name: "TunnelKit", url: "https://github.com/passepartoutvpn/tunnelkit", .revision("36ed23ccc4e6083d671b6b823f50787b018f2844")), .package(name: "TunnelKit", url: "https://github.com/passepartoutvpn/tunnelkit", .revision("e2aaffc06f1d59a96e55e77d2a70d15c7f58b585")),
// .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")

View File

@ -45,6 +45,8 @@ public protocol VPNManager {
@discardableResult @discardableResult
func connect(with profileId: UUID, toServer newServerId: String) async throws -> Profile func connect(with profileId: UUID, toServer newServerId: String) async throws -> Profile
func reconnect() async
func modifyActiveProfile(_ block: (inout Profile) -> Void) async throws func modifyActiveProfile(_ block: (inout Profile) -> Void) async throws
func disable() async func disable() async

View File

@ -97,11 +97,17 @@ public class DefaultVPNManager<ProfileManagerType: ProfileManagerWithCurrentProf
} }
func reconnect(_ configuration: VPNConfiguration) async { func reconnect(_ configuration: VPNConfiguration) async {
pp_log.info("Reconnecting VPN") pp_log.info("Reconnecting VPN (with new configuration)")
clearLastError() clearLastError()
await strategy.connect(configuration: configuration) await strategy.connect(configuration: configuration)
} }
public func reconnect() async {
pp_log.info("Reconnecting VPN")
clearLastError()
await strategy.reconnect()
}
public func disable() async { public func disable() async {
pp_log.info("Disabling VPN") pp_log.info("Disabling VPN")
clearLastError() clearLastError()

View File

@ -58,6 +58,23 @@ public class MockVPNManagerStrategy: VPNManagerStrategy {
startCountingData() 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 @MainActor
public func disconnect() { public func disconnect() {

View File

@ -43,6 +43,8 @@ public class TunnelKitVPNManagerStrategy: VPNManagerStrategy {
self.vpnStatus = vpnStatus self.vpnStatus = vpnStatus
} }
} }
private static let reconnectionSeconds = 2
private let appGroup: String private let appGroup: String
@ -149,13 +151,19 @@ public class TunnelKitVPNManagerStrategy: VPNManagerStrategy {
bundleIdentifier, bundleIdentifier,
configuration: configuration.neConfiguration, configuration: configuration.neConfiguration,
extra: configuration.neExtra, extra: configuration.neExtra,
after: .seconds(2) after: .seconds(Self.reconnectionSeconds)
) )
} catch { } catch {
pp_log.error("Unable to connect: \(error)") pp_log.error("Unable to connect: \(error)")
} }
} }
public func reconnect() async {
try? await vpn.reconnect(
after: .seconds(Self.reconnectionSeconds)
)
}
public func disconnect() async { public func disconnect() async {
await vpn.disconnect() await vpn.disconnect()
} }

View File

@ -33,6 +33,8 @@ public protocol VPNManagerStrategy {
func reinstate(configuration: VPNConfiguration) async func reinstate(configuration: VPNConfiguration) async
func connect(configuration: VPNConfiguration) async func connect(configuration: VPNConfiguration) async
func reconnect() async
func disconnect() async func disconnect() async