I've implemented a custom VPN for macOS (system extension, Packet Tunnel Provider, Developer ID). My tunneling logic uses BSD sockets.
My VPN is configured with on-demand and should always connect when there's traffic:
targetManager?.isOnDemandEnabled = true
targetManager?.onDemandRules = [NEOnDemandRuleConnect()]
I have encountered some issues when the device enters sleep (or waking up from sleep). I've tried two scenarios.
Scenario 1:
protocolConfiguration?.disconnectOnSleep = true
With this flag set, the OS will disconnect the VPN just before entering to sleep. However, there were cases when the OS disconnected the VPN but immediately restarted it - probably because of how I defined the on-demand rules. This resulted in the VPN disconnection, then trying to reconnect, and then the Mac entered sleep.
When the Mac woke up, the VPN didn't work well.
Is there a way to avoid waking up, just before the Mac enters sleep?
Scenario 2:
protocolConfiguration?.disconnectOnSleep = false
Disconnect on sleep is unset, and I've implemented the sleep/wake functions at the provider.
With this configuration, the OS won't disconnect the VPN, so even in sleep, the extension should stay 'alive,' so it won't have the problem from (1).
But in this case, I had other problems:
On sleep, I'm disconnecting the tunnel. But sometimes, on wake(), all my network calls fail. Are the interfaces still down? How can I detect this case from the system extension?
Is it possible that the OS would call sleep and then quickly call wake?
Is it possible that after sleep, the OS would call the startTunnelWithOptions() function?
Is it possible to restart the extension from a clean state right from the wake() function?
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
Activity
Hi,
DNS resolution using libresolv (res_nquery) fails in 15.4 when connected to VPN. The same is working fine for 15.3 and lower and this happens for all the domains. The method returns -1 and res->res_h_errno is set to 2.
In wireshark we can see that the DNS request is sent and server also returns the response successfully.
The same works fine if we use TCP instead of UDP by setting the following option
res->options |= RES_USEVC;
We are a hardware manufacturer. Our devices are connected via Ethernet to Mac mini systems, where our custom macOS application is installed and communicates with the connected hardware. The application is signed and deployed as a standard application bundle.
Description
The application performs a UDP broadcast using the Universal Plug and Play (UPnP) discovery mechanism to locate devices connected to the same local network segment.
We have observed a reproducible issue with macOS 15.x (confirmed with 15.1 through 15.4), where the discovery fails under specific circumstances. The behavior is as follows:
If the application is launched via Finder (e.g., double-clicked by the user), no device is discovered.
If the same binary is launched from the Terminal, discovery works as expected and the connected device is found.
Downgrading the affected Mac mini to macOS 14.x (e.g., Sonoma 14.0 or 14.1) restores the expected behavior—discovery works via Finder as well.
The issue is observed only on Intel-based Mac minis.
On Apple Silicon (ARM-based) Mac minis, the discovery via Finder works correctly, even on macOS 15.4.
What we know
The problem is tied to how the network stack or sandboxing behaves when the application is launched via Finder.
There are no visible error messages.
It is unclear whether the broadcast packet is being blocked, or if the response from the device is dropped or filtered by the system.
Reproduction Steps
Install our signed application bundle on a Mac mini (Intel).
Connect our device via Ethernet to the Mac mini.
Launch the application via Finder – the device is not found.
Quit the application.
Launch the same binary from Terminal – the device is correctly discovered.
Downgrade the same system to macOS 14.x – discovery works in both cases (Finder and Terminal).
Upgrade to macOS 15.x – the issue reappears.
Technical Details
macOS Version(s) Affected: 15.x (confirmed with 15.1 through 15.4),
Mac mini Model: Intel-based Mac minis
Type of Communication: UDP broadcast using UPnP
Reproducibility: 100% reproducible with affected macOS versions.
Software Environment: Custom application developed by us, running as a user-space application under standard macOS network APIs.
No Issues: When the same setup is used on earlier macOS versions.
Request
Can you confirm whether this is expected behavior due to changes in macOS 15 (e.g., sandboxing, entitlements, network permissions)?
What steps or configuration changes are required to ensure UDP discovery works again when the application is launched via Finder?
Are there relevant macOS logs (e.g., Console, system logs) we can inspect for network-related blocks or errors?
We would appreciate any guidance or clarification on how to adapt our application or system configuration to restore expected network discovery behavior.
Thank you in advance for your support!
hello
I am testing the use of network extension. When we use dnsproxy to proxy DNS requests,
we will send you a message that the udp pcbcount of your system continues to increase.
For example
for ((i=1; i<=99999; i++));do
echo "Attempt $i:"
dig google.com
done
when the dig command is used continuously,
the dig command will show the following errors when pcbcount reaches a certain number.
isc_socket_bind: address not available
Can you help us determine what the problem might be? thank you
When creating multiple QUIC streams (NWConnections) sharing one QUIC tunnel (using NWMultiplexGroup), is it possible to assign different priorities to the streams? And if yes, how?
The only prioritization option I found so far is NWConnection.ContentContext.relativePriority, but I assume that is for prioritizing messages within a single NWConnection?
Hello,
I am working to integrate the new com.apple.developer.networking.carrier-constrained.app-optimized entitlement in my iOS 26 app so that my app can use a carrier-provided satellite network, and want to confirm my understanding of how to detect and optimize for satellite network conditions.
(Ref: https://developer.apple.com/documentation/bundleresources/entitlements/com.apple.developer.networking.carrier-constrained.app-optimized )
My current approach:
I plan to set the entitlement to true once my app is optimized for satellite networks.
To detect if the device is connected to a satellite network, I intend to use the Network framework’s NWPath properties:
isUltraConstrained — I understand this should be set to true when the device is connected to a satellite network.
(Ref: https://developer.apple.com/documentation/network/nwpath/isultraconstrained )
linkQuality == .minimal — I believe this will also be set in satellite scenarios, though it may not be exclusive to satellite connections.
(Ref:
https://developer.apple.com/documentation/network/nwpath/linkquality-swift.enum/minimal )
Questions:
Is it correct that isUltraConstrained will reliably indicate a satellite connection?
Should I also check for linkQuality == .minimal, or is isUltraConstrained sufficient?
Are there any additional APIs or best practices for detecting and optimizing for satellite connectivity that I should be aware of?
Thank you for confirming whether my understanding and approach are correct, and for any additional guidance.
iOS 18.4 introduced some requirements on the Key Usage of 802.1x server certificates, as described here. https://support.apple.com/en-us/121158
When using TLS_ECDHE_RSA or TLS_DHE_RSA cipher suites, 802.1X server certificates containing a Key Usage extension must have Digital Signature key usage set.
When using the TLS_RSA cipher suite, 802.1X server certificates containing a Key Usage extension must have Key Encipherment key usage set.
It reads like the change is supposed to affect 802.1x only. However, we have found out that the new restrictions are actually imposed on all TLS connections using the Network framework, including in Safari.
Unlike other certificate errors which can be either ignored by users (as in Safari) or by code (via sec_protocol_options_set_verify_block), these new ones can't. Even if passing completion(true) in the TLS verification block, the connection still ends up in waiting state with error -9830: illegal parameter.
I understand that these requirements are valid ones but as a generic TLS library I also expect that Network framework could at least allow overriding the behavior. The current treatment is not consistent with those on other certificate errors.
Since I can't upload certificates, here is how to reproduce a certificate that fails.
Create a OpenSSL config file test.cnf
[ req ]
default_bits = 2048
distinguished_name = dn
x509_extensions = v3_ca
prompt = no
[ dn ]
CN = example.com
[ v3_ca ]
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid:always,issuer
basicConstraints = CA:TRUE
keyUsage = critical, keyCertSign, cRLSign
Generate certificate and private key
openssl req -x509 -new -nodes -keyout key.pem -out cert.pem -days 365 -config test.cnf
And here is the client code to test.
// Target server and port
let host = NWEndpoint.Host("example.com")
let port = NWEndpoint.Port("443")!
// Configure insecure TLS options
let tlsOptions = NWProtocolTLS.Options()
sec_protocol_options_set_verify_block(tlsOptions.securityProtocolOptions, { _, _, completion in
// Always trust
completion(true)
}, DispatchQueue.global())
let params = NWParameters(tls: tlsOptions)
let connection = NWConnection(host: .init(host), port: .init(rawValue: port)!, using: params)
connection.stateUpdateHandler = { newState in
switch newState {
case .ready:
print("TLS connection established")
case .failed(let error):
print("Connection failed: \(error)")
case .cancelled:
print("Connection canceled")
case .preparing:
print("Connection preparing")
case .waiting(let error):
print("Connection waiting: \(error)")
case .setup:
print("Connection setup")
default:
break
}
}
connection.start(queue: .global())
Output
Connection preparing
Connection waiting: -9830: illegal parameter
Previously reported as FB17099740
Hi,
I've created a packet tunnel but my packetFlow object isn't get called with any packets. Do I need to do something else to configure the packetFlow? Maybe I have to link it to a NWUDPSession?
Thanks,
Dave
class PacketTunnelProvider: NEPacketTunnelProvider {
override func startTunnel(options: [String : NSObject]?, completionHandler: @escaping (Error?) -> Void) {
let settings = NEPacketTunnelNetworkSettings(tunnelRemoteAddress: tunnelRemoteAddress)
settings.ipv4Settings = NEIPv4Settings(addresses: [tunnelRemoteAddress], subnetMasks: ["255.255.255.255"])
settings.ipv4Settings?.includedRoutes = [NEIPv4Route.default()]
setTunnelNetworkSettings(settings) { error in
completionHandler(error)
self.readPacketObjects()
}
}
private func readPacketObjects() {
self.packetFlow.readPacketObjects() { packets in
// It never gets here.
self.logMessage("Got '\(packets.count)' packet(s)")
self.packetFlow.writePacketObjects(packets)
self.readPacketObjects()
}
}
}
Hello ,
I have obtained three strings from the server: ca (the root certificate), cert (the client certificate), and privateKey (the private key) for authentication between the iOS client and server. I have successfully used ca for server authentication.
However, I am having trouble generating an NSURLCredential from the cert and privateKey strings for client authentication. Can anyone guide me on how to convert these strings into an NSURLCredential? Any example code would be greatly appreciated!
Thank you for your help!
Hello! 👋
I am noticing new failures in the iOS 18.5 Developer Beta build (22EF5042g) when calling the system call connect() (from C++ source, in network extension).
When using cell/mobile data (Mint & T-Mobile) this returns with EINTR (interrupted system call) right away. When I switch over to wifi, everything works fine.
Note: I have not tested on other mobile carriers; which could make a difference since T-Mobile/Mint are IPv6 networks.
FWIW, this is working in the previous developer beta (18.4).
Anyone have any ideas?
I'm writing an LDAP Browser app using SwiftUI. I tested my LDAP code using a command line app that uses the exact same libraries and it successfully connects to my LDAP server over a TLS connection. I did need to install the CA cert into the system keychain.
The SwiftUI version, using the exact same code and parameters returns an "Unknown CA" error. It works fine without TLS. Can anyone explain why certificate validation is different for a GUI app?
Topic:
App & System Services
SubTopic:
Networking
Hi, I would like to know if it is safe to call the uploadTask from URLSession from the main thread ?
We've a user who is reporting repeated crashes at startup, here is the stack we see:
Exception Type: EXC_CRASH (SIGKILL)
Exception Codes: 0x0000000000000000, 0x0000000000000000
Termination Reason: FRONTBOARD 2343432205
<RBSTerminateContext| domain:10 code:0x8BADF00D explanation:scene-update watchdog transgression: app<com.appspot.myApp(E7590BB1-722C-491D-9199-F867DE4B880A)>:2212 exhausted real (wall clock) time allowance of 10.00 seconds
ProcessVisibility: Background
ProcessState: Running
WatchdogEvent: scene-update
WatchdogVisibility: Background
WatchdogCPUStatistics: (
"Elapsed total CPU time (seconds): 21.260 (user 10.230, system 11.030), 35% CPU",
"Elapsed application CPU time (seconds): 0.006, 0% CPU"
) reportType:CrashLog maxTerminationResistance:Interactive>
Triggered by Thread: 0
Thread 0 name: Dispatch queue: com.apple.main-thread
Thread 0 Crashed:
0 libsystem_kernel.dylib 0x1def7a688 mach_msg2_trap + 8
1 libsystem_kernel.dylib 0x1def7dd98 mach_msg2_internal + 80
2 libsystem_kernel.dylib 0x1def7dcb0 mach_msg_overwrite + 424
3 libsystem_kernel.dylib 0x1def7dafc mach_msg + 24
4 libdispatch.dylib 0x1968d8f14 _dispatch_mach_send_and_wait_for_reply + 544
5 libdispatch.dylib 0x1968d92b4 dispatch_mach_send_with_result_and_wait_for_reply + 60
6 libxpc.dylib 0x21714a930 xpc_connection_send_message_with_reply_sync + 256
7 Foundation 0x18d80a3ac __NSXPCCONNECTION_IS_WAITING_FOR_A_SYNCHRONOUS_REPLY__ + 16
8 Foundation 0x18d806b14 -[NSXPCConnection _sendInvocation:orArguments:count:methodSignature:selector:withProxy:] + 2160
9 CoreFoundation 0x18eb868dc ___forwarding___ + 1004
10 CoreFoundation 0x18eb86430 _CF_forwarding_prep_0 + 96
11 CFNetwork 0x1900c71e0 -[__NSURLBackgroundSession setupBackgroundSession] + 800
12 CFNetwork 0x1900b3e80 -[__NSURLBackgroundSession initWithConfiguration:delegate:delegateQueue:delegateDispatchQueue:] + 552
13 CFNetwork 0x1900b4784 +[NSURLSession _sessionWithConfiguration:delegate:delegateQueue:delegateDispatchQueue:] + 1496
14 MyApp 0x1054210b4 CombineBgXferRepository.session.getter (in MyApp) (CombineBgXferRepository.swift:62) + 7966900
15 MyApp 0x105422fa4 CombineBgXferRepository.startUploadTask(fileURL:request:) (in MyApp) (CombineBgXferRepository.swift:310) + 7974820
If it is ok to call this uploadTask from the main thread, does this crash indicate a problem with the operating system? Are there scenarios where the background upload service does not respond to requests?
Apologies if this is not the correct topic to post under.
EpochField 5.2 is our application. It's a .NET MAUI application built against XCode 16. A customer of ours uses another app, TN3270, to connect to a mainframe host. After installing our app on an iPad and restarting the device, the TN3270 app will disconnect when suspended. Uninstalling our app (EpochField) will allow the TN3270 to suspend without disconnecting. We have tried removing background services, setting UIRequiresFullScreen to false or removing it entirely, and several other ideas. The only remedy seems to be uninstalling EpochField.
On an iPad device:
Install MochaSoft’s TN3270 app (free version is fine). Create a connection to ssl3270.nccourts.org, port 2023, SSL/TLS turned on, keep alive turned on.
Verify that you can connect. Suspend the app by swiping up or choosing another app. Go back to TN3270 and verify that the app has not disconnected.
Install EpochField 5.2. Do not run or configure the app, just install it.
Repeat step 2.
Restart the device.
Open EpochField 5.2. You do not need to configure the app or login. Sometimes it isn't necessary to ever open EpochField to get the disconnects, but this is the most reliable way to reproduce the situation.
Repeat step 2. The TN3270 app will now disconnect when suspended, even if EpochField is closed. You may need to wait a few seconds after suspending.
Uninstall EpochField 5.2.
Repeat step 2: the TN3270 app will now remain connected when suspended.
Topic:
App & System Services
SubTopic:
Networking
I have read all the information and forum posts about local network, such as TN3179, etc., and have added NSLocalNetworkUsageDescription, but it does not solve my problem.
The problem I encountered is described as follows:
Device: iOS18.1.1
Signing method: automatic
Xcode debug directly runs, and the app can access 17.25.11.128 normally. However, relase run or packaged into adhoc installation, this IP cannot be accessed. There is a phenomenon that the app package of the App Store can also be used.
Our test team has few iOS18+ devices, and internal testing is not possible. Please contact us as soon as possible, thank you.
=======
我已经了解了所有关于local network 相关的资料和论坛帖子,比如TN3179 等等, 已经添加了 NSLocalNetworkUsageDescription, 但是不解决我的问题。
我遇到的问题描述如下:
设备:iOS18.1.1
签名方式:自动
xcode debug 直接运行,app是可以正常访问17.25.11.128的。 但是 relase run 或者 打包成 adhoc 安装,就无法访问这个IP了。 有一个现象, App Store 的app包 也是可以的。
我们的测试团队,iOS18+的设备就没几个,还不能内部测试了。请尽快联系我们,谢谢。
I am trying to connect an iPhone 16 (iOS 18.3) to a Wi-Fi device with the SSID "DIRECT-DR_6930_KP201128", but every time, without being able to enter the Wi-Fi password, the message "Unable to join the network 'DIRECT-DR_6930_KP201128'" is displayed. Below are the system logs from the connection failure. Could you please tell me the cause of the connection failure?
By the way, an iPhone SE 2nd (iOS 18.2.1) can connect to the same Wi-Fi device without any issues.
System Logs:
・Jan 31 19:18:14 900-iPhone-16-docomo Preferences(WiFiKit)[351] : {ASSOC-} association finished for DIRECT-DR_6930_KP201128 - success 0
・Jan 31 19:18:14 900-iPhone-16-docomo runningboardd(RunningBoard)[33] : Assertion 33-351-4412 (target:[app<com.apple.Preferences(DE1AB487-615D-473C-A8D6-EAEF07337B18)>:351]) will be created as inactive as start-time-defining assertions exist
・Jan 31 19:18:14 900-iPhone-16-docomo Preferences(WiFiKit)[351] : association failure: (error Error Domain=com.apple.wifikit.error Code=12 "Unknown Error" UserInfo={NSDebugDescription=Unknown Error, NSUnderlyingError=0x303307660 {Error Domain=com.apple.corewifi.error.wifid Code=-3938 "(null)"}})
・Jan 31 19:18:14 900-iPhone-16-docomo Preferences(WiFiKit)[351] : dismissing credentials view controller for DIRECT-DR_6930_KP201128
when i am running this app on Iphone13 facing these errors
On starting Publisher: failed(-11992: Wi-Fi Aware)
[L1 ready, local endpoint: , parameters: udp, traffic class: 700, interface: nan0, local: ::.0, definite, attribution: developer, server, port: 65041, path satisfied (Path is satisfied), interface: nan0[802.11], ipv4, uses wifi, LQM: unknown, service: com.example.apple-samplecode.Wi-FiAwareSample94KV3E626L._sat-fileservice._udp scope:0 route:0 custom:107]: waiting(POSIXErrorCode(rawValue: 50): Network is down)
[L1 cancelled, local endpoint: , parameters: udp, traffic class: 700, interface: nan0, local: ::.0, definite, attribution: developer, server, port: 65041, path , service: com.example.apple-samplecode.Wi-FiAwareSample94KV3E626L._sat-fileservice._udp scope:0 route:0 custom:107]: ready
[L1 cancelled, local endpoint: , parameters: udp, traffic class: 700, interface: nan0, local: ::.0, definite, attribution: developer, server, port: 65041, path , service: com.example.apple-samplecode.Wi-FiAwareSample94KV3E626L._sat-fileservice._udp scope:0 route:0 custom:107]: failed(-11992: Wi-Fi Aware)
OnStarting Subscriber : -11992: Wi-Fi Aware
B1 <nw_browse_descriptor application_service _sat-simulation._udp bundle_id=com.example.apple-samplecode.Wi-FiAwareSample94KV3E626L device_types=7f device_scope=ff custom:108>, generic, interface: nan0, multipath service: interactive, attribution: developer: failed(-11992: Wi-Fi Aware)
I am trying to make http3 client with Network.framework on Apple platforms.
Codes that implement NWConnectionGroup.start with NWListener don't always work with warning below.
I assume NWConnectionGroup.newConnectionHandler or NWListener.newConnectionHandler will be called to start connection from the server if it works.
nw_protocol_instance_add_new_flow [C1.1.1:2] No listener registered, cannot accept new flow
quic_stream_add_new_flow [C1.1.1:2] [-fde1594b83caa9b7] failed to create new stream for received stream id 3
so I tried:
create the NWListener -> not work
check whether NWConnectionGroup has a member to register or not NWListener -> not work (it doesn't have).
use NWConnection instead of NWConnectionGroup -> not work
Is my understanding correct?
How should I do to set or associate listener with NWConnection/Group for newConnectionHandler is called and to delete wanings?
What is the best practice in the case?
Sample codes are below.
Thanks in advance.
// http3 needs unidirectional stream by the server and client.
// listener
private let _listener: NWListener
let option: NWProtocolQUIC.Options = .init(alpn:["h3"])
let param: NWParameters = .init(quic: option)
_listener = try! .init(using: param)
_listener.stateUpdateHandler = { state in
print("listener state: \(state)")
}
_listener.newConnectionHandler = { newConnection in
print("new connection added")
}
_listener.serviceRegistrationUpdateHandler = { registrationState in
print("connection registrationstate")
}
// create connection
private let _group: NWConnectionGroup
let options: NWProtocolQUIC.Options = .init(alpn: ["h3"])
options.direction = .unidirectional
options.isDatagram = false
options.maxDatagramFrameSize = 65535
sec_protocol_options_set_verify_block(options.securityProtocolOptions, {(_: sec_protocol_metadata_t, _: sec_trust_t, completion: @escaping sec_protocol_verify_complete_t) in
print("cert completion.")
completion(true)
}, .global())
let params: NWParameters = .init(quic: options)
let group: NWMultiplexGroup = .init(
to: .hostPort(host: NWEndpoint.Host("google.com"),
port: NWEndpoint.Port(String(443))!))
_group = .init(with: group, using: params)
_group.setReceiveHandler {message,content,isComplete in
print("receive: \(message)")
}
_group.newConnectionHandler = {newConnection in
print("newConnectionHandler: \(newConnection.state)")
}
_group.stateUpdateHandler = { state in
print("state: \(state)")
}
_group.start(queue: .global())
_listener.start(queue: .global())
if let conn = _group.extract() {
let data: Data = .init()
let _ = _group.reinsert(connection: conn)
conn.send(content: data, completion: .idempotent)
}
I'm using the NEHotspotConfigurationManager class, with joinOnce = false, to connect to a Wi-Fi network that lacks internet access (IoT device).
After restarting my iPhone, the first connection to this network disconnects automatically in less than a minute. All subsequent connections remain stable without disconnecting. What could be causing this?
Hi there, I have some thread related questions regards to network framework completion callbacks. In short, how should I process cross thread data in the completion callbacks?
Here are more details. I have a background serial dispatch queue (call it dispatch queue A) to sequentially process the nw_connection and any network io events. Meanwhile, user inputs are handled by serial dispatch queue ( dispatch queue B). How should I handle the cross thread user data in this case?
(I write some simplified sample code below)
struct {
int client_status;
char* message_to_sent;
}user_data;
nw_connection_t nw_connection;
dispatch_queue_t dispatch_queue_A
static void send_message(){
dispatch_data_t data = dispatch_data_create(message, len(message), dispath_event_loop->dispatch_queue, DISPATCH_DATA_DESTRUCTOR_DEFAULT);
nw_connection_send(
nw_connection, data, NW_CONNECTION_DEFAULT_MESSAGE_CONTEXT, false, ^(nw_error_t error) {
user_data.client_status = SENT;
mem_release(user_data.message_to_sent); });
});
}
static void setup_connection(){
dispatch_queue_A=
dispatch_queue_create("unique_id_a", DISPATCH_QUEUE_SERIAL);
nw_connection = nw_connection_create(endpoint, params);
nw_connection_set_state_changed_handler(){
if (state == nw_connection_state_ready) {
user_data.client_status = CONNECTED
}
// ... other operations ...
}
nw_connection_start(nw_connection);
nw_retain(nw_connection);
}
static void user_main(){
setup_connection()
user_data.client_status = INIT;
dispatch_queue_t dispatch_queue_B = dispatch_queue_create("unique_id_b", DISPATCH_QUEUE_SERIAL);
// write socket
dispatch_async(dispatch_queue_B, ^(){
if (user_data.client_status != CONNECTED ) return;
user_data.message_to_sent = malloc(XX,***)
// I would like to have all io events processed on dispatch queue A so that the io events would not interacted with the user events
dispatch_async_f(dispatch_queue_A, send_message);
// Disconnect block
dispatch_async(dispatch_queue_B, ^(){
dispatch_async_f(dispatch_queue_A, ^(){
nw_connection_cancel(nw_connection)
});
user_data.client_status = DISCONNECTING;
});
// clean up connection and so on...
}
To be more specific, my questions would be:
As I was using serial dispatch queue, I didn't protect the user_data here. However, which thread would the send_completion_handler get called? Would it be a data race condition where the Disconnect block and send_completion_handler both access user_data?
If I protect the user_data with lock, it might block the thread. How does the dispatch queue make sure it would NOT put a related execution block onto the "blocked thread"?
Dear Apple:
We encountered a problem when using the Wi-Fi connection feature. When calling the Wi-Fi connection interface NEHotspotConfigurationManager applyConfiguration, it fails probabilistically. After analyzing the air interface packets, it appears that the Apple device did not send the auth message. How should we locate this issue? Are there any points to pay attention to when calling the Wi-Fi connection interface? Thanks