DispatchQueue behavior on sleep() in Packet Tunnel extension

Hi,


after several user reports started with iOS 13, I found the root cause of an issue with my VPN app.


Context:


- My networking code runs in a custom DispatchQueue with QoS .utility, as per a suggestion by eskimo in another thread.

- The NEVPNProtocol.disconnectOnSleep flag is set to false.

- I do not override the sleep/wake handlers in NEPackeTunnelProvider.


Until iOS 12, the VPN would keep working across the sleep/wake cycles, with the socket handlers surviving the sleep state. This doesn't seem to be the case in iOS 13, so I dug further.


By overriding sleep() and wake() in the provider, for logging purposes, I noticed that after a "longer" sleep, DispatchQueue.async() blocks hang up. They literally stop running, to then revive immediately after waking up the device. The effect is that the VPN doesn't disconnect on the sleep event, but triggers a ping timeout as soon as the device is turned on again. Due to inactivity.


I can't find a way to restore former "Keep alive on sleep" behavior, because even if the VPN is not actively disconnected on sleep, it still stops working. I mean, does Apple want us to kill the VPN on sleep? Is it an option or a requirement? It's not 100% clear to me from the documentation:


https://developer.apple.com/documentation/networkextension/neprovider/1406731-sleep


> NEProvider subclasses should override this method if the provider needs to perform any tasks before the device sleeps, such as disconnecting a tunnel connection.


Had this been a requirement, it would IMHO be in contradiction with the existence of "disconnectOnSleep". At this point I even wonder if former behavior (iOS 12) was the side-effect of a bug (= queue surviving sleep), eventually fixed in iOS 13.


I'd like to know more about this, before looking for a fix in an app that TBH had performed very well until iOS 13.


Thanks,

Davide

DispatchQueue behavior on sleep() in Packet Tunnel extension
 
 
Q