I've implemented a VPN app for macOS using Packet Tunnel Provider. The user can include routes of IPv4 and IPv6, and also to enable split-tunnel.
However there's a combination that's not working well -
if the user includes the IPv6 default route,
but for IPv4 he enables the split tunnel and including only some routes, it seems that all IPv4 routes are included in the tunnel.
A code example:
I think that at the Console logs, the tunnel configuration looks good:
addresses = (
<12-char-str>,
)
subnetMasks = (
255.255.255.255,
)
includedRoutes = (
{
destinationAddress = <13-char-str>
destinationSubnetMask = 255.255.0.0
},
{
destinationAddress = <11-char-str>
destinationSubnetMask = 255.255.255.255
},
{
destinationAddress = <7-char-str>
destinationSubnetMask = 255.255.255.255
},
{
destinationAddress = <7-char-str>
destinationSubnetMask = 255.255.255.255
},
{
destinationAddress = <7-char-str>
destinationSubnetMask = 255.255.255.255
},
{
destinationAddress = <14-char-str>
destinationSubnetMask = 255.255.255.255
},
)
overridePrimary = NO
}
IPv6Settings = {
configMethod = automatic
addresses = (
<3-char-str>,
)
networkPrefixLengths = (
128,
)
includedRoutes = (
{
destinationAddress = <2-char-str>
destinationNetworkPrefixLength = 0
},
)
}
But when testing the VPN I see that all IPv4 traffic goes via the tunnel, and not only the included routes.
However there's a combination that's not working well -
if the user includes the IPv6 default route,
but for IPv4 he enables the split tunnel and including only some routes, it seems that all IPv4 routes are included in the tunnel.
A code example:
Code Block let newSettings = NEPacketTunnelNetworkSettings(tunnelRemoteAddress: serverAddress) newSettings.ipv4Settings = NEIPv4Settings(addresses: [localAddressString], subnetMasks: ["255.255.255.255"]) newSettings.ipv6Settings = NEIPv6Settings(addresses: ["2001:0db8:85a3:0000:0000:8a2e:0370:7334"], networkPrefixLengths: [64]) //fake IPv6 address newSettings.ipv6Settings?.includedRoutes = [NEIPv6Route.default()] let someRoute = NEIPv4Route(destinationAddress: "x.x.x.x", subnetMask: "255.255.255.255") let someOtherRoute = NEIPv4Route(destinationAddress: "y.y.y.y", subnetMask: "255.255.255.255") var routesToIncludeArr = [NEIPv4Route]() routesToIncludeArr.append(someRoute) routesToIncludeArr.append(someOtherRoute) newSettings.ipv4Settings?.includedRoutes = routesToIncludeArr
I think that at the Console logs, the tunnel configuration looks good:
configMethod = PPPIPv4Settings = {
addresses = (
<12-char-str>,
)
subnetMasks = (
255.255.255.255,
)
includedRoutes = (
{
destinationAddress = <13-char-str>
destinationSubnetMask = 255.255.0.0
},
{
destinationAddress = <11-char-str>
destinationSubnetMask = 255.255.255.255
},
{
destinationAddress = <7-char-str>
destinationSubnetMask = 255.255.255.255
},
{
destinationAddress = <7-char-str>
destinationSubnetMask = 255.255.255.255
},
{
destinationAddress = <7-char-str>
destinationSubnetMask = 255.255.255.255
},
{
destinationAddress = <14-char-str>
destinationSubnetMask = 255.255.255.255
},
)
overridePrimary = NO
}
IPv6Settings = {
configMethod = automatic
addresses = (
<3-char-str>,
)
networkPrefixLengths = (
128,
)
includedRoutes = (
{
destinationAddress = <2-char-str>
destinationNetworkPrefixLength = 0
},
)
}
But when testing the VPN I see that all IPv4 traffic goes via the tunnel, and not only the included routes.