Network Extension

RSS for tag

Customize and extend the core networking features of iOS, iPad OS, and macOS using Network Extension.

Posts under Network Extension tag

200 Posts
Sort by:

Post

Replies

Boosts

Views

Activity

Network Extension Resources
General: DevForums tag: Network Extension Network Extension framework documentation Routing your VPN network traffic article Filtering Network Traffic sample code TN3120 Expected use cases for Network Extension packet tunnel providers technote TN3134 Network Extension provider deployment technote TN3165 Packet Filter is not API technote Network Extension and VPN Glossary DevForums post Debugging a Network Extension Provider DevForums post Exporting a Developer ID Network Extension DevForums post Network Extension vs ad hoc techniques on macOS DevForums post Extra-ordinary Networking DevForums post Wi-Fi management: Wi-Fi Fundamentals DevForums post TN3111 iOS Wi-Fi API overview technote How to modernize your captive network developer news post iOS Network Signal Strength DevForums post See also Networking Resources. Share and Enjoy — Quinn “The Eskimo!” @ Developer Technical Support @ Apple let myEmail = "eskimo" + "1" + "@" + "apple.com"
0
0
2.4k
3d
Will an iPhone reconnect automatically to a wifi network we connected to previously with joinOnce = false?
PLATFORM AND VERSION: iOS Development environment: Xcode 15.3, macOS 14.7.1 (23H222) Run-time configuration: iOS 18.3.1 DESCRIPTION OF PROBLEM: Our app uses NEHotspotConfigurationManager with joinOnce set to false to connect to an IoT device's Wi-Fi hotspot. Later, we programmatically disconnect from this hotspot. We are wondering if, after this programmatic disconnection, there is a possibility that the iPhone will automatically reconnect to the hotspot (even when our app is not running). Does it matter if the hotspot's SSID is hidden or not? This concern arises because the iPhone is already familiar with the hotspot's network configuration. Our testing indicates that this does not happen, but we want to be certain. This is a behavior we do NOT want to occur. We set joinOnce to false because we experience connectivity issues with the IoT device when joinOnce is true (there are several discussions in forums regarding issues with setting it to true). Thank you. Thanks.
4
0
154
12h
May be port leak when use handleNewUDPFlow in Network Extension
When handleNewUDPFlow in NETransparentProxyProvider is used to handle UDP data from port 53, at the same time, run the script continuously to execute nslookup or dig, about tens of thousands of times later, the nslookup shows the error "isc_socket_bind: address not available". So I check the system port status, and find all of the ports from 49152 to 65535 are occupied. The number of net.inet.udp.pcbcount is also very high. net.inet.udp.pcbcount: 91433 Then I made the following attempts: handleNewUDPFlow function return false directly, the nslookup script runs with no problems. I write a simple network extension that use handleNewUDPFlow to reply the mock data directly, and only hijack the UDP data from my test program (HelloWorld-5555). My network exntension code: override func handleNewUDPFlow(_ flow: NEAppProxyUDPFlow, initialRemoteEndpoint remoteEndpoint: NWEndpoint) -> Bool { guard let tokenData = flow.metaData.sourceAppAuditToken, tokenData.count == MemoryLayout<audit_token_t>.size else { return false } let audit_token = tokenData.withUnsafeBytes { buf in buf.baseAddress?.assumingMemoryBound(to: audit_token_t.self).pointee } let pid = audit_token_to_pid(audit_token ?? audit_token_t()) if (!flow.metaData.sourceAppSigningIdentifier.starts(with: "HelloWorld-5555")) { return false } Logger.statistics.log("handleNewUDPFlow \(remoteEndpoint.debugDescription, privacy: .public) \(flow.hash), pid:\(pid), \(flow.metaData.sourceAppSigningIdentifier, privacy: .public)") flow.open(withLocalEndpoint: nil) { error in if let error { os_log("flow open error: %@", error.localizedDescription) return } flow.readDatagrams { data_grams, remote_endpoints, read_err in guard let read_data_grams = data_grams, let read_endpoints = remote_endpoints, read_err == nil else { os_log("readDatagrams failed") flow.closeReadWithError(nil) flow.closeWriteWithError(nil) return } let mockData = Data([0x01,0x02,0x03]) let datagrams = [ mockData ] guard let remoteEnd = remoteEndpoint as? NWHostEndpoint else { os_log("Not the NWHostENdpoint") flow.closeReadWithError(nil) flow.closeWriteWithError(nil) return } let endpoints = [ NWHostEndpoint(hostname: remoteEnd.hostname, port: remoteEnd.port) ] flow.writeDatagrams(datagrams, sentBy: endpoints) { error in if let error { os_log("writeDatagrams error: %@", error.localizedDescription) } os_log("writeDatagrams close") flow.closeReadWithError(nil) flow.closeWriteWithError(nil) } } } return true } My test program code: void send_udp() { int sockfd; struct sockaddr_in server_addr; char buffer[BUFFER_SIZE]; int bytes_sent; // create socket if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { perror("socket create failed"); exit(EXIT_FAILURE); } struct sockaddr_in local_addr; memset(&local_addr, 0, sizeof(local_addr)); local_addr.sin_family = AF_INET; local_addr.sin_addr.s_addr = htonl(INADDR_ANY); local_addr.sin_port = htonl(0); // bind if (bind(sockfd, (struct sockaddr*)&local_addr, sizeof(local_addr)) < 0) { printf("IPV4 bind errno:%d\n", errno); close(sockfd); return; } // server addr memset(&server_addr, 0, sizeof(server_addr)); server_addr.sin_family = AF_INET; server_addr.sin_port = htons(SERVER_PORT); server_addr.sin_addr.s_addr = inet_addr(SERVER_IP); // send & recv strcpy(buffer, "Hello, UDP server!"); bytes_sent = sendto(sockfd, buffer, strlen(buffer), 0, (struct sockaddr *)&server_addr, sizeof(server_addr)); if (bytes_sent < 0) { perror("sendto failed"); close(sockfd); exit(EXIT_FAILURE); } printf("sendto ok\n"); char recvbuf[128] = {0}; socklen_t len = sizeof(server_addr); int sz = recvfrom(sockfd, recvbuf, sizeof(recvbuf), MSG_WAITALL, (struct sockaddr *) &server_addr, &len); printf("recv sz: %d\n", sz); close(sockfd); return; } int main() { send_udp(); return 0; } 2.1 When I use bind in my program, after the program running tens of thousands of times, the ports are exhausted, and nslookup return the error "isc_socket_bind: address not available". The case looks like running the nslookup script, because the nslookup will call the bind. 2.2 When I remove the bind from my program, all the tests are go. I have made the above experiments on different systems: 13.x, 14.x, 15.x, and read the kernel source code about bind and port assignment, bsd/netinet/in_pcb.c bsd/netinet/udp_usrreq.c and find kernel will do different action for network extension by call necp_socket_should_use_flow_divert I have checked my network extension process by lsof and netstat, its sockets or flows are all closed properly. I don't know how I can avoid this problem to ensure my network extension to work long time properly. Apparently, the port exhaustion is related to the use of bind function and network extension. I doubt there is a port leak problem in system when use network extension. Hope for your help.
2
0
478
4d
Content Filter Providers in unsupervised and unmanaged iOS devices
I'm looking at implementing an iOS app that has includes a Content Filter Provider to block access to certain domains when accessed on the device. This uses NEFilterManager, NEFilterDataProvider and NEFilterControlProvider to handle configuration and manage the network flows and block as necessary. My question is can you deploy this in an iOS 18+ app on the App Store to devices which are unmanaged, unsupervised and don't use Screen Time APIs? Although not 100% clear, this technote seems to say it is not possible: https://developer.apple.com/documentation/Technotes/tn3134-network-extension-provider-deployment Testing this on a Developer device and build works successfully without any MDM profiles installed. A similar approach using the same APIs also works on macOS once user permissions have been given. If it can't work on unsupervised, unmanaged iOS devices, is possible for the user to first manually install a MDM profile which includes the required 'Content Filter' details and then have it work? If not, how would you filter iOS network traffic on an unmanaged, unsupervised device? Is it necessary to use a VPN or DNS approach instead (which may be a lot less privacy compliant)?
6
0
250
4d
Can NETunnelProviderManager.protocolConfiguration be changed on the fly?
I am learning about layer 3 VPN implementations for MacOS, and am slowly making my way through docs and tutorials. I noticed that part of creating an instance of NETunnelProviderManager on the app side of the project requires the specification of protocolConfiguration via an instance of NETunnelProviderProtocol. One of the arguments for this class is serverAdress, which to my understanding, tells the OS where to route traffic towards at the end of the day. My question: many VPNs these days allow the option to specify the location for which you want your traffic to be routed through. I imagine this would necessitate changing this serverAddress field in the backend. However, setting this option (on a commercially available VPN) doesn't typically prompt the OS notification that you get when initially installing a VPN configuration for the first time. How is this functionality achieved? I could see one possible solution being that most VPN providers route through a main service beforehand (so the first IP in the chain never has to change), though I could see this being problematic for a number of other reasons. Assuming you have a valid NETunnelProviderManager object called manager, is this valid? self.manager?.protocolConfiguration?.serverAddress = "somewhereElse" Even if it compiles, will the traffic be properly re-routed? My understanding of the flow right now is that in order to "lock in" a new configuration, or modify it, you need to call manager.saveToPreferences, which triggers the OS notification I mentioned earlier.
1
0
201
1w
[networkextesion] dnsproxy
hello I am testing the use of network extension. When we use dnsproxy to proxy DNS requests, we will send you a message that the udp pcbcount of your system continues to increase. For example for ((i=1; i<=99999; i++));do echo "Attempt $i:" dig google.com done when the dig command is used continuously, the dig command will show the following errors when pcbcount reaches a certain number. isc_socket_bind: address not available Can you help us determine what the problem might be? thank you
5
0
158
5d
OAuth login from NEPacketTunnelProvider
How can NEPacketTunnelProvider launch the companion application, or notify user to launch the application? I have built an iOS VPN that uses credentials stored in the keychain, and it works as expected. Now I'm trying to add OAuth login support. Everything works fine at first. I login from the companion application, store tokens in the keychain, then launch the VPN from either System Settings or the companion application. However, when the OAuth refresh tokens expire, or the OAuth IdP otherwise requires login, I can't perform the OAuth login from the NEPacketTunnelProvider. Login must happen from the companion application, which likely isn't running. I need the NEPacketTunnelProvider to either launch the companion application directly or to notify the user to do so. Searching and reading docs yields: You can't perform OAuth login from within the NEPacketTunnelProvider because it requires user interaction There is no way to guarantee that the companion application is running on iOS (otherwise one would use NEVPNStatusDidChange) You can't launch the companion application from NEPacketTunnelProvider using a custom URL because of security concerns You might be able to launch the companion application from a system extension... Some sources say you still can't guarantee that the system extension is loaded whenever the NEPacketTunnelProvider needs it anyway. Of course, any of these conclusions could be wrong. At this point I'm not sure where to begin. Is there another approach that could be initiated by the NEPacketTunnelProvider (push notifications, system notifications, smoke signals)? Any help would be appreciated. Thanks, Bill Welch
1
0
181
1w
Download speed Issue with Per-App VPN Using WireGuard Protocol
DESCRIPTION OF PROBLEM We have developed an app and server based on the WireGuard protocol. While we have successfully implemented device-wide VPN, we are now working on enabling per-app VPN functionality. The per-app VPN payload is successfully delivered, and the designated app can read the configuration and establish a connection to the VPN server. However, we are experiencing extremely slow download data rates, measuring only in bytes. Steps Taken: Created an app-layer payload. Configured NETestAppMapping in the app’s Info.plist, using the VPNUUID defined in the payload for the Chrome app. Despite these configurations, data transfer remains significantly slow. We would appreciate any insights into potential causes or recommendations to resolve this performance issue. Thank you for your assistance.
3
0
255
1w
How to Confirm Wi-Fi Connection Success in App Clip Without Access Wi-Fi Information Entitlement?
My app helps users connect to Wi-Fi networks, and I have requested the Access Wi-Fi information entitlement. This allows the app to retrieve the current Wi-Fi information to ensure the user’s connection is successful. Now, we are trying to implement an App Clip that enables users to connect to a specific Wi-Fi network through a QR code scan or NFC in certain scenarios. In the App Clip, I’ve requested the Hotspot entitlement, which allows the app to use the hotspot manager to configure Wi-Fi networks. However, since I cannot access the current Wi-Fi information in the App Clip, I’m unable to confirm whether the connection was successful.
2
0
210
1w
wifi connect fail
Dear Apple: We encountered a problem when using the Wi-Fi connection feature. When calling the Wi-Fi connection interface NEHotspotConfigurationManager applyConfiguration, it fails probabilistically. After analyzing the air interface packets, it appears that the Apple device did not send the auth message. How should we locate this issue? Are there any points to pay attention to when calling the Wi-Fi connection interface? Thanks
3
0
229
1w
Getting connection settings from method handleNewUDPFlow
I'm using NETransparentProxyProvider to intercept udp sockets using the method handleNewUDPFlow. An application may create a UDP socket and set the DONTFRAG using setsockopt method setsockopt(s, IPPROTO_IP, IP_DONTFRAG, &val, sizeof(val)) In this case, do I have option in this case, to get the connection settings inside the callback (void)handleNewUDPFlow:(NEAppProxyUDPFlow *)flow initialRemoteEndpoint:(NWEndpoint *)remoteEndpoint; So in this case, I would be able to create the outgoing socket with the exact same characteristics, after the original app socket got intercepted by my proxy provider ?
1
0
237
2w
Can we create a MDM profile for Transparent Proxy without remote server address
We have an application which is written in Swift, which activates network extension (Transparent Proxy). We want to use MDM deployment for this network system extension. Our Transparent Proxy module is a system extension, which is exposing an app proxy provider interface (We are using NETransparentProxyProvider class and in extension’s Info.plist we use com.apple.networkextension.app-proxy key.) We don’t have any remote server setup to forward the traffic, instead we open a connection with a certain localhost:port to redirect the traffic which is received in our transparent proxy. We have another module that listens to the particular localhost:port to process the traffic further. As per https://developer.apple.com/documentation/devicemanagement/vpn/transparentproxy documentation, we noticed that we can use the VPN payload with app-proxy as Provider Type for Transparent Proxy. We were able to install the profile created via Jamf Pro and also while in stalling our product the Transparent Proxy gets mapped with the one which is installed via profile. However after that the network is broken and hence unable to browse anything. We are suspecting the remote server filed is causing this. So we tried creating the custom profile without remote server address for VPN payload, but we are unable to install the profile. It throws below error: 2025-02-11 16:43:55.193348+0530 0x2f880 Error 0x0 6815 0 mdmclient: (NetworkExtension) [com.apple.networkextension:] Failed to save configuration DGWebProxy because it is invalid: Error Domain=NEConfigurationErrorDomain Code=2 "configuration is invalid: Missing server address" UserInfo={NSLocalizedDescription=configuration is invalid: Missing server address}
2025-02-11 16:43:55.193376+0530 0x2f880 Error 0x0 6815 0 mdmclient: (NetworkExtension) [com.apple.networkextension:] NEProfileIngestion Error occurred when saving configuration 'DGWebProxy': configuration is invalid: configuration is invalid: Missing server address 
2025-02-11 16:43:55.196159+0530 0x2f880 Error 0x0 6815 7 mdmclient: [com.apple.ManagedClient:CPDomainPlugIn] [ERROR] [0:MDMDaemon:CPDomainPlugIn:<0x2f880>] <<<<< PlugIn: InstallPayload [NEProfileIngestionPlugin] Error: Error Domain=ConfigProfilePluginDomain Code=-319 "The ‘VPN Service’ payload could not be installed. The VPN service could not be created." UserInfo={NSLocalizedDescription=The ‘VPN Service’ payload could not be installed. The VPN service could not be created.} <<<<<
2025-02-11 16:43:55.196826+0530 0x2f880 Error 0x0 6815 7 mdmclient: [com.apple.ManagedClient:MDMDaemon] [ERROR] [0:MDMDaemon:<0x2f880>] [CE] PlugIn_InstallPayload ==> Error Domain=ConfigProfilePluginDomain Code=-319 "The ‘VPN Service’ payload could not be installed. The VPN service could not be created." UserInfo={NSLocalizedDescription=The ‘VPN Service’ payload could not be installed. The VPN service could not be created.} Can we create MDM profile for Transparent Proxy without remote server address?
1
5
237
2w
When updating a VPN app with `includeAllNetworks`, the newer instance of the packet tunnel is not started via on-demand rules
When installing a new version the app while a tunnel is connected, seemingly the old packet tunnel process gets stopped but the new one does not come back up. Reportedly, a path monitor is reporting that the device has no connectivity. Is this the expected behavior? When installing an update from TestFlight or the App store, the packet tunnel instance from the old tunnel is stopped, but, due to the profile being on-demand and incldueAllNetworks, the path monitoring believes the device has no connectivity - so the new app is never downloaded. Is this the expected behavior? During development, the old packet tunnel gets stopped, the new app is installed, but the new packet tunnel is never started. To start it, the user has to toggle the VPN twice from the Settings app. The tunnel could be started from the VPN app too, if we chose to not take the path monitor into account, but then the user still needs to attempt to start the tunnel twice - it only works on the second try. As far as we can tell, the first time around, the packet tunnel never gets started, the app receives an update about NEVPNStatus being set to disconnecting yet NEVPNConnection does not throw. The behavior I was naively expecting was that the packet tunnel process would be stopped only when the new app is fully downloaded and when the update is installed, Are we doing something horribly wrong here?
5
3
292
2w
In-tunnel networking when `includeAllNetworks` is set.
When setting up a packet tunnel with a profile that has includeAllNetworks set to true, we seemingly cannot send any traffic inside the tunnel using any kind of an API. We've tried using BSD sockets, as we ping a host only reachable within the tunnel to establish whether we have connectivity - this does not work. When using NWConnection from the Network framework and specifying the required interface via virtualInterface from the packet tunnel, the connection state never reaches ready. Our interim solution is to, as ridiculous as it sounds, include a whole userspace networking stack so we can produce valid TCP packets just to send into our own tunnel. We require a TCP connection within our own tunnel to do some configuration during tunnel setup. Is there no better solution?
5
3
225
2w
Checking Wi-Fi Status for Location Accuracy in iOS App
I am working on a duress app and would like to improve location accuracy by encouraging users to enable Wi-Fi. In Apple Maps, I noticed that when Wi-Fi is off, a dialog prompts users to turn on Wi-Fi to enhance location accuracy. I am looking to implement similar functionality in my app. Specifically, I would like to check whether Wi-Fi is enabled on the user's device (even if it is not connected to a network). Despite exploring several methods, I have been unable to determine a reliable way to check the Wi-Fi status. Can you guide me on whether it is possible to access this functionality in iOS, and if so, how I can implement it within my app?
2
0
278
2w