Packet Tunnel Provider - write packets to flow

I've implemented a vpn app with PacketTunnelProvider.

When doing a speed test, I can see that the VPN is decreasing the download speed by a large number.

I have a suspect that might cause this, but I'm not sure -


When I want to write packets to the tunnel, I get the packets as an UnsafeMutablePointer<CChar>

then I convert it to NSData:

let data = NSData(bytes: buffer, length: Int(length))

and then I send it to the packetFlow

packetFlow.writePackets([data!], withProtocols: [NSNumber(int: AF_INET)])


Am I right to suspect this might cause the slowness?

I'm sending each packet the moment I get it, so most of the time the array contains only 1 object. Is it ok?

Accepted Reply

Am I right to suspect this might cause the slowness?

I doubt it. While it’s true that creating an NSData from a buffer in the way you’ve shown will make a copy of the bytes in the buffer, I very much doubt that’s the biggest factor in your performance problem. It’s more likely to be related to the number of times that the data is bouncing in and out of the kernel, which is kinda unavoidable in the Network Extension provider model.

Investigating performance issues like this is not easy. I recommend you start by creating a rigorous performance metric. For example, you could create an app that sends data to a server on the local Wi-Fi, or vice versa. You’ll want to use UDP, not TCP, so you can focus on how packets flow through your VPN. You can then vary the frequency and size of these packets to see how the performance varies based on those factors. Based on that info you can start to optimise.

I suspect you’ll find that the size of the packets doesn’t really affect performance, which is evidence for my theory that these data copies aren’t the issue. However, that’s really just a guess, and I encourage you to not guess and instead actually test.

Share and Enjoy

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

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

Replies

Am I right to suspect this might cause the slowness?

I doubt it. While it’s true that creating an NSData from a buffer in the way you’ve shown will make a copy of the bytes in the buffer, I very much doubt that’s the biggest factor in your performance problem. It’s more likely to be related to the number of times that the data is bouncing in and out of the kernel, which is kinda unavoidable in the Network Extension provider model.

Investigating performance issues like this is not easy. I recommend you start by creating a rigorous performance metric. For example, you could create an app that sends data to a server on the local Wi-Fi, or vice versa. You’ll want to use UDP, not TCP, so you can focus on how packets flow through your VPN. You can then vary the frequency and size of these packets to see how the performance varies based on those factors. Based on that info you can start to optimise.

I suspect you’ll find that the size of the packets doesn’t really affect performance, which is evidence for my theory that these data copies aren’t the issue. However, that’s really just a guess, and I encourage you to not guess and instead actually test.

Share and Enjoy

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

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

Will do, thanks for the advice