Route not deleted after 'setTunnelNetworkSettings:nil'

We have a packettunnelprovider which we are using for intercepting IP packets. We define includeroutes while setting tunnel using 'setTunnelNetworkSettings'.

But later when we want to disable packet interception, we want to do it from packettunnelprovider extension itself by reseting tunnel settings, for which we set 'NETunnelNetworkSettings' to nil in setTunnelNetworkSettings call. This deletes most of the routes added by includeroutes but few are always left out.

% ifconfig utun3                  
utun3: flags=8051<UP,POINTOPOINT,RUNNING,MULTICAST> mtu 1300
	options=6463<RXCSUM,TXCSUM,TSO4,TSO6,CHANNEL_IO,PARTIAL_CSUM,ZEROINVERT_CSUM>

% netstat -rn -f inet | grep utun3
11.99/24            link#25            UCS             utun3       
269.254            link#25            UCS             utun3       
192.168.0          link#25            UCS             utun3  

Code which we use to reset packet tunnel:

[g_PacketTunnelProvider setTunnelNetworkSettings:nil completionHandler:^(NSError * _Nullable errorNE) {
        if (errorNE != nil) {
            // handle error
        } else {
            // handle success
        }
    }];

Can you please help in what could be the reason behind it?

Note: I am aware that VPN can be disabled from provider app, but I want to handle this in packettunnelprovider extension by resetting 'NETunnelNetworkSettings'.

Accepted Reply

Please suggest if there is any way we can handle it inside provider extension itself.

I don’t see any way to do that, other than by doing what you’re already doing, calling -setTunnelNetworkSettings:completionHandler:, which doesn’t work )-: That seems bugworthy to me. Please post your bug number, just for the record.

Another potential option would be to force the tunnel down from your provider by calling -cancelTunnelWithError:.

Share and Enjoy

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

Replies

If you stop the provider, does that undo the routing table change?

I realise you don’t want to do that, I’m just trying to establish a data point.

Share and Enjoy

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

Yes if I do stopVPNTunnel from provider app then along with utun interface all routes for utun interface also deletes. But as you said I dont want to do that. Please suggest if there is any way we can handle it inside provider extension itself.

Please suggest if there is any way we can handle it inside provider extension itself.

I don’t see any way to do that, other than by doing what you’re already doing, calling -setTunnelNetworkSettings:completionHandler:, which doesn’t work )-: That seems bugworthy to me. Please post your bug number, just for the record.

Another potential option would be to force the tunnel down from your provider by calling -cancelTunnelWithError:.

Share and Enjoy

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

I have files the feedback 13167536

Thanks for the tip on '-cancelTunnelWithError:', with this I am able to cancel the tunnel and catch the notification in provider app to reset the tunnel manager thus the virtual interface and related route table. This clears the route entries for utun3 (in my case).

In provider app, I was able to collect the custom error domain and code using -fetchLastDisconnectErrorWithCompletionHandler:. But this API is only available in macOS 13.0 and later. How do I collect Disconnection Error in older macos version (Bigsur and Monterey)? I can see the '_lastDisconnectError' is available in debuger, but is there a way I can collect it in my program?

(lldb) p ((NETunnelProviderSession*)(statusChangeNotification.object))->_lastDisconnectError
(NSError *) $4 = 0x000060000037d680 domain: "MyTunnelErrorDomain" - code: 1

I have files the feedback FB13167536

Thanks.

is there a way I can collect it in my program?

There’s almost certainly a way, but it’s not something I’m comfortable going into here on DevForums. Please open a DTS tech support incident and we can pick things up there.

Alternatively, there are other approaches you could take. For example, you could have the main app use XPC to talk to you sysex to get this state.

Share and Enjoy

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