Skip to content

Commit 207da24

Browse files
committed
force review
1 parent deb773a commit 207da24

File tree

5 files changed

+41
-48
lines changed

5 files changed

+41
-48
lines changed

Coder Desktop/Coder Desktop/Coder_DesktopApp.swift

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,8 +49,7 @@ class AppDelegate: NSObject, NSApplicationDelegate {
4949

5050
func applicationShouldTerminate(_: NSApplication) -> NSApplication.TerminateReply {
5151
Task {
52-
await vpn.stop()
53-
NSApp.reply(toApplicationShouldTerminate: true)
52+
await vpn.quit()
5453
}
5554
return .terminateLater
5655
}

Coder Desktop/Coder Desktop/VPNService.swift

Lines changed: 29 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -45,8 +45,8 @@ enum VPNServiceError: Error, Equatable {
4545
@MainActor
4646
final class CoderVPNService: NSObject, VPNService {
4747
var logger = Logger(subsystem: Bundle.main.bundleIdentifier!, category: "vpn")
48-
// TODO: better init maybe? kinda wonky
49-
lazy var xpc = VPNXPCInterface(vpn: self)
48+
lazy var xpc: VPNXPCInterface = .init(vpn: self)
49+
var terminating = false
5050

5151
@Published var tunnelState: VPNServiceState = .disabled
5252
@Published var sysExtnState: SystemExtensionState = .uninstalled
@@ -76,44 +76,39 @@ final class CoderVPNService: NSObject, VPNService {
7676
}
7777
}
7878

79-
var startTask: Task<Void, Never>?
8079
func start() async {
81-
if await startTask?.value != nil {
82-
return
83-
}
80+
guard tunnelState == .disabled else { return }
8481
// this ping is somewhat load bearing since it causes xpc to init
8582
xpc.ping()
86-
startTask = Task {
87-
tunnelState = .connecting
88-
await enableNetworkExtension()
89-
logger.debug("network extension enabled")
90-
}
91-
defer { startTask = nil }
92-
await startTask?.value
83+
tunnelState = .connecting
84+
await enableNetworkExtension()
85+
logger.debug("network extension enabled")
9386
}
9487

95-
var stopTask: Task<Void, Never>?
9688
func stop() async {
97-
// Wait for a start operation to finish first
98-
await startTask?.value
99-
guard state == .connected else { return }
100-
if await stopTask?.value != nil {
89+
guard tunnelState == .connected else { return }
90+
tunnelState = .disconnecting
91+
await disableNetworkExtension()
92+
logger.info("network extension stopped")
93+
}
94+
95+
// Instructs the service to stop the VPN and then quit once the stop event
96+
// is read over XPC.
97+
// MUST only be called from `NSApplicationDelegate.applicationShouldTerminate`
98+
// MUST eventually call `NSApp.reply(toApplicationShouldTerminate: true)`
99+
func quit() async {
100+
guard tunnelState == .connected else {
101+
NSApp.reply(toApplicationShouldTerminate: true)
101102
return
102103
}
103-
stopTask = Task {
104-
tunnelState = .disconnecting
105-
await disableNetworkExtension()
106-
logger.info("network extension stopped")
107-
tunnelState = .disabled
108-
}
109-
defer { stopTask = nil }
110-
await stopTask?.value
104+
terminating = true
105+
await stop()
111106
}
112107

113108
func configureTunnelProviderProtocol(proto: NETunnelProviderProtocol?) {
114109
Task {
115-
if proto != nil {
116-
await configureNetworkExtension(proto: proto!)
110+
if let proto {
111+
await configureNetworkExtension(proto: proto)
117112
// this just configures the VPN, it doesn't enable it
118113
tunnelState = .disabled
119114
} else {
@@ -122,7 +117,7 @@ final class CoderVPNService: NSObject, VPNService {
122117
neState = .unconfigured
123118
tunnelState = .disabled
124119
} catch {
125-
logger.error("failed to remoing network extension: \(error)")
120+
logger.error("failed to remove network extension: \(error)")
126121
neState = .failed(error.localizedDescription)
127122
}
128123
}
@@ -148,9 +143,13 @@ final class CoderVPNService: NSObject, VPNService {
148143
func onExtensionStop() {
149144
logger.info("network extension reported stopped")
150145
tunnelState = .disabled
146+
if terminating {
147+
NSApp.reply(toApplicationShouldTerminate: true)
148+
}
151149
}
152150

153151
func onExtensionError(_ error: NSError) {
154-
logger.info("network extension reported error: \(error)")
152+
logger.error("network extension reported error: \(error)")
153+
tunnelState = .failed(.internalError(error.localizedDescription))
155154
}
156155
}

Coder Desktop/Coder Desktop/XPCInterface.swift

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -23,29 +23,23 @@ import VPNXPC
2323
super.init()
2424

2525
xpcConn.exportedObject = self
26-
xpcConn.invalidationHandler = { [weak self] in
27-
guard let self else { return }
26+
xpcConn.invalidationHandler = { [logger] in
2827
Task { @MainActor in
29-
self.logger.error("XPC connection invalidated.")
28+
logger.error("XPC connection invalidated.")
3029
}
3130
}
32-
xpcConn.interruptionHandler = { [weak self] in
33-
guard let self else { return }
31+
xpcConn.interruptionHandler = { [logger] in
3432
Task { @MainActor in
35-
self.logger.error("XPC connection interrupted.")
33+
logger.error("XPC connection interrupted.")
3634
}
3735
}
3836
xpcConn.resume()
39-
40-
xpc.ping {
41-
print("Got response from XPC")
42-
}
4337
}
4438

4539
func ping() {
4640
xpc.ping {
4741
Task { @MainActor in
48-
print("Got response from XPC")
42+
self.logger.info("Connected to NE over XPC")
4943
}
5044
}
5145
}

Coder Desktop/VPN/PacketTunnelProvider.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -84,15 +84,15 @@ class PacketTunnelProvider: NEPacketTunnelProvider, @unchecked Sendable {
8484
if let conn = globalXPCListenerDelegate.getActiveConnection() {
8585
conn.onStart()
8686
} else {
87-
logger.info("no active connection")
87+
logger.info("no active XPC connection")
8888
}
8989
completionHandler(nil)
9090
} catch {
9191
logger.error("error starting manager: \(error.description, privacy: .public)")
9292
if let conn = globalXPCListenerDelegate.getActiveConnection() {
9393
conn.onError(error as NSError)
9494
} else {
95-
logger.info("no active connection")
95+
logger.info("no active XPC connection")
9696
}
9797
completionHandler(error as NSError)
9898
}
@@ -119,7 +119,7 @@ class PacketTunnelProvider: NEPacketTunnelProvider, @unchecked Sendable {
119119
if let conn = globalXPCListenerDelegate.getActiveConnection() {
120120
conn.onStop()
121121
} else {
122-
logger.info("no active connection")
122+
logger.info("no active XPC connection")
123123
}
124124
globalXPCListenerDelegate.vpnXPCInterface.setManager(nil)
125125
completionHandler()

Coder Desktop/VPN/XPCInterface.swift

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,14 +10,15 @@ import VPNXPC
1010

1111
func setManager(_ newManager: Manager?) {
1212
managerLock.lock()
13+
defer { managerLock.unlock() }
1314
manager = newManager
14-
managerLock.unlock()
1515
}
1616

1717
func getManager() -> Manager? {
1818
managerLock.lock()
19+
defer { managerLock.unlock() }
1920
let m = manager
20-
managerLock.unlock()
21+
2122
return m
2223
}
2324

0 commit comments

Comments
 (0)