Networking

RSS for tag

Explore the networking protocols and technologies used by the device to connect to Wi-Fi networks, Bluetooth devices, and cellular data services.

Networking Documentation

Posts under Networking subtopic

Post

Replies

Boosts

Views

Created

WiFi Connect error,NEHotspotConfigurationErrorDomain code=11
hi everybody, When I use the following code to connect to WiFi network, an error message of "error=null" or "error='Error Domain=NEHotspotConfigurationErrorDomain Code=11 "" UserInfo={NSLocalizedDescription=}' " will occur. It has been uploaded to Feedback. Feedback ID: FB16819345 (WiFi-无法加入网络) NEHotspotConfiguration *hotspotConfig = [[NEHotspotConfiguration alloc] initWithSSID:ssid passphrase:psk isWEP:NO]; [[NEHotspotConfigurationManager sharedManager] applyConfiguration:hotspotConfig completionHandler:^(NSError * _Nullable error) { }];
15
0
626
Mar ’25
NERelay save to preferences error
I am developing an App based on Network Extension that lets all network requests on device access the Internet through a private Relay. I created an empty iOS App and only the entitlements file and ViewController.swift(Main.storyboard) file have been modified. The code was copied from the official video https://developer.apple.com/videos/play/wwdc2023/10002/ But, running the App on iPhone, the saveToPreferences API reported Error Domain=NERelayErrorDomain Code=3 "(null)" and the App doesn't look like it's changed at all (it doesn't jump to the Settings - VPN&Relay). Does anyone know why?Any reply would be greatly appreciated. The contents of the entitlements file: <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> <key>com.apple.developer.networking.networkextension</key> <array> <string>relay</string> </array> </dict> </plist> ViewController.swift: import UIKit import NetworkExtension class ViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view. } @IBAction func tap(_ sender: Any) { let newRelay = NERelay() let relayURL = URL(string: "https://relay.example.com:443/") newRelay.http3RelayURL = relayURL newRelay.http2RelayURL = relayURL newRelay.additionalHTTPHeaderFields = ["Authorization" : "PrivateToken=123"] let manager = NERelayManager.shared() manager.relays = [newRelay] manager.matchDomains = ["internal.example.com"] manager.isEnabled = false manager.saveToPreferences { err in print(err) } } }
1
0
179
Mar ’25
Technical Inquiry about CoreBluetooth Scanning & NEHotspotConfigurationManager Workflow
I am writing to seek clarification on two technical issues related to iOS frameworks (CoreBluetooth and NetworkExtension). These observations are critical for optimizing our app's performance, and I would appreciate any official guidance or documentation references. CoreBluetooth Scanning Frequency and Cycle Issue: We noticed inconsistent BLE device discovery times (ranging from 0.5s to 1.5s) despite the peripheral advertising at 2Hz (500ms interval). Questions: Does iOS regulate the BLE scan interval or duty cycle internally? If yes, what factors affect this behavior (e.g., foreground/background state, connected devices)? Are there recommended practices to reduce discovery latency for peripherals with fixed advertising intervals? Is there a way to configure scan parameters (e.g., scan window/interval) programmatically, similar to Android's BluetoothLeScanner? Test Context: Device: iPhone 13 mini (iOS 17.6.1) Code: CBCentralManager.scanForPeripherals(withServices: nil, options: [CBCentralManagerScanOptionAllowDuplicatesKey: true]) NEHotspotConfigurationManager Workflow and Latency Issue: Using NEHotspotConfigurationManager.shared.apply(_:) to connect to Wi-Fi occasionally takes up to 8 seconds to complete. Questions: What is the internal workflow of the apply method? Does it include user permission checks, SSID scanning, authentication, or IP assignment steps? Are there known scenarios where this method would block for extended periods (e.g., waiting for user interaction, network timeouts)? Is the latency related to system-level retries or radio coexistence with other wireless activities (e.g., Bluetooth)? Test Context: Configuration: NEHotspotConfiguration(ssid: "TestSSID") Behavior: Delay occurs even when the Wi-Fi network is in range and credentials are correct.
1
0
188
Mar ’25
Technical Inquiry about CoreBluetooth Scanning & NEHotspotConfigurationManager Workflow
I am writing to seek clarification on two technical issues related to iOS frameworks (CoreBluetooth and NetworkExtension). These observations are critical for optimizing our app's performance, and I would appreciate any official guidance or documentation references. CoreBluetooth Scanning Frequency and Cycle Issue: We noticed inconsistent BLE device discovery times (ranging from 0.5s to 1.5s) despite the peripheral advertising at 2Hz (500ms interval). Questions: Does iOS regulate the BLE scan interval or duty cycle internally? If yes, what factors affect this behavior (e.g., foreground/background state, connected devices)? Are there recommended practices to reduce discovery latency for peripherals with fixed advertising intervals? Is there a way to configure scan parameters (e.g., scan window/interval) programmatically, similar to Android's BluetoothLeScanner? Test Context: Device: iPhone 13 mini (iOS 17.6.1) Code: CBCentralManager.scanForPeripherals(withServices: nil, options: [CBCentralManagerScanOptionAllowDuplicatesKey: true]) NEHotspotConfigurationManager Workflow and Latency Issue: Using NEHotspotConfigurationManager.shared.apply(_:) to connect to Wi-Fi occasionally takes up to 8 seconds to complete. Questions: What is the internal workflow of the apply method? Does it include user permission checks, SSID scanning, authentication, or IP assignment steps? Are there known scenarios where this method would block for extended periods (e.g., waiting for user interaction, network timeouts)? Is the latency related to system-level retries or radio coexistence with other wireless activities (e.g., Bluetooth)? Test Context: Configuration: NEHotspotConfiguration(ssid: "TestSSID") Behavior: Delay occurs even when the Wi-Fi network is in range and credentials are correct.
1
0
259
Mar ’25
Local Network Privacy not Working as Documented
In TN3179 under "macOS considerations" there are a set of instances where local network privacy does not apply: macOS automatically allows local network access by: Any daemon started by launchd Any program running as root Command-line tools run from Terminal or over SSH, including any child processes they spawn I am running some tests in my app that use the local network, attempting to run them from both the terminal app and from a VScode terminal and I am getting permissions prompts. After allowing these pop ups, some of the tests still fail as if networking was blocked.
3
0
274
Mar ’25
Macos pf.conf
I have a question regarding /etc/pf.conf. If I use this rule, rdr pass on bridge100 inet proto tcp from 192.168.2.104 to any port {80, 443, 8883} -> 127.0.0.1 port 8080 all other traffic on bridge100 will not function properly, even the traffic that is not destined for 192.168.2.104. Additionally, the hotspot generated through bridge100 will also become unavailable. Even if I comment out this rule and run sudo pfctl -e -f /etc/pf.conf, the problem still persists. The situation will only return to normal when I restart my Mac. my macos:15.3.2 my /etc/pf.conf # scrub-anchor "com.apple/*" nat-anchor "com.apple/*" rdr-anchor "com.apple/*" rdr pass on bridge100 inet proto tcp from 192.168.2.104 to any port {80, 443, 8883} -> 127.0.0.1 port 8080 dummynet-anchor "com.apple/*" anchor "com.apple/*" load anchor "com.apple" from "/etc/pf.anchors/com.apple"
1
0
314
Mar ’25
NetworkExtension
I am working on a macos application that uses NetworkExtension and works fine in the debug environment. However, when I use the Release package, I am always prompted that my description file does not contain NetworkExtension. I am sure that my description file does contain NetworkExtension. How to solve this problem
1
0
279
Mar ’25
Macos nentwork pf.conf
I have a question regarding /etc/pf.conf. If I use this rule, rdr pass on bridge100 inet proto tcp from 192.168.2.104 to any port {80, 443, 8883} -> 127.0.0.1 port 8080 all other traffic on bridge100 will not function properly, even the traffic that is not destined for 192.168.2.104. Additionally, the hotspot generated through bridge100 will also become unavailable. Even if I comment out this rule and run sudo pfctl -e -f /etc/pf.conf, the problem still persists. The situation will only return to normal when I restart my Mac. my macos:15.3.2 my /etc/pf.conf # scrub-anchor "com.apple/*" nat-anchor "com.apple/*" rdr-anchor "com.apple/*" rdr pass on bridge100 inet proto tcp from 192.168.2.104 to any port {80, 443, 8883} -> 127.0.0.1 port 8080 dummynet-anchor "com.apple/*" anchor "com.apple/*" load anchor "com.apple" from "/etc/pf.anchors/com.apple"
1
0
337
Mar ’25
macos 15.3.x local network restrictions leading to EHOSTUNREACH "No route to host"
Continuing with my investigations of several issues that we have been noticing in our testing of the JDK with macosx 15.x, I have now narrowed down at least 2 separate problems for which I need help. For a quick background, starting with macosx 15.x several networking related tests within the JDK have started failing in very odd and hard to debug ways in our internal lab. Reading through the macos docs and with help from others in these forums, I have come to understand that a lot of these failures are to do with the new restrictions that have been placed for "Local Network" operations. I have read through https://developer.apple.com/documentation/technotes/tn3179-understanding-local-network-privacy and I think I understand the necessary background about these restrictions. There's more than one issue in this area that I will need help with, so I'll split them out into separate topics in this forum. That above doc states: macOS 15.1 fixed a number of local network privacy bugs. If you encounter local network privacy problems on macOS 15.0, retest on macOS 15.1 or later. We did have (and continue to have) 15.0 and 15.1 macos instances within our lab which are impacted by these changes. They too show several networking related failures. However, I have decided not to look into those systems and instead focus only on 15.3.1. People might see unexpected behavior in System Settings > Privacy & Security if they have multiple versions of the same app installed (FB15568200). This feedback assistant issue and several others linked in these documentations are inaccessible (even when I login with my existing account). I think it would be good to have some facility in the feedback assistant tool/site to make such issues visible (even if read-only) to be able to watch for updates to those issues. So now coming to the issue. Several of the networking tests in the JDK do mulicasting testing (through BSD sockets API) in order to test the Java SE multicasting socket API implementations. One repeated failure we have been seeing in our labs is an exception with the message "No route to host". It shows up as: Process id: 58700 ... java.net.NoRouteToHostException: No route to host at java.base/sun.nio.ch.DatagramChannelImpl.send0(Native Method) at java.base/sun.nio.ch.DatagramChannelImpl.sendFromNativeBuffer(DatagramChannelImpl.java:914) at java.base/sun.nio.ch.DatagramChannelImpl.send(DatagramChannelImpl.java:871) at java.base/sun.nio.ch.DatagramChannelImpl.send(DatagramChannelImpl.java:798) at java.base/sun.nio.ch.DatagramChannelImpl.blockingSend(DatagramChannelImpl.java:857) at java.base/sun.nio.ch.DatagramSocketAdaptor.send(DatagramSocketAdaptor.java:178) at java.base/java.net.DatagramSocket.send(DatagramSocket.java:593) (this is just one example stacktrace from java program) That "send0" is implemented by the JDK by invoking the sendto() system call. In this case, the sendto() is returning a EHOSTUNREACH error which is what is then propagated to the application. The forum text editor doesn't allow me to post long text, so I'm going to post the rest of this investigation and logs as a reply.
9
0
714
Mar ’25
sendto() system call doesn't return an error even when there is one
Please consider this very trivial C code, which was run on 15.3.1 of macos: #include <stdio.h> #include <stdlib.h> #include <netinet/in.h> #include <arpa/inet.h> #include "sys/socket.h" #include <string.h> #include <unistd.h> #include <ifaddrs.h> #include <net/if.h> // prints out the sockaddr_in6 void print_addr(const char *msg_prefix, struct sockaddr_in6 sa6) { char addr_text[INET6_ADDRSTRLEN] = {0}; printf("%s%s:%d, addr family=%u\n", msg_prefix, inet_ntop(AF_INET6, &sa6.sin6_addr, (char *) &addr_text, INET6_ADDRSTRLEN), sa6.sin6_port, sa6.sin6_family); } // creates a datagram socket int create_dgram_socket() { const int fd = socket(AF_INET6, SOCK_DGRAM, 0); if (fd < 0) { perror("Socket creation failed"); return -1; } return fd; } int main() { printf("current process id:%ld parent process id: %ld\n", (long) getpid(), (long) getppid()); // // hardcode a link-local IPv6 address of a interface which is down // ifconfig: // ,,, // awdl0: flags=8822<BROADCAST,SMART,SIMPLEX,MULTICAST> mtu 1500 // options=6460<TSO4,TSO6,CHANNEL_IO,PARTIAL_CSUM,ZEROINVERT_CSUM> // ... // inet6 fe80::34be:50ff:fe14:ecd7%awdl0 prefixlen 64 scopeid 0x10 // nd6 options=201<PERFORMNUD,DAD> // media: autoselect (<unknown type>) // status: inactive // const char *ip6_addr_str = "fe80::34be:50ff:fe14:ecd7"; // link-local ipv6 address from above ifconfig output // parse the string literal to in6_addr struct in6_addr ip6_addr; int rv = inet_pton(AF_INET6, ip6_addr_str, &ip6_addr); if (rv != 1) { fprintf(stderr, "failed to parse ipv6 addr %s\n", ip6_addr_str); exit(EXIT_FAILURE); } // create a AF_INET6 SOCK_DGRAM socket const int sock_fd = create_dgram_socket(); if (sock_fd < 0) { exit(EXIT_FAILURE); } printf("created a socket, descriptor=%d\n", sock_fd); // create a destination sockaddr which points to the above // ipv6 link-local address and an arbitrary port const int dest_port = 12345; struct sockaddr_in6 dest_sock_addr; memset((char *) &dest_sock_addr, 0, sizeof(struct sockaddr_in6)); dest_sock_addr.sin6_addr = ip6_addr; dest_sock_addr.sin6_port = htons(dest_port); dest_sock_addr.sin6_family = AF_INET6; dest_sock_addr.sin6_scope_id = 0x10; // scopeid from the above ifconfig output // now sendto() to that address, whose network interface is down. // we expect sendto() to return an error print_addr("sendto() to ", dest_sock_addr); const char *msg = "hello"; const size_t msg_len = strlen(msg) + 1; rv = sendto(sock_fd, msg, msg_len, 0, (struct sockaddr *) &dest_sock_addr, sizeof(dest_sock_addr)); if (rv == -1) { perror("sendto() expectedly failed"); close(sock_fd); exit(EXIT_FAILURE); } printf("sendto() unexpectedly succeeded\n"); // should not reach here, we expect sendto() to return an error return 0; } It creates a SOCK_DGRAM socket and attempts to sendto() to a link-local IPv6 address of a local network interface which is not UP. The sendto() is expected to fail with a "network is down" (or at least fail with some error). Let's see how it behaves. Copy that code to a file called netdown.c and compile it as follows: clang netdown.c Now run the program: ./a.out That results in the following output: current process id:29290 parent process id: 21614 created a socket, descriptor=3 sendto() to fe80::34be:50ff:fe14:ecd7:14640, addr family=30 sendto() unexpectedly succeeded (To reproduce this locally, replace the IPv6 address in that code with a link-local IPv6 address of an interface that is not UP on your system) Notice how the sendto() returned successfully without any error giving an impression to the application code that the message has been sent. In reality, the message isn't really sent. Here's the system logs from that run: PID Type Date & Time Process Message debug 2025-03-13 23:36:36.830147 +0530 kernel Process (a.out) allowed via dev tool environment (/System/Applications/Utilities/Terminal.app/Contents/MacOS/Terminal) debug 2025-03-13 23:36:36.833054 +0530 kernel [SPI][HIDSPI] TX: 80 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 RX: 20 02 00 00 00 00 38 00 10 02 00 17 00 00 2E 00 26700 error 2025-03-13 23:36:36.838607 +0530 nehelper Failed to get the signing identifier for 29290: No such process 26700 error 2025-03-13 23:36:36.838608 +0530 nehelper Failed to get the code directory hash for 29290: No such process default 2025-03-13 23:36:36.840070 +0530 kernel cfil_dispatch_attach_event:3507 CFIL: Failed to get effective audit token for <sockID 22289651233205710 <4f3051d7ec2dce>> 26700 error 2025-03-13 23:36:36.840678 +0530 nehelper Failed to get the signing identifier for 29290: No such process 26700 error 2025-03-13 23:36:36.840679 +0530 nehelper Failed to get the code directory hash for 29290: No such process default 2025-03-13 23:36:36.841742 +0530 kernel cfil_hash_entry_log:6082 <CFIL: Error: sosend_reinject() failed>: [29290 ] <UDP(17) out so 891be95f39bd0385 22289651233205710 22289651233205710 age 0> lport 60244 fport 12345 laddr fe80::34be:50ff:fe14:ecd7 faddr fe80::34be:50ff:fe14:ecd7 hash D7EC2DCE default 2025-03-13 23:36:36.841756 +0530 kernel cfil_service_inject_queue:4466 CFIL: sosend() failed 50 Notice the last line where it states the sosend() (and internal impl detail of macos) failed with error code 50, which corresponds to ENETDOWN ("Network is down"). However, like I noted, this error was never propagated back to the application from the sendto() system call. The documentation of sendto() system call states: man sendto ... Locally detected errors are indicated by a return value of -1. ... RETURN VALUES Upon successful completion, the number of bytes which were sent is returned. Otherwise, -1 is returned and the global variable errno is set to indicate the error. So I would expect sendto() to return -1, which it isn't. The 15.3.1 source of xnu hasn't yet been published but there is the 15.3 version here https://github.com/apple-oss-distributions/xnu/tree/xnu-11215.81.4 and looking at the corresponding function cfil_service_inject_queue, line 4466 (the one which is reported in the logs) https://github.com/apple-oss-distributions/xnu/blob/xnu-11215.81.4/bsd/net/content_filter.c#L4466, the code there logs this error and the cfil_service_inject_queue function then returns back the error. However, looking at the call sites of the call to cfil_service_inject_queue(...), there are several places within that file which don't track the return value (representing an error value) and just ignore it. Is that intentional and does that explain this issue? Does this deserve to be reported as a bug through feedback assistant?
2
0
402
Mar ’25
After the device wake ups, NEFilterDataProvider causes internet access issue intermittently
We have a NEFilterDataProvider extension that intercepts all TCP and UDP IPv4/6 traffic. At times just after wakeup from sleep, it causes internet access issues, such as showing "This site can't be reached" when opening websites. The traffic is not being dropped by the extension. According to the logs, the connection is being closed after approximately 4 minutes. During the issue, the flow logs are as follows: Flow 515129771 is connecting New flow: NEFlow type = stream, app = com.google.Chrome.helper... Detaching, ref count = 2 (logged after ~4 minutes) Sending close, how = 2 Removing from group 2, ref count = 2 Destroying, app tx 0, tunnel tx 0, tunnel rx 0 Closing reads, not closed by plugin Closing writes, not sending close Any suggestions on the possible cause and how to further debug it?
2
0
223
Mar ’25
sendto() system call - Nondeterministic "No route to host" due to local network restrictions
Please consider this trivial C code which deals with BSD sockets. This will illustrate an issue with sendto() which seems to be impacted by the recent "Local Network" restrictions on 15.3.1 macos. #include <stdio.h> #include <stdlib.h> #include <netinet/in.h> #include <arpa/inet.h> #include "sys/socket.h" #include <string.h> #include <unistd.h> #include <ifaddrs.h> #include <net/if.h> // prints out the sockaddr_in6 void print_addr(const char *msg_prefix, struct sockaddr_in6 sa6) { char addr_text[INET6_ADDRSTRLEN] = {0}; printf("%s%s:%d, addr family=%u\n", msg_prefix, inet_ntop(AF_INET6, &sa6.sin6_addr, (char *) &addr_text, INET6_ADDRSTRLEN), sa6.sin6_port, sa6.sin6_family); } // creates a datagram socket int create_dgram_socket() { const int fd = socket(AF_INET6, SOCK_DGRAM, 0); if (fd < 0) { perror("Socket creation failed"); return -1; } return fd; } // returns a string representing the current local time char *current_time() { time_t seconds_since_epoch; time(&seconds_since_epoch); char *res = ctime(&seconds_since_epoch); const size_t len = strlen(res); // strip off the newline character that's at the end of the ctime() output res[len - 1] = '\0'; return res; } // Creates a datagram socket and then sends a messages (through sendto()) to a valid // multicast address. This it does two times, to the exact same destination address from // the exact same socket. // // Between the first and the second attempt to sendto(), there is // a sleep of 1 second. // // The first time, the sendto() succeeds and claims to have sent the expected number of bytes. // However system logs (generated through "log collect") seem to indicate that the message isn't // actually sent (there's a "cfil_service_inject_queue:4466 CFIL: sosend() failed 65" in the logs). // // The second time the sendto() returns a EHOSTUNREACH ("No route to host") error. // // If the sleep between these two sendto() attempts is removed then both the attempts "succeed". // However, the system logs still suggest that the message isn't actually sent. int main() { printf("current process id:%ld parent process id: %ld\n", (long) getpid(), (long) getppid()); // valid multicast address as specified in // https://www.iana.org/assignments/ipv6-multicast-addresses/ipv6-multicast-addresses.xhtml const char *ip6_addr_str = "ff01::1"; struct in6_addr ip6_addr; int rv = inet_pton(AF_INET6, ip6_addr_str, &ip6_addr); if (rv != 1) { fprintf(stderr, "failed to parse ipv6 addr %s\n", ip6_addr_str); exit(EXIT_FAILURE); } // create a AF_INET6 SOCK_DGRAM socket const int sock_fd = create_dgram_socket(); if (sock_fd < 0) { exit(EXIT_FAILURE); } printf("created a socket, descriptor=%d\n", sock_fd); const int dest_port = 12345; // arbitrary port struct sockaddr_in6 dest_sock_addr; memset((char *) &dest_sock_addr, 0, sizeof(struct sockaddr_in6)); dest_sock_addr.sin6_addr = ip6_addr; // the target multicast address dest_sock_addr.sin6_port = htons(dest_port); dest_sock_addr.sin6_family = AF_INET6; print_addr("test will attempt to sendto() to destination host:port -> ", dest_sock_addr); const char *msg = "hello"; const size_t msg_len = strlen(msg) + 1; for (int i = 1; i <= 2; i++) { if (i != 1) { // if not the first attempt, then sleep a while before attempting to sendto() again int num_sleep_seconds = 1; printf("sleeping for %d second(s) before calling sendto()\n", num_sleep_seconds); sleep(num_sleep_seconds); } printf("%s attempt %d to sendto() %lu bytes\n", current_time(), i, msg_len); const size_t num_sent = sendto(sock_fd, msg, msg_len, 0, (struct sockaddr *) &dest_sock_addr, sizeof(dest_sock_addr)); if (num_sent == -1) { fprintf(stderr, "%s ", current_time()); perror("sendto() failed"); close(sock_fd); exit(EXIT_FAILURE); } printf("%s attempt %d of sendto() succeeded, sent %lu bytes\n", current_time(), i, num_sent); } return 0; } What this program does is, it uses the sendto() system call to send a message over a datagram socket to a (valid) multicast address. It does this twice, from the same socket to the same target address. There is a sleep() of 1 second between these two sendto() attempts. Copy that code into noroutetohost.c and compile: clang noroutetohost.c Then run: ./a.out This generates the following output: current process id:58597 parent process id: 21614 created a socket, descriptor=3 test will attempt to sendto() to destination host:port ->ff01::1:14640, addr family=30 Fri Mar 14 20:34:09 2025 attempt 1 to sendto() 6 bytes Fri Mar 14 20:34:09 2025 attempt 1 of sendto() succeeded, sent 6 bytes sleeping for 1 second(s) before calling sendto() Fri Mar 14 20:34:10 2025 attempt 2 to sendto() 6 bytes Fri Mar 14 20:34:10 2025 sendto() failed: No route to host Notice how the first call to sendto() "succeeds", even the return value (that represents the number of bytes sent) matches the number of bytes that were supposed to be sent. Then notice how the second attempt fails with a EHOSTUNREACH ("No route to host") error. Looking through the system logs, it appears that the first attempt itself has failed: 2025-03-14 20:34:09.474797 default kernel cfil_hash_entry_log:6082 <CFIL: Error: sosend_reinject() failed>: [58597 a.out] <UDP(17) out so 891be95f3a70c605 22558774573152560 22558774573152560 age 0> lport 0 fport 12345 laddr :: faddr ff01::1 hash 1003930 2025-03-14 20:34:09.474806 default kernel cfil_service_inject_queue:4466 CFIL: sosend() failed 65 (notice the time on that log messages, they match the first attempt from the program's output log) So even though the first attempt failed, it never got reported back to the application. Then after sleeping for (an arbitrary amount of) 1 second, the second call fails with the EHOSTUNREACH. The system logs don't show any error (at least not the one similar to that previous one) for the second call. If I remove that sleep() between those two attempts, then both the sendto() calls "succeed" (and return the expected value for the number of bytes sent). However, the system logs show that the first call (and very likely even the second) has failed with the exact same log message from the kernel like before. If I'm not wrong then this appears to be some kind of a bug in the "local network" restrictions. Should this be reported? I can share the captured logs but I would prefer to do it privately for this one. Another interesting thing in all this is that there's absolutely no notification to the end user (I ran this program from the Terminal) about any of the "Local Network" restrictions.
4
0
468
Mar ’25
DNS Proxy network extension doesn't start even after saving preferences successfully
Hello, I'm having some problems starting my DNS proxy network extension. Even after I call NEDNSProxyManager.saveToPreference() successfully I don't see any logs from my dns proxy. This is the code from the user space app: import SwiftUI import NetworkExtension func configureDNSProxy() { let dnsProxyManager = NEDNSProxyManager.shared() dnsProxyManager.loadFromPreferences { error in if let error = error { print("Error loading DNS proxy preferences: \(error)") return } dnsProxyManager.localizedDescription = "my DNS proxy" let proto = NEDNSProxyProviderProtocol() proto.providerBundleIdentifier = "com.myteam.dns-proxy-tests.ne" dnsProxyManager.providerProtocol = proto // Enable the DNS proxy. dnsProxyManager.isEnabled = true dnsProxyManager.saveToPreferences { error in if let error = error { print("Error saving DNS proxy preferences: \(error)") } else { NSLog("DNS Proxy enabled successfully") } } } } @main struct dns_proxy_testsApp: App { var body: some Scene { WindowGroup { ContentView() } } init() { configureDNSProxy() } } This is the code for my network extension(DNSProxyProvider.swift): import NetworkExtension class DNSProxyProvider: NEDNSProxyProvider { override func startProxy(options:[String: Any]? = nil, completionHandler: @escaping (Error?) -> Void) { NSLog("dns proxy ne started") completionHandler(nil) } override func stopProxy(with reason: NEProviderStopReason, completionHandler: @escaping () -> Void) { NSLog("dns proxy ne stopped") completionHandler() } override func sleep(completionHandler: @escaping () -> Void) { NSLog("dns proxy ne sleep") completionHandler() } override func wake() { NSLog("dns proxy ne wake") } override func handleNewFlow(_ flow: NEAppProxyFlow) -> Bool { NSLog("dns proxy ne flow") return true } } The bundle identifier for my network extension is: com.myteam.dns-proxy-tests.ne and both the user space app and the network extension have the DNS Proxy capability. Both have the same app group capability with the same group name group.com.myteam.dns-proxy-test. The info.plist from the network extension look like this(I didn't really modify it from the default template created by xcode) <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> <key>NetworkExtension</key> <dict> <key>NEMachServiceName</key> <string>$(TeamIdentifierPrefix)com.example.app-group.MySystemExtension</string> <key>NEProviderClasses</key> <dict> <key>com.apple.networkextension.dns-proxy</key> <string>$(PRODUCT_MODULE_NAME).DNSProxyProvider</string> </dict> </dict> </dict> </plist> In the logs I do see DNS Proxy enabled successfully and also I see: NESMDNSProxySession[Primary Tunnel:my DNS proxy:<...>:(null)] starting with configuration: { name = my DNS proxy identifier = <..> applicationName = dns-proxy-tests application = com.myteam.dns-proxy-tests grade = 1 dnsProxy = { enabled = YES protocol = { type = dnsProxy identifier = <...> identityDataImported = NO disconnectOnSleep = NO disconnectOnIdle = NO disconnectOnIdleTimeout = 0 disconnectOnWake = NO disconnectOnWakeTimeout = 0 disconnectOnUserSwitch = NO disconnectOnLogout = NO includeAllNetworks = NO excludeLocalNetworks = NO excludeCellularServices = YES excludeAPNs = YES excludeDeviceCommunication = YES enforceRoutes = NO pluginType = com.myteam.dns-proxy-tests providerBundleIdentifier = com.myteam.dns-proxy-tests.ne designatedRequirement = identifier "com.myteam.dns-proxy-tests.ne" <...> /* exists */ } } } But then I see: Checking for com.myteam.dns-proxy-tests.ne - com.apple.networkextension.dns-proxy But then finally Found 0 registrations for com.myteam.dns-proxy-tests.ne (com.apple.networkextension.dns-proxy) So I think that last log probably indicates the problem. I'm a bit lost at what I'm doing wrong so I'd be super thankful for any pointer!
17
0
709
Mar ’25
Local Network Permission Issue
We're experiencing an issue with Local Network Permission. When trying to connect to a socket, the Local Network Permission alert pops up. To trigger the permission request at the start of the app, we used the following code to ask for permission and receive a callback on whether it's granted. However, this approach doesn't always trigger the permission alert, or it gets automatically dismissed after 30 seconds, only to reappear later. What could be causing this inconsistent behavior? func checkLocalNetworkPermission(_ completed: Optional&lt;(Bool) -&gt; Void&gt; = .none) { DispatchQueue.global(qos: .userInitiated).async { let hostName = ProcessInfo.processInfo.hostName let isGranted = hostName.contains(".local") if let completed { DispatchQueue.main.async { completed(isGranted) } } } }
1
0
244
Mar ’25
SecTrustEvaluateAsyncWithError keeps complaining “'DigiCert Global Root G3' certificate is not trusted" with self signed CA on iOS
I created a self signed CA and use it to generate/sign a client cert using openssl. Then I use the self signed client cert to do TLS client authentication with my server (which also uses the self signed CA). The issue I have is when I validate the self signed CA, by calling SecTrustEvaluateAsyncWithError, it always complains this error “'DigiCert Global Root G3' certificate is not trusted". However that CA (DigiCert Global Root G3) is not my self signed CA (my CA is 'MQTTSampleCA' and I attached a dump of the my CA cert in the PR in the end of this post), so I'm confused why the API keeps complaining that CA. After some researching, I see that is a well known CA so I download its cert from https://www.digicert.com/kb/digicert-root-certificates.htm, install and trust it on my iOS device, but that doesn't help and I still get the same error. I provide all the repro steps in this PR: https://github.com/liumiaojq/EmCuTeeTee/pull/1, including how I generate the certs and the source codes of a test app that I used to do cert validation. I appreciate if anyone can share insights how to resolve this error.
1
0
315
Mar ’25
PF rules issue on MacOS 15
Hey! We are investigating a problem pf rules being ignored by some processes. Despite blocking all traffic, some outgoing unicast packets can be seen in tcpdump. Issue is present in MacOS 15.0.0 - 15.3.1 (Newest at the time of writing). I tested MacOS 14.7.4 and pf rules there behaved as expected. Steps to reproduce the issue: $ cat pf.conf block all $ sudo pfctl -e -F all -f ./pf.conf Password: pfctl: Use of -f option, could result in flushing of rules present in the main ruleset added by the system at startup. See /etc/pf.conf for further details. No ALTQ support in kernel ALTQ related functions disabled rules cleared nat cleared dummynet cleared 0 tables deleted. 196 states cleared source tracking entries cleared pf: statistics cleared pf: interface flags reset pfctl: pf already enabled After executing these commands MacOS 14 will block all outgoing unicast traffic, and on MacOS 15 data can be sent to arbitrary addresses: $ ifconfig en0 en0: flags=8863<UP,BROADCAST,SMART,RUNNING,SIMPLEX,MULTICAST> mtu 1500 options=6460<TSO4,TSO6,CHANNEL_IO,PARTIAL_CSUM,ZEROINVERT_CSUM> ether b6:5e:a5:c5:1e:db inet6 fe80::1090:9c8:4325:329a%en0 prefixlen 64 secured scopeid 0xe inet 192.168.50.144 netmask 0xffffff00 broadcast 192.168.50.255 nd6 options=201<PERFORMNUD,DAD> media: autoselect status: active $ sudo tcpdump -k A -i any -n src 192.168.50.144 tcpdump: data link type PKTAP tcpdump: verbose output suppressed, use -v[v]... for full protocol decode listening on any, link-type PKTAP (Apple DLT_PKTAP), snapshot length 524288 bytes 12:05:12.673472 (en0, proc com.apple.geod:1286:, svc BE, out, ch, flowid 0x0, ttag 0x0, dlt 0x1, cmpgc 0x0) IP 192.168.50.144.52012 > 17.253.15.196.443: Flags [P.], seq 1888882378:1888882402, ack 3554898220, win 2048, options [nop,nop,TS val 2752050055 ecr 1291585385], length 24 12:05:13.793937 (en0, proc com.apple.WebKit:974:, eproc Safari:804:, svc BE, out, ch, flowid 0x0, ttag 0x0, dlt 0x1, cmpgc 0x0) IP 192.168.50.144.52024 > 3.65.102.105.443: Flags [P.], seq 2011312019:2011312073, ack 673002582, win 2048, options [nop,nop,TS val 777228223 ecr 484269939], length 54 Was there any change in the way pfctl is used or is this a bug? This issue affects negatively privacy features of our product.
1
0
321
Mar ’25
Is changing macOS Network Locations programmatically allowed in Mac App Store apps?
I would like to develop a macOS app that would automatically switch Network Locations based on certain criteria. I want to publish this on the Mac App Store, but I'm unsure if this functionality is permitted. I've searched through the App Store Review Guidelines and documentation on NetworkExtension and SystemConfiguration frameworks, but I haven't found clear information on whether: Programmatically changing Network Locations is allowed in sandboxed App Store apps What specific entitlements would be required If there are any API-approved ways to do this without shell commands I'd like to avoid investing significant development time if this type of functionality would ultimately be rejected. As a relatively new Apple platform developer, any guidance on: The appropriate frameworks/APIs to use Required entitlements Whether this functionality is even permitted for App Store distribution would be incredibly helpful. Thank you in advance for any insights!
2
0
213
Mar ’25
WiFi Connect Error
When I used the iPhone 11 to scan the wifi connection, the system reported an error,   ‘’’ let config = NEHotspotConfiguration(ssid: name, passphrase: passwd, isWEP: false) let manager = NEHotspotConfigurationManager() manager.apply(config) { error in      } ’’’ NEHotspotConfigurationErrorDomain Code=8 “internal error.” , the only thins that fixes this issue it restarting the iPhone. What is the reason for this and how to solve it? Reference link: https://developer.apple.com/forums/thread/111638 https://cloud.tencent.com/developer/ask/sof/114654981
1
0
79
Mar ’25
SSH app
Hello. I would like to develop an application that sends SSH commands via my phone to the server. I know that applications of this type exist, but they are not suitable for my use as a blind person who uses a screen reader. I hope you can help me find libraries that will assist me in development, or ready-made, open-source projects that I can develop and modify if necessary. Thank you in advance.
1
0
58
Mar ’25
Unexpected partition property set on cookies in iOS 18.4 beta
On iOS 18.3, I noted that partition "HTTPCookiePropertyKey: StoragePartition" is not observed to be set for cookies returned from the wkwebview cookie store. Now on 18.4 beta 4 we are now seeing those same cookies are populated with a partition property. Is there documentation for this change? Is it intended to be suddenly populated in 18.4? Now that partition property is set, HTTPCookieStorage.shared.cookies(for: serverUri) doesn't seem to return the expected cookies correctly. For context, we are using the cookies extracted from wkwebview, setting them in HTTPCookieStorage.shared and using URLSession to make network calls outside the webivew. Works fine once I forcefully set partition on the cookie to nil. More details on what the cookie looks like here: https://feedbackassistant.apple.com/feedback/16906526 Hopefully this is on your radar?
1
0
254
Mar ’25