iOS 9.3 to iOS 10.0 NetworkExtension Not Sending Packets

Hello,


I currently have an application that works on my iPad Mini 2 running iOS 9.3. It is a VPN application utilizing the Network Extension framework to make use of a "custom" protocol (That currently doesn't change the packets at all). Right now it takes the packets from the packetflow, and writes them to my VPN server, then reads the return packets from the VPN server, then writes those return packets back to the packetflow. That is all working correctly on the iPad. When I switched to my main device, an iPhone 7 running iOS 10.0, the initial handshake packets aren't even sent to the VPN server to establish the connection in the first place.


This works fine on the iPad Mini, but doesn't send on the iPhone. I looked at the changelog from iOS version 9.3 to 10.0, and didn't see anything that would directly impact this. I am not seeing any related errors or crashes in the device logs, and can determine that it isn't sending by using tcpdump and debug outputting received packets on the VPN server. I also tried changing the iOS deployment target in the Build Settings, and didn't make a difference either way.

Any thoughts?


Any feedback is greatly appreciated, thank you very much in advance!


EDIT:

(Got rid of some of the above post)

Did debugging and found that I was getting this error while saving. I fixed it by referring to this post: (Eskimo's answer of saving twice)

`Error Domain=NEVPNErrorDomain Code=1 "(null)"`

https://forums.developer.apple.com/thread/25928

The configuration is now saving and loading correctly.

Since I added a bunch of debug outputs to the log, I noticed that doing:

NETunnelProviderSession *session = (NETunnelProviderSession*) manager.connection;
[session startVPNTunnelWithOptions:options andReturnError: &err];

Does not actually invoke the method startTunnelWithOptions in the PacketTunnelProvider class. My 'err' variable returns null(no errors). The code above isn't even being called because of that reason. Any thoughts on why the startVPNTunnelWithOptions isn't working on the iPhone in iOS 10.0 but is working on the iPad Mini in iOS 9.3?

Thanks!

Accepted Reply

Sorry I didn’t notice this thread earlier.

Make sure you sleep in that loop.

That’s better, but it’s still not good. The expected way to monitor the state of an NWUDPSession is to add a KVO observer on the

state
property. Your observer will then fire as the state changes. This is much better than polling the state.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

Replies

Figured it out! UDP Session wasn't ready and I was attempting to send the packet before everything was done. I added a simple:


while (udpSession.state != NWUDPSessionStateReady){
        // Wait for connection to be ready.
}


Before trying to send my initialization handshake packet. Hope this helps someone else in need!

Make sure you sleep in that loop.


while (udpSession.state != NWUDPSessionStateReady)
   sleep(0.1);

Sorry I didn’t notice this thread earlier.

Make sure you sleep in that loop.

That’s better, but it’s still not good. The expected way to monitor the state of an NWUDPSession is to add a KVO observer on the

state
property. Your observer will then fire as the state changes. This is much better than polling the state.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"