Replace continuations with natively async methods (#284)

This commit is contained in:
Davide De Rosa 2022-10-12 22:28:33 +02:00 committed by GitHub
parent a3822678cf
commit 080ee35e61
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 51 additions and 98 deletions

View File

@ -14,6 +14,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Changed ### Changed
- Upgrade OpenSSL to 1.1.1q. - Upgrade OpenSSL to 1.1.1q.
- Use natively async methods from NetworkExtension. [#284](https://github.com/passepartoutvpn/tunnelkit/pull/284)
### Fixed ### Fixed

View File

@ -31,7 +31,6 @@ private let log = SwiftyBeaver.self
/// `VPN` based on the NetworkExtension framework. /// `VPN` based on the NetworkExtension framework.
public class NetworkExtensionVPN: VPN { public class NetworkExtensionVPN: VPN {
private let semaphore = DispatchSemaphore(value: 1)
/** /**
Initializes a provider. Initializes a provider.
@ -49,11 +48,7 @@ public class NetworkExtensionVPN: VPN {
// MARK: Public // MARK: Public
public func prepare() async { public func prepare() async {
await withCheckedContinuation { (continuation: CheckedContinuation<Void, Never>) in _ = try? await NETunnelProviderManager.loadAllFromPreferences()
NETunnelProviderManager.loadAllFromPreferences { managers, error in
continuation.resume()
}
}
} }
public func install( public func install(
@ -104,48 +99,30 @@ public class NetworkExtensionVPN: VPN {
} }
public func disconnect() async { public func disconnect() async {
do { guard let managers = try? await lookupAll() else {
let managers = try await lookupAll()
await withCheckedContinuation { (continuation: CheckedContinuation<Void, Never>) in
guard !managers.isEmpty else {
continuation.resume()
return return
} }
managers.forEach { guard !managers.isEmpty else {
let isLast = ($0 == managers.last) return
$0.connection.stopVPNTunnel()
$0.isOnDemandEnabled = false
$0.isEnabled = false
$0.saveToPreferences { _ in
if isLast {
continuation.resume()
} }
} for m in managers {
} m.connection.stopVPNTunnel()
} m.isOnDemandEnabled = false
} catch { m.isEnabled = false
try? await m.saveToPreferences()
} }
} }
public func uninstall() async { public func uninstall() async {
do { guard let managers = try? await lookupAll() else {
let managers = try await lookupAll()
await withCheckedContinuation { (continuation: CheckedContinuation<Void, Never>) in
guard !managers.isEmpty else {
continuation.resume()
return return
} }
managers.forEach { guard !managers.isEmpty else {
let isLast = ($0 == managers.last) return
$0.connection.stopVPNTunnel()
$0.removeFromPreferences { _ in
if isLast {
continuation.resume()
} }
} for m in managers {
} m.connection.stopVPNTunnel()
} try? await m.removeFromPreferences()
} catch {
} }
} }
@ -190,7 +167,6 @@ public class NetworkExtensionVPN: VPN {
protocolConfiguration: NETunnelProviderProtocol, protocolConfiguration: NETunnelProviderProtocol,
onDemandRules: [NEOnDemandRule] onDemandRules: [NEOnDemandRule]
) async throws -> NETunnelProviderManager { ) async throws -> NETunnelProviderManager {
try await withCheckedThrowingContinuation { continuation in
manager.localizedDescription = title manager.localizedDescription = title
manager.protocolConfiguration = protocolConfiguration manager.protocolConfiguration = protocolConfiguration
@ -202,57 +178,33 @@ public class NetworkExtensionVPN: VPN {
} }
manager.isEnabled = true manager.isEnabled = true
manager.saveToPreferences { error in do {
if let error = error { try await manager.saveToPreferences()
try await manager.loadFromPreferences()
notifyReinstall(manager)
return manager
} catch {
manager.isOnDemandEnabled = false manager.isOnDemandEnabled = false
manager.isEnabled = false manager.isEnabled = false
continuation.resume(throwing: error) notifyInstallError(error)
self.notifyInstallError(error) throw error
} else {
manager.loadFromPreferences { error in
if let error = error {
continuation.resume(throwing: error)
self.notifyInstallError(error)
} else {
continuation.resume(returning: manager)
self.notifyReinstall(manager)
}
}
}
}
} }
} }
private func retainManagers(_ managers: [NETunnelProviderManager], isIncluded: (NETunnelProviderManager) -> Bool) async { private func retainManagers(_ managers: [NETunnelProviderManager], isIncluded: (NETunnelProviderManager) -> Bool) async {
await withCheckedContinuation { (continuation: CheckedContinuation<Void, Never>) in
let others = managers.filter { let others = managers.filter {
!isIncluded($0) !isIncluded($0)
} }
guard !others.isEmpty else { guard !others.isEmpty else {
continuation.resume()
return return
} }
others.forEach { for o in others {
let isLast = ($0 == others.last) try? await o.removeFromPreferences()
$0.removeFromPreferences { _ in
if isLast {
continuation.resume()
}
}
}
} }
} }
private func lookupAll() async throws -> [NETunnelProviderManager] { private func lookupAll() async throws -> [NETunnelProviderManager] {
try await withCheckedThrowingContinuation { continuation in try await NETunnelProviderManager.loadAllFromPreferences()
NETunnelProviderManager.loadAllFromPreferences { managers, error in
if let error = error {
continuation.resume(throwing: error)
} else {
continuation.resume(returning: managers ?? [])
}
}
}
} }
// MARK: Notifications // MARK: Notifications