VPN routes not applied to the netork extension.

Hi,

We are building a VPN application with a packet tunnel network extension. The NE (network extension) provides the VPN itself (obviously) alongside some VPN related functionalities. The VPN does not intends to capture all the network, instead it just give access to one or several remote network (aka we are only routing some subnet to the NE).

The issue is that for some functionalities, we would need the NE to create network connection that might need to be routed through the tunnel. The issue is that the routes that we declared with the NE are not applied to the network traffic emanating from the NE itself.

I do understand that this is a requirement to avoid VPN loop, moreover with VPN that capture all the traffic. But in our case we know we will avoid collision since we only route some networks.

What solution do we have ? Is there an option somewhere to for the application of all route to the NE ?

Answered by DTS Engineer in 808798022
We thought about binding the socket to the tun interface

Right. With BSD Sockets that’s the path forward.

Note that you don’t have to use bind for this. Rather, use the IP_BOUND_IF (IPv4) or IPV6_BOUND_IF (IPv6) socket options.

Of could, you still have to know what interface to bind to. Nowadays that’s pretty straightforward. Fetch the virtualInterface property and get its index property [1].

On older systems things are significantly less convenient. The best option I’ve seen is to get the interface list (getifaddrs) and look for the interface that has the same address setup that you configured on your tunnel.

Share and Enjoy

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

[1] In C, the virtualInterface property is of type nw_interface_t, and you call the nw_interface_get_index function to get its index.

for some functionalities, we would need the NE to create network connection that might need to be routed through the tunnel.

Yep. That’s relatively uncommon, but definitely supported.

For some context, have a read of A Peek Behind the NECP Curtain.

As to what you should do, that depends the specific API you’re using for these connections. Is it Network framework? URLSession? BSD Sockets? Or something more obscure?

Share and Enjoy

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

Hi

Thanks or the peek.

For the API we use, I would say BSD sockets (some UPD sockets created from rust code)

We thought about binding the socket to the tun interface but that would be inconvenient (as we would need to known when to bind or not to bind, which boils down to re-implementing the routing) Having a global switch would be ideal, but a option on the socket itself could work too

Accepted Answer
We thought about binding the socket to the tun interface

Right. With BSD Sockets that’s the path forward.

Note that you don’t have to use bind for this. Rather, use the IP_BOUND_IF (IPv4) or IPV6_BOUND_IF (IPv6) socket options.

Of could, you still have to know what interface to bind to. Nowadays that’s pretty straightforward. Fetch the virtualInterface property and get its index property [1].

On older systems things are significantly less convenient. The best option I’ve seen is to get the interface list (getifaddrs) and look for the interface that has the same address setup that you configured on your tunnel.

Share and Enjoy

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

[1] In C, the virtualInterface property is of type nw_interface_t, and you call the nw_interface_get_index function to get its index.

Thanks, it does work.

Just in case someone else stumble into this post, is there documentation somewhere for the other uses cases ? (network framwork and UrlSession)

For Network framework this is straightforward: You get the virtualInferface property and apply that to the requiredInterface property to the NWParameters you use to create the connection.

I don’t think there’s a good option when it comes to URLSession )-: URLSession has infrastructure for this [1] but it’s not exposed as public API.

Share and Enjoy

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

[1] It’s what underlies this call.

VPN routes not applied to the netork extension.
 
 
Q