Replace continuations with natively async methods (#284)
This commit is contained in:
parent
a3822678cf
commit
080ee35e61
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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,13 +48,9 @@ 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(
|
||||||
_ tunnelBundleIdentifier: String,
|
_ tunnelBundleIdentifier: String,
|
||||||
configuration: NetworkExtensionConfiguration,
|
configuration: NetworkExtensionConfiguration,
|
||||||
|
@ -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()
|
return
|
||||||
await withCheckedContinuation { (continuation: CheckedContinuation<Void, Never>) in
|
}
|
||||||
guard !managers.isEmpty else {
|
guard !managers.isEmpty else {
|
||||||
continuation.resume()
|
return
|
||||||
return
|
}
|
||||||
}
|
for m in managers {
|
||||||
managers.forEach {
|
m.connection.stopVPNTunnel()
|
||||||
let isLast = ($0 == managers.last)
|
m.isOnDemandEnabled = false
|
||||||
$0.connection.stopVPNTunnel()
|
m.isEnabled = false
|
||||||
$0.isOnDemandEnabled = false
|
try? await m.saveToPreferences()
|
||||||
$0.isEnabled = false
|
|
||||||
$0.saveToPreferences { _ in
|
|
||||||
if isLast {
|
|
||||||
continuation.resume()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch {
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public func uninstall() async {
|
public func uninstall() async {
|
||||||
do {
|
guard let managers = try? await lookupAll() else {
|
||||||
let managers = try await lookupAll()
|
return
|
||||||
await withCheckedContinuation { (continuation: CheckedContinuation<Void, Never>) in
|
}
|
||||||
guard !managers.isEmpty else {
|
guard !managers.isEmpty else {
|
||||||
continuation.resume()
|
return
|
||||||
return
|
}
|
||||||
}
|
for m in managers {
|
||||||
managers.forEach {
|
m.connection.stopVPNTunnel()
|
||||||
let isLast = ($0 == managers.last)
|
try? await m.removeFromPreferences()
|
||||||
$0.connection.stopVPNTunnel()
|
|
||||||
$0.removeFromPreferences { _ in
|
|
||||||
if isLast {
|
|
||||||
continuation.resume()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch {
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -190,69 +167,44 @@ 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
|
|
||||||
|
|
||||||
if !onDemandRules.isEmpty {
|
if !onDemandRules.isEmpty {
|
||||||
manager.onDemandRules = onDemandRules
|
manager.onDemandRules = onDemandRules
|
||||||
manager.isOnDemandEnabled = true
|
manager.isOnDemandEnabled = true
|
||||||
} else {
|
} else {
|
||||||
manager.isOnDemandEnabled = false
|
manager.isOnDemandEnabled = false
|
||||||
}
|
}
|
||||||
|
|
||||||
manager.isEnabled = true
|
manager.isEnabled = true
|
||||||
manager.saveToPreferences { error in
|
do {
|
||||||
if let error = error {
|
try await manager.saveToPreferences()
|
||||||
manager.isOnDemandEnabled = false
|
try await manager.loadFromPreferences()
|
||||||
manager.isEnabled = false
|
notifyReinstall(manager)
|
||||||
continuation.resume(throwing: error)
|
return manager
|
||||||
self.notifyInstallError(error)
|
} catch {
|
||||||
} else {
|
manager.isOnDemandEnabled = false
|
||||||
manager.loadFromPreferences { error in
|
manager.isEnabled = false
|
||||||
if let error = error {
|
notifyInstallError(error)
|
||||||
continuation.resume(throwing: error)
|
throw 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 {
|
return
|
||||||
continuation.resume()
|
}
|
||||||
return
|
for o in others {
|
||||||
}
|
try? await o.removeFromPreferences()
|
||||||
others.forEach {
|
|
||||||
let isLast = ($0 == others.last)
|
|
||||||
$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
|
||||||
|
|
Loading…
Reference in New Issue