NEPacketTunnelProvider and IPv6 DNS resolution

My application implements and IPv6 over IPv4 tunnel using NEPacketTunnelProvider. The tunnelling system works perfect but iOS is only requesting IPv4 resolution so it makes the system quite unusefulness.

 

If I understood correctly how iOS works, the system don’t use IPv6 resolution because it doesn’t detect a primary interface with IPv6 address (despite the tun interface has an IPv6 address assigned). I think that in order to have an IPv6 address I have to have a default IPv6 route pointing to the tun interface. If I use tunSettings.ipv6Settings?.includedRoutes = [NEIPv6Route.default()], full network doesn’t work (wireless notification icon disappear) but if I add the two routes ::/1 and 8000::/1 I have IP connectivity but not DNS resolution.

 

What I should do to have IPv6 resolution?

 

On the other hand and just for curiosity. If what I have explained is correct and we need to have an IPv6 default route to the interface to have IPv6 resolution, how it would work If I only want to tunnel part of the  traffic?

 

Logs when using NEIPv6Route.default()  can be found here http://openoverlayrouter.org/downloads/logs.txt

 

The code I am using is:

 

class PacketTunnelProvider: NEPacketTunnelProvider{

  

    ….

    var completionHandler: ((Error?) -> Void)?

  

    //Fake VPN server IP address

    var tunSettings = NEPacketTunnelNetworkSettings(tunnelRemoteAddress: “0.0.0.0”)

  

 

    override func startTunnel(options: [String : NSObject]? = nil, completionHandler: @escaping (Error?) -> Void) {

        self.completionHandler = completionHandler

 

        //TUN IP address

        let eid = defaults?.string(forKey: “eid”)

        if validateIPv4(ip: eid!) {

            tunSettings.ipv4Settings = NEIPv4Settings(addresses: [eid!], subnetMasks: [“255.255.255.255”])

            // Networks to be routed through TUN

            tunSettings.ipv4Settings?.includedRoutes = [NEIPv4Route.default()]

        } else if validateIPv6(ip: eid!) {

            tunSettings.ipv6Settings = NEIPv6Settings(addresses: [eid!], networkPrefixLengths: [128 as NSNumber])

            // Networks to be routed through TUN, it appears that there is some bug with defualt IPv6 route ::/0, so we define 2 routes with 2 big networks.

            let route1 = NEIPv6Route(destinationAddress: “::”, networkPrefixLength: 1)

            let route2 = NEIPv6Route(destinationAddress: “8000::”, networkPrefixLength: 1)

            tunSettings.ipv6Settings?.includedRoutes = [route1, route2]

        }

 

        tunSettings.mtu = 1440

      

    // When using IPv6 configuration, the system doesn’t send the DNS request to this server. For IPv4 it works

        tunSettings.dnsSettings = NEDNSSettings(servers: [(defaults?.string(forKey: “dnsServer”))!])

      

        // Apply settings and create TUN

        setTunnelNetworkSettings(tunSettings) { error in

            if error != nil {

                NSLog(“PacketTunnelProvider.startTunnel.setTunnelNetworkSettingsError (String(describing: error))”)

                completionHandler(error)

            }

            // Tell to the system that the fake VPN is “up”

            completionHandler(nil)

        }

 

    ….

}

Powered by WPeMatico

About

You may also like...

Comments are closed.