Network connections send and receive data using transport and security protocols.

Posts under Network tag

200 Posts
Sort by:

Post

Replies

Boosts

Views

Activity

UDP Connection issue after updating Xcode 15.3
I am using UDP communication in a app. Here is what i do, Initialises a UDP broadcast connection object. Bind it with a port to listen Receives the IP & Port from the UDP connection to connect further with TCP connection. After updating Xcode 15.3, It works until the iPad is connected with mac in debug mode. When i create build to test remotely, it stops receiving IP & Port from UDP connection. Here is how i concluded this is Xcode issue, I tried to debug this issue with Xcode 15.2 and it works as expected with debug and after creating build also. Any help / suggestion would be appreciated.
1
0
426
Mar ’24
Troubleshooting Peer-to-Peer Connection Failure between iOS Apps Using NWListener, NWConnection, and STUN
I am currently developing two iOS applications that require peer-to-peer connectivity. To facilitate this, I've implemented NWListener and NWConnection in both apps for network communication. To determine each device's public IP address and port—necessary for establishing a connection over the internet through my mobile operator's Carrier-Grade NAT (CGNAT)—I'm using a STUN server. Despite successfully retrieving the external IP addresses and ports for both devices, I am unable to establish a peer-to-peer connection between them. My current setup involves initiating a connection using the public addresses and ports discovered through the STUN server response. However, all attempts to connect the devices directly have been unsuccessful. I am seeking guidance on whether there are additional considerations or specific configurations needed when using NWListener, NWConnection, and a STUN server to establish a direct connection between devices in a CGNAT environment. Is there a particular step or network configuration I might be missing to successfully connect both iOS devices to each other using their external network details?
1
0
465
Mar ’24
QUIC connection error
Hi, we are currently implementing below method for a quick POC in iOS (Xcode 15.3/macOS Sonoma 14.0): func startQUICConnection() async { // Set the initial stream to bidirectional. options.direction = .bidirectional self.mainConn?.stateUpdateHandler = { [weak self] state in print("Main Connection State: \(state)") switch state { case .ready: print("Ready...") default: break } } // Don't forget to start the connection. self.mainConn?.start(queue: self.queue) } This is what we have in the initializer of the class: parameters = NWParameters(quic: options) mainConn = NWConnection(to: endpoint, using: parameters) These are the class's properties: let endpoint = NWEndpoint.hostPort(host: "0.0.0.0", port: .init(integerLiteral: 6667)) let options = NWProtocolQUIC.Options(alpn: ["echo"]) let queue = DispatchQueue(label: "quic", qos: .userInteractive) var mainConn: NWConnection? = nil let parameters: NWParameters! As per the logs, we never get to the .ready state for the NWConnection. Logs: nw_path_evaluator_create_flow_inner failed NECP_CLIENT_ACTION_ADD_FLOW (null) evaluator parameters: quic, attach protocol listener, attribution: developer, context: Default Network Context (private), proc: 022B7C28-0271-3628-8E5E-26B590B50E5B nw_path_evaluator_create_flow_inner NECP_CLIENT_ACTION_ADD_FLOW 8FEBF750-979D-437F-B4A8-FB71F4C5A882 [22: Invalid argument] nw_endpoint_flow_setup_channel [C2 0.0.0.0:6667 in_progress channel-flow (satisfied (Path is satisfied), interface: en0[802.11], ipv4, ipv6, dns, uses wifi)] failed to request add nexus flow Main Connection State: preparing Main Connection State: waiting(POSIXErrorCode(rawValue: 22): Invalid argument) We're running a local server using proxygen on port 6667. It connects with the proxygen client though... Have tried several thing but results are the same.
1
0
976
Mar ’24
Trouble with inbound multicast on home network
I am using UDP multicast to send messages to an embedded host (Raspberry Pi) in my home network but I am running into issues receiving multicast traffic on Ventura 13.4. I have a simple Python receiver/sender script: receiver.py (with from_nic_ip set as the local address related to the port that I want to bind to, multicast addr: 224.0.0.0, multicast port: 42073) def receive_loop(from_nic_ip, multicast_group_ip, multicast_port): receiver = socket.socket(family=socket.AF_INET, type=socket.SOCK_DGRAM,\ proto=socket.IPPROTO_UDP, fileno=None) multicast_group = (multicast_group_ip, multicast_port) receiver.bind(multicast_group) if from_nic_ip == '0.0.0.0': mreq = struct.pack("=4sl", socket.inet_aton(multicast_group_ip), socket.INADDR_ANY) else: mreq = struct.pack("=4s4s",\ socket.inet_aton(multicast_group_ip), socket.inet_aton(from_nic_ip)) receiver.setsockopt(socket.IPPROTO_IP, socket.IP_ADD_MEMBERSHIP, mreq) while True: buf, _ = receiver.recvfrom(BUFSIZE) msg = buf.decode() print(msg) reciver.close() sender.py def send_loop(host_ip_addr, multicast_group_ip, multicast_port): sender = socket.socket(family=socket.AF_INET, type=socket.SOCK_DGRAM,\ proto=socket.IPPROTO_UDP, fileno=None) multicast_group = (multicast_group_ip, multicast_port) sender.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, 1) sender.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_IF,\ socket.inet_aton(host_ip_addr)) while True: print("Sending data!") sender.sendto("test".encode(), multicast_group) time.sleep(1) sender.close() If I run macOS as a sender and the Raspberry Pi as the receiver, I get the expected output: "test" printed continuously. If I reverse the roles, I see no "test" output. I have verified that the script works as a sender/receiver by duplicating the test on a Linux desktop and I see that the two nodes can communicate with each other as both a sender or receiver.
1
0
263
Mar ’24
Handle multiple AsyncThrowingStreams in structured concurrency?
Hello, im currently rewriting my entire network stuff to swift concurrency. I have a Swift Package which contains the NWConnection with my custom framing protocol. So Network framework does not support itself concurrency so I build an api around that. To receive messages I used an AsyncThrowingStream and it works like that: let connection = MyNetworkFramework(host: "example.org") Task { await connection.start() for try await result in connection.receive() { // do something with result } } that's pretty neat and I like it a lot but now things got tricky. in my application I have up to 10 different tcp streams I open up to handle connection stuff. so with my api change every tcp connection runs in it's own task like above and I have no idea how to handle the possible errors from the .receive() func inside the tasks. First my idea was to use a ThrowingTaskGroup for that and I think that will work but biggest problem is that I initially start with let's say 4 tcp connections and I need the ability to add additional ones later if I need them. so it seems not possible to add a Task afterwards to the ThrowingTaskGroup. So what's a good way to handle a case like that? i have an actor which handles everything in it's isolated context and basically I just need let the start func throw if any of the Tasks throw I open up. Here is a basic sample of how it's structured. Thanks Vinz internal actor MultiConnector { internal var count: Int { connections.count } private var connections: [ConnectionsModel] = [] private let host: String private let port: UInt16 private let parameters: NWParameters internal init(host: String, port: UInt16, parameters: NWParameters) { self.host = host self.port = port self.parameters = parameters } internal func start(count: Int) async throws -> Void { guard connections.isEmpty else { return } guard count > .zero else { return } try await sockets(from: count) } internal func cancel() -> Void { guard !connections.isEmpty else { return } for connection in connections { connection.connection.cancel() } connections.removeAll() } internal func sockets(from count: Int) async throws -> Void { while connections.count < count { try await connect() } } } // MARK: - Private API - private extension MultiConnector { private func connect() async throws -> Void { let uuid = UUID(), connection = MyNetworkFramework(host: host, port: port, parameters: parameters) connections.append(.init(id: uuid, connection: connection)) let task = Task { [weak self] in guard let self else { return }; try await stream(connection: connection, id: uuid) } try await connection.start(); await connection.send(message: "Sample Message") // try await task.value <-- this does not work because stream runs infinite until i cancel it (that's expected and intended but it need to handle if the stream throws an error) } private func stream(connection: MyNetworkFramework, id: UUID) async throws -> Void { for try await result in connection.receive() { if case .message(_) = result { await connection.send(message: "Sample Message") } // ... more to handle } } }
3
0
620
Mar ’24
nw_interface_radio_type_t
我想用Network.framework中path_monitor来监听网络状态的变化,在Network.framework的interface.h中有一个枚举定义nw_interface_radio_type_t,我没有找到关于它的使用方法。 I want to use path_monitor in Network.framework to monitor changes in network status. There is an enumeration definition nw_interface_radio_type_t in interface.h of Network.framework. I have not found how to use it.
1
0
332
Mar ’24
NWParemeters.requiredLocalEndpoint is ignored in VisionOS
I have a an application that incorporates a RTCP client to communicate with a local networked device. The device's RTCP implementation requires that the local RTCP port be 6970 even for the initial outbound connection. I have an implementation that is working just fine on macOS and iOS, but I when I port this to visionOS, I see that the local connection is ignoring my .requiredLocalEndpoint specification and choosing a random port (I can see this is happening in Wireshark via the VisionOS simulator.) let remoteRtcpEndpoint = NWEndpoint.hostPort(host: NWEndpoint.Host(remoteRTCPAddress), port: NWEndpoint.Port(rawValue: remoteRTCPPort)!) let rtcpParameters = NWParameters.udp let localEndpoint = NWEndpoint.hostPort(host: NWEndpoint.Host("0.0.0.0"), port: NWEndpoint.Port(rawValue: localRTPPort)!) Self.logger.info("Starting rtcp with local port \(localRTPPort), remote address \(remoteRTCPAddress), endpoint \(String(describing: localEndpoint))") rtcpParameters.requiredLocalEndpoint = localEndpoint rtcpParameters.allowLocalEndpointReuse = true remoteRtcpConnection = NWConnection(to: remoteRtcpEndpoint, using: rtcpParameters) remoteRtcpConnection.start(queue: .global()) And here's the code that sends the command. remoteRtcpConnection.send(content: RtcpPacket.vdly(delayMs: HUGE_FIXED_VDLY_MS).packet(), completion: .contentProcessed({ error in if let error = error { Self.logger.warning("Error sending VDLY packet \(error)") continuation.resume(throwing: error) } else { Self.logger.debug("VDLY Sent \(self.HUGE_FIXED_VDLY_MS)") continuation.resume(returning: ()) } })) If this is a known limitation of the Network framework, should I revert to BSD sockets or something? How can I work around this? Additionally, I don't have a VisionOS device, so I am using the simulator, could this be a problem with the simulator's network bridge?
4
0
354
Mar ’24
NWConnection vs. nw_connection_t
I have ported my code from BSD sockets over to Network.framework, and while blocking issues remain (https://forums.developer.apple.com/forums/thread/747815) and while I can not yet properly instrument my code because os_signpost does not seem to work on XCTestCases profiled directly from Xcode (https://forums.developer.apple.com/forums/thread/748059) I do already have some initial observations. Perf test case of sending full (~1280 bytes) UDP datagrams back and forth over lo0 indicates that BSD sockets code can achieve 20% higher throughput (in packets per second) than Network.framework based code. That is not what I expected, and I will continue investigating but for the moment I have one question I did not find answer to. Will using C based Network.framework API instead of Swift based one bring performance gains? For example, nw_connection_t provides an interface to send non-contiguous segments of dispatch_data_t without copying, whereas NWConnection only deals with contiguous Data. Thanks for any insights.
2
0
440
Mar ’24
send udp socket multicast address in network framework iOS 17 version
Hi, I am trying send data multicast address via using NWConnectionGroup, I tried below code at iOS 15 version it works, it sends data and I received sended data, but When I try at iOS 17 version it connects successfully url and port, but it doesn't sending data, Why I can't send data from iOS 17 version, Can I need get specific permission func init() { var group: NWConnectionGroup! connect(withHost: "235.10.10.100", port: 3333) } func connect(withHost: NWEndpoint.Host, port: NWEndpoint.Port) { let multicast = try! NWMulticastGroup(for: [.hostPort(host: withHost, port: port)]) group = NWConnectionGroup(with: multicast, using: .udp) group.setReceiveHandler(maximumMessageSize: 128) { message, data, b in print("Received message:") } group.stateUpdateHandler = { (newState) in print("Group entered state \(String(describing: newState))") } group.start(queue: .global()) } func sendData() { let groupSendContent = Data("helloAll".utf8) self.group.send(content: groupSendContent) { error in (error) print("Send complete with error (String(describing: error))") } }
1
0
303
Mar ’24
[iOS 17.4, XCode 15.3] Previously working NWConnection for peer-to-peer connection now permanently stuck on "Preparing"
After updating my devices to iOS/iPadOS 17.4, and XCode to 15.3, Network framework peer-to-peer connections have stopped working entirely. The system was working fine before and the code has not been changed. On the client side (NWBrowser) the server (NWListener) can be seen, but upon attempting to establish a connection the client-side NWConnection.State gets permanently stuck at .preparing. NWConnection.stateUpdateHandler doesn't enter any other state. It doesn't seem as though it's taking a long time to prepare; it's just stuck. This situation occurs across multiple connection modes (wired, common wifi, separate wifi). Additional information I didn't participate in the 17.4 beta and RC The code in "Creating a custom peer-to-peer protocol" works--this code forms the basis of my code
2
0
1.1k
Mar ’24
Need help determining what to select for Encryption Export Regulations
Ok, so I am making an app, and I’m not sure exactly what I need to select for the Encryption Export Regulations pop-up nor if I can exempt. Here’s what I can say that my app uses HTTPS Connection HS256 Encryption for JWT Bearer Token Authentication (Encryption is done on a server and not the device) That’s pretty much it. Thank you to anyone that can help.
0
0
238
Mar ’24
Advanced UDP with Network.framework
I finally found a time to experiment with Network.framework and I find the experience very pleasant. The API looks well thought out and is a pleasure to work with. My app (on the App Store for around 13 years) uses UDP networking to create a mesh between multiple devices where each device acts as a server and client at the same time. It does that by creating one UDP socket on each device bound to a *:<port> and then uses that socket to sendmsg to other peers. That way all peers can communicate with each other using their well known <port>. This all works great and fine. To test the performance and verify the functionality I have multiple XCTestCase scenarios where I create multiple peers and simulate various communications and verify their correctness. Within the XCTestCase process that means creating multiple underlying sockets and then bind them to multiple local random <port>s. Works great. Now I'm trying to port this functionality to Network.framework. Let's assume two peers for now. Code simplified. Prepare NWParameter instances for both peers, plain UDP for now. // NOTE: params for peer 1 let p1 = NWParameters(dtls: nil, udp: .init()) p1.requiredLocalEndpoint = .hostPort(host: "0.0.0.0", port: 2222) p1.allowLocalEndpointReuse = true // NOTE: params for peer 2 let p2 = NWParameters(dtls: nil, udp: .init()) p2.requiredLocalEndpoint = .hostPort(host: "0.0.0.0", port: 3333) p2.allowLocalEndpointReuse = true Create NWListeners for each peer. // NOTE: listener for peer 1 - callbacks omitted for brevity let s1 = try NWListener(using: parameters) s1.start(queue: DispatchQueue.main) // NOTE: listener for peer 2 - callbacks omitted for brevity let s2 = try NWListener(using: parameters) s2.start(queue: DispatchQueue.main) The listeners start correctly and I can verify that I have two UDP ports open on my machine and bound to port 2222 and 3333. I can use netcat -u to send UDP packets to them and correctly see the appropriate NWConnection objects being created and all callbacks invoked. So far so good. Now in that XCTestCase, I want to exchange a packets between peer1 and peer2. So I will create appropriate NWConnection and send data. // NOTE: connection to port 3333 from port 2222 let c1 = NWConnection(host: "127.0.0.1", port: 3333, using: p1) c2.start(queue: DispatchQueue.main) // NOTE: wait for the c1 state .ready c2.send(content: ..., completion: ...) And now comes the problem. The connection transitions to .preparing state, with correct parameters, and then to .waiting state with Error 48. [L1 ready, local endpoint: <NULL>, parameters: udp, local: 0.0.0.0:2222, definite, attribution: developer, server, port: 3333, path satisfied (Path is satisfied), interface: en0[802.11], ipv4, dns, uses wifi, service: <NULL>] [L2 ready, local endpoint: <NULL>, parameters: udp, local: 0.0.0.0:3333, definite, attribution: developer, server, port: 2222, path satisfied (Path is satisfied), interface: en0[802.11], ipv4, dns, uses wifi, service: <NULL>] nw_socket_connect [C1:1] connectx(6 (guarded), [srcif=0, srcaddr=0.0.0.0:2222, dstaddr=127.0.0.1:3333], SAE_ASSOCID_ANY, 0, NULL, 0, NULL, SAE_CONNID_ANY) failed: [48: Address already in use] nw_socket_connect [C1:1] connectx failed (fd 6) [48: Address already in use] nw_socket_connect connectx failed [48: Address already in use] state: preparing connection: [C1 127.0.0.1:2222 udp, local: 0.0.0.0:2222, attribution: developer, path satisfied (Path is satisfied), interface: lo0] state: waiting(POSIXErrorCode(rawValue: 48): Address already in use) connection: [C1 127.0.0.1:3333 udp, local: 0.0.0.0:2222, attribution: developer, path satisfied (Path is satisfied), interface: lo0] I believe this happens because the connection c1 essentially tries to create under the hood a new socket or something instead of reusing the one prepared for s1. I can make the c1 work if I create the NWConnection without binding to the same localEndpoint as the listener s1. But in that case the packets sent via c1 use random outgoing port. What am I missing to make this scenario work in Network.framework ? P.S. I was able to make it work using the following trick: bind the s1 NWListener local endpoint to ::2222 (IPv6) connect the c1 NWConnection to 127.0.0.1:3333 (IPv4) That way packets on the wire are sent/received correctly. I would believe that this is a bug in the Network.framework. I can open a DTS if more information is needed.
4
0
624
Mar ’24
wifi & proxy settings have disappeared from all iOS phone simulators!
Seems bizarre but since updating to Sonoma (14.2), I've actually lost menu items in the iOS phone simulators. Basically there is no longer any Settings->wifi item in the simulators' menu at all, so I can't do what I've always done & set a manual proxy (in order to use Charles proxy). I've been doing this for years & we generally use about 4 or 5 simulators for testing with Xcode, and now suddenly there's no ability to set a manual proxy on any of them - they have all lost these menu items. Does anyone know what has gone one & how I fix this, please !!!! I can't find info about this via the usual googling. If it makes any difference I'm using Xcode 15.2, 16" MacBook 2019 with intel chipset.
0
0
300
Mar ’24
Crash in background for iOS 17.3.0 and later devices
We found crash reports from Xcode organizer about some crashes happening only in iOS and iPadOS version 17.3.0 and later across all our releases mostly in background state related to Network SDK. Unfortunately, we are unable to reproduce the issue. On the crashed thread, it seems to refer to process from Network SDK but we never import and use it directly in our project. Most of the functions found in the main thread in the crash report can't be accessed from the project, it seems to be internal framework calls in iOS SDK. The crash pointing to this line of code: nw_protocol_error Bug number: FB13661192 Somehow I cannot attach any crash report here, it always return error This post contains sensitive language. Please revise it in order to continue. whenever I try to submit it. If I remove it, I can submit the post.
4
0
627
Mar ’24
kSecTrustResultProceed misbehave
"kSecTrustResultProceed indicates that the user has explicitly trusted a certificate." Problem: kSecTrustResultProceed returned from 'SecTrustEvaluate' for some users(733/million), while their cert chain contains non explicitly trusted certs: cert chain: ***.***.com Go Daddy Secure Certificate Authority - G2 Go Daddy Root Certificate Authority - G2 (Go Daddy is trusted on iOS, not explicitly trusted) I cannot reproduce this on my phone, but it does exist, for some users, including iOS 17. Any thoughts? SecTrustResultType res = kSecTrustResultInvalid; SecTrustEvaluate(secTrust, &res); if (res == kSecTrustResultUnspecified) { return YES; } if (res == kSecTrustResultProceed) { // some check... found this question return YES; } if (res != kSecTrustResultRecoverableTrustFailure) { return NO; } // some recover... return recovered;
2
0
251
Feb ’24
App Transport Security: changes in iOS/tvOS 17
Hello! I'm working on VLC, that is a multimedia playback app available for any platform. Among many things, we support discovery of servers on the local network using Bonjour, UPnP and NETBIOS with consecutive connections to those servers for media playback purposes. Additionally, we allow connections to unicast and multicast streams based on any domain name or IP (i.e. "rtsp://207.254.***.***"). Discovery of the mentioned services works very well with the Multicast entitlement along with NSLocalNetworkUsageDescription also on iOS 17. According to documentation, iOS 17 prohibits any IP based connections by default, which breaks the entire functionality mentioned above that was previously enabled by including the NSAllowsArbitraryLoads key with the value TRUE in Info.plist. We amended the Info.plist with the following configuration and still fail to connect to hosts in that IP range. <key>NSAllowsLocalNetworking</key> <true/> <key>NSExceptionDomains</key> <dict> <key>192.168.0.0/24</key> <dict> <key>NSTemporaryExceptionAllowsInsecureHTTPLoads</key> <true/> <key>NSIncludesSubdomains</key> <true/> <key>NSExceptionRequiresForwardSecrecy</key> <false/> <key>NSExceptionAllowsInsecureHTTPLoads</key> <true/> <key>NSExceptionAllowsLocalNetworking</key> <true/> </dict> </dict> Additionally, there does not seem to be a viable, publicly documented solution to connect to any server on the internet based on an IP address. Further, the process for IPv6 seems unclear. Any help how to solve this so we can transition to the iOS/tvOS 17 SDK in time would be very much appreciated.
1
0
699
Feb ’24