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

Post

Replies

Boosts

Views

Activity

Issue with WebSocket Secure (wss) connection on iOS (works on Node.js, fails on iOS app)
Hello everyone, I’m developing an iOS application that uses WebSocket Secure (wss) to connect to a backend server, which is working correctly. The server is hosted on Render.com and accepts connections over https and wss. Context: • I can connect to the backend without issues using HTTPS from both the app and a web browser. • Using Node.js and the Socket.IO client, the WebSocket connection to the server works correctly over wss://. • The server is configured with a valid SSL certificate (the HTTPS connection is verified and works in a browser). • The problem occurs when I try to connect from the iOS client (using Socket.IO in Swift) to the server through wss://social-gamer-backend.onrender.com. The connection consistently fails on iOS. The Issue: Even though the URL is correctly configured, and I can connect via Node.js, when I attempt to connect from the iOS app, I get connection-related errors. The most common error is: Error while connecting to the socket: Tried emitting when not connected • The server URL is correct (wss://social-gamer-backend.onrender.com). • The JWT token is being sent correctly in the headers. • There are no visible SSL certificate issues since the HTTPS connection works fine. • I’ve tried enabling and disabling App Transport Security (ATS) in the Info.plist. • From Node.js, the same connection code works fine, indicating that the WebSocket server is active and operational. Current iOS Configuration: let manager = SocketManager(socketURL: url, config: [ .log(true), .compress, .reconnects(true), .forceWebsockets(true), .extraHeaders(["Authorization": "Bearer (token)"]) ]) What I’ve tried so far: 1. I’ve tested the connection on different networks, including Wi-Fi and mobile data. 2. I’ve checked the iOS device restrictions and disabled potential network limitations. 3. I’ve enabled detailed logs in Crashlytics, but I can’t find any relevant information indicating why the connection is failing. 4. The same URL with wss:// works on Node.js, so it’s not an issue with the WebSocket server. Question: What could be preventing the iOS app from establishing a successful connection to the WebSocket server over wss://? Is there anything else I should configure in the app or server to allow iOS to handle secure WebSocket connections? I would appreciate any help or suggestions to resolve this issue. Thank you in advance.
1
0
244
Oct ’24
Switch VPN configurations from background
Hi, Goal: I want to change VPN configuration when app is closed and user joins unsecure wifi. (a wifi without a password). Possible solution. With help of an Hotspot helper I can listen the wifi changes when app is closed and if above criteria matches, execute code. (Start a new VPN Tunnel / change VPN configuration). Questions. Is this allowed. Can we get hotspot helper entitlement for this kind of usage. Is there other way to do this?
2
0
199
Oct ’24
Single Local Network permission entry shown for different applications
I have two applications (MinimServer and MinimWatch) that run on macOS. Both use the local network. On Sequoia, starting MinimWatch for the very first time after installing Sequoia shows a prompt for permission to access the local network. If the user agrees, an enabled entry for MinimWatch appears in the Privacy & Security > Local Network section as expected. If MinimServer is then started for the very first time, there is no prompt and the existing Local Network entry for MinimWatch now controls local network access for both MinimWatch and MinimServer. If ths above order is reversed (start MinimServer first after installing Sequoia and then start MinimWatch), Local Network shows a single entry for MinimServer which controls network access for both MinimServer and MinimWatch. It appears there is a false positive match when the second application is started. Sequoia finds the Local Network entry for the first application and incorrectly idenfies this as matching the second application. Both applications are written in Java and have a similar internal structure. The app packages contain some identical files but the following files are different: The bundle executable in the MacOS folder Other executables in the MacOS folder launched by the bundle executable The Info.plist keys CFBundleName, CFBundleIdentifier, CFBundleExecutable, CFBundleIconFile and JVMMainJarName What might be the similarity between these app packages that is causing Sequoia to incorrectly identify one of these applications as being the other application?
2
0
234
Oct ’24
What is the exact function of UIRequiresPersistentWiFi?
According to the Apple documentation, if this value is NO, the Wi-Fi connection will be disconnected after the application is used for 30 minutes; but after actual testing, it doesn't happen. So what exactly is the specific function of UIRequiresPersistentWiFi? If the value of UIRequiresPersistentWiFi is NO, it will disconnect Wi-Fi. What conditions does the device need to meet or in which situations will it disconnect Wi-Fi?
1
0
138
Oct ’24
About ipv6 support (gateway.icloud.com.cn/gsa.apple.com)
We are developing an iOS app and are using Firebase's Auth module. During IPv6 network testing, we found that the app fails when calling Apple's login authorization in an IPv6 environment. After investigation, we confirmed that the following two API calls: https://gateway.icloud.com.cn:443/ckdatabase/api/client/record/save https://gsa.apple.com/grandslam/GsService2 remain in a pending state. We tested gateway.icloud.com.cn and gsa.apple.com and found that these two domains do not support IPv6 DNS. What we would like to understand is whether these two domains truly do not support IPv6 DNS, and how we can implement Apple's login authorization in an IPv6 environment.
2
0
219
Oct ’24
NETransparentProxyProvider handleNewFlow vs handleNewUDPFlow
NETransparentProxyProvider having these two methods: override func handleNewFlow(_ flow: NEAppProxyFlow) -> Bool override func handleNewUDPFlow( _ flow: NEAppProxyUDPFlow, initialRemoteEndpoint remoteEndpoint: NWEndpoint ) -> Bool During initial days when NETransparentProxyProvider was introduced, We used handleNewFlow to handle NEAppProxyTCPFlow and handleNewUDPFlow to handle NEAppProxyUDPFlow . Since handleNewUDPFlow is now deprecated, is it just okay to use handleNewFlow to handle both NEAppProxyTCPFlow & NEAppProxyUDPFlow? will this works always or there are some scenario where keeping handleNewUDPFlow will be usefull?
3
0
287
Oct ’24
NWConnection is crashed on iOS 15 and 16, but it works well on 17
Hello 👋 I need to implement a logic for searching for devices with our own service type using Bonjour. Using the NWBrowser, I can receive a list of all devices and connect to them. I need to utilize a WebSocket connection. By the property endpoint of NWBrowser.Result objects I can create NWConnection. Below is my implementation which works fine on iOS 17: let params = NWParameters.tcp let webSocketOptions = NWProtocolWebSocket.Options() params.defaultProtocolStack.applicationProtocols.insert(webSocketOptions, at: 0) // The `endpoint` is from `browseResultsChangedHandler` of NWBrowser let connection = NWConnection(to: endpoint, using: params) However, it doesn't work on iOS 15 and 16 because of the crash: 2024-06-01 16:07:18.136068+0300 MyApp[591:16845549] [] nw_endpoint_get_url called with null endpoint 2024-06-01 16:07:18.136932+0300 MyApp[591:16845549] [] nw_endpoint_get_url called with null endpoint, dumping backtrace: [arm64] libnetcore-3100.102.1 0 Network 0x000000018530e174 __nw_create_backtrace_string + 188 1 Network 0x000000018538ba20 nw_endpoint_get_url + 852 2 Network 0x0000000185310020 nw_ws_create_client_request + 84 3 Network 0x0000000184f4b3cc __nw_ws_create_state_block_invoke + 416 4 Network 0x000000018504bc68 nw_protocol_options_access_handle + 92 5 Network 0x0000000184f41e98 nw_ws_create_state + 204 6 Network 0x0000000184f41aec __nw_protocol_copy_ws_definition_block_invoke_2 + 176 7 Network 0x0000000184f69188 nw_framer_protocol_connected + 348 8 Network 0x00000001854a6638 _ZL29nw_socket_handle_socket_eventP9nw_socket + 1560 9 libdispatch.dylib 0x0000000126b89d50 _dispatch_client_callout + 16 10 libdispatch.dylib 0x0000000126b8d208 _dispatch_continuation_pop + 756 11 libdispatch.dylib 0x0000000126ba48d4 _dispatch_source_invoke + 1676 12 libdispatch.dylib 0x0000000126b94398 _dispatch_workloop_invoke + 2428 13 libdispatch.dylib 0x0000000126ba0b74 _dispatch_workloop_worker_thread + 1716 14 libsystem_pthread.dylib 0x000000012371f814 _pthread_wqthread + 284 15 libsystem_pthread.dylib 0x000000012371e5d4 start_wqthread + 8 Also, there is the stack trace of bt-command in the debug console: * thread #20, queue = 'com.apple.network.connections', stop reason = EXC_BAD_ACCESS (code=1, address=0x0) * frame #0: 0x0000000123078c24 libsystem_platform.dylib`_platform_strlen + 4 frame #1: 0x00000001803c538c CoreFoundation`CFStringCreateWithCString + 40 frame #2: 0x0000000185310030 Network`nw_ws_create_client_request + 100 frame #3: 0x0000000184f4b3cc Network`__nw_ws_create_state_block_invoke + 416 frame #4: 0x000000018504bc68 Network`nw_protocol_options_access_handle + 92 frame #5: 0x0000000184f41e98 Network`nw_ws_create_state + 204 frame #6: 0x0000000184f41aec Network`__nw_protocol_copy_ws_definition_block_invoke_2 + 176 frame #7: 0x0000000184f69188 Network`nw_framer_protocol_connected + 348 frame #8: 0x00000001854a6638 Network`nw_socket_handle_socket_event(nw_socket*) + 1560 frame #9: 0x0000000126b89d50 libdispatch.dylib`_dispatch_client_callout + 16 frame #10: 0x0000000126b8d208 libdispatch.dylib`_dispatch_continuation_pop + 756 frame #11: 0x0000000126ba48d4 libdispatch.dylib`_dispatch_source_invoke + 1676 frame #12: 0x0000000126b94398 libdispatch.dylib`_dispatch_workloop_invoke + 2428 frame #13: 0x0000000126ba0b74 libdispatch.dylib`_dispatch_workloop_worker_thread + 1716 frame #14: 0x000000012371f814 libsystem_pthread.dylib`_pthread_wqthread + 284 I have found out a couple things: There are no crashes if I initialize the NWConnection object with using, for instance, the NWEndpoint.url(_:). initializer: let urlHost = URL(string: "ws://10.20.30.40:5060")! let endpoint = NWEndpoint.url(urlHost) let params = NWParameters.tcp let webSocketOptions = NWProtocolWebSocket.Options() params.defaultProtocolStack.applicationProtocols.insert(webSocketOptions, at: 0) let connection = NWConnection(to: endpoint, using: params) self.connection = connection But, in this case, I must extract IP-addresses 🙇‍♂️ Meanwhile, there is a topic such as Don’t Try to Get the Device’s IP Address.. I have tried to find anything that could help me move forward in this problem and run into some odd behaviour. There is a property skipHandshake of NWProtocolWebSocket.Options object. If I set the property value to true, there are no crashes as well as no connection to a device.
2
1
593
Jun ’24
Unable to install Network Extension of System Extension, stuck on validating
I'm trying to create a network extension packaged as a system extension on macOS, let request = OSSystemExtensionRequest.activationRequest(forExtensionWithIdentifier: "com.example.Desktop.PacketTunnelDesktop", queue: DispatchQueue.main) request.delegate = delegate // Submit the request to the system. let extensionManager = OSSystemExtensionManager.shared extensionManager.submitRequest(request) The application is installed in /Applications, I have also turned off SIP and systemextensionsctl developer on I'm not getting any breakpoint hits on my request delegate, but I am getting some logs in the console app: making activation decision for extension with teamID teamID("XXXXXX"), identifier com.example.Desktop.PacketTunnelDesktop no related kext found for sysex `com.example.Desktop.PacketTunnelDesktop` extension XXXXXXX com.example.Desktop.PacketTunnelDesktop (1.0/1) advancing state from validating to validating_by_category validate: category: com.apple.system_extension.network_extension, extension: com.example.Desktop.PacketTunnelDesktop waiting for external validation of extension with identifier com.example.Desktop.PacketTunnelDesktop It seems to stop here, and running systemsextensionsctl list shows: [validating by category] as the status. I'm trying to find some barebones example code for a network extension packaged as system extension but couldn't find any. Any ideas where to go from here?
2
0
238
Oct ’24
Regarding Long-Term Socket Connections in iOS Apps (TCP/UDP)
I am developing an app designed for use in hospital environments where public internet access may not be available. The app consists of two parts: the main app and a Local Connectivity Extension. Both components rely on socket connections (TCP and UDP) to maintain communication with a server. We have observed consistent disconnections occurring every 1-2 hours when app in the foreground (both extension and app), and would like to clarify Apple's guidelines regarding long-term socket connections. Specifically, is it permissible to keep a continuous socket connection (both TCP and UDP) active for an extended period? If so, are there any restrictions or best practices we should follow to ensure stable connectivity? Thank you for your assistance.
3
0
233
Oct ’24
Error using VPN profile from app extension in system extension
Hi, We are currently working on porting our PacketTunnelProvider app extension to run as a system extension. Things are mostly working great, but we're now testing upgrades from the existing app extension to a system extension. We have an existing configuration that gets created and runs perfectly fine with the app extension. Then, when we go and upgrade to the system extension, and attempt to connect using the same existing configuration. We see this error in the nesessionmanager logs: 10:00:57.717694-0700 nesessionmanager Signature check failed: code failed to satisfy specified code requirement(s) error 10:00:57.717914-0700 nesessionmanager Rejecting agent com.agentBundleID.bundleID because it does not satisfy the code signature requirements error 10:00:57.717937-0700 nesessionmanager Failed to launch com.agentBundleID.bundleID If we create a new configuration profile in our upgraded app w/system extension it works fine. The problem only occurs with existing profiles. Our app doesn't even get any notification about this error, startVPNTunnelWithOptions:andReturnError: doesn't return any error that we can work with. My gut tells me this has to do with the ProviderDesignatedRequirement not being correct, but I really have no way to confirm this at all. The NETunnelProviderProtocol has no way to specify that in its API. Our providerBundleIdentifier was unchanged between the two extensions. Is there anything that we can do here? Or are we stuck re-creating the configuration profile after an upgrade?
2
0
226
Oct ’24
Network Extension icon missing in System Settings
In macOS 15 Sequoia (tested on 15.0 and 15.0.1), the icon of our network extension (and of other third party apps) is missing. See the attached screenshot, instead of the generic app icon there should be the icon of our app. Is this a bug, or is there something we developers can/should do? I tried adding an asset catalog with the app icon, and specifying that using ASSETCATALOG_COMPILER_APPICON_NAME like we do in the main app. Even though the icon is added to the Resources folder of our .systemextension, and is referenced in the Info.plist using CFBundleIconFile and CFBundleIconName, the icon is still not showing in the System Settings.
3
1
344
Oct ’24
Clarification on Apple Prioritizing IPv6 over IP4
I’m seeking clarification on why iOS prioritizes IPv6 when both IPv4 and IPv6 are available. Does iOS always default to using IPv6 in such scenarios? Is this happening by design as Apple developer docs never explicitly state the prioritization rules. This might explain us why the issue doesn’t occur as frequently in IPv4-only environments
1
0
160
Oct ’24
Uninstall System Extension Silently
Hello Team, I want to know if there's a way to uninstall System Extension without prompting the user for authorisation. These are ways I found to uninstall System Extension The deactivationRequest api prompts the user for uninstalling System extension. If I use Apple script to drag and drop the application[which is embedded with System Extension] to trash also prompts the user. The only workaround that doesn't prompt is by disabling SIP and using the systemextensionsctl uninstall command. I want to know if there's any other solution that can uninstall System Extension without prompting the user for authorisation. Thanks!
1
0
257
Oct ’24
UDP Receive is not working
Hello everyone I'm new to swift and I can't quite figure it out yet:( I am developing a simple online game for mac os that involves two players connected to the same WIFI. I need to constantly receive information from the server and I don't understand how to implement it. If I call the receive function indefinitely, then my program freezes. I realized that this should happen asynchronously, but that's just how my program understands when a package came from the server. I understand that I need a delegate or handler, but I don't understand how to do it. Please help me to add the receive function and everything that is necessary for it import Foundation import Network enum CustomErrors: Error { case DataError case NetworkError case DecoderError case InvalidAddress } class TapperConnection: ObservableObject { private var _serverAlive = false private var connection: NWConnection! private var serverPort: UInt16 = 20001 private var serverIp: String = "127.0.0.1" private var _myDeviceName = Host.current().localizedName ?? "" @Published var messageDc: [HostData] = [] @Published var messageLobby: [HostData] = [] @Published var messageState: GameData = GameData() private var buffer = 2048 private var _inputData = "" private var _outputData = "" private var _myIp = "" private var isServer = false private var isClient = false var myIp: String { return _myIp } var myDeviceName: String { return _myDeviceName } private func getMyIp() -> String? { var address: String? var ifaddr: UnsafeMutablePointer<ifaddrs>? guard getifaddrs(&ifaddr) == 0 else { return nil } guard let firstAddr = ifaddr else { return nil } for ifptr in sequence(first: firstAddr, next: { $0.pointee.ifa_next }) { let interface = ifptr.pointee let addrFamily = interface.ifa_addr.pointee.sa_family if addrFamily == UInt8(AF_INET) || addrFamily == UInt8(AF_INET6) { let name = String(cString: interface.ifa_name) if name == "en0" || name == "en2" || name == "en3" || name == "en4" || name == "pdp_ip0" || name == "pdp_ip1" || name == "pdp_ip2" || name == "pdp_ip3" { var hostname = [CChar](repeating: 0, count: Int(NI_MAXHOST)) getnameinfo(interface.ifa_addr, socklen_t(interface.ifa_addr.pointee.sa_len), &hostname, socklen_t(hostname.count), nil, socklen_t(0), NI_NUMERICHOST) address = String(cString: hostname) } } } freeifaddrs(ifaddr) return address } private func isValidIP(_ ip: String) -> Bool { let regex = try! NSRegularExpression(pattern: "^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$") return regex.firstMatch(in: ip, range: NSRange(location: 0, length: ip.utf16.count)) != nil } @Sendable private func updateServerState(to state: NWConnection.State) { switch state { case .setup: _serverAlive = true case .waiting: _serverAlive = true case .ready: _serverAlive = true case .failed: _serverAlive = false case .cancelled: _serverAlive = false case .preparing: _serverAlive = false default: _serverAlive = false } } func createConnection() throws { let ip = getMyIp() if ip != nil { serverIp = ip! _myIp = ip! } else { throw CustomErrors.NetworkError } isServer = true do { try connectToServer() } catch { throw CustomErrors.NetworkError } } func createConnection(ip: String) throws { if isValidIP(ip) { serverIp = ip } else { throw CustomErrors.InvalidAddress } let _ip = getMyIp() if _ip != nil { _myIp = _ip! } else { throw CustomErrors.NetworkError } isClient = true do { try connectToServer() } catch { throw CustomErrors.NetworkError } } private func connectToServer() throws { if isServer { // ............... // run server exec // ............... } let _params = NWParameters(dtls: nil, udp: .init()) _params.requiredLocalEndpoint = NWEndpoint.hostPort(host: NWEndpoint.Host(_myIp), port: 20002) connection = NWConnection(host: NWEndpoint.Host(serverIp), port: NWEndpoint.Port(rawValue: serverPort)!, using: _params) connection.stateUpdateHandler = updateServerState(to:) connection.start(queue: .global()) while !_serverAlive {} do { try send(message: "im:\(_myDeviceName)") receive() } catch { print("Error sending disconnect message: \(error)") } } func closeConnection() { do { try send(message: "dc:\(_myDeviceName)") } catch { print("Error sending disconnect message: \(error)") } _serverAlive = false connection.cancel() } func send(message: String) throws { var error = false connection.send(content: message.data(using: String.Encoding.utf8), completion: NWConnection.SendCompletion.contentProcessed(({ NWError in if NWError == nil { print("Data was sent!") } else { error = true } }))) if error { throw CustomErrors.NetworkError } } func receive() { self.connection.receive(minimumIncompleteLength: 1, maximumLength: 65535) { data, _, isComplete, _ in if isComplete { if data != nil { let response: String = String(decoding: data!, as: UTF8.self) var decodeData: Any var messageType: MessageType (decodeData, messageType) = try! Decoder.decodeMessage(response) switch messageType { case MessageType.lobby: self.messageLobby = decodeData as! [HostData] case MessageType.state: self.messageState = decodeData as! GameData case MessageType.dc: self.messageDc = decodeData as! [HostData] } } self.receive() } } } }
1
0
171
Oct ’24
Detect nearby users on the same app
I am developing an application that allows you to interact with people on your local network. I have a view called ProfileView() which has has identifiers inside of it such as that build up the profile for each person. Essentially, what I want to do is discover people who are on this app on your local network, or who are nearby to you based on bluetooth. I do not want to use a server, as I would like this to be an application that does not require internet access to function. Also if possible, I would like a toggle to allow yourself to be discovered in the background, even if not using the app. Any ideas how to do this? Also, is there any better way to do this instead of Bluetooth and Local Network? Thank you Possible code chunks needed: Discover nearby bluetooth users Discover nearby network users Toggle for discovery Toggle for background discovery (while not using app) Share profile (mainly just text and a profile image)
2
0
246
Oct ’24
Local Network policy for applications coming in MacOs 15.0
Hi, I upgraded my MacOs to 15.0. I work with maven in my environment. Normally, while running tests with maven in my environment in Sonomo 14.5, I was connecting to my test database environment with the postgresql library in the background. But after the upgrade, I realized that maven could not do this. After some research, I saw that this policy for applications was newly added at https://support.apple.com/en-us/121011. So, starting from 15.0, we have to allow "Local Network" usage for each application. But when I run the "mvn test" command from the terminal, it does not ask me if I allow Local Network usage and that's why my mvn test gets an error. But in normal applications, the same transaction works differently; For example, if I use the terminal of VSCode.app, it pops up a popup asking if I allow it and I allow it. Then, I see that this application has been added under Local Network. I definitely think there is a bug here. Even though I allowed the postgresql jdbc driver with the "socketfilterfw" command, it doesn't work. Even though I allowed maven, it doesn't come under "Local Network applications". 1- Here, there definitely needs to be an option to add an application to the "Local Network" screen. 2- We need to define the "Local Network" usage authorization for all my applications or the relevant user with a single permission. The worst part here is for CI servers. There are too many application runtimes in CI. It is unnecessary to bother with authorizing all of them here.
4
0
274
Oct ’24
Get Process ID (pid) from NEFilterFlow & sourceAppAuditToken
Dear all,In macOS Catalina we have the new NetworkExtension framework that can filter network trafic on a computer.In my usecase I need the PID of the process that is the originator of the network flow. I'm aware that PID are not a reliable way to identify a process (since PIDs can be reused), but in my usecase only PID can identify what I need.In handleNewFlow(_ flow: NEFilterFlow) we can get the sourceAppAuditToken (flow.sourceAppAuditToken), where sourceAppAuditToken is a Data type. Is there a way to convert this sourceAppAuditToken to a PID value?I'm also aware of getting the signature of the process (eventually the Bundle ID) with SecCodeCopySigningInformation / kSecCSDynamicInformation, but again in my usecase it does not help.A way to do this is to call "netstat" and look for the local port in the output and get the PID from there, but sometimes this is not very reliable.Any ideas how to do this?Regards,Alex
9
1
4.6k
Dec ’19
NEDNSSettings with onDemandRule for .wifi or .cellular
Hi, Is it possible to get NEDNSSettings to enable for only .wifi or only .cellular? I tried using interfaceTypeMatch = .wifi standalone and I also tried it together with a NEEvaluateConnectionRule matching all domains but it skips using the EDNSSettings also on .cellular even if .interfaceTypeMatch is .wifi. This is the more advanced example of the two and it seems to not care about the interfaceTypeMatch flag: let evaluateRule = NEEvaluateConnectionRule(matchDomains: [], andAction: .neverConnect) let evaluateConnectionRule = NEOnDemandRuleEvaluateConnection() evaluateConnectionRule.connectionRules = [evaluateRule] evaluateConnectionRule.interfaceTypeMatch = .wiFi self.dnsManager.onDemandRules = [evaluateConnectionRule] Should this be possible or does it only work with VPN?
0
0
132
Oct ’24