Recently, we've started seeing NSURLSession requested by the NEPacketTunnelProvider itself failing on iOS 16.2. Specifically, we're seeing this error:
Error Domain=NSURLErrorDomain Code=-1009 "The Internet connection appears to be offline." UserInfo={_kCFStreamErrorCodeKey=50, NSUnderlyingError=0x10b944130 {Error Domain=kCFErrorDomainCFNetwork Code=-1009 "(null)" UserInfo={_NSURLErrorNWPathKey=unsatisfied (No network route), interface: utun29, scoped, _kCFStreamErrorCodeKey=50, _kCFStreamErrorDomainKey=1}}, _NSURLErrorFailingURLSessionTaskErrorKey=LocalDataTask <7D0450F9-2229-459E-9A6E-DFD5C0D7D325>.<1>, _NSURLErrorRelatedURLSessionTaskErrorKey=(
"LocalDataTask <7D0450F9-2229-459E-9A6E-DFD5C0D7D325>.<1>"
), NSLocalizedDescription=The Internet connection appears to be offline., NSErrorFailingURLStringKey=https:/..., NSErrorFailingURLKey=https:/..., _kCFStreamErrorDomainKey=1}
When we analyzed this, we can see the NE's NSURLSession actually "loopback" thru the NE (e.g. we see the SYN and subsequent ClientHello packets come in right after issuing the NSURLSession for the destination IP), which appears to be a change in behavior since:
We were not seeing this on previous iOS versions (e.g. iOS 15)
This "loopback" is supposed to only occur when using createXyzThroughTunnelToEndpoint methods: https://developer.apple.com/forums/thread/94430?answerId=286978022#286978022
We're even seeing DNS queries (e.g. from these NSURLSessions) loopback into the NE.
This wouldn't be a problem except that these NE's NSURLSessions are now failing on iOS 16. We see two different behaviors for these failed NSURLSessions:
NE receives the SYN/ClientHello packets and sends them thru to the server, but the NSURLSession fails after a few secs with Code=-1009.
NE doesn't receive any packets from its NSURLSession, which fails immediately with Code=-1009.
Could there be something we're doing that can cause the "loopback" of our NE's NSURLSessions?
If not, has anyone else reported a similar issue with iOS 16?
Post
Replies
Boosts
Views
Activity
Hi - We have had a packettunnel working well on iOS for a long time and now looking into one for Mac OS. However, we haven't been able to get it to work.Summary of what we see:The app can successfully install the VPN profile:nesessionmanager 11:06:26.027252-0700 NESMVPNSession[Primary Tunnel:XyzCatalyst:E2A089D5-A18B-4543-94F5-827E4DB3357D
:(null)]: handling configuration changed: {
name = XyzlizeCatalyst
identifier = E2A089D5-A18B-4543-94F5-827E4DB3357D
applicationName = XyzCatalyst
application = com.xyz.mac.vpn
grade = 1
VPN = {
enabled = YES
onDemandEnabled = NO
disconnectOnDemandEnabled = NO
protocol = {
type = plugin
identifier = 0A3DA48C-EE69-479C-A2CD-994028B01CC0
serverAddress = 127.0.0.1
identityDataImported = NO
disconnectOnSleep = NO
disconnectOnIdle = NO
disconnectOnIdleTimeout = 0
disconnectOnWake = NO
disconnectOnWakeTimeout = 0
disconnectOnUserSwitch = NO
disconnectOnLogout = NO
includeAllNetworks = NO
excludeLocalNetworks = NO
pluginType = com.xyz.mac.vpn
authenticationMethod = 0
reassertTimeout = 0
providerBundleIdentifier = com.xyz.mac.vpn.PacketTunnelProvider
designatedRequirement = identifier "com.xyz.mac.vpn.PacketTunnelProvider" and anchor apple generic and
certificate leaf[subject.CN] = "Apple Development: xyz (XYZ)"
and certificate 1[field.1.2.840.113635.100.6.2.1] /* exists */
}
tunnelType = packet
}
}But when trying to start the PT, the appex is never found:nesessionmanager 11:06:26.025938-0700 Found 0 (0 active) registrations for com.xyz.mac.vpn.PacketTunnelProvider
(com.apple.networkextension.packet-tunnel)Things we've tried w/o any success starting the PT:Created a new target for the PT specifically for macOS, per this discussion: https://forums.developer.apple.com/thread/126355Tried an empty PT (instead of our existing iOS PT)Created a new app target specifically for macOS (instead of Catalyst)Installed manually using pluginkit from command lineThe entitlements appear correct:App:<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>com.apple.application-identifier</key>
<string>XYZ.com.xyz.mac.vpn</string>
<key>com.apple.developer.networking.networkextension</key>
<array>
<string>packet-tunnel-provider</string>
</array>
<key>com.apple.developer.team-identifier</key>
<string>XYZ</string>
<key>com.apple.security.app-sandbox</key>
<true/>
<key>com.apple.security.get-task-allow</key>
<true/>
<key>com.apple.security.network.client</key>
<true/>
<key>com.apple.security.network.server</key>
<true/>
</dict>
</plist>PT:<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>com.apple.application-identifier</key>
<string>XYZ.com.xyz.mac.vpn.PacketTunnelProvider</string>
<key>com.apple.developer.networking.networkextension</key>
<array>
<string>packet-tunnel-provider</string>
</array>
<key>com.apple.developer.team-identifier</key>
<string>XYZ</string>
<key>com.apple.security.app-sandbox</key>
<true/>
<key>com.apple.security.network.client</key>
<true/>
<key>com.apple.security.network.server</key>
<true/>
<key>keychain-access-groups</key>
<array>
<string>XYZ.group.xyz</string>
</array>
</dict>
</plist>We also confirmed that the PT is registered:pluginkit -mDv |grep Packet
com.xyz.mac.vpn.PacketTunnelProvider(1.0) BE156DB2-1A2D-4AB2-8CD9-6E7E22D2B807 2020-05-28 03:20:10 +0000
/Users/xyz/Documents/xyz/xyz/iOS/DerivedData/xyz/Build/Products/Debug-maccatalyst/XyzCatalyst.app/Contents
/PlugIns/PacketTunnelMac.appexIs there something we're doing wrong? I can provide the full console output if that would help.
We are trying to reduce the memory footprint of our PacketTunnelProvider so we're using Instruments. The soonest point that we can attach Instruments is in startTunnel, since that's where we can put in a delay to give a developer sufficient time to attach Instruments to the PT process.However, the memory footprint of our PT is already many MBs in size at that point. We've tried to use the Xcode memory graph but it's extremely difficult to use this approach since there are 1000s of objects created already and no way to associate them to a call tree.Is there a way to attach Instruments near the initial launch of the PT process, ideally where its memory usage is as close to 0 as possible?