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

Activity

Pre-approving network extension VPN permission with MDM
I have a macOS app with Network Extension. It requests VPN permission with the code like this: self.tunnelManager = [NETunnelProviderManager new]; NETunnelProviderProtocol *protocol = [NETunnelProviderProtocol new]; protocol.providerBundleIdentifier = @"com.myapp.macos.tunnelprovider"; self.tunnelManager.protocolConfiguration = protocol; [self.tunnelManager setOnDemandRules:nil]; [self.tunnelManager setOnDemandEnabled:NO]; [self.tunnelManager setEnabled:YES]; [self.tunnelManager saveToPreferencesWithCompletionHandler:^(NSError * _Nullable saveError) {}]; A lot of my app users are businesses and they would like to have pre-install VPN config. We currently do it like this: <array> <dict> <key>PayloadDisplayName</key> <string>MyAppName</string> <key>PayloadType</key> <string>com.apple.vpn.managed</string> <key>UserDefinedName</key> <string>MyAppName</string> <key>VPN</key> <dict> <key>AuthenticationMethod</key> <string>Password</string> <key>ProviderBundleIdentifier</key> <string>com.myapp.macos.tunnelprovider</string> <key>ProviderDesignatedRequirement</key> <string>anchor apple generic and identifier "com.myapp.macos.tunnelprovider" and (certificate leaf[field.1.2.3] /* exists */ or certificate 1[field.1.2.3] /* exists */ and certificate leaf[field.1.2.3] /* exists */ and certificate leaf[subject.OU] = "123")</string> <key>RemoteAddress</key> <string/> </dict> <key>VPNSubType</key> <string>com.myapp.macos</string> <key>VPNType</key> <string>VPN</string> </dict> </array> Now, if the users installs my app first and allows the VPN permission, then MDM will set the profile above to the user, the user will end up with two VPN profiles in settings. They will be called "My App" and "My App 1" At first we thought it's harmless, but users with two VPN profiles sometimes have app update issues, where after update the newer version of client fails to communicate with the older version of tunnel, it cannot even tell it to quit. The tunnel must be force-quit by the user in this case. We suspect two profiles to be the reason for that. Is there a way to make sure duplicate VPN profiles do not happen?
2
0
512
Oct ’24
How to reset (remove) apps from "Local Network" privacy settings?
macOS 15 has added a new "Local Network" permission under Security & Privacy. I had a bug in my app that led to a crash when the user denied this permission. Now I've fixed it and would like to verify that it all works fine. The problem is: I need to remove my app from the settings so that macOS will show the prompt again (e.g. to verify that my custom message appears correctly). Usually, sudo tccutil reset All would do the trick. But not for this permission! The apps do not get cleared with this command. So, there's two issues: tccutil should remove it but doesn't. How can I remove this settings? Update I had a look at the "TCC.db" (see https://www.rainforestqa.com/blog/macos-tcc-db-deep-dive), and it seems to me that the Local Network permission isn't even managed by the TCC system, as it doesn't appear in it. This is odd.
20
3
11k
Oct ’24
EPERM when connecting to Socket with Posix
I want to connect my iOS App with a MQTT Server via a Kotlin Multiplatform XCFramework. This Framework uses the library KMQTT to connect to our MQTT Server. As you can see Here KMQTT uses the default POSIX commands to connect to a socket. This setup works great on Android, not so much for iOS: When connecting to a IPv6 Address iOS devices get the POSIX Error 47, this was "fixed" by only using IPv4 more importantly: On ~50% of devices, when connecting to the socket they get the POSIX Error 1 (EPERM). The devices are iPhone 13, 14 Pro and a 15 and they all use either iOS 17 or iOS 18. When trying to open the ip via Safari they can connect. This problem seems to come from the Provider, as when i open a Hotspot from a device that doesn't work, all connected iOS Devices also don't work and when another device that works opens a hotspot and the not-working device connects to it, this device works. Do you guys have any idea, why this error is thrown?
3
0
431
Oct ’24
Errors codes for invalid resumeData with URLSession UploadTask?
I'm coding resumable uploads using iOS 17's URLSession's uploadTask(withResumeData:. This function returns a non-Optional URLSessionUploadTask and does not throw. In cases where the system determines the resumeData is no longer valid, how do I detect that (so I can create a new URLSessionUploadTask from scratch)? I'm doing this for background uploads, so it's all URLSessionDelegate apis, but what are the failure modes, and what Error types and Codes would we get specially? Obviously, I expect the resume data is no longer usable or necessary when get a server success i.e. in the 2xx range. Does the resume data also become invalid for other server responses, like 4xx's? or 5xx's?. I expect the resume data usually shouldn't become invalid when getting URLError's like .networkConnectionLost, since that's like half the point of having the feature in the first place, to resume after the a broken network connection. But I do expect that if the resumeData is invalid, then I should be able to reach the server and get a server response, so in that case what Code would we get? I'm assuming the system is caching our upload file somewhere, and the resume data somehow makes a reference to it, so does that file get optimized away at some point in time when left untouched, and need us to start a fresh upload? We are also saving the file for potential future re-uploads, until we get certain assurances of completion from our backend, but I am just wondering on which logic branches I need to determine that the resumeData I thought I could use is no longer usable.
3
0
372
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
1
611
Oct ’24
Trying to regain the reins of control
Hey all so I’m just looking to normalize my ifconfig loadout. Essentially I have many interfaces and as many as 25-50 interfaces on my device. special clauses: -i may not factory reset the device including all data because AppleID phone number and password have been lost -i have access to blink shell for a llimited number of days -I have had permission denied in every way accessing the device via other shells and have no desire to do this via SSH ; simply put i think that if my phone is set up like this; THERE MUST be SOME way to get these interfaces flags down AT LEAST. And possibly in theory I should be able to even UNINSTALL these many, many interfaces!! reaching out here seems to be the brightest idea, because of the scope of this task i realize I am not a fully stacked developer and have some desire to be one but realistically I wont be one so hopefully my task is clear -remove interfaces from ifconfig -a ‘s list of enummerated network interfaces. Even flags down will do. thank you for not deleting my thread please move it if possible I do have a copy
2
0
261
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!
3
0
732
Oct ’24
Issue with Multiple NWListeners on the Same Port in Network Framework
Hello, I'm working with the Network framework in Swift and have encountered an issue when attempting to create multiple NWListener instances on the same port. I am specifically trying to set the allowLocalEndpointReuse property on the NWParameters used for both listeners, but it seems that even with this property set, the second listener fails to start. Here’s a simplified version of my implementation: import Foundation import Network class UDPServer { private var listener1: NWListener? private var listener2: NWListener? private let port: NWEndpoint.Port init(port: UInt16) { self.port = NWEndpoint.Port(rawValue: port) ?? NWEndpoint.Port(45000) startListeners() } private func startListeners() { let udpOptions = NWProtocolUDP.Options() let params = NWParameters(udp: udpOptions) params.allowLocalEndpointReuse = true // Create first listener do { listener1 = try NWListener(using: params, on: port) listener1?.start(queue: .global()) } catch { print("Failed to create Listener 1: \(error)") } // Create second listener do { listener2 = try NWListener(using: params, on: port) listener2?.start(queue: .global()) } catch { print("Failed to create Listener 2: \(error)") } } } // Usage example let udpServer = UDPServer(port: 45000) RunLoop.main.run() Observations: I expect both listeners to operate without issues since I set allowLocalEndpointReuse to true. However, when I attempt to start the second listener on the same port, it fails with an error. output nw_path_evaluator_evaluate NECP_CLIENT_ACTION_ADD error [48: Address already in use] nw_path_create_evaluator_for_listener nw_path_evaluator_evaluate failed nw_listener_start_on_queue [L2] nw_path_create_evaluator_for_listener failed Listener 1 ready on port 45000 Listener 2 failed: POSIXErrorCode(rawValue: 48): Address already in use Listener 2 cancelled Questions: Is there a limitation in the Network framework regarding multiple listeners on the same port even with allowLocalEndpointReuse? Should I be using separate NWParameters for each listener, or is it acceptable to reuse them? Even when trying to initialize NWParameters with NWProtocolUDP.Options, it doesn't seem to change anything. What steps should I take to modify these properties effectively? If I wanted to set the noDelay option for TCP, how would I do that? Even when initializing NWParameters with init(.tls: , .tcp:), it doesn't seem to have any effect. Any insights or recommendations would be greatly appreciated! Thank you!
8
1
730
Oct ’24
Http get request is replayed by NSURLSession when switch network type
最近服务器做了防重放功能,发现iOS有很多命中重放错误,因为我们的请求使用了UUID签名,排除了算法问题 经过排查发现iOS在请求过程中,如果网络发生变化,例如开启和断开vpn,或者开启和关闭WIFI,就会导致系统把正在进行的请求多次重放,这会导致从App的感知来看,请求和响应都只调用了一次,但是服务端却收到了多次 具体操作步骤: 1、开启抓包工具,例如wireshark 2、使用demo代码发送请求(先开启慢速网络,不然速度太快来不及操作): 3、不等请求完成,关闭wifi,这时会切换到蜂窝数据 4、等待请求完成后,通过日志可以看出请求的发送和响应都只进行了一次,但是抓包工具可以看到请求被发送了2次 demo如下: // Create a URLSession with the default configuration NSURLSession *defaultSession = [NSURLSession sharedSession]; // Setup the request to the URL NSTimeInterval ms = [NSDate.date timeIntervalSinceReferenceDate] * 1000; NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:@"https://static.fusionbank.com/resource/20240930/8f54352194ac8beecbd5d3f5842b27bb.png?_t=%f",ms]]; NSMutableURLRequest *urlRequest = [NSMutableURLRequest requestWithURL:url]; urlRequest.timeoutInterval = 20; // Create dataTask NSLog(@"--- request start"); dataTask = [defaultSession dataTaskWithRequest:urlRequest completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) { dispatch_async(dispatch_get_main_queue(), ^{ NSLog(@"--- request finish %@", [error localizedDescription]); // Handle your response here [self.loadingView stopAnimating]; if (data) { UIImage* img = [UIImage imageWithData:data]; self.imageView.image = img; } }); }]; // Fire the request [dataTask resume]; 日志如下: 111.log 抓包工具显示请求发了2次: 请求和响应情况:
1
0
264
Oct ’24
How to create NSURLCredential from certificate and private key strings for client authentication?
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!
5
0
648
Oct ’24
defaultPath deprecated in NEProvider
The documentation for the defaultPath property of NEProvider is as follows: This NWPath object contains information about which physical network interface will be used by connections opened by the Network Extension provider. You can determine when this physical interface changes by observing this property using KVO. However, I have noticed that it is deprecated as of iOS 18. Is there any existing replacement for this functionality since it has been deprecated, or is a new replacement on the horizon? This is very useful for network extensions in order to detect changes to the network, for instance when moving from WiFi to mobile data.
1
0
463
Oct ’24
How can I use a keychain item with access control ".userPresence" in a VPN Network extension
I am building a NEPacketTunnelProvider, and in its configuration I set a SecIdentity persistent reference. That reference is passed to the tunnel provider but when I try to use it there, I get an errSecInteractionNotAllowed error. The private key for that identity is protected by .userPresence. If I remove the protection, the network extension can access the identity and the private key. Is there any way that a VPN network extension can use a keychain item protected by .userPresence?
2
0
400
Oct ’24
How do I make a network call that is longer than 30 seconds?
I have a network call that can sometimes take longer than 30 seconds and user might sometimes background the app after waiting a bit (think like a image generation done on a server which takes a while). I want to make sure that I have exhausted all the options available to provide the best possible solution for the user (1) Use beginBackgroundTask. The downside to this is that I'm only given about 30 seconds or so, and if it takes longer, the call just get killed. (2) Use URLSessionConfiguration.background. The upside is that this can take as long as it needs but it seems to be delegated to the system, and you never know when it will run? What if the user stays in the foreground and now the user will not know when the call will even begin (determined by the OS) (3) Use BGProcessingTask. Again problem is that we cant control when the task is run (which in this case we want it to be immediately). So really none of the options really is ideal. Are there other options? What I would like ideally is The call should start immediately upon user request The call should go on indefinitely when the app stays in foreground The call should go on for an extended period (like 2 minutes) if the user puts the app in background If the call is completed in the background, have a way for the app to retrieve the result when the user brings the app back in the foreground
1
0
353
Oct ’24
Why is there a 1 second delay when sending or receiving from a socket?
I am creating a VoIP application. The VoIP application needs to send and receive RTP packets at 20 ms intervals. The application calls sendto() of the Socket API at 20 ms intervals, but the iPhone buffers the send data inside iOS and then sends RTP packets in batches at 1 second intervals. (I captured the sned packets of iPhone with rvctl and confirmed this. please reffer "Sending at 1 second intervals.png" for detail) Similarly, other devices send RTP packets to the iPhone at 20 millisecond intervals, but the iPhone only receives them at 1 second intervals. (please reffer "Receiving at 1 second intervals.png" for detail) Why is this? If the cause of the delay is in the Wi-Fi protocol and the cause can be found from sysdiagnose, please tell me the search key for sysdiagnose that shows the cause of the delay and the meaning of the corresponding log. I uploaded sysdiagnose and result of lan capture to below. [sysdiagnose and lan capture] https://drive.google.com/file/d/149OPmePAF4hnZj6NeSnKc5NizfitPQDS/view?usp=sharing And, the start and end times, packet number in the lan capture of the call shown in the png example are below Start time; 13:57:22.349608/packet number; 948 End time; 13:57:37.482874/packet number; 2583
6
0
419
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
613
Oct ’24
iOS app that can support multiple hardware devices simultaneously
Hello, I am planning to create an app that can transfer files to hardware devices via WiFi. With devices like GoPro, I believe the typical setup involves the GoPro creating a WiFi hotspot to which the iOS app connects, allowing file transfers. But this setup establishes a 1:1 connection between the app and the hardware. To support multiple hardware devices simultaneously, I am considering reversing this setup: the iOS device would create a personal hotspot, and the hardware devices would connect to it. However, I have concerns about this approach: Reliability: I have read that the personal hotspot feature on iOS devices can be unreliable, especially with non-Apple devices, which tend to disconnect frequently. Manual Setup: There is no API to programmatically create the personal hotspot, so users would have to enable it manually in the Settings. I can use isIdleTimerDisabled to prevent the iOS screen from going to sleep, which might help with disconnection issues. Aside from this, are there other things I can do to ensure a stable connection? Given my limited experience with hardware connections, I am uncertain if having the iOS device act as the WiFi access point is a good design. Any advice or alternative solutions would be greatly appreciated. Thank you in advance!
4
0
778
Oct ’24
How to transition from a non-background upload to a background one
A few months ago, I remember reading some official documentation that was describing how to switch to a background upload when the app is about to be suspended. Unfortunately, I can't find that resource back, so it would be fantastic if someone would point it out to me. If I remember correctly, the procedure described was to start a regular upload task within some UIApplication.backgroundTask, and in any case the upload wasn't finished at the moment the system would call the suspension handler, the upload was "transitioned" into a a background one while preserving the current progress (I think because it was using the same URLSession or something, hence why I want to find back the documentation!) Note that I don't want to start a background upload from the beginning (this is what we do already!). I'm mostly looking for that piece of documentation to experiment if that scheme would improve our upload performance. Thanks!
1
0
374
Oct ’24
the app in ipad(ios 18) can not connect to tcp server in the same local network
the app in ipad can not connect to tcp server in the same local network. libinfo check path: unsatisfied (Local network prohibited) reproduce steps: I update my ipad to iapd iOS/18.0 install the app make the app connect to tcp server in the windows which is in the same local network. the ipad trigger Local Network privacy alert I tap the allow button, I check the toggle of Local Network privacy is on as well I try to make the app connect to tcp server in the windows again, but can not connect to tcp server, the ipad system log: nw_path_libinfo_path_check [8F864AB4-C5E1-488D-B396-ECEC2F3FB77E IPv4#0423cc45:9520 tcp, legacy-socket, attribution: developer] libinfo check path: unsatisfied (Local network prohibited), interface: en0[802.11], ipv4, uses wifi 7. I try to make the app connect to tcp server in other windows. It connects successful. the ipad system log: nw_path_libinfo_path_check [C84DC25A-5A14-4080-ABAA-10ED24AE2D6D IPv4#7df62769:9520 tcp, legacy-socket, attribution: developer] libinfo check path: satisfied (Path is satisfied), interface: en0[802.11], ipv4, dns, uses wifi So please apple developer help investigate why the app can not connect to the tcp sever in the same local network, even though the toggle of local network permission is on in ipad os 18
2
0
707
Oct ’24