Hi There, I am using NETunnelProviderManager to configure and start a NEPacketTunnelProvider on macOS. Most of time, it works just fine, however, under some edge cases, NEPacketTunnelProvider will not start and NEVPNConnectionStatus changes directly from NEVPNStatusConnecting to NEVPNStatusDisconnected from the NEVPNStatusDidChangeNotification I received. What is the best way to handle this edge case? It seems like normally retry the startVPNTunnelWithOptions:andReturnError: shortly after would just fix the issue somehow.
Core logic to start the NEPacketTunnelProvider:
...
[manager
loadFromPreferencesWithCompletionHandler:^(NSError *loadError) {
[self observeConnection:manager.connection];
NSError *error;
BOOL success = [manager.connection
startVPNTunnelWithOptions:options andReturnError:&error];
NSLog(@"start tunnel succeeded: %d error: %@", success, error);
}];
...
- (void)vpnConnectionDidChange:(NSNotification *)notification {
NEVPNConnection *connection =
(NEVPNConnection *)notification.object;
NSLog(@"connection.status: %ld", (long)connection.status);
}
NEPacketTunnelProvider code to verify the provider is started
@implementation MyMacPacketTunnelProvider {
- (instancetype)init {
NSLog(@"tunnel init");
...
}
- (void)startTunnelWithOptions:(NSDictionary<NSString *, id> *)options
completionHandler:(void (^)(NSError *_Nullable error))completionHandler {
NSLog(@"startTunnelWithOptions called");
Logs when hitting edge case:
start tunnel succeeded: 1, andReturnError: (null)
connection.status: 2
connection.status: 2
connection.status: 1
connection.status: 1
connection.status: 1
Logs happy path:
start tunnel succeeded: 1, andReturnError: (null)
connection.status: 2
connection.status: 2
tunnel init
startTunnelWithOptions called
connection.status: 3
connection.status: 3
In case of an exception, it feels like the VPN service is not enabled. None of the init methods in MyMacPacketTunnelProvider are called.
This problem was reported by users. I tested various possible scenarios myself, but none of them reproduced. Users also only have this problem occasionally, and cannot reproduce it stably, nor can they capture related logs.
This doesn't look like a code logic problem, is this a bug in the iOS system? Under what circumstances will this problem occur? How can I solve it?
Please get back to me with this question ASAP, my client is waiting for me to fix this, thanks.