From db11801b7ab93cbe1fb3eb94d192857ce7b47929 Mon Sep 17 00:00:00 2001
From: Ethan Dickson <ethan@coder.com>
Date: Fri, 21 Feb 2025 12:23:06 +1100
Subject: [PATCH 1/3] fix: improve wake & sleep handling

---
 Coder Desktop/VPN/PacketTunnelProvider.swift | 17 +++++++++++------
 1 file changed, 11 insertions(+), 6 deletions(-)

diff --git a/Coder Desktop/VPN/PacketTunnelProvider.swift b/Coder Desktop/VPN/PacketTunnelProvider.swift
index 190bb870..80ac7dd5 100644
--- a/Coder Desktop/VPN/PacketTunnelProvider.swift	
+++ b/Coder Desktop/VPN/PacketTunnelProvider.swift	
@@ -48,16 +48,16 @@ class PacketTunnelProvider: NEPacketTunnelProvider, @unchecked Sendable {
         options _: [String: NSObject]?, completionHandler: @escaping (Error?) -> Void
     ) {
         logger.info("startTunnel called")
+        guard manager == nil else {
+            logger.error("startTunnel called with non-nil Manager")
+            completionHandler(nil)
+            return
+        }
         start(completionHandler)
     }
 
     // called by `startTunnel` and on `wake`
     func start(_ completionHandler: @escaping (Error?) -> Void) {
-        guard manager == nil else {
-            logger.error("startTunnel called with non-nil Manager")
-            completionHandler(makeNSError(suffix: "PTP", desc: "Already running"))
-            return
-        }
         guard let proto = protocolConfiguration as? NETunnelProviderProtocol,
               let baseAccessURL = proto.serverAddress
         else {
@@ -123,9 +123,9 @@ class PacketTunnelProvider: NEPacketTunnelProvider, @unchecked Sendable {
                 logger.error("error stopping manager: \(error.description, privacy: .public)")
             }
             globalXPCListenerDelegate.vpnXPCInterface.manager = nil
+            self.manager = nil
             completionHandler()
         }
-        self.manager = nil
     }
 
     override func handleAppMessage(_ messageData: Data, completionHandler: ((Data?) -> Void)?) {
@@ -142,6 +142,11 @@ class PacketTunnelProvider: NEPacketTunnelProvider, @unchecked Sendable {
     }
 
     override func wake() {
+        guard !reasserting else { return }
+        guard manager == nil else {
+            logger.error("wake called with non-nil Manager")
+            return
+        }
         logger.debug("wake called")
         reasserting = true
         currentSettings = .init(tunnelRemoteAddress: "127.0.0.1")

From 4d65979c18da3babaacc76fcefabefc6e6a99649 Mon Sep 17 00:00:00 2001
From: Ethan Dickson <ethan@coder.com>
Date: Mon, 24 Feb 2025 14:04:29 +1100
Subject: [PATCH 2/3] comments

---
 Coder Desktop/VPN/PacketTunnelProvider.swift | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/Coder Desktop/VPN/PacketTunnelProvider.swift b/Coder Desktop/VPN/PacketTunnelProvider.swift
index 80ac7dd5..f0f538b3 100644
--- a/Coder Desktop/VPN/PacketTunnelProvider.swift	
+++ b/Coder Desktop/VPN/PacketTunnelProvider.swift	
@@ -50,6 +50,7 @@ class PacketTunnelProvider: NEPacketTunnelProvider, @unchecked Sendable {
         logger.info("startTunnel called")
         guard manager == nil else {
             logger.error("startTunnel called with non-nil Manager")
+            // If the tunnel is already running, then we can just mark as connected.
             completionHandler(nil)
             return
         }
@@ -123,6 +124,8 @@ class PacketTunnelProvider: NEPacketTunnelProvider, @unchecked Sendable {
                 logger.error("error stopping manager: \(error.description, privacy: .public)")
             }
             globalXPCListenerDelegate.vpnXPCInterface.manager = nil
+            // Mark teardown as complete by setting manager to nil, and 
+            // calling the completion handler.
             self.manager = nil
             completionHandler()
         }
@@ -142,6 +145,8 @@ class PacketTunnelProvider: NEPacketTunnelProvider, @unchecked Sendable {
     }
 
     override func wake() {
+        // It's possible the tunnel is still starting up, if it is, wake should
+        // be a no-op.
         guard !reasserting else { return }
         guard manager == nil else {
             logger.error("wake called with non-nil Manager")

From 28487b86f4c0e17efc3176f92b78af92dd1e74dd Mon Sep 17 00:00:00 2001
From: Ethan Dickson <ethan@coder.com>
Date: Mon, 24 Feb 2025 14:11:26 +1100
Subject: [PATCH 3/3] fmt

---
 Coder Desktop/VPN/PacketTunnelProvider.swift | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/Coder Desktop/VPN/PacketTunnelProvider.swift b/Coder Desktop/VPN/PacketTunnelProvider.swift
index f0f538b3..a5bfb15c 100644
--- a/Coder Desktop/VPN/PacketTunnelProvider.swift	
+++ b/Coder Desktop/VPN/PacketTunnelProvider.swift	
@@ -124,7 +124,7 @@ class PacketTunnelProvider: NEPacketTunnelProvider, @unchecked Sendable {
                 logger.error("error stopping manager: \(error.description, privacy: .public)")
             }
             globalXPCListenerDelegate.vpnXPCInterface.manager = nil
-            // Mark teardown as complete by setting manager to nil, and 
+            // Mark teardown as complete by setting manager to nil, and
             // calling the completion handler.
             self.manager = nil
             completionHandler()