@@ -70,8 +70,6 @@ final class CoderVPNService: NSObject, VPNService {
70
70
Task {
71
71
await loadNetworkExtensionConfig ( )
72
72
}
73
- xpc. connect ( )
74
- xpc. getPeerState ( )
75
73
NotificationCenter . default. addObserver (
76
74
self ,
77
75
selector: #selector( vpnDidUpdate ( _: ) ) ,
@@ -93,8 +91,6 @@ final class CoderVPNService: NSObject, VPNService {
93
91
}
94
92
95
93
await startTunnel ( )
96
- xpc. connect ( )
97
- xpc. ping ( )
98
94
logger. debug ( " network extension enabled " )
99
95
}
100
96
@@ -162,6 +158,7 @@ final class CoderVPNService: NSObject, VPNService {
162
158
}
163
159
164
160
extension CoderVPNService {
161
+ // swiftlint:disable:next cyclomatic_complexity
165
162
@objc private func vpnDidUpdate( _ notification: Notification ) {
166
163
guard let connection = notification. object as? NETunnelProviderSession else {
167
164
return
@@ -176,9 +173,21 @@ extension CoderVPNService {
176
173
}
177
174
}
178
175
case . connecting:
179
- tunnelState = . connecting
176
+ // If transitioning to 'connecting' from any other state,
177
+ // then the network extension is running, and we can connect over XPC
178
+ if tunnelState != . connecting {
179
+ xpc. connect ( )
180
+ xpc. ping ( )
181
+ tunnelState = . connecting
182
+ }
180
183
case . connected:
181
- tunnelState = . connected
184
+ // If transitioning to 'connected' from any other state, the tunnel has
185
+ // finished starting, and we can learn the peer state
186
+ if tunnelState != . connected {
187
+ xpc. connect ( )
188
+ xpc. getPeerState ( )
189
+ tunnelState = . connected
190
+ }
182
191
case . reasserting:
183
192
tunnelState = . connecting
184
193
case . disconnecting:
0 commit comments