VPN: Restart tunnel after modifying a currently active configuration
Signed-off-by: Roopesh Chander <roop@roopc.net>
This commit is contained in:
@@ -273,6 +273,8 @@ class TunnelDetailTableViewStatusCell: UITableViewCell {
|
|||||||
text = "Reactivating"
|
text = "Reactivating"
|
||||||
case .resolvingEndpointDomains:
|
case .resolvingEndpointDomains:
|
||||||
text = "Resolving domains"
|
text = "Resolving domains"
|
||||||
|
case .restarting:
|
||||||
|
text = "Restarting"
|
||||||
}
|
}
|
||||||
textLabel?.text = text
|
textLabel?.text = text
|
||||||
DispatchQueue.main.async { [weak statusSwitch] in
|
DispatchQueue.main.async { [weak statusSwitch] in
|
||||||
|
|||||||
@@ -186,6 +186,12 @@ class TunnelsManager {
|
|||||||
} else {
|
} else {
|
||||||
s.delegate?.tunnelModified(at: tunnel.index)
|
s.delegate?.tunnelModified(at: tunnel.index)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (tunnel.status == .active || tunnel.status == .activating || tunnel.status == .reasserting) {
|
||||||
|
// Turn off the tunnel, and then turn it back on, so the changes are made effective
|
||||||
|
tunnel.beginRestart()
|
||||||
|
}
|
||||||
|
|
||||||
completionHandler(nil)
|
completionHandler(nil)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -312,7 +318,7 @@ class TunnelContainer: NSObject {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fileprivate func startActivation(completionHandler: @escaping (Error?) -> Void) {
|
fileprivate func startActivation(completionHandler: @escaping (Error?) -> Void) {
|
||||||
assert(status == .inactive)
|
assert(status == .inactive || status == .restarting)
|
||||||
assert(self.dnsResolver == nil)
|
assert(self.dnsResolver == nil)
|
||||||
|
|
||||||
guard let tunnelConfiguration = tunnelConfiguration() else { fatalError() }
|
guard let tunnelConfiguration = tunnelConfiguration() else { fatalError() }
|
||||||
@@ -446,6 +452,14 @@ class TunnelContainer: NSObject {
|
|||||||
session.stopTunnel()
|
session.stopTunnel()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fileprivate func beginRestart() {
|
||||||
|
assert(status == .active || status == .activating || status == .reasserting)
|
||||||
|
assert(statusObservationToken != nil)
|
||||||
|
status = .restarting
|
||||||
|
let session = (tunnelProvider.connection as! NETunnelProviderSession)
|
||||||
|
session.stopTunnel()
|
||||||
|
}
|
||||||
|
|
||||||
private func startObservingTunnelStatus() {
|
private func startObservingTunnelStatus() {
|
||||||
if (statusObservationToken != nil) { return }
|
if (statusObservationToken != nil) { return }
|
||||||
let connection = tunnelProvider.connection
|
let connection = tunnelProvider.connection
|
||||||
@@ -453,12 +467,17 @@ class TunnelContainer: NSObject {
|
|||||||
forName: .NEVPNStatusDidChange,
|
forName: .NEVPNStatusDidChange,
|
||||||
object: connection,
|
object: connection,
|
||||||
queue: nil) { [weak self] (_) in
|
queue: nil) { [weak self] (_) in
|
||||||
let status = TunnelStatus(from: connection.status)
|
guard let s = self else { return }
|
||||||
if let s = self {
|
if ((s.status == .restarting) && (connection.status == .disconnected || connection.status == .disconnecting)) {
|
||||||
s.status = status
|
// Don't change s.status when disconnecting for a restart
|
||||||
if (status == .inactive) {
|
if (connection.status == .disconnected) {
|
||||||
s.stopObservingTunnelStatus()
|
self?.startActivation(completionHandler: { _ in })
|
||||||
}
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
s.status = TunnelStatus(from: connection.status)
|
||||||
|
if (s.status == .inactive) {
|
||||||
|
s.stopObservingTunnelStatus()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -475,8 +494,9 @@ class TunnelContainer: NSObject {
|
|||||||
case activating
|
case activating
|
||||||
case active
|
case active
|
||||||
case deactivating
|
case deactivating
|
||||||
case reasserting // On editing an active tunnel, the tunnel shall deactive and then activate
|
case reasserting // Not a possible state at present
|
||||||
|
|
||||||
|
case restarting // Restarting tunnel (done after saving modifications to an active tunnel)
|
||||||
case resolvingEndpointDomains // DNS resolution in progress
|
case resolvingEndpointDomains // DNS resolution in progress
|
||||||
|
|
||||||
init(from vpnStatus: NEVPNStatus) {
|
init(from vpnStatus: NEVPNStatus) {
|
||||||
|
|||||||
Reference in New Issue
Block a user