@@ -70,8 +70,6 @@ final class CoderVPNService: NSObject, VPNService {
7070Task {
7171await loadNetworkExtensionConfig ( )
7272}
73- xpc. connect ( )
74- xpc. getPeerState ( )
7573NotificationCenter . default. addObserver (
7674self ,
7775 selector: #selector( vpnDidUpdate ( _: ) ) ,
@@ -93,8 +91,6 @@ final class CoderVPNService: NSObject, VPNService {
9391}
9492
9593await startTunnel ( )
96- xpc. connect ( )
97- xpc. ping ( )
9894 logger. debug ( " network extension enabled " )
9995}
10096
@@ -162,28 +158,47 @@ final class CoderVPNService: NSObject, VPNService {
162158}
163159
164160extension CoderVPNService {
161+ // The number of NETunnelProviderSession states makes the excessive branching
162+ // necessary.
163+ // swiftlint:disable:next cyclomatic_complexity
165164@objc private func vpnDidUpdate( _ notification: Notification ) {
166165guard let connection= notification. objectas? NETunnelProviderSession else {
167166return
168167}
169- switch connection. status{
170- case . disconnected:
168+ switch ( tunnelState, connection. status) {
169+ // Any -> Disconnected: Update UI w/ error if present
170+ case ( _, . disconnected) :
171171 connection. fetchLastDisconnectError { errin
172172self . tunnelState= if let err{
173173. failed( . internalError( err. localizedDescription) )
174174} else {
175175. disabled
176176}
177177}
178- case . connecting:
178+ // Connecting -> Connecting: no-op
179+ case ( . connecting, . connecting) :
180+ break
181+ // Connected -> Connected: no-op
182+ case ( . connected, . connected) :
183+ break
184+ // Non-connecting -> Connecting: Establish XPC
185+ case ( _, . connecting) :
186+ xpc. connect ( )
187+ xpc. ping ( )
179188 tunnelState= . connecting
180- case . connected:
189+ // Non-connected -> Connected: Retrieve Peers
190+ case ( _, . connected) :
191+ xpc. connect ( )
192+ xpc. getPeerState ( )
181193 tunnelState= . connected
182- case . reasserting:
194+ // Any -> Reasserting
195+ case ( _, . reasserting) :
183196 tunnelState= . connecting
184- case . disconnecting:
197+ // Any -> Disconnecting
198+ case ( _, . disconnecting) :
185199 tunnelState= . disconnecting
186- case . invalid:
200+ // Any -> Invalid
201+ case ( _, . invalid) :
187202 tunnelState= . failed( . networkExtensionError( . unconfigured) )
188203@unknown default :
189204 tunnelState= . disabled