New 60s timer when instantiating PacketTunnelProvider

Somewhere between iOS 16 and iOS 16.5, we've been noticing a new timer when starting up our PacketTunnelProvider.

When we start the VPN session and if we take longer than 60 seconds to call the completion handler in

(void)startTunnelWithOptions:(NSDictionary *)options completionHandler:(void (^)(NSError *))completionHandler

We see that our VPN gets shutdown by the OS.

11:19:15.371532-0700	nesessionmanager	NESMVPNSession[Primary Tunnel:test:7A492A00-109B-4DC9-970F-563A7BBC65A6:(null)]: Plugin NEVPNTunnelPlugin(com.netmotionwireless.Mobility[inactive]) initialized with Mach-O UUIDs (
    "69923795-443E-3B0D-9D51-1DC84EB26A08"
)
11:19:15.372733-0700	nesessionmanager	NESMVPNSession[Primary Tunnel:test:7A492A00-109B-4DC9-970F-563A7BBC65A6:(null)] in state NESMVPNSessionStateStarting: plugin NEVPNTunnelPlugin(com.netmotionwireless.Mobility[inactive]) started with PID 27315 error (null)
11:19:15.389348-0700	nesessionmanager	NESMVPNSession[Primary Tunnel:test:7A492A00-109B-4DC9-970F-563A7BBC65A6:(null)] in state NESMVPNSessionStateStarting: plugin NEVPNTunnelPlugin(com.netmotionwireless.Mobility[inactive]) attached IPC with endpoint 0xd5a820210
.
.
.
11:20:15.290251-0700	nesessionmanager	NESMVPNSession[Primary Tunnel:test:7A492A00-109B-4DC9-970F-563A7BBC65A6:(null)]: State timer (60 seconds) fired in state NESMVPNSessionStateStarting
11:20:15.290375-0700	nesessionmanager	NESMVPNSession[Primary Tunnel:test:7A492A00-109B-4DC9-970F-563A7BBC65A6:(null)] in state NESMVPNSessionStateStarting: timed out
11:20:15.293574-0700	nesessionmanager	NESMVPNSession[Primary Tunnel:test:7A492A00-109B-4DC9-970F-563A7BBC65A6:(null)]: Leaving state NESMVPNSessionStateStarting
11:20:15.293813-0700	nesessionmanager	NESMVPNSession[Primary Tunnel:test:7A492A00-109B-4DC9-970F-563A7BBC65A6:(null)]: Entering state NESMVPNSessionStateStopping, timeout 20 seconds
11:20:15.294034-0700	nesessionmanager	NESMVPNSession[Primary Tunnel:test:7A492A00-109B-4DC9-970F-563A7BBC65A6:(null)]: config request: pushing handler [(null)] (null)
11:20:15.294286-0700	nesessionmanager	<NESMServer: 0xd5a904120>: Request to uninstall session: NESMVPNSession[Primary Tunnel:test:7A492A00-109B-4DC9-970F-563A7BBC65A6:(null)]
11:20:15.294426-0700	nesessionmanager	NESMVPNSession[Primary Tunnel:test:7A492A00-109B-4DC9-970F-563A7BBC65A6:(null)]: status changed to disconnecting

We can see this with the log message State timer (60 seconds) fired in state NESMVPNSessionStateStarting

Is there anything we can do to influence the length of this timer or change the state the VPN is in, other than calling the completion handler?

Thanks

Somewhere between iOS 16 and iOS 16.5, we've been noticing a new timer when starting up our PacketTunnelProvider.

Right. I asked the NE team about this and they confirmed that 16.5 and later impose a new 60 second startup time limit [1].

Is there anything we can do to influence the length of this timer … ?

No.

or change the state the VPN is in, other than calling the completion handler?

No.

Can you explain more about how you’re hitting this limit? Is it because the network is super slow? Or because your VPN server is super slow? Or something else?

Share and Enjoy

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

[1] Technically this isn’t new. Rather, we always intended to have this limit but, due to a bug (r. 78812166), it was previously applied only in very obscure circumstances.

That 60 second timer is potentially a problem for our VPN app as well. The documentation for startTunnelWithOptions:completionHandler: says to call the completion handler "when the tunnel is fully established, or when the tunnel cannot be started due to an error".

But establishing the tunnel may involve asking the user for credentials, possibly multiple times (first username + password, and then optionally an OTP) which may take the user some time. (We do this by posting a user notification from the Network Extension; user is supposed to tap it, which then shows a credentials dialog in the app, and then sends a provider message to the Network Extension with the answer.) The 60 seconds can be hit if the user is slow to respond.

What's the preferred way to handle a scenario like this? Does calling the completion handler early have any negative side-effects?

I have received some customer feedback that after upgrading iOS to 16.5, the VPN will disconnect frequently and randomly. They reported that they had never encountered this problem before upgrading, and I did not find any crash records on the App Store. I suspect something to do with the iOS timer implementation.

After they upgraded to iOS 16.5.1, the problem persisted.

I also have an old app that hasn't been updated in 2 years and has always been very stable. They reported that after upgrading iOS to 16.5, it will also be automatically disconnected.

Oddly for those customers who didn't experience this issue, the VPN never disconnected automatically. For devices that encounter this problem, whether it is restarting, reinstalling, or resetting the network, it cannot be solved.

@eskimo We are also facing the same issue with our VPN solution. Moving the authentication into the App will create challenges for Per-App and On-Demand VPN connections. Kindly let us know if Apple has any solution for this ?

@buman56 , We wanted to check if you were able to find solution for this. If you could, kindly share it with us.

@eskimo : We are also facing the same issue with our VPN solution. Moving the authentication into the App will create challenges for Per-App and On-Demand VPN connections. Kindly let us know if Apple has any solution for this ?

I don’t know of any way to disable or increase this timeout.

In the specific case of user authentication, it’s clear that such a facility is necessary, and I encourage you to file a bug describing what you need to do, how it was previously working, and why it’s now failing.

Please post your bug number, just for the record.

Share and Enjoy

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

New 60s timer when instantiating PacketTunnelProvider
 
 
Q