Support multiple Network extension Targets in a single app

I have an iOS app with two network extension targets(tunnel1 and tunnel2) in it. Use case is explained below:-

  1. One target i.e Tunnel1 will be used for public traffic. Traffic not part of Tunnel2 will go through this tunnel
  2. Second target i.e Tunnel2 will be used for private traffic.This will be configured as per app vpn so that only those apps can have access to private resources.

MDMs can push two VPN profiles along with Provider Bundle Indentifier so that designated tunnel can start based on source app. So far this works well.

Issue:-

We have thousands of deployments already in place where VPN profiles did not contain Provider Bundle Indentifier because so far our app had just one tunnel target. Now , after upgrade to New App version(with two NE targets) , sometimes Tunnel1 starts , sometimes Tunnel2 . Its purely random and dont know logic behind it.

Question:-

Is there any way to always prefer Tunnel1 when there is no Provider Bundle Indentifier in MDM pushed VPN profile?

Answered by DTS Engineer in 798381022
Is there any way to always prefer Tunnel1 … ?

At the code level, no. If you have multiple NE providers of the same type, it’s unspecified which one starts in the absence of the provider bundle identifier setting.

Honestly, I’m a little surprised it’s seemingly random, but I can see how that might come about.

Share and Enjoy

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

Is there any way to always prefer Tunnel1 … ?

At the code level, no. If you have multiple NE providers of the same type, it’s unspecified which one starts in the absence of the provider bundle identifier setting.

Honestly, I’m a little surprised it’s seemingly random, but I can see how that might come about.

Share and Enjoy

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

Honestly, I’m a little surprised it’s seemingly random, but I can see how that might come about.

What are your expectations from iOS implementation? Can you please explain OS preference behaviour?

Further testing concluded that Tunnel2(newly created target) launch frequency is higher(7 out of 10) than Tunnel(old target). Any specific change we can make at target build settings to prefer Tunnel1 ?

Did more digging an this and looks like its dependent on order of PluginBundleIds array

Sys logs when tunnel2 is launched.

{"msg":"computing freshAuthorizationContext", "Client":"icom.testapp.testapp:", "ClientDictionary":"{\n    BundleId = \"com.testapp.testapp\";\n    BundlePath = \"\/private\/var\/containers\/Bundle\/Application\/777F64D2-D076-4B63-9AAD-A8DDA3C20A4E\/testapp.app\";\n    Executable = \"\/private\/var\/containers\/Bundle\/Application\/777F64D2-D076-4B63-9AAD-A8DDA3C20A4E\/testapp.app\/testapp\";\n    ExistsInLSDatabase = 1;\n    InUseLevel = 5;\n    PluginBundleIds =     (\n        \"com.testapp.testapp.cfcp\",\n        \"com.testapp.testapp.cfdp\",\n        \"com.testapp.testapp.tunnel2\",\n        \"com.testapp.testapp.tunnel1\"\n    );\n    SuppressShowingInSettings = 1;\n}", "BigSwitch":1, "InUseLevel":{"type":"decode failure","raw value":5,"expected type":"Generic"}}
com.apple.networkextension	default	11145	2024-08-08 14:54:18.995142 -0700	neagent	Looking for an extension with identifier com.testapp.testapp.tunnel2 and extension point com.apple.networkextension.packet-tunnel

Sys logs when tunnel1 is launched

com.apple.locationd.Core	default	75	2024-08-08 15:03:57.357930 -0700	locationd	{"msg":"computing freshAuthorizationContext", "Client":"icom.testapp.testapp:", "ClientDictionary":"{\n    BundleId = \"com.testapp.testapp\";\n    BundlePath = \"\/private\/var\/containers\/Bundle\/Application\/93129BC4-3C01-41DE-B51D-A55B2831988D\/testapp.app\";\n    Executable = \"\/private\/var\/containers\/Bundle\/Application\/93129BC4-3C01-41DE-B51D-A55B2831988D\/testapp.app\/testapp\";\n    ExistsInLSDatabase = 1;\n    InUseLevel = 5;\n    PluginBundleIds =     (\n        \"com.testapp.testapp.cfdp\",\n        \"com.testapp.testapp.cfcp\",\n        \"com.testapp.testapp.tunnel1\",\n        \"com.testapp.testapp.tunnel2\"\n    );\n    SuppressShowingInSettings = 1;\n}", "BigSwitch":1, "InUseLevel":{"type":"decode failure","raw value":5,"expected type":"Generic"}}
com.apple.networkextension	default	11145	2024-08-08 15:04:11.909990 -0700	neagent	Looking for an extension with identifier com.testapp.testapp.tunnel1 and extension point com.apple.networkextension.packet-tunnel

Question now is , how can I ensure that tunnel1 is first items in the plugins folder of my ipa file? Any recommendation from your side?

Another update:- I made sure tunnel2 is behind tunnel1 in plugins folder as they are sorted alphabetically. But still I see on certain occasion tunnel 2 is launched despite second in plugins folder.

Can you please explain OS preference behaviour?

No. This behaviour is unspecified, meaning that you get whatever you get based on various implementation details.

Share and Enjoy

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

Support multiple Network extension Targets in a single app
 
 
Q