Packet Tunnel Provider - life cycle / memory

I have some questions regarding life cycle of Packet Tunnel Provider: I have some static vars at the PacketTunnelProvider. The user connected to the VPN, then disconnected, so I called the relevant compilation handler. After some time, the user will start VPN again, PacketTunnelProvider will be recreated.

  1. Will it use the same class as before, and all static vars will hold their last value? Or would it create a new PacketTunnelProvider?
  2. Is it the same behavior for Network Extension vs System Extension?
  3. Is it the same behavior for macOS vs iOS?
  4. What about running threads? If I created a thread, and then I called the completion handler, will this thread continue to run?

P.S If I'm adding exit(0) before 'quitting' the Packet Tunnel Provider, it will force cleaning the memory. But I guess it's not a good behavior for a System Extension to use exit(0)

class PacketTunnelProvider: NEPacketTunnelProvider {
static var isInitiated = false
...
}

override func startTunnel(options: [String : NSObject]?, completionHandler: @escaping (Error?) -> Void) {
...
PacketTunnelProvider.isInitiated = true
...

Will it use the same class as before, and all static vars will hold their last value? Or would it create a new PacketTunnelProvider? Is it the same behavior for Network Extension vs System Extension? Is it the same behavior for macOS vs iOS?

If the extension is still loaded into memory, and there is an instance of NEPacketTunnelProvider hanging around, yes the static var will still hold their values. That is of course if a new instance of the provider is not created and the existing instance is started with something like on-demand rules etc...

I cannot speak to any differences between Network Extensions and System Extensions, or iOS vs macOS here, but if the extension is in memory then any state that is set on the provider would still be preserved until that extension is disposed. Also take note of the main file for a System Extension:

import NetworkExtension

/// The main entry point for the system extension.
func main() -> Never {
    autoreleasepool {
        NEProvider.startSystemExtensionMode()
    }
    dispatchMain()
}

main()

This at least keeps the System Extension infrastructure held in-memory so if your provider has not crashed or a new instance has not been created the previous state should be help in memory too.

Matt Eaton
DTS Engineering, CoreOS
meaton3@apple.com

Thanks @meaton!

Regarding

so if your provider has not crashed or a new instance has not been created the previous state should be help in memory too

If the user presses the 'connect' button, startTunnelWithOptions is called, then user disconnects, completion handler is called from the provider, and after a few minutes, the user reconnects again. I saw that it's still using the same provider, and not creating a new instance. Is this expected? Will it behave differently if the new connection will be started via on-demand rules (and not manually by the user)?

If the user presses the 'connect' button, startTunnelWithOptions is called, then user disconnects, completion handler is called from the provider, and after a few minutes, the user reconnects again. I saw that it's still using the same provider, and not creating a new instance. Is this expected?

Yes, this is what I would have expected because your provider instance is still held in memory. However, if your On-Demand rules start the tunnel again your virtual interface configuration will be recreated.

Regarding:

Will it behave differently if the new connection will be started via on-demand rules (and not manually by the user)?

No. You should be able to verify this by the logs too. In the console look for the nesessionmanager finding an active registration for your existing Network System Extension:

Default     0x0       347    0    nesessionmanager: [com.apple.networkextension:] Found 1 (1 active) registrations for com.your.app.packettunnel (com.apple.networkextension.packet-tunnel)
Matt Eaton
DTS Engineering, CoreOS
meaton3@apple.com
Packet Tunnel Provider - life cycle / memory
 
 
Q