Bonjour, also known as zero-configuration networking, enables automatic discovery of devices and services on a local network using industry standard.

Posts under Bonjour tag

48 Posts
Sort by:

Post

Replies

Boosts

Views

Activity

Getting Started with Bonjour
Every now and then I talk to someone who’s trying to use Bonjour and just can’t get over the first hurdle. That happened today, and so I decided to share my write-up for the benefit of others. Questions or comments? Put them in a new thread here on DevForums, tagging it with Bonjour so that I see it. Share and Enjoy — Quinn “The Eskimo!” @ Developer Technical Support @ Apple let myEmail = "eskimo" + "1" + "@" + "apple.com" Getting Started with Bonjour Bonjour is an Apple term for a variety of Internet standards [1]. Bonjour allows your app to browse for and connect to services on the network without infrastructure support. For example, Bonjour lets you find and connect to a printer even if the network has no DHCP server to hand out IP addresses. If you’re new to Bonjour, a good place to start is the Bonjour Overview. It’s in the documentation archive, so it hasn’t been updated in a while, but the fundamentals haven’t changed. There are, however, two things that have changed: Network framework has new Bonjour APIs, and the old ones are now deprecated. iOS 14 introduced local network privacy. This post shows how to get started with Bonjour, taking into account these new developments. [1] Specifically: RFC 3927 Dynamic Configuration of IPv4 Link-Local Addresses RFC 6762 Multicast DNS RFC 6763 DNS-Based Service Discovery Start Browsing Let’s start by implementing a service browser. To simplify things, this browses for SSH services. That way you can get started with the browser without first having to implement a server to register your service. If you don’t already have an SSH service registered on your network, start one by enabling System Settings > General > Sharing > Remote Login on your Mac. The SSH service type is, unsurprisingly, _ssh._tcp. First, on your Mac, run the dns-sd tool to confirm that you have an SSH service visible on your network: % dns-sd -B "_ssh._tcp" "local." % dns-sd -B "_ssh._tcp" "local." … Timestamp A-R Flags if Domain Service Type Instance Name … 11:54:43.315 Add 2 6 local. _ssh._tcp. Fluffy … 11:54:43.725 Add 2 6 local. _ssh._tcp. SAM the Robot 12 ^C This shows that I have two services, one called Fluffy and the other called SAM the Robot 12. Let’s write some iOS code to browse for those. To start, create an app from the iOS > App template and connect a button to the startStop() method of a class like this: import Foundation import Network class AppModel { var browserQ: NWBrowser? = nil func start() -> NWBrowser { print("browser will start") let descriptor = NWBrowser.Descriptor.bonjour(type: "_ssh._tcp", domain: "local.") let browser = NWBrowser(for: descriptor, using: .tcp) browser.stateUpdateHandler = { newState in print("browser did change state, new: \(newState)") } browser.browseResultsChangedHandler = { updated, changes in print("browser results did change:") for change in changes { switch change { case .added(let result): print("+ \(result.endpoint)") case .removed(let result): print("- \(result.endpoint)") case .changed(old: let old, new: let new, flags: _): print("± \(old.endpoint) \(new.endpoint)") case .identical: fallthrough @unknown default: print("?") } } } browser.start(queue: .main) return browser } func stop(browser: NWBrowser) { print("browser will stop") browser.stateUpdateHandler = nil browser.cancel() } func startStop() { if let browser = self.browserQ { self.browserQ = nil self.stop(browser: browser) } else { self.browserQ = self.start() } } } Note I’m using SwiftUI, but if you chose to use UIKit you could add this code directly to your view controller. Of course, whether you want to add networking code to your view controller is another question. The answer is, natch, “No”, except when creating a tiny test project like this one (-: Now build and run in the simulator and click your buton. It’ll print something like this: browser will start browser did change state, new: ready browser results did change: + SAM the Robot 12._ssh._tcp.local. + Fluffy._ssh._tcp.local. As you can see, it’s found our two SSH services. Yay! Run on the Device Now stop the app and run it on a real device. This time the Test button results in: browser will start … browser did change state, new: failed(-65555: NoAuth) This is local network privacy kicking in. There are two things you need to do: Add a NSBonjourServices property to your Info.plist to declare what service types you’re using. Add a NSLocalNetworkUsageDescription property to your Info.plist to explain what you’re doing with the local network. Do that and run your app again. On tapping the Test button you’ll see an alert asking you to grant your app access to the local network. Tap Allow and the browser will start generating results as before. Respond to Updates When working with Bonjour it’s important to keep your browser running to update your app’s state. To test this, start a Remote Login on a different machine and look for a new result being printed: browser results did change: + Slimey._ssh._tcplocal. And then turn it off: browser results did change: - Slimey._ssh._tcplocal. If you don’t have another Mac to test this with, start a dummy service using dns-sd: % dns-sd -R "Guy Smiley" "_ssh._tcp" "local." 12345 Registering Service Test._ssh._tcp.local. port 12345 … Press control-C to stop the dns-sd tool, which unregisters the service. Connect When the user choose a service, it’s time to connect. There are two ways to do this, depending on the networking API you use to run your connection. NWConnection can connect directly to a Bonjour service endpoint. For example, you might have code that connects to a DNS name and port: func makeConnection(host: String, port: UInt16) -> NWConnection { let host = NWEndpoint.Host(host) let port = NWEndpoint.Port(rawValue: port)! let endpoint = NWEndpoint.hostPort(host: host, port: port) return NWConnection(to: endpoint, using: .tcp) } Replace that with code that takes the endpoint you get back from the browser: func makeConnection(endpoint: NWEndpoint) -> NWConnection { return NWConnection(to: endpoint, using: .tcp) } If you’re using a legacy API, like BSD Sockets, you’ll need to resolve the Bonjour service endpoint to a DNS name and then pass that DNS name into your connection code. Network framework does not support resolving Bonjour service endpoints out of the box, so you’ll have to do that yourself. For an example of how you might do this, see this post. IMPORTANT For this to work reliably, your BSD Sockets code must support Happy Eyeballs. See TN3151 Choosing the right networking API for specific advice on that front. Register a Service Now let’s look at the server side. To listen for connections with Network framework, you might write code like this: import Foundation import Network class AppModel { var listenerQ: NWListener? = nil func start() -> NWListener? { print("listener will start") guard let listener = try? NWListener(using: .tcp) else { return nil } listener.stateUpdateHandler = { newState in print("listener did change state, new: \(newState)") } listener.newConnectionHandler = { connection in connection.cancel() } listener.start(queue: .main) return listener } func stop(listener: NWListener) { print("listener will stop") listener.stateUpdateHandler = nil listener.cancel() } func startStop() { if let listener = self.listenerQ { self.listenerQ = nil self.stop(listener: listener) } else { self.listenerQ = self.start() } } } To register your service with Bonjour, add these lines before the call to start(queue:): listener.service = .init(type: "_ssh._tcp") listener.serviceRegistrationUpdateHandler = { change in print(change) } The listener calls your service registration update handler to tell you the name of the service. Typically you display this value somewhere in your UI. For more about this, see Showing Connection Information in an iOS Server. To confirm that your service is running, open Terminal and choose Shell > New Remote Command. Your service should show up in the Secure Shell (ssh) list. Alternatively, browse for SSH services using the dns-sd tool, as illustrated in the Start Browsing section above.
0
0
1.8k
Aug ’23
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.
0
0
61
1d
MDNS Peer to Peer + Network Extension
I have an app that utilizes the Network Extension ( Packet Tunnel Provider ), but also uses MDNS to find local devices for data transfer via Network Extensions. However, once connected over Peer to Peer using AWDL0 or NWConnections, it works as expected until a user shuts the screen down. It looks like there's a difference in behavior when the device is plugged in vs when it's on just battery alone. So we can be happily sending data over p2p ( awdl0 ) then a screen shuts off and it kills the connection. Is this expected behavior and if so is there documentation? Also, Network Extensions do not appear to be able to discover over P2P, they can only connect to endpoints directly. Is this expected behavior? My thoughts; If a user allows both the Network Extension Permission and Local Network Permissions that the Network Extension should be able to discover peers via p2p. The connections ( if not asleep ) should stay active while in use.
1
0
153
1w
iOS 14 CoreFoundation crash with EXC_BREAKPOINT
Hi, I am facing a strange issue in my app with iOS14 there is a intermittent crash, i am using NetServiceBrowser for MDNS discovery not sure if that is causing the problem crash log has below information: Crashed: com.apple.main-thread 0 CoreFoundation 0x1a906c4c4 CFAssertMismatchedTypeID + 108 1 CoreFoundation 0x1a8f7db0c CFRunLoopSourceRemoveFromRunLoop + 298 2 CFNetwork 0x1a96255b0 CFNetServiceBrowserStopSearch + 460 3 CoreFoundation 0x1a8f81240 CFRUNLOOPISCALLINGOUTTOASOURCE0PERFORMFUNCTION + 24 4 CoreFoundation 0x1a8f81140 CFRunLoopDoSource0 + 204 5 CoreFoundation 0x1a8f80488 CFRunLoopDoSources0 + 256 6 CoreFoundation 0x1a8f7aa40 CFRunLoopRun + 776 7 CoreFoundation 0x1a8f7a200 CFRunLoopRunSpecific + 572 8 GraphicsServices 0x1bf075598 GSEventRunModal + 160 9 UIKitCore 0x1ab840004 -[UIApplication run] + 1052 10 UIKitCore 0x1ab8455d8 UIApplicationMain + 164
29
1
9.7k
3w
in-addr.arpa default search domains
Hi, I observed some unexpected behavior and hope that someone can enlighten me as to what this is about: mDNSResponder prepends IP / network based default search domains that are checked before any other search domain. E.g. 0.1.168.192.in-addr.arpa. would be used for an interface with an address in the the 192.168.1.0/24 subnet. This is done for any configured non-link-local IP address. I tried to find any mention of an approach like this in RFCs but couldn't spot anything. Please note that this is indeed a search domain and different from reverse-DNS lookups. Example output of tcpdump for ping devtest: 10:02:13.850802 IP (tos 0x0, ttl 64, id 43461, offset 0, flags [none], proto UDP (17), length 92) 192.168.1.2.52319 > 192.168.1.1.53: 54890+ [1au] A? devtest.0.1.168.192.in-addr.arpa. (64) I was able to identify the code that adds those default IP subnet based search domains but failed to spot any indication as to what this is about: https://github.com/apple-oss-distributions/mDNSResponder/blob/d5029b5/mDNSMacOSX/mDNSMacOSX.c#L4171-L4211 Does anyone here have an ideas as to what this might be about?
0
0
162
May ’24
debugging issues with Shared Private Key Bonjour connections
Like the post at https://forums.developer.apple.com/forums/thread/118035, I'm hitting an issue where I'm receiving: boringssl_session_set_peer_verification_state_from_session(448) [C1.1.1.1:2][0x12b667210] Unable to extract cached certificates from the SSL_SESSION object In my app logs. I tried to pin the SSL version to TLS 1.2 per Quinn's advice in that post, and then started digging further enabling CFNETWORK_DIAGNOSTICS=3 to see what was exposed on the Console.log (since it didn't show up in the Xcode console) The related log lines: 0 debug boringssl 15:43:04.978874-0700 MeetingNotes boringssl_context_log_message(2206) [C5:2][0x11080a760] Reading SSL3_RT_HANDSHAKE 16 bytes 0 debug boringssl 15:43:04.979007-0700 MeetingNotes boringssl_context_log_message(2206) [C5:2][0x11080a760] Writing SSL3_RT_CHANGE_CIPHER_SPEC 1 bytes 0 debug boringssl 15:43:04.979141-0700 MeetingNotes boringssl_context_log_message(2206) [C5:2][0x11080a760] Writing SSL3_RT_HANDSHAKE 16 bytes 0 debug boringssl 15:43:04.979260-0700 MeetingNotes nw_protocol_boringssl_write_bytes(87) [C5:2][0x11080a760] write request: 51 0 debug boringssl 15:43:04.979387-0700 MeetingNotes nw_protocol_boringssl_write_bytes(158) [C5:2][0x11080a760] total bytes written: 51 921460 debug boringssl 15:43:09.937961-0700 MeetingNotes boringssl_context_log_message(2206) [C5:2][0x11080a760] Writing SSL3_RT_ALERT 2 bytes 0 error boringssl 15:43:04.979630-0700 MeetingNotes boringssl_session_set_peer_verification_state_from_session(448) [C5:2][0x11080a760] Unable to extract cached certificates from the SSL_SESSION object Have a number of references to SSL3_RT in the messages, and I was curious if that indicated that I was using TLS1.3, which apparently doesn't support private shared keys. The constraints that I used riffs on the sample code from the tic-tac-toe example project: private static func tlsOptions(passcode: String) -> NWProtocolTLS.Options { let tlsOptions = NWProtocolTLS.Options() let authenticationKey = SymmetricKey(data: passcode.data(using: .utf8)!) let authenticationCode = HMAC<SHA256>.authenticationCode( for: "MeetingNotes".data(using: .utf8)!, using: authenticationKey ) let authenticationDispatchData = authenticationCode.withUnsafeBytes { DispatchData(bytes: $0) } // Private Shared Key (https://datatracker.ietf.org/doc/html/rfc4279) is *not* supported in // TLS 1.3 [https://tools.ietf.org/html/rfc8446], so this pins the TLS options to use version 1.2: // @constant tls_protocol_version_TLSv12 TLS 1.2 [https://tools.ietf.org/html/rfc5246] sec_protocol_options_set_max_tls_protocol_version(tlsOptions.securityProtocolOptions, .TLSv12) sec_protocol_options_set_min_tls_protocol_version(tlsOptions.securityProtocolOptions, .TLSv12) sec_protocol_options_add_pre_shared_key( tlsOptions.securityProtocolOptions, authenticationDispatchData as __DispatchData, stringToDispatchData("MeetingNotes")! as __DispatchData ) /* RFC 5487 - PSK with SHA-256/384 and AES GCM */ // Forcing non-standard cipher suite value to UInt16 because for // whatever reason, it can get returned as UInt32 - such as in // GitHub actions CI. let ciphersuiteValue = UInt16(TLS_PSK_WITH_AES_128_GCM_SHA256) sec_protocol_options_append_tls_ciphersuite( tlsOptions.securityProtocolOptions, tls_ciphersuite_t(rawValue: ciphersuiteValue)! ) return tlsOptions } Is there something I'm missing in setting up the proper constraints to request TLS version 1.2 with a private shared key to be used? And beyond that, any suggestions for debugging or narrowing down what might be failing?
5
0
392
Apr ’24
Can't connect Mac to Apple Vision Pro for XCode Development
I am trying to download XCode apps from my Mac to my Apple Vision Pro for testing. I have tried following the instructions by going into Settings-&gt;General-&gt;Remote Devices on my Apple Vision Pro, but there my Mac does not show up as a possible connection. Per this page, I have made sure that both devices are connected to the same WiFi network, updated my Mac to Sonoma, and updated my AVP to the latest OS, and everything else that it asks for. I am able to mirror my display from my Mac but downloading apps from XCode does not work. I have also looked to enable Developer Mode by going to Settings -&gt; Privacy &amp; Security -&gt; Enable Developer Mode, but there is no option for enabling developer mode here. Per this forum, my best guess is that it is a Bonjour Protocol compatibility issue since both devices are on university wifi (WPA2), but I also tried connecting both over a hotspot which also did not work.
1
1
323
Apr ’24
Why Does the Multipeer Connectivity Framework Documentation Mention Bluetooth if It's No Longer Supported?
Since the Multipeer Connectivity framework no longer supports Bluetooth. (https://developer.apple.com/forums/thread/749346) Why does its official documentation still mention "In iOS, the framework uses infrastructure Wi-Fi networks, peer-to-peer Wi-Fi, and Bluetooth personal area networks for the underlying transport." ?(https://developer.apple.com/documentation/multipeerconnectivity) What is the purpose of using Bluetooth personal area networks for the underlying transport?
2
0
339
Apr ’24
Multipeer Connectivity Framework Capabilities and Permission Requirements
Hello, In this inquiry(https://developer.apple.com/forums/thread/747860), I came across this conclusion. “Apple disabled TCP/IP networking over Bluetooth completely. Apple’s peer-to-peer networking APIs now run exclusively over Wi-Fi." I have three questions I would like to ask. The Multipeer Connectivity Framework supports Wi-Fi networks, peer-to-peer Wi-Fi, and Bluetooth personal area networks. Since the framework abstracts away the underlying protocols, we cannot specify which protocol to choose. Can this framework still establish a pure Bluetooth connection now? (Not just using Bluetooth for the discovery phase). Given that the framework supports Bluetooth protocols, why does it not require Bluetooth permissions but only local network permissions? Does the Bluetooth protocol supported by the framework have the capability to discover traditional Bluetooth devices and services that the Core Bluetooth framework can discover?
1
0
392
Apr ’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
517
Feb ’24
Crashed: com.apple.root.default-qos EXC_BAD_ACCESS KERN_INVALID_ADDRESS 0x0000000000000007
I am facing this error on my SDK project. Could not identify what's the actual issue. I've added the Firebase crash logs below. Crashed: com.apple.root.default-qos 0 libdispatch.dylib 0x1a778 dispatch_channel_cancel + 12 1 libdispatch.dylib 0x1a778 dispatch_source_cancel + 12 2 libsystem_dnssd.dylib 0x2084 DNSServiceProcessResult + 860 3 Common 0x2df04 __swift_memcpy5_4 + 25916 4 Common 0x10b00 block_destroy_helper.10 + 188 5 libdispatch.dylib 0x26a8 _dispatch_call_block_and_release + 32 6 libdispatch.dylib 0x4300 _dispatch_client_callout + 20 7 libdispatch.dylib 0x744c _dispatch_queue_override_invoke + 928 8 libdispatch.dylib 0x15be4 _dispatch_root_queue_drain + 392 9 libdispatch.dylib 0x163ec _dispatch_worker_thread2 + 156 10 libsystem_pthread.dylib 0x1928 _pthread_wqthread + 228 11 libsystem_pthread.dylib 0x1a04 start_wqthread + 8
2
0
638
Feb ’24
How to get full DNS responses from the system resolver? DNSServiceQueryRecord not returning errors..
I would like to get the full DNS responses from the system resolver. I'm using DNSServiceQueryRecord, but I can't get negative responses. How do I get the negative responses? I need the full response because they have clues about network-level censorship. For instance, mismatched case in the name, bad answer RR type, missing SOA record on no answers response. On Android I can use android_res_nquery, but I couldn't find anything similar on iOS and macOS. The closest I found was DNSServiceQueryRecord, which at least gives me resource records, so I can inspect TTL and name case. After some struggle, I was able to make it work. I'm using Go with cgo for that: https://github.com/fortuna/gio-test/blob/fortuna-dns/sysresolver_darwin.go https://github.com/fortuna/gio-test/blob/fortuna-dns/sysresolver_darwin_export.go My sequence of calls is: DNSServiceQueryRecord(sdRef, 0, 0, fullname, rrtype, rrclass, (DNSServiceQueryRecordReply)goCallback, context); fd := C.DNSServiceRefSockFD(sdRef) nReady, err := unix.Poll([]unix.PollFd{{Fd: int32(fd), Events: unix.POLLIN | unix.POLLERR | unix.POLLHUP}}, timeout) serviceErr = C.DNSServiceProcessResult(sdRef) // Here my callback gets called, multiple times for multiple answers. C.DNSServiceRefDeallocate(sdRef) I'm able to get positive answers, even multiple answers. But the Poll doesn't return when there are no answers (like for CNAME www.example.com). I expected the poll to return on negative answers, and my callback to be called with an error when calling DNSServiceProcessResult. Is that not the expected behavior? How do I get notified that a query has no answers?
2
0
452
Feb ’24
Apple devices can't ping each other in local network
Hi, I have a strange problem. In my local network, I have some apple devices (including mac, iphone, ipad) and a windows computer. The windows pc and any of the apple devices can ping each other, while every two of the apple devices can't ping each other. Whether udp or tcp are in the same situation. As is the situation, the firewall/mask/local ip are not the problems. I can't use wireshark to debug, because there is not any packet between these apple devices. Does someone know what the problem it may be? Or could someone tell me how to debug this? Thanks in advance!
2
0
692
Feb ’24
iOS 17 device undiscoverable via Bonjour ?
After upgrading to iOS 17 (now 17.2.1) on iPhone 11 pro the device does not appear to be discoverable on the local network via Bonjour. This is impeding, e.g., connecting to the device with iMazing etc. I looked at the local network with the Discovery app for Bonjour and while an iPad running iOS 16 is visible, the iPhone with iOS 17 is not. Any ideas ? We need to connect with iMazing via wifi since the mighty lightning port is predictably hosed for USB connection. Any insight appreciated. Thanks!
1
0
639
Dec ’23
NetService can't resolve(withTimeout:) service connected via ethernet for iOS 17.1+ (NSNetServicesErrorDomain: 10, NSNetServicesErrorCode: -72007)
It worked fine before iOS 17.1. Just checked with iOS 16 on real device. And my teammate from QA department confirmed it works for iOS 17.0.1. The problem occurs only with device in local network connected via ethernet. The device itself has two options for connection - via Wi-Fi and Ethernet. It works for all iOS versions via Wi-Fi. But it can't resolve host for Ethernet connection. Error appears in func netService(_ sender: NetService, didNotResolve errorDict: [String : NSNumber]) looks like that: (NSNetServicesErrorDomain: 10, NSNetServicesErrorCode: -72007) Could you please explain this error code?
1
0
563
Dec ’23
Confused about DNSServiceGetAddrInfo
I expect there is a shockingly obvious answer to this, but I've been stuck a couple of days on Problem Obvious and could use a tip / cake-with-file to escape from development jail. I have used DNSServiceRef / Bonjour to advertise my service, and have used the same to get a list of what is advertised (using the hit on lo0 for the moment since still testing). So, now I have a machine name "mymachine.local." and the right port number to connect to. Yay! What I can not figure out is how to get that information into a (IPV6) sockaddr so I can use it with connect. The point of confusion for me is that DNSServiceGetAddrInfo() does not take a port argument, and I see no other place to squeeze this information into the sockaddr returned by the DNSServiceGetAddrInfoReply. If I just use a IPV6 socket with that sockaddr, I get back EADDRNOTAVAIL. Haven't tried IPv4. No error is returned from DNSServiceGetAddrInfo. I'm reading around that this may be because the port is 0, and indeed I can't find any spot in this pathway to squeeze that information in. I'll attach an obligatory bit of code so that the reader may feel more grounded: // My DNSServiceGetAddrInfoReply void ServiceList::Node::AddressInfoCallback( DNSServiceRef __nonnull _sdRef, DNSServiceFlags _flags, uint32_t _interfaceIndex, DNSServiceErrorType _errorCode, const char * __nullable _hostname, const struct sockaddr * __nullable _address, uint32_t UNUSED _ttl, void * __nonnull context) { printf( "AddressInfo: \"%s\"\n", _hostname); AddrInfo * info = (AddrInfo*) context; if( kDNSServiceErr_NoError != _errorCode || NULL == _hostname || NULL == _address) { LOG_ERROR("Failed to get address info on \"%s\"\n", (const char*) info->hostTarget); delete info; return; } int err = connect(info->socket, _address, _address->sa_len); // returns EADDRNOTAVAIL on IPv6 socket. What am I really trying to do? I'd like to connect to the address and port that I from my DNSServiceResolveReply.
2
0
463
Dec ’23