Closed jcwren closed 8 years ago
Thanks for the report.
Thing is: There really is not much parsing going on. Here is the stop condition. It looks like Mac OS thinks we're done... :-/
Just to make sure it is not on our end: Could you downgrade to mdns v2.2.1 for a second and see if that works better?
Another thing that helped in the past with odd Mac OS issues was disabling IPv6 support:
networksetup -setv6off wi-fi
networksetup -setv6off Ethernet
Taken from #51 (which is unrelated).
HTH
Here's what I found so far. In lib/resolver_sequence_tasks.js, DNSServiceGetAddrInfo(), sets family_flags=0. The docs at https://developer.apple.com/library/IOs/documentation/Networking/Reference/DNSServiceDiscovery_CRef/index.html#//apple_ref/c/func/DNSServiceGetAddrInfo say that passing in 0 applies an algorithm.
I decided to try and force IPv4 by setting family_flags=dns_sd.kDNSServiceProtocol_IPv4. This failed:
events.js:72 throw er; // Unhandled 'error' event ^ TypeError: argument 4 must be an integer (DNSServiceProtocol) at Array.DNSServiceGetAddrInfo as 1 at next (/Users/jcw/Practiscore/pme/node_modules/mdns/lib/browser.js:97:21) at MDNSService.on_resolver_done (/Users/jcw/Practiscore/pme/node_modules/mdns/lib/resolver_sequence_tasks.js:33:11) at SocketWatcher.MDNSService.self.watcher.callback (/Users/jcw/Practiscore/pme/node_modules/mdns/lib/mdns_service.js:17:38)
Added a couple console.logs() to display dns_sd.kDNSServiceProtocol_IPv4 and dns_sd.kDNSServiceProtocol_IPv6, and they're undefined.
Looked through src/dns_sd.cpp, and I see a lot of NODE_DEFINE_CONSTANTS, but none for those two variables.
If I hardcode family_flags=1, everything starts working again. If I set it to 3, it apparently behaves just as it does when it's 0. Disabling IPv6 via the networksetup commands had no impact. I don't mind forcing IPv4 for my app. The application running on the iPads is not yet IPv6 aware, so that won't cause any problems in the short term.
Thanks for putting in the work. One result seems to be: We're missing kDNSServiceProtocol_IPv4
and kDNSServiceProtocol_IPv6
. I'll look into adding them. Unfortunately this is not as easy as it looks, because of ... well... long story.
Any chance you could tell us a long story? :)
This is a real PITA on an OSX system. Not all apps are yet IPv6 aware, and not being able to detect said IPv4-only app comes online is very troublesome.
For whatever reason, BonjourBrowser always finds both. The author of BonjourBrowser had this to say: "There's significant discussion about the "interface index" parameter passed to DNSServiceResolve() and DNSServiceQueryRecord(). Along with a reference to if_nametoindex(3), they also discuss in "Constants for specifying an interface index" how Any doesn't include P2P, and that additional resolution may appear as an ADD.
I avoid the C interface because it's rarely necessary, and you might have an easier time writing a wrapper over NSNetService. Otherwise, the source has plenty of examples http://www.opensource.apple.com/source/mDNSResponder/mDNSResponder-561.1.1, including the dns-sd utility's implementation."
Any chance you could tell us a long story? :)
Short version of a long story is: Since node switched the build system from waf to gyp a few years back add-ons lack a configure phase, There simply is no way to detect the presence of said constants.
IMHO, the best cause of action is to hardcode the constant on your end like you did. I really can not see why this is a PITA...
Not all apps are yet IPv6 aware
Well... it's 2015...
Sorry, the PITA part is not getting IPv4 addresses.
I can go the hard-coding route. But if the build system can't detect the constants, could node_mdns determine which OS it's running on when the module loads, then make a best guess for what the constants should be? Or maybe throw an error if they're both zero?
Nope. Wild-ass guessing based on the OS is exactly what library code should not do. It would break on older Mac OS versions and for anybody using mDNSResponder on Linux.
So, the OS test should go in your code...
Running into an issue on OSX 10.10 with node-mdns 2.2.2 under NodeJS 0.10.33 where the IPv4 address isn't always returned in the addresses array. I've included wireshark captures with the IPv4 address both being returned and not returned. An iPad running iOS 8.1.1 is the device advertising, although I get the same behavior with an iPad running iOS 7.x. This used to work reliably, but I'm not sure if it was an upgrade to OSX 10.10 or node-mdns 2.2.2 that broke it.
The address is present in the mDNS packet, but it appears that node-mdns isn't parsing it out properly. The Bonjour Browser sees both addresses all the time.
I would have attached this as a file, but it seems only image files can be attached.