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 .
Networking
RSS for tagExplore the networking protocols and technologies used by the device to connect to Wi-Fi networks, Bluetooth devices, and cellular data services.
Selecting any option will automatically load the page
Post
Replies
Boosts
Views
Created
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
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
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.)
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
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
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
Topic:
App & System Services
SubTopic:
Networking
Tags:
Extensions
Network
Network Extension
CFNetwork
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?
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.
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.
Topic:
App & System Services
SubTopic:
Networking
There is a problem with the Apple local network setting api, iOS18 system, you turn off the local network permissions of the APP, uninstall the APP, and then re-install, the local network permissions even if opened, there is no effect, only restart the phone is useful
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.
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!
Topic:
App & System Services
SubTopic:
Networking
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 :)
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?
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.
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
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?
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!
Topic:
App & System Services
SubTopic:
Networking
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 :)