First sorry for the long message, but I wanted to give as much info as possible.
I have a VPN app that uses Network Extension and OpenVPN on Ventura (13.1). Before Ventura everything worked fine.
I have a problem with sockets created from network extension. The sockets created into the extension are assigned on the tunnel interface (utun3 in my case).
Scenario:
- Start the VPN (includeAllNetworks=true) => OS creates utun3 and enters into
startTunnel
from NE app - On extension the app connects to VPN server.
- Call
setTunnelNetworkSettings
with the new configuration and when finished calls the completionBlock fromstartTunnel
andreasseting = false
- After 2 seconds create a new socket (C API) into NE and connect => socket is bound to tunnel interface.
# lsof output wifi ip=192.168.0.163 utun3 IP=10.7.1.4
8u IPv4 0xb394555904672715 0t0 TCP 192.168.0.163:60266->VPN_SERVER_IP (ESTABLISHED)
9u IPv4 0xb394555904673d35 0t0 TCP 10.7.1.4:60284->SOME_WEBSITE_IP:http (ESTABLISHED)
From this point on, all the sockets created from the NE app are bounded to the tunnel, instead of wifi interface. The tunnel must be restarted to work again.
What "helps" to fix this is to call with delay at least of 0.5 (less is not working) the completion block from startTunnel
and reasseting=false
, after VPN is connected, into the completion block from setTunnelNetworkSettings
:
// connection to VPN server is made
setTunnelNetworkSettings(networkSettings) { error in
DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
start_tunnel_completion_block()
reasserting = false
DispatchQueue.main.async {
self.connectToSomeSocket()
}
}
I've activated the extra loggins for necp, and I've saw that necp creates a new rule (if no delay is used) for the VPN app that has to bind to utun3.
My system configuration is :
- wifi/en0 interface has index 15
- utun3, created when the tunnel starts is index 22.
- in this case Network extension app, tunnel app, has PID 37567.
- Policy ID is 14569, which is created after the app calls the completion block from
startTunnel
andreasseting=false
Necp log (not the same with the lsof from above):
# While connection to VPN server, the socket matched other rules that have interface index 22 (en0)
error 10:44:55.101389+0100 kernel necp_socket_find_policy_match_with_info_locked: DATA-TRACE <SOCKET>: EXAMINING - policy id=14557 session_order=2002 policy_order=10806 result=IP_TUNNEL (cond_policy_id 0)
error 10:44:55.101392+0100 kernel necp_socket_check_policy: DATA-TRACE <SOCKET>: ------ matching <NECP_KERNEL_CONDITION_BOUND_INTERFACE> <value (15 / 0xF) (0 / 0x0) (0 / 0x0) input (15 / 0xF) (0 / 0x0) (0 / 0x0)>
error 10:44:55.101397+0100 kernel necp_socket_check_policy: DATA-TRACE <SOCKET>: ------ matching <NECP_KERNEL_CONDITION_APP_ID> <value (66309 / 0x10305) (0 / 0x0) (0 / 0x0) input (66309 / 0x10305) (0 / 0x0) (0 / 0x0)>
error 10:44:55.101401+0100 kernel necp_socket_check_policy: DATA-TRACE <SOCKET>: ------ matching <NECP_KERNEL_CONDITION_PID> <value (37567 / 0x92BF) (0 / 0x0) (0 / 0x0) input (37567 / 0x92BF) (0 / 0x0) (0 / 0x0)>
error 10:44:55.101404+0100 kernel necp_socket_find_policy_match_with_info_locked: DATA-TRACE <SOCKET <private>>: MATCHED POLICY - proto 6 port <local 53511/53511 remote 1231/1231> <drop-all order 11001> <pid=37567 Application 66309 Real Application 66309 BoundInterface 15> (policy id=14557 session_order=2002 policy_order=10806 result=IP_TUNNEL)
# after connected to VPN server and called the completion block from `startTunnel` and `reasseting=false`
....
default 10:44:55.511326+0100 kernel necp_kernel_socket_policy_add: Added kernel policy: socket, id=14569, mask=4202
...
default 10:44:55.512624+0100 kernel necp_kernel_socket_policies_dump_all: 5. Policy ID: 14569 Process: nesessionm Order: 2002.10806 Mask: 4202 Result: IPTunnel (utun3)
....
error 10:45:12.225306+0100 kernel necp_socket_find_policy_match_with_info_locked: DATA-TRACE <SOCKET>: EXAMINING - policy id=14569 session_order=2002 policy_order=10806 result=IP_TUNNEL (cond_policy_id 0)
error 10:45:12.225308+0100 kernel necp_socket_check_policy: DATA-TRACE <SOCKET>: ------ matching <NECP_KERNEL_CONDITION_BOUND_INTERFACE> <value (22 / 0x16) (0 / 0x0) (0 / 0x0) input (22 / 0x16) (0 / 0x0) (0 / 0x0)>
error 10:45:12.225312+0100 kernel necp_socket_check_policy: DATA-TRACE <SOCKET>: ------ matching <NECP_KERNEL_CONDITION_APP_ID> <value (66309 / 0x10305) (0 / 0x0) (0 / 0x0) input (66309 / 0x10305) (0 / 0x0) (0 / 0x0)>
error 10:45:12.225316+0100 kernel necp_socket_check_policy: DATA-TRACE <SOCKET>: ------ matching <NECP_KERNEL_CONDITION_PID> <value (37567 / 0x92BF) (0 / 0x0) (0 / 0x0) input (37567 / 0x92BF) (0 / 0x0) (0 / 0x0)>
error 10:45:12.225320+0100 kernel necp_socket_find_policy_match_with_info_locked: DATA-TRACE <SOCKET <private>>: MATCHED POLICY - proto 6 port <local 53537/53537 remote 1231/1231> <drop-all order 11001> <pid=37567 Application 66309 Real Application 66309 BoundInterface 22> (policy id=14569 session_order=2002 policy_order=10806 result=IP_TUNNEL)
default 10:45:12.225327+0100 kernel necp_socket_find_policy_match: Socket Policy: <private> (BoundInterface 22 Proto 6) Policy 14569 Result 6 Parameter 22
Do you have any suggestions why would kernel bound sockets from NE app to the utun interface or how to future investigate this?
And maybe any suggestions how to properly fix this, instead of adding delay to setTunnelNetworkSettings
?
Thanks