Post

Replies

Boosts

Views

Activity

Reply to Update from Big Sur Beta 3 to Beta 4 fails
Huh… I'm currently working on a System Extension and the system often gets into a broken state that can only be fixed by a reboot. So I was rebooting for the 4th time in a few hours and all of a sudden the reboot took veeery long again: stuck at about 20% or so, like FxFactory said. But this time, when the system came up, if finally was at Beta 4. Sorry, no idea what was different this time.
Aug ’20
Reply to How to receive UDP packets that have no checksum
Did you get it sorted out? We're running into the exact same issue on a Big Sur system now: IPsec ESP-in-UDP packets are dropped on that system since the packets from the VPN gateway have a UDP checksum of 0 (prior packets with IKE on that same port with valid UDP checksum are received just fine). We can see the packets in tcpdump but they do not get delivered to the socket (a normal UDP socket).
Nov ’20
Reply to How to receive UDP packets that have no checksum
I figured it out. The UDP checksum was a red herring. That actual problem is the kernel having explicit code to grab ESP-in-UDP packets. For macOS 10.15.6 xnu's sources, it can be found at bsd/netinet/udp_usrreq.c in function void udp_input(struct mbuf *m, int iphlen). There's this check: if (ipsec_bypass == 0 && (esp_udp_encap_port & 0xFFFF) != 0 && 						(uh->uh_dport == ntohs((u_short)esp_udp_encap_port) || 						uh->uh_sport == ntohs((u_short)esp_udp_encap_port))) { ... } ipsec_bypass gets set to 0 at various places. esp_udp_encap_port is exposed via the sysctl net.inet.ipsec.esp_port and defaults to 0. But if it gets set to 4500, the system will now "hijack" the UDP packets if they have a SA != 0. That is why the IKE packets (which have a valid checksum in our case) get passed to our socket, but the actual ESP packets are re-routed to the kernel IPsec code. There are two solutions: Either sysctl -w net.inet.ipsec.esp_port=0 (or something not equal to 4500), or open your NAT-T socket from an arbitrary port. RFC 3947 says we MUST use 4500 for source and destination, but on the other hand a server must handle NAT-T traffic from arbitrary source ports; that's the point of NAT-T.
Nov ’20
Reply to iOS Network Extension life cycle after stop
Hi Matt, thank you for your speedy reply! Since the user is starting the connection, what is wrong with having the user initiate the connection from either the container app or the VPN Settings in the Settings app? We support both, but that's not what this is about. :-) My concern is: if the user stops the connection and the house-keeping is taking very long (say, it takes a minute), it would be good if the user would still be able to start a new connection. As a test I just delayed calling the callback of stopTunnelWithReason: using dispatch_after by 30 seconds. During this time, the connection is in "stopping" state and the user has to wait this whole time until they can start the connection again. As for keeping the process alive, no, stopTunnelWithReason is call as part of the process to destroy the packet tunnel provider so any attempts to keep the process alive could end up with strange behavior. I was hoping that I could do the cleanup in something like the background tasks for UI processes: https://developer.apple.com/documentation/uikit/app_and_environment/scenes/preparing_your_ui_to_run_in_the_background/extending_your_app_s_background_execution_time If something like this would be supported in a network extension, I could bring the connection down, then call the stopTunnelWithReason: callback, and only then do the house-keeping. This ways the user (or system, with on-demand rules) would be able to restart the connection more quickly. Tear everything down, do house-keeping, and then call cancelTunnelWithError. Thank you for clearing this up.
Mar ’22
Reply to iOS Network Extension life cycle after stop
Yes, I'm able to do that, it works. I'm really grateful you're taking the time to answer my questions and I don't mean to be rude, but I think you're missing my point. Right now, the cleanup must be done before calling the callback, and that's blocking the VPN connection (from a user's point of view) on stop. The user or OS (on-demand rule) is not able to start the connection until the cleanup is done, but actually we would be able to restart it already. Since this cleanup can take some time, it would be good if we could signal to the OS "the connection is done and could get restarted" (what calling the callback is doing), and then do some additional work without the OS killing the process. So what I would like to do (which is not possible right now, it seems): -stopTunnelWithReason: is called. We stop the network part of the connection ("logout"). Call the stopTunnelWithReason: callback or otherwise signal to iOS: the connection has stopped and is now ready to be restarted. Then do some additional cleanup. I understand that right now, I need to do step 4 before 3. But it would be a better experience for the user if the delay introduced by then cleanup were not considered part of the stop procedure. I guess I'm going to write a Feedback describing the whole scenario in the next days, maybe it's something you guys would consider supporting.
Mar ’22
Reply to Embed Widget in Network Extension
I just tried calling WidgetCenter.shared.reloadAllTimelines() from our Network Extension on iOS 15.7 and iOS 16, and it works as expected on both. So as long as the NE is stopped gracefully (as opposed to crashes or getting killed by the system), we're now able to tell our widgets that a connection is running or has stopped, and reload the the widgets.
Sep ’22
Reply to New 60s timer when instantiating PacketTunnelProvider
That 60 second timer is potentially a problem for our VPN app as well. The documentation for startTunnelWithOptions:completionHandler: says to call the completion handler "when the tunnel is fully established, or when the tunnel cannot be started due to an error". But establishing the tunnel may involve asking the user for credentials, possibly multiple times (first username + password, and then optionally an OTP) which may take the user some time. (We do this by posting a user notification from the Network Extension; user is supposed to tap it, which then shows a credentials dialog in the app, and then sends a provider message to the Network Extension with the answer.) The 60 seconds can be hit if the user is slow to respond. What's the preferred way to handle a scenario like this? Does calling the completion handler early have any negative side-effects?
Jun ’23
Reply to Xcode 15 has problem of generated Swift NSObject headers: Property type 'NSInteger' (aka 'long') is incompatible with type 'NSUInteger' (aka 'unsigned long') inherited from 'NSObject'
We're running into the exact same issue in one of our products, and are unable to produce a demo project. The error does not trigger in the demo project, even though the type for hash is NSInteger in the header generated by Swift as well. I've tried to find out how to disable this error by having a look at the clang source code, but it doesn't seem to be tied to a warning flag. Created another radar as well: FB12485128
Jun ’23