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

iOS VPN: Loss of Internet Connectivity on iOS Device post Packet Tunnel Crashes
Title: Loss of Internet Connectivity on iOS Device When Packet Tunnel Crashes Feedback ticket: https://feedbackassistant.apple.com/feedback/14162605 Product: iPhone 12 Version: iOS - 17.5.1 Configuration: NETunnelProviderManager Configuration Description: We are developing an iOS VPN client and have configured our packet tunnel provider according to Apple's guidelines. The configuration is as follows: includeAllNetworks = YES excludeLocalNetworks = NO enforceRoutes = NO This setup works as expected when the VPN successfully connects. However, we encounter a blocker issue where the device loses internet connectivity if the packet tunnel crashes. Steps to Reproduce: Configure the NETunnelProviderManager with the above settings. Connect the VPN, which successfully establishes a connection. Verify that resources are accessible and internet connectivity is functional. Packet tunnel to crash unexpectedly.Observe that the NE process (Packet Tunnel) restarts automatically, as expected and attempts to reconnect the VPN; however, the device now lacks internet connectivity, preventing VPN reconnection. Try accessing resources using Safari or any other internet-dependent app, resulting in an error indicating the device is not connected to the internet. Actual Results: The device loses internet connectivity after the packet tunnel crashes and fails to regain it automatically, preventing the VPN from reconnecting. Expected Results: The device should maintain internet connectivity or recover connectivity to allow the VPN to reconnect successfully after the packet tunnel process restarts. Workaround - iPhone device needs a restart to regain internet connectivity .
2
0
580
Jul ’24
Crash in connection loader from CFNetwork with stack traces referring to internal Apple SDKs
We found there is a significant crash reports (most of them are from iOS 17, the rest are iOS 16 and 15) comes from network loader from CFNetwork. Apparently it seems there are two types of crashes if we checked from the stack trace, the one we found from both Xcode organizer and 3rd party crash reporter is referring to URLConnectionLoader::loadWithWhatToDo and the other one from our 3rd party crash reporter (didn’t found the report from Xcode organizer) referring to _CFURLResponseCreateFromArchiveList (this one only happened on iOS 17.5 and later devices). It seems that they are both kinda similar which might point to the same root cause. From what I’ve seen, we never touch the lower level API directly, we usually use the URLSession to manage our API request. The crashed stack trace also didn’t give any indication about which of our app code that triggered the crash, it only shows calls to Apple’s internal SDKs so we are unsure how to approach this issue meanwhile the crash event already reached 800+ in the last 30 days. Unfortunately, we cannot reproduce the issue as the stack trace itself seems unclear to us. I have submitted a report through feedback assistant with number: FB14679252. Would appreciate if anyone can give any advice on what we can do to avoid this in the future and probably any hint on why it could happened. Hereby I attached the crash reports that we found each from Xcode crash report and our 3rd party crash reporter (the report said it crashed on com.apple.CFNetwork.LoaderQ) so you could get a glimpse of the similarity. Xcode crash report xcode crash report.crash 3rd party crash report 3rd party crash report.txt
5
1
1.6k
Aug ’24
Unable to recover after URLSession encounters the SSL error -9816
For years our iOS apps have experienced a networking problem, which blocks them connecting to our servers via their API endpoint domains. How can we recover after the scenario described below? Using 3rd party error logging solutions, which have different endpoint domains, we can record the error: NSUnderlyingError": Error Domain=kCFErrorDomainCFNetwork Code=-1200 "(null)" UserInfo={_kCFStreamPropertySSLClientCertificateState=0, _kCFNetworkCFStreamSSLErrorOriginalValue=-9816, _kCFStreamErrorDomainKey=3, _kCFStreamErrorCodeKey=-9816, _NSURLErrorNWPathKey=satisfied (Path is satisfied), viable, interface: pdp_ip0[lte], ipv4, dns, expensive, uses cell}, "_NSURLErrorFailingURLSessionTaskErrorKey": LocalDataTask <DEDBFA4D-810D-4438-A6A0-95E3B9668B9E>.<308>, "_kCFStreamErrorDomainKey": 3, "_NSURLErrorRelatedURLSessionTaskErrorKey": <__NSSingleObjectArrayI 0x301f82e60>( LocalDataTask <DEDBFA4D-810D-4438-A6A0-95E3B9668B9E>.<308> ) "NSLocalizedDescription": An SSL error has occurred and a secure connection to the server cannot be made., "NSLocalizedRecoverySuggestion": Would you like to connect to the server anyway? -9816 is the "server closed session with no notification" error based on comments in CoreFoundation source files. Subsequent API endpoint calls to the same domain return the same error. The SSL error occurs most prevalently after a server outage. However, despite our best efforts, we have been unable to replicate triggering the problem for development purposes via experiments with our server. When the error occurs the users report that: Fully closing (i.e. not just sending to background) and reopening the app does NOT clear connectivity to our server being blocked. Problem seems more prevalent when using mobile/cell data. Switching from mobile/cell data to WIFI resolves the connection problem and then switching back to mobile/cell data shows the problem again. So the underlying problem is not cleared. All other apps on the same device and mobile/cell data or WIFI connection, like Safari, have no problems connecting to the Internet. Deleting and reinstalling, or updating (when an update is available) resolves the problem. Or after waiting a few days the problem seems to resolve itself. The last two point above suggest that something is persisted/cached in the app preventing it from connecting properly with subsequent network attempts. Notes: We have one shared instance of the URLSession in the app for its networking because we are aware of the perils of multiple URLSession instances. We recently added conditions to call the URLSession await reset() method when detecting the SLL errors before repeating the request. It is debatable whether this reduces the problem as we still see logged cases with the subsequent requests hitting the same -9816 error. URLSession configuration: let config = URLSessionConfiguration.default config.timeoutIntervalForResource = 22 config.timeoutIntervalForRequest = 20 config.requestCachePolicy = .reloadIgnoringLocalCacheData config.urlCache = nil
7
3
1.5k
Aug ’24
RCS failing on iOS 18 when VPN active
When a VPN is active, RCS messaging does not work on iOS 18. I work on an iOS VPN app, and we were very appreciative of the excludeCellularServices network flag that was released during the iOS 16 cycle. It's a great solution to ensure the VPN doesn't interfere with cellular network features from the cellular provider. Separately - As a user, I'm excited that iOS 18 includes RCS messaging. Unfortunately, RCS messaging is not working when our VPN is active (when checking on the iOS 18 release candidate). My guess is that RCS is not excluded from the VPN tunnel, even when excludeCellularServices is true. It seems like RCS should be added in this situation, as it is a cell provider service. Can RCS be added as a service that is excluded from the VPN tunnel when excludeCellularServices is true? (I've also sent this via feedback assistant, as 15094270.)
11
4
2.4k
Sep ’24
Local Network permission prompt for daemon on macOS 15
Hi Team, OS is prompting for local network permission for our application which runs as root level daemon. As per the our analysis, it looks like it is prompting from our own library which is trying to get network info ' using /usr/sbin/system_profiler with "-xml -detailLevel basic SPNetworkDataType" and then trying to iterate to find DNS.ServerAddresses for each item. Then using [NSHost hostWithAddress:IPAddress];(When this library is not linked to the app then there is no prompt, so most likely this is the code that is resulting in the prompt). Is this expected ? . Is there any other way that we can get DNS host name without being prompted for local network permission on mac OS 15
28
2
4k
Sep ’24
How to find WHY my app triggers LNP popoup on MacOS 15
My App is a rather small menu-bar status-item app with 2 informational windows. It does NOT make use of ANY of the APIs mentioned here: https://developer.apple.com/forums/thread/663874 that are bound to need "Local Network" hence trigger TCC dialog. Yet - on first run of the app, the dialog pops. App is Obj-C, and the only APIs used are Notification-Center (for scheduling local notifications to the user), XPC connections and calls to other (our) apps for gathering that information, plus normal AppKit windowing (Controls, Text-fields, etc.) nothing else. Obviously SOMETHING I do causes the thing - and I know for sure this app DOES NOT NEED access to the local network - only I do not know how to identify the specific API I need to avoid using (or change the way I'm using) Are there any specific system logs to watch for? Is there any official set of APIs that will trigger the dialog? Provided that I cannot avoid this - could this permission be granted via MDM profile payload? Our product comes with
8
1
867
Sep ’24
A server with the specified hostname could not be found exception
Hi, I have been working on the app that implements DNS Proxy Extension for a while now, and after a couple builds to TestFlight I noticed that I got a couple crashes that seem to be triggered by EXC_BREAKPOINT (SIGTRAP) After some investigation, it was found that crashes are connected to CFNetwork framework. So, I decided to additionally look into memory issues, but I found the app has no obvious memory leaks, no memory regression (within recommended 25%, actual value is at 20% as of right now), but the app still uses 11mb of memory footprint and most of it (6.5 mb is Swift metadata). At this point, not sure what's triggering those crashes, but I noticed that sometimes app will return message like this to the console (this example is for PostHog api that I use in the app): Task <0ABDCF4A-9653-4583-9150-EC11D852CA9E>.<1> finished with error [18 446 744 073 709 550 613] Error Domain=NSURLErrorDomain Code=-1003 "A server with the specified hostname could not be found." UserInfo={_kCFStreamErrorCodeKey=8, NSUnderlyingError=0x1072df0f0 {Error Domain=kCFErrorDomainCFNetwork Code=-1003 "(null)" UserInfo={_kCFStreamErrorDomainKey=12, _kCFStreamErrorCodeKey=8, _NSURLErrorNWResolutionReportKey=Resolved 0 endpoints in 2ms using unknown from cache, _NSURLErrorNWPathKey=satisfied (Path is satisfied), interface: en0[802.11], ipv4, dns, uses wifi}}, _NSURLErrorFailingURLSessionTaskErrorKey=LocalUploadTask <0ABDCF4A-9653-4583-9150-EC11D852CA9E>.<1>, _NSURLErrorRelatedURLSessionTaskErrorKey=( "LocalUploadTask <0ABDCF4A-9653-4583-9150-EC11D852CA9E>.<1>" ), NSLocalizedDescription=A server with the specified hostname could not be found., NSErrorFailingURLStringKey=https://us.i.posthog.com/batch, NSErrorFailingURLKey=https://us.i.posthog.com/batch, _kCFStreamErrorDomainKey=12} If DNS Proxy Provider uses custom DoH server for resolving packets, could the cache policy for URLSession be a reason? I had a couple other ideas (HTTP3 failure, CFNetwork core issues like described here) but not sure if they are valid Would be grateful if someone could give me a hint of what I should look at
19
1
3.4k
Sep ’24
How to set NEDNSSettings port, or how to bind on port 53 for MacOS Network Extension?
In my Packet Tunnel Provider, I'm setting the NEDNSSettings to localhost as I have a local DNS server listening on port 53 (this is a dns forwarder which conditionally forwards to different upstreams based on rules). On iOS it works just fine, I'm able to listen on localhost:53 in the Network Extension, then set NEDNSSettings servers to "127.0.0.1". However on macOS due to the port being under 1024, I get a Permission denied OS code 13 error. I'm assuming this is due to the Network Extension not running as root. Can this be changed? This could be rectified if you could customize the port in NEDNSSettings, as the listener could be on port 5353, but it doesn't look like it is possible? Just wondering if there is some other way to accomplish what I'm trying to do in the macOS Network Extension?
6
0
486
Sep ’24
What is the command to list all socket filters/extensions in use?
I am in the middle of investigating an issue arising in the call to setsockopt syscall where it returns an undocumented and unexpected errno. As part of that, I'm looking for a way to list any socket content filters or any such extensions are in play on the system where this happens. To do that, I ran: systemextensionsctl list That retuns the following output: 0 extension(s) which seems to indicate there's no filters or extensions in play. However, when I do: netstat -s among other things, it shows: net_api: 2 interface filters currently attached 2 interface filters currently attached by OS 2 interface filters attached since boot 2 interface filters attached since boot by OS ... 4 socket filters currently attached 4 socket filters currently attached by OS 4 socket filters attached since boot 4 socket filters attached since boot by OS What would be the right command/tool/options that I could use to list all the socket filters/extensions (and their details) that are in use and applicable when a call to setsockopt is made from an application on that system? Edit: This is on a macosx-aarch64 with various different OS versions - 13.6.7, 14.3.1 and even 14.4.1.
8
0
805
Sep ’24
macOS Sequoia No Route to Host on first request. Retries work.
My app has local network permission on macOS Sequoia and works in most cases. I've noticed that after unlocking my MacBook Pro, the very first request will regularly fail with a No Route to Host. A simple retry resolves the issue, but I would have expected the very first request to succeed. Is this is a known issue on macOS Sequoia or by design? I'd prefer not to add a retry for this particular request as the app is a network utility.
6
1
1.9k
Oct ’24
Does URLSession support ticket-based TLS session resumption
My company has a server that supports ticket-based TLS session resumption (per RFC 5077). We have done Wireshark captures that show that our iOS client app, which uses URLSession for REST and WebSocket connections to the server, is not sending the TLS "session_ticket" extension in the Client Hello package that necessary to enable ticket-based resumption with the server. Is it expected that URLSession does not support ticket-based TLS session resumption? If "yes", is there any way to tell URLSession to enable ticket-based session resumption? the lower-level API set_protocol_options_set_tls_tickets_enabled() hints that the overall TLS / HTTP stack on IOS does support ticket-based resumption, but I can't see how to use that low-level API with URLSession. I can provide (lots) more technical details if necessary, but hopefully this is enough context to determine whether ticket-based TLS resumption is supported with URLSession. Any tips / clarifications would be greatly appreciated.
6
2
645
Oct ’24
IOS app on MacOS 15 local network access
Our app is developed for iOS, but some users also run it on macOS (as an iOS app via Apple Silicon). The app requires local network permission, which works perfectly on iOS. Previously, the connection also worked fine on macOS, but since the recent macOS update, the app can no longer connect to our device. Additionally, our app on macOS doesn't prompt for local network permission at all, whereas it does on iOS. Is this a known issue with iOS apps running on macOS? Has anyone else experienced this problem, or is there a workaround? Any help would be appreciated!
9
0
852
Oct ’24
How to Reply to a Message Received by Multicast Receiver and Extract Connection for Communication
Hello everyone, I’m currently working on a Swift project using the Network framework to create a multicast-based communication system. Specifically, I’m implementing both a multicast receiver and a sender that join the same multicast group for communication. However, I’ve run into some challenges with the connection management, replying to multicast messages, and handling state updates for both connections and connection groups. Below is a breakdown of my setup and the specific issues I’ve encountered. I have two main parts in the implementation: the multicast receiver and the multicast sender. The goal is for the receiver to join the multicast group, receive messages from the sender, and send a reply back to the sender using a direct connection. Multicast Receiver Code: import Network import Foundation func setupMulticastGroup() -> NWConnectionGroup? { let multicastEndpoint1 = NWEndpoint.hostPort(host: NWEndpoint.Host("224.0.0.1"), port: NWEndpoint.Port(rawValue: 45000)!) let multicastParameters = NWParameters.udp multicastParameters.multipathServiceType = .aggregate do { let multicastGroup = try NWMulticastGroup(for: [multicastEndpoint1], from: nil, disableUnicast: false) let multicastConnections = NWConnectionGroup(with: multicastGroup, using: multicastParameters) multicastConnections.stateUpdateHandler = InternalConnectionStateUpdateHandler multicastConnections.setReceiveHandler(maximumMessageSize: 16384, rejectOversizedMessages: false, handler: receiveHandler) multicastConnections.newConnectionHandler = newConnectionHandler multicastConnections.start(queue: .global()) return multicastConnections } catch { return nil } } func receiveHandler(message: NWConnectionGroup.Message, content: Data?, isComplete: Bool) { print("Received message from \(String(describing: message.remoteEndpoint))") if let content = content, let messageString = String(data: content, encoding: .utf8) { print("Received Message: \(messageString)") } let remoteEndpoint = message.remoteEndpoint message.reply(content: "Multicast group on 144 machine ACK from recv handler".data(using: .utf8)) if let connection = multicastConnections?.extract(connectionTo: remoteEndpoint) { connection.stateUpdateHandler = InternalConnectionRecvStateUpdateHandler connection.start(queue: .global()) connection.send(content: "Multicast group on 144 machine ACK from recv handler".data(using: .utf8), completion: NWConnection.SendCompletion.contentProcessed({ error in print("Error code: \(error?.errorCode ?? 0)") print("Ack sent to \(connection.endpoint)") })) } } func newConnectionHandler(connection: NWConnection) { connection.start(queue: .global()) connection.send(content: "Multicast group on 144 machine ACK".data(using: .utf8), completion: NWConnection.SendCompletion.contentProcessed({ error in print("Error code: \(error?.errorCode ?? 0)") print("Ack sent to \(connection.endpoint)") })) } func InternalConnectionRecvStateUpdateHandler(_ pState: NWConnection.State) { switch pState { case .setup: NSLog("The connection has been initialized but not started") case .preparing: NSLog("The connection is preparing") case .waiting(let error): NSLog("The connection is waiting for a network path change. Error: \(error)") case .ready: NSLog("The connection is established and ready to send and receive data.") case .failed(let error): NSLog("The connection has disconnected or encountered an error. Error: \(error)") case .cancelled: NSLog("The connection has been canceled.") default: NSLog("Unknown NWConnection.State.") } } func InternalConnectionStateUpdateHandler(_ pState: NWConnectionGroup.State) { switch pState { case .setup: NSLog("The connection has been initialized but not started") case .waiting(let error): NSLog("The connection is waiting for a network path change. Error: \(error)") case .ready: NSLog("The connection is established and ready to send and receive data.") case .failed(let error): NSLog("The connection has disconnected or encountered an error. Error: \(error)") case .cancelled: NSLog("The connection has been canceled.") default: NSLog("Unknown NWConnection.State.") } } let multicastConnections = setupMulticastGroup() RunLoop.main.run() Multicast Sender Code: import Foundation import Network func setupConnection() -> NWConnection { let params = NWParameters.udp params.allowLocalEndpointReuse = true return NWConnection(to: NWEndpoint.hostPort(host: NWEndpoint.Host("224.0.0.1"), port: NWEndpoint.Port(rawValue: 45000)!), using: params) } func sendData(using connection: NWConnection, data: Data) { connection.send(content: data, completion: .contentProcessed { nwError in if let error = nwError { print("Failed to send message with error: \(error)") } else { print("Message sent successfully") } }) } func setupReceiveHandler(for connection: NWConnection) { connection.receive(minimumIncompleteLength: 1, maximumLength: 65000) { content, contentContext, isComplete, error in print("Received data:") print(content as Any) print(contentContext as Any) print(error as Any) setupReceiveHandler(for: connection) } } let connectionSender = setupConnection() connectionSender.stateUpdateHandler = internalConnectionStateUpdateHandler connectionSender.start(queue: .global()) let sendingData = "Hello, this is a multicast message from the process on mac machine 144".data(using: .utf8)! sendData(using: connectionSender, data: sendingData) setupReceiveHandler(for: connectionSender) RunLoop.main.run() Issues Encountered: Error Code 0 Even When Connection Refused: On the receiver side, I encountered this log: nw_socket_get_input_frames [C1.1.1:1] recvmsg(fd 8, 9216 bytes) [61: Connection refused] Error code: 0 Ack sent to 10.20.16.144:62707 Questions: how do I reply to the message if above usage pattern is wrong? how do I get a NWConnection from the received message to create a separate connection for communication with the sender. Any insights or suggestions on resolving these issues or improving my multicast communication setup would be greatly appreciated. Thanks :)
4
0
641
Oct ’24
IP Address for Socket Server and Client
I am developing an App using the Networking framework, which can be either a Socket Server or a Socket Client, such that 2 devices can communicate remotely. For the most part I have it working, except: I am not sure of the best way to determine the IP Address for the Socket Server in order to allow the Client app to connect. I am currently using either of Cloud Functions, or lookup webpages (such as ipify.org) and even reading the IP addresses locally from within the device (this returns many, but not all of them connect successfully). These options seem to work if the Socket Server app is connected to the internet with an IPv6 address, but I find that when the Socket Server app is connected with an IPv4 address, the Client app never successfully connects. How should I: a) force the Socket Server app to have/use an IPV6 address at all times? or b) allow the Client app to connect successfully via an IPv4 address? And is there a simple way to know what IP Address the Socket Server is listening from?
8
0
711
Oct ’24
Outgoing SSL connections fail on macOS 15, work fine on earlier versions
The OpenSSL library interface to Allegro Common Lisp system stopped working with macOS 15.x (15.0.1 and 15.1). We have tried many versions of OpenSSL. 1.1.1t (which we built ourselves), 3.0.x, 3.3.x, 3.4.0. All work fine on macOS 14 and earlier. All fail on macOS 15. What is bizarre about the failure: we can load the SSL libraries fine, but when we try to make an outgoing connection it fails (with varying errors). Also, trying to use lldb to debug just hangs, once we step into the SSL libraries. More specifically, using Homebrew OpenSSL 3.0.15 gives an exception that we see in lldb, but we cannot step into SSL_ctrl(), which is in libssl.3.dylib, provided by Homebrew. We have also tried a version of OpenSSL 1.1.1t that we built ourselves (and codesigned and is included in the notarized app), and it fails with a SEGV, rather than the error below, which is using 3.0.15: What started this were errors using the OpenSSL libraries. Here's the use case: cl-user(2): (net.aserve.client:do-http-request "https://franz.com") (net.aserve.client:do-http-request "https://franz.com") Error: Received signal number 0 [condition type: synchronous-operating-system-signal] Restart actions (select using :continue): 0: Return to Top Level (an "abort" restart). 1: Abort entirely from this (lisp) process. [1] cl-user(3): :zo :all t :count 5 :zo :all t :count 5 Evaluation stack: ... 5 more newer frames ... (excl::SSL_ctrl 6133462816 55 ...) (excl::ssl-device-open-common #<excl::ssl-client-stream closed fd # @ #x3079fed32> nil ...) ->((method device-open (excl::ssl-client-stream t t)) #<excl::ssl-client-stream closed fd # @ #x3079fed32> t ...) ((:internal (:effective-method 3 nil nil nil t) 0) #<excl::ssl-client-stream closed fd # @ #x3079fed32> t ...) ((:runsys sys::lisp_apply)) [... excl::function_lisp_apply ] (excl::caching-miss #<standard-generic-function device-open> (# t #) ...) [... device-open ] ... more older frames ... [1] cl-user(4): If you want to see the problem for yourself, I created a new, signed and notarized version of our application https://franz.com/ftp/pri/layer/acl11.0express-macos-arm64.dmg. To use it, install Homebrew and do brew install openssl@3.0, then execute the following to get the error: cd /Applications/AllegroCL64express.app/Contents/Resources env ACL_OPENSSL_VERSION=30 DYLD_LIBRARY_PATH="$(brew --prefix openssl@3.0)/lib:$DYLD_LIBRARY_PATH" ./alisp (progn (require :ssl)(require :aserve)) (net.aserve.client:do-http-request "https://franz.com") You should get the error shown above. Here's what we see when we set a breakpoint at SSL_ctrl: lldb alisp _regexp-env ACL_OPENSSL_VERSION=30 _regexp-env DYLD_LIBRARY_PATH=/opt/homebrew/opt/openssl@3.0/lib: br s -n SSL_ctrl run (progn (require :ssl)(require :aserve)) (net.aserve.client:do-http-request "https://franz.com") Then, we see this: cl-user(2): (net.aserve.client:do-http-request "https://franz.com") (net.aserve.client:do-http-request "https://franz.com") Process 5886 stopped * thread #1, queue = 'com.apple.main-thread', stop reason = breakpoint 1.2 frame #0: 0x0000000102081090 libssl.3.dylib`SSL_ctrl libssl.3.dylib`SSL_ctrl: -> 0x102081090 <+0>: stp x20, x19, [sp, #-0x20]! 0x102081094 <+4>: stp x29, x30, [sp, #0x10] 0x102081098 <+8>: add x29, sp, #0x10 0x10208109c <+12>: mov x20, x2 (lldb) si <<<hang here>>> Again, it only started with macOS 15. We have not seen this on any previous version. More detail: $ codesign -vvvv /Applications/AllegroCL64express.app /Applications/AllegroCL64express.app: valid on disk /Applications/AllegroCL64express.app: satisfies its Designated Requirement $ $ codesign -d --entitlements - /Applications/AllegroCL64express.app Executable=/Applications/AllegroCL64express.app/Contents/MacOS/AllegroCL64express [Dict] [Key] com.apple.security.cs.allow-dyld-environment-variables [Value] [Bool] true [Key] com.apple.security.cs.allow-jit [Value] [Bool] true [Key] com.apple.security.cs.disable-library-validation [Value] [Bool] true [Key] com.apple.security.get-task-allow [Value] [Bool] true $ The other thing we noticed in debugging this is even though we set DYLD_LIBRARY_PATH, another libssl seemed to be found by lldb. For example, in this case 3 versions of SSL_new were found by lldb: $ lldb alisp (lldb) target create "alisp" Current executable set to '/Applications/AllegroCL64express.app/Contents/Resources/alisp' (arm64). (lldb) _regexp-env ACL_OPENSSL_VERSION=30 (lldb) _regexp-env DYLD_LIBRARY_PATH=/opt/homebrew/opt/openssl@3.0/lib: (lldb) br s -n SSL_new br s -n SSL_new Breakpoint 1: 2 locations. (lldb) run Process 6339 launched: '/Applications/AllegroCL64express.app/Contents/Resources/alisp' (arm64) Copyright (C) 1985-2023, Franz Inc., Lafayette, CA, USA. All Rights Reserved. ... CL-USER(1): (progn (require :ssl)(require :aserve)) ; Fast loading ; /Applications/AllegroCL64express.app/Contents/Resources/code/SSL.002 ... T CL-USER(2): (net.aserve.client:do-http-request "https://franz.com") Process 6339 stopped * thread #1, queue = 'com.apple.main-thread', stop reason = breakpoint 1.3 frame #0: 0x00000001020803ec libssl.3.dylib`SSL_new libssl.3.dylib`SSL_new: -> 0x1020803ec <+0>: stp x20, x19, [sp, #-0x20]! 0x1020803f0 <+4>: stp x29, x30, [sp, #0x10] 0x1020803f4 <+8>: add x29, sp, #0x10 0x1020803f8 <+12>: cbz x0, 0x102080700 ; <+788> (lldb) br list Current breakpoints: 1: name = 'SSL_new', locations = 3, resolved = 3, hit count = 1 1.1: where = libboringssl.dylib`SSL_new, address = 0x0000000193f1b160, resolved, hit count = 0 1.2: where = libssl.48.dylib`SSL_new, address = 0x000000026907f64c, resolved, hit count = 0 1.3: where = libssl.3.dylib`SSL_new, address = 0x00000001020803ec, resolved, hit count = 1 (lldb) We are out of ideas on how to debug this.
23
0
1.5k
Oct ’24
Content Filter: sourceAppAuditToken empty only for Firefox
Starting on macOS Sequoia, flows originated in Firefox have an empty sourceAppAuditToken. Other apps contain a valid token. Background: in order to fetch process info for a certain NEFilterFlow, my content filter extension uses sourceAppAuditToken, audit_token_to_pid() and proc_* (as recommended in #126820). When that fails, we use SecCodeCopyGuestWithAttributes, recommended in some other thread as a better alternative. Both approaches break when the sourceAppAuditToken is empty since they need the pid. Debugging: My logging shows audit token is empty for Firefox Typical logs from com.apple.networkextension also indicate it fails to fetch the same info I'm looking for: com.apple.networkextension debug 11:22:07.024588-0300 Fetching appInfo from cache for pid: 948 uuid: 5C40B765-C6C9-3641-A822-2BC44D264361 bundle id: (null) com.apple.networkextension debug 11:22:07.024657-0300 Calling delegate lookup handler with pid: 948, uuid: 5C40B765-C6C9-3641-A822-2BC44D264361, bundleID: (null) com.apple.networkextension debug 11:22:07.025856-0300 Could not look up appInfo for pid: 948 bundle id: (null) uuid: 5C40B765-C6C9-3641-A822-2BC44D264361 com.apple.networkextension error 11:22:07.025897-0300 Could not find app info, return the original flow without filling in app info Handling new flow: identifier = D89B5B5D-793C-4940-D992-4E90F2AD1900 procPID = 953 eprocPID = 948 direction = outbound inBytes = 0 outBytes = 0 signature = {length = 32, bytes = 0x4afeafde b484aa0c c5cb8698 0567343d ... 7cdee33e 135666dd } socketID = 19adf2904e92d9 localEndpoint = 0.0.0.0:0 remoteEndpoint = 17.33.202.170:443 protocol = 6 family = 2 type = 1 procUUID = 0C68E603-967E-3643-B225-378BD2A655F7 eprocUUID = 5C40B765-C6C9-3641-A822-2BC44D264361 Perhaps there's a bug when generating the audit token or could it be something with the Firefox signature? I double-checked Firefox and it seems fine: $ codesign --verify --verbose /Applications/Firefox.app /Applications/Firefox.app: valid on disk /Applications/Firefox.app: satisfies its Designated Requirement Not sure if relevant, but codesign with -dv showed different flags in CodeDirectory when compared to chrome: codesign -dv /Applications/Firefox.app ... CodeDirectory v=20500 size=863 flags=0x10000(runtime) hashes=18+5 ... Versus chrome CodeDirectory v=20500 size=1821 flags=0x12a00(kill,restrict,library-validation,runtime) hashes=46+7 location=embedded
3
0
498
Nov ’24
Missing flows for content filter on macOS 15 Sequoia
We use as content filter in our app to monitor flows, we gather data about the flow and block flows deemed suspicious. Our content filter is activated/deactivated by a UI app but the flows are reported via XPC to a separate daemon process for analysis. As of macOS 15, we are seeing cases where flows are missing or flows are not received at all by the content filter. The behaviour is not consistent, some devices seem to receive flows normally but others don't. It appears Intel devices are much less prone to showing the problem, whereas Arm devices routinely exhibit missing flows. On macOS 14 or earlier, there is no sign of missing flows. Testing on earlier beta versions of macOS 15 did not appear to show the problem, however I can't rule out if issue was present but it wasn't spotted. Experimenting with simple examples of using a content filter (e.g. QNE2FilterMac) does not appear to reproduce the issue. Questions, What has changed between macOS 14 and 15 that could be the cause of the lack of flows? Is our approach to using an app activated content filter reporting to a daemon connected via XPC unsupported?
7
1
972
Nov ’24
NWConnection and "Network is Down" error connecting to ip address and port
I have a pretty straightforward code to connect to a given ip address and port using NWConnection. On the first attempt to connect to the Local Network I see the "Local Network Privacy" dialog and sometimes if I press "Don't Allow" on that dialog everything starts to fail. No matter I do I keep receiving the following error: POSIXErrorCode(rawValue: 50): Network is down Obviously going to settings and allowing local network access to the app doesn't fix the issue. Neither deleting the app and installing it again. The only workaround I found is to restart my device which is unacceptable for a user. My code is really simple, I tried a lot of different approaches to connect but neither approach worked. I am on iOS 18. Is it a known bug? could be possible a bug on my code? Any idea would be really appreciated, thanks!
14
3
2.5k
Nov ’24
Using Network Framework + Bonjour + QUIC + TLS
Hello, I was able to use the TicTackToe code base and modify it such that I have a toggle at the top of the screen that allows me to start / stop the NWBrowser and NWListener. I have it setup so when the browser finds another device it attempts to connect to it. I support N devices / connections. I am able to use the NWParameters extension that is in the TickTackToe game that uses a passcode and TLS. I am able to send messages between devices just fine. Here is what I used extension NWParameters { // Create parameters for use in PeerConnection and PeerListener. convenience init(passcode: String) { // Customize TCP options to enable keepalives. let tcpOptions = NWProtocolTCP.Options() tcpOptions.enableKeepalive = true tcpOptions.keepaliveIdle = 2 // Create parameters with custom TLS and TCP options. self.init(tls: NWParameters.tlsOptions(passcode: passcode), tcp: tcpOptions) // Enable using a peer-to-peer link. self.includePeerToPeer = true } // Create TLS options using a passcode to derive a preshared key. private static func tlsOptions(passcode: String) -> NWProtocolTLS.Options { let tlsOptions = NWProtocolTLS.Options() let authenticationKey = SymmetricKey(data: passcode.data(using: .utf8)!) let authenticationCode = HMAC<SHA256>.authenticationCode(for: "HI".data(using: .utf8)!, using: authenticationKey) let authenticationDispatchData = authenticationCode.withUnsafeBytes { DispatchData(bytes: $0) } sec_protocol_options_add_pre_shared_key(tlsOptions.securityProtocolOptions, authenticationDispatchData as __DispatchData, stringToDispatchData("HI")! as __DispatchData) sec_protocol_options_append_tls_ciphersuite(tlsOptions.securityProtocolOptions, tls_ciphersuite_t(rawValue: TLS_PSK_WITH_AES_128_GCM_SHA256)!) return tlsOptions } // Create a utility function to encode strings as preshared key data. private static func stringToDispatchData(_ string: String) -> DispatchData? { guard let stringData = string.data(using: .utf8) else { return nil } let dispatchData = stringData.withUnsafeBytes { DispatchData(bytes: $0) } return dispatchData } } When I try to modify it to use QUIC and TLS 1.3 like so extension NWParameters { // Create parameters for use in PeerConnection and PeerListener. convenience init(psk: String) { self.init(quic: NWParameters.quicOptions(psk: psk)) self.includePeerToPeer = true } private static func quicOptions(psk: String) -> NWProtocolQUIC.Options { let quicOptions = NWProtocolQUIC.Options(alpn: ["h3"]) let authenticationKey = SymmetricKey(data: psk.data(using: .utf8)!) let authenticationCode = HMAC<SHA256>.authenticationCode(for: "hello".data(using: .utf8)!, using: authenticationKey) let authenticationDispatchData = authenticationCode.withUnsafeBytes { DispatchData(bytes: $0) } sec_protocol_options_set_min_tls_protocol_version(quicOptions.securityProtocolOptions, .TLSv13) sec_protocol_options_set_max_tls_protocol_version(quicOptions.securityProtocolOptions, .TLSv13) sec_protocol_options_add_pre_shared_key(quicOptions.securityProtocolOptions, authenticationDispatchData as __DispatchData, stringToDispatchData("hello")! as __DispatchData) sec_protocol_options_append_tls_ciphersuite(quicOptions.securityProtocolOptions, tls_ciphersuite_t(rawValue: TLS_AES_128_GCM_SHA256)!) sec_protocol_options_set_verify_block(quicOptions.securityProtocolOptions, { _, _, sec_protocol_verify_complete in sec_protocol_verify_complete(true) }, .main) return quicOptions } // Create a utility function to encode strings as preshared key data. private static func stringToDispatchData(_ string: String) -> DispatchData? { guard let stringData = string.data(using: .utf8) else { return nil } let dispatchData = stringData.withUnsafeBytes { DispatchData(bytes: $0) } return dispatchData } } I get the following errors in the console boringssl_session_handshake_incomplete(241) [C3:1][0x109d0c600] SSL library error boringssl_session_handshake_error_print(44) [C3:1][0x109d0c600] Error: 4459057536:error:100000ae:SSL routines:OPENSSL_internal:NO_CERTIFICATE_SET:/Library/Caches/com.apple.xbs/Sources/boringssl/ssl/tls13_server.cc:882: boringssl_session_handshake_incomplete(241) [C4:1][0x109d0d200] SSL library error boringssl_session_handshake_error_print(44) [C4:1][0x109d0d200] Error: 4459057536:error:100000ae:SSL routines:OPENSSL_internal:NO_CERTIFICATE_SET:/Library/Caches/com.apple.xbs/Sources/boringssl/ssl/tls13_server.cc:882: nw_endpoint_flow_failed_with_error [C3 fe80::1884:2662:90ca:b011%en0.65328 in_progress channel-flow (satisfied (Path is satisfied), viable, interface: en0[802.11], scoped, ipv4, dns, uses wifi)] already failing, returning nw_endpoint_flow_failed_with_error [C4 192.168.0.98:65396 in_progress channel-flow (satisfied (Path is satisfied), viable, interface: en0[802.11], scoped, ipv4, dns, uses wifi)] already failing, returning quic_crypto_connection_state_handler [C1:1] [2ae0263d7dc186c7-] TLS error -9858 (state failed) nw_connection_copy_connected_local_endpoint_block_invoke [C3] Client called nw_connection_copy_connected_local_endpoint on unconnected nw_connection nw_connection_copy_connected_remote_endpoint_block_invoke [C3] Client called nw_connection_copy_connected_remote_endpoint on unconnected nw_connection nw_connection_copy_protocol_metadata_internal_block_invoke [C3] Client called nw_connection_copy_protocol_metadata_internal on unconnected nw_connection quic_crypto_connection_state_handler [C2:1] [84fdc1e910f59f0a-] TLS error -9858 (state failed) nw_connection_copy_connected_local_endpoint_block_invoke [C4] Client called nw_connection_copy_connected_local_endpoint on unconnected nw_connection nw_connection_copy_connected_remote_endpoint_block_invoke [C4] Client called nw_connection_copy_connected_remote_endpoint on unconnected nw_connection nw_connection_copy_protocol_metadata_internal_block_invoke [C4] Client called nw_connection_copy_protocol_metadata_internal on unconnected nw_connection Am I missing some configuration? I noticed with the working code that uses TCP and TLS that there is an NWParameters initializer that accepts tls options and tcp option but there isnt one that accepts tls and quic. Thank you for any help :)
19
0
1.7k
Nov ’24