From 9b82d7f9ec1f783afc3ed44835e73ebc8d652d6e Mon Sep 17 00:00:00 2001 From: Davide De Rosa Date: Sat, 9 May 2020 00:46:16 +0200 Subject: [PATCH] Evaluate reconnection without touching reasserting Use a different variable to signal an upcoming reconnection. Make sure that reasserting is never set to false with the meaning of "do not reconnect", because doing so would trigger a transient "connected" state in the VPN. Reverts use of cancelTunnelWithError() in sessionDidStop. --- .../AppExtension/OpenVPNTunnelProvider.swift | 22 ++++++++++--------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/TunnelKit/Sources/Protocols/OpenVPN/AppExtension/OpenVPNTunnelProvider.swift b/TunnelKit/Sources/Protocols/OpenVPN/AppExtension/OpenVPNTunnelProvider.swift index 6190ae1..260949b 100644 --- a/TunnelKit/Sources/Protocols/OpenVPN/AppExtension/OpenVPNTunnelProvider.swift +++ b/TunnelKit/Sources/Protocols/OpenVPN/AppExtension/OpenVPNTunnelProvider.swift @@ -128,6 +128,8 @@ open class OpenVPNTunnelProvider: NEPacketTunnelProvider { private var isCountingData = false + private var shouldReconnect = false + // MARK: NEPacketTunnelProvider (XPC queue) open override var reasserting: Bool { @@ -341,7 +343,7 @@ open class OpenVPNTunnelProvider: NEPacketTunnelProvider { } private func finishTunnelDisconnection(error: Error?) { - if let session = session, !(reasserting && session.canRebindLink()) { + if let session = session, !(shouldReconnect && session.canRebindLink()) { session.cleanup() } @@ -419,7 +421,7 @@ extension OpenVPNTunnelProvider: GenericSocketDelegate { /// :nodoc: public func socketDidTimeout(_ socket: GenericSocket) { log.debug("Socket timed out waiting for activity, cancelling...") - reasserting = true + shouldReconnect = true socket.shutdown() // fallback: TCP connection timeout suggests falling back @@ -438,7 +440,7 @@ extension OpenVPNTunnelProvider: GenericSocketDelegate { } if session.canRebindLink() { session.rebindLink(producer.link(withMTU: cfg.mtu)) - reasserting = false + shouldReconnect = false } else { session.setLink(producer.link(withMTU: cfg.mtu)) } @@ -478,17 +480,18 @@ extension OpenVPNTunnelProvider: GenericSocketDelegate { } // reconnect? - if reasserting { + if shouldReconnect { log.debug("Disconnection is recoverable, tunnel will reconnect in \(reconnectionDelay) milliseconds...") tunnelQueue.schedule(after: .milliseconds(reconnectionDelay)) { - log.debug("Tunnel is about to reconnect...") - // give up if reasserting cleared in the meantime - guard self.reasserting else { - log.warning("Reasserting flag was cleared in the meantime") + // give up if shouldReconnect cleared in the meantime + guard self.shouldReconnect else { + log.warning("Reconnection flag was cleared in the meantime") return } + log.debug("Tunnel is about to reconnect...") + self.reasserting = true self.connectTunnel(upgradedSocket: upgradedSocket) } return @@ -579,7 +582,6 @@ extension OpenVPNTunnelProvider: OpenVPNSessionDelegate { public func sessionDidStop(_: OpenVPNSession, withError error: Error?, shouldReconnect: Bool) { if let error = error { log.error("Session did stop with error: \(error)") - cancelTunnelWithError(error) } else { log.info("Session did stop") } @@ -587,7 +589,7 @@ extension OpenVPNTunnelProvider: OpenVPNSessionDelegate { isCountingData = false refreshDataCount() - reasserting = shouldReconnect + self.shouldReconnect = shouldReconnect socket?.shutdown() }