NEPacketTunnelProvider Cannot Be Started

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

IMO the best way to tackle this is to investigate why your packet tunnel provider didn’t start in the first place. That’s because working around it in the container app only helps if the user starts the tunnel from the container app. A lot of users start the tunnel from other places — Settings, or using VPN On Demand — and those don’t benefit from any retry logic you add to your container app.

So why is your packet tunnel provider failing to start?

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

Ok, I found some useful information from system logs:

default	10:21:37.723793-0700	nesessionmanager	NESMVPNSession[Primary Tunnel:VPN:F7D46517-00D5-48AB-A688-36E945AADA94:(null)]: Received a start command from VPN
default	10:21:37.724400-0700	nesessionmanager	<NESMServer: 0x122e0afb0>: Register Enterprise VPN Session: NESMVPNSession[Primary Tunnel:VPN:F7D46517-00D5-48AB-A688-36E945AADA94:(null)]
error	10:21:37.723536-0700	analyticsd	[XPC Server] managed connection recieved connection invalidated: Connection invalid
default	10:21:37.727338-0700	nesessionmanager	NEVPNTunnelPlugin(com.google.one.dev[inactive]): Sending start command
default	10:21:37.727468-0700	nesessionmanager	com.myvpn.dev[inactive]: starting
error	10:21:37.728363-0700	nesessionmanager	com.myvpn.dev[1300]: Tearing down XPC connection due to setup error: Error Domain=NEAgentErrorDomain Code=2 "(null)"
default	10:21:37.731436-0700	nesessionmanager	NESMVPNSession[Primary Tunnel:VPN:F7D46517-00D5-48AB-A688-36E945AADA94:(null)] in state NESMVPNSessionStateStarting: plugin NEVPNTunnelPlugin(com.myvpn.dev[inactive]) started with PID 0 error Error Domain=NEAgentErrorDomain Code=2 "(null)"
error	10:21:37.728040-0700	neagent	NEAgentSession: failed to create the delegate
default	10:21:37.728519-0700	nesessionmanager	com.myvpn.dev[1300]: XPC connection went away

Not sure if I understand it, but it seems the packet tunnel provider is not started because of a XPC error?

it seems the packet tunnel provider is not started because of a XPC error?

I think you have that backwards, that is, the XPC connection went away because the process running your provider terminated. Do you see a crash report generated in this case?

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

The only crashes I saw are all looking like this one and it seems like you are right, the process is killed by the system:

OS Version:          macOS 12.6 (21G115)
Release Type:        User
Report Version:      104

Exception Type:  EXC_CRASH (SIGKILL (Code Signature Invalid))
Exception Codes: 0x0000000000000000, 0x0000000000000000
Exception Note:  EXC_CORPSE_NOTIFY
Termination Reason: SIGNAL 15 Terminated: 15
Terminating Process: launchd [1]

Highlighted by Thread:  0

Backtrace not available

No thread state (register information) available

Binary Images:
Binary images description not available

Error Formulating Crash Report:
_dyld_process_info_create failed with 6
dyld_process_snapshot_get_shared_cache failed
Failed to create CSSymbolicatorRef - corpse still valid ¯\_(ツ)_/¯
thread_get_state(PAGEIN) returned 0x10000003: (ipc/send) invalid destination port
thread_get_state(EXCEPTION) returned 0x10000003: (ipc/send) invalid destination port
thread_get_state(FLAVOR) returned 0x10000003: (ipc/send) invalid destination port

However, this Code Signature Invalid doesn't make sense to me because I really didn't need to do anything but simply just re-enable the VPN to connect with no issue. Since I am not even re-compiling the project, how would code signature change for the second run?

Is your provider packages as a sysex or an appex?

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

It is a system network extension on macOS.

It is a system network extension on macOS.

OK. Have you enable sysex developer mode? Or are you running from /Applications?

If it’s the latter, how do you copy it there?

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

I tried both way:

  1. Disable SIP, enable developer mode and launch directly.
  2. Archive the project, move the DMG to the applications and launch from there.

I can reproduce it using either of them.

Hmmm. I don’t really have an answer for you here. I have a whole treatise on how to debug Code Signature Invalid problems — if you’re curious, see Resolving Trusted Execution Problems — but none of these match the symptoms you’re seeing. This sort of weird intermittent failure is most commonly the result of the problems described Updating Mac Software but the processes you’ve outlined don’t match that well either.

To investigate this further I’d need to dig much deeper into the system log, which isn’t something I can do in the time that I have available for DevForums. If you want to do this yourself, there are plenty of cues about what to look for in the examples in Resolving Trusted Execution Problems. Also, make sure to configure you system to record private data, per the advice in Your Friend the System Log. Actually, that post describes other stuff that’ll be useful, like using log collect to snapshot the log immediately after seeing the problem and then doing offline analysis.

If you want help with this, open a DTS tech support incident and we can pick it up in a formal context.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

I also encountered the same problem, do you finally have a solution to this problem? Or have you found what is causing this?

NEPacketTunnelProvider Cannot Be Started
 
 
Q