node_mdns icon indicating copy to clipboard operation
node_mdns copied to clipboard

Raspberry PI 2 getaddrinfo 3008 error

Open dennismadsen opened this issue 9 years ago • 22 comments

I've this sample script:

var mdns = require('mdns');

var browser = mdns.createBrowser(mdns.tcp('http'));
browser.on('error', function (error) {
    console.log("error");
    console.log(error);
});
browser.on('serviceUp', function (service) {
    console.log("serviceUp");
    console.log(service);
});
browser.start();

On my Mac it's working fine, and two services is found. If I run the exact same script on my Raspberry PI 2 running Raspbean (connected to the same network), I get this output:

pi@raspberrypi ~ $ node mdns.js 
*** WARNING *** The program 'node' uses the Apple Bonjour compatibility layer of Avahi.
*** WARNING *** Please fix your application to use the native API of Avahi!
*** WARNING *** For more information see <http://0pointer.de/avahi-compat?s=libdns_sd&e=node>
*** WARNING *** The program 'node' called 'DNSServiceRegister()' which is not supported (or only supported partially) in the Apple Bonjour compatibility layer of Avahi.
*** WARNING *** Please fix your application to use the native API of Avahi!
*** WARNING *** For more information see <http://0pointer.de/avahi-compat?s=libdns_sd&e=node&f=DNSServiceRegister>
error
{ [Error: getaddrinfo -3008] code: -3008, errno: -3008, syscall: 'getaddrinfo' }
error
{ [Error: getaddrinfo -3008] code: -3008, errno: -3008, syscall: 'getaddrinfo' }

This issue, states that it's fair to ignore the warnings.

But what about the two errors? Is this an issue with this module or some kind of configuration issue on Raspberry PI?

dennismadsen avatar Apr 12 '15 15:04 dennismadsen

This issue, states that it's fair to ignore the warnings.

Yup.

But what about the two errors?

It is a system/config thing on the raspberry. My guess is that the system name service switch does not perform mdns lookups. On Linux these things are configured in /etc/nss.conf, IIRC. First step is to lookup error code -3008, though. It probably is "Host not found"...

agnat avatar Apr 13 '15 13:04 agnat

I've been searching for this error code without any luck. If you can give me any clue on how to proceed from this, I would be very happy.

Anyone that have been able to use this module on an Raspberry PI?

dennismadsen avatar Apr 13 '15 17:04 dennismadsen

As I said: I think it's a name service switch thing. Read the nsswitch.conf man page...

Specifically:

The service specifications supported on your system depend on the presence of shared libraries, and are therefore extensible. Libraries called /lib/libnss_SERVICE.so.X will provide the named SERVICE. On a standard installation, you can use "files", "db", "nis", and "nisplus". For the hosts database, you can additionally specify "dns". For the passwd, group, and shadow databases, you can additionally specify "compat" (see Compatibility mode below). The version number X may be 1 for glibc 2.0, or 2 for glibc 2.1 and later. On systems with additional libraries installed, you may have access to further services such as "hesiod", "ldap", "winbind" and "wins".

Just fire up a grown-up non-embedded linux box, take a look at nsswitch.conf and start comparing...

agnat avatar Apr 17 '15 09:04 agnat

I am getting the same thing ('Error: getaddrinfo -3008') on Ubuntu 14.0.4 x64 using node_mdns 2.2.8

danyocom avatar Apr 17 '15 13:04 danyocom

Look like the issue on my machine is with resolving IPv6 addresses. I have a tempoarary workaround (for me at least). If I modify Browser.defaultResolverSequence in lib/browser.js to only use IPv4 my issue goes away.

here is my new Browser.defaultResolverSequence:

Browser.defaultResolverSequence = [
  rst.DNSServiceResolve()
, 'DNSServiceGetAddrInfo' in dns_sd ? rst.DNSServiceGetAddrInfo() : rst.getaddrinfo({families:[4]})
, rst.makeAddressesUnique()
];

danyocom avatar Apr 17 '15 14:04 danyocom

in my code above passing {families:[0]} instead of {familes:[4]} should allow things to work with both IPv4 and IPv6.

passing in 0 causes getaddrinfo to use an ai_family of AF_UNSPEC ... which indicates that getaddrinfo() should return socket addresses for any address family (either IPv4 or IPv6)

danyocom avatar Apr 17 '15 14:04 danyocom

Wow, thank you! That's also solved the issue for me.

Should this solution be integrated into master?

dennismadsen avatar Apr 17 '15 14:04 dennismadsen

Thanks for looking into this.

Should this solution be integrated into master?

Not sure yet. Needs closer inspection. In any case you guys can pass a custom resolver chain instead of modifying the default... Just to make the workaround less intrusive.

agnat avatar Apr 17 '15 16:04 agnat

Hello, I have the same kind of problem with either io.js 1.6.4 or node 0.12.2 I found use the following workaround: adding this line mdns.Browser.defaultResolverSequence[1] = 'DNSServiceGetAddrInfo' in mdns.dns_sd ? mdns.rst.DNSServiceGetAddrInfo() : mdns.rst.getaddrinfo({families:[4]}); right after the require. var mdns = require('mdns');

tberthe avatar Apr 20 '15 16:04 tberthe

I have [email protected] and facing same error. I was trying to add the work around mentioned by danyocom. Strangely the source file in browser.js was not what he mentioned in his comment. In fact in the browser.js file i see, there is no argument for rst.getaddrinfo() in that particular place.

Also tried without success the workaround mentioned by tberthe. So, Any pointers to work around this would be useful.

goldenmean avatar Apr 22 '15 10:04 goldenmean

although different thing is I am testing this on Ubuntu 11.10

goldenmean avatar Apr 22 '15 10:04 goldenmean

How can I do the other non-intrusive work around of modifying resolver chain?

goldenmean avatar Apr 22 '15 10:04 goldenmean

I guess you've found out by now, but for future reference you can change this:

var browser = mdns.createBrowser(mdns.tcp('http'));

into this:

var sequence = [
    mdns.rst.DNSServiceResolve(),
    'DNSServiceGetAddrInfo' in mdns.dns_sd ? mdns.rst.DNSServiceGetAddrInfo() : mdns.rst.getaddrinfo({families:[4]}),
    mdns.rst.makeAddressesUnique()
];
var browser = mdns.createBrowser(mdns.tcp('http'), {resolverSequence: sequence});

That resolver sequence made it work for me on Raspberry Pi.

jswetzen avatar Jul 12 '15 15:07 jswetzen

Thank you so much @jswetzen! Using the resolverSequence works like a charm for me. I do prefer to use

{families:[0]}

as pointed out by @danyocom

cwegener avatar Sep 07 '15 13:09 cwegener

You just saved 3 hours of my weekend. Much appreciated.

svenkrb avatar Oct 24 '15 14:10 svenkrb

Hi everyone, It would seem that the solution is no longer working @jswetzen.

OS: Ubuntu 16.04 LTS NODE_MDNS: 2.3.3 PROGRAM: https://github.com/spacebro/spacebro-client/tree/electron-mdns-linux

How to replicate error:

  1. nvm use
  2. yarn
  3. node example/simple-node/index-port-discovery.js

I am getting the following error:

spacebro-client - { Error: getaddrinfo -3008
    at errnoException (/home/mina/sources/nodejs/spacebro-client/node_modules/mdns/lib/resolver_sequence_tasks.js:199:11)
    at getaddrinfo_complete (/home/mina/sources/nodejs/spacebro-client/node_modules/mdns/lib/resolver_sequence_tasks.js:112:10)
    at GetAddrInfoReqWrap.oncomplete (/home/mina/sources/nodejs/spacebro-client/node_modules/mdns/lib/resolver_sequence_tasks.js:120:9) code: -3008, errno: -3008, syscall: 'getaddrinfo' }
    

Has anyone found a solution to this problem ?

MPolymath avatar Jan 24 '17 14:01 MPolymath

We're actually not using mdns in my project any longer but switched to the bonjour package. It's a pure js implementation.

jswetzen avatar Jan 24 '17 14:01 jswetzen

Thank you @jswetzen,

we would rather however not use the bonjour package, as it does seem to suffer from many issues, and does not seem to be very active community wise.

MPolymath avatar Jan 24 '17 15:01 MPolymath

@jswetzen the bonjour package doesn't work well, it misses some devices depending on the order you switch them on (and start advertising).

I got the same -3008 error on ubuntu 16.04, I managed to understand that it only appends when the library calls getaddrinfo_0_11(host, family, cb) with family === 6. is works fine with ipv4 only.

a temporary fix is to deactivate ipv6 by applying this patch:

diff --git a/lib/browser.js b/lib/browser.js
index 02b6044..4b148ab 100644
--- a/lib/browser.js
+++ b/lib/browser.js
@@ -116,7 +116,7 @@ Browser.create = function create(serviceType, options) {
 
 Browser.defaultResolverSequence = [
   rst.DNSServiceResolve()
-, 'DNSServiceGetAddrInfo' in dns_sd ? rst.DNSServiceGetAddrInfo() : rst.getaddrinfo()
+, 'DNSServiceGetAddrInfo' in dns_sd ? rst.DNSServiceGetAddrInfo({families: [4]}) : rst.getaddrinfo({families: [4]})
 , rst.makeAddressesUnique()
 ];
 

az0uz avatar Feb 09 '17 20:02 az0uz

I'm using the sequence with only IPv4 enabled, but am still getting the same error :/

skerit avatar Feb 20 '17 17:02 skerit

After some debugging on debian/stretch, I've found some more info on this : error -3008 is from uv_getaddrinfo, returning UV__EAI_NONAME, which is -3008 (ref.)

It's not "normal behaviour" as the service has been detected so there must be a way to reach it.

Meanwhile, a more intuitive handling might be done by modifying lib/resolver_sequence_tasks.js :109

  function getaddrinfo_complete(err, addresses, cb) {
    if (addresses) {
      cb(undefined, addresses);
-    } else if (err === 'ENOENT') {
+   } else if (err === 'ENOENT' || err == -3008) {
      cb(undefined, []);
    } else {
      cb(errnoException(err, 'getaddrinfo'));
    }
  }

I'm not even sure getaddrinfo could return 'ENOENT' btw?

Concerning the core issue of having a service without any valid reaching address, I'm still looking into it but as previously said by others, it most probably comes from a malformed network stack configuration.

sdumetz avatar May 17 '18 09:05 sdumetz

I just happened on this with node_mdns 2.5.1 on Ubuntu 18.04 with its default /etc/nsswitch.conf saying

hosts:          files mdns4_minimal [NOTFOUND=return] dns myhostname

Replacing that by

hosts:          files mdns_minimal [NOTFOUND=return] dns mdns myhostname

fixes the issue, however in order to make node_mdns fail more gracefully in the former case, @danyocom’s solution seems to work well:

diff --git a/lib/browser.js b/lib/browser.js
index 02b6044..0ed3ff7 100644
--- a/lib/browser.js
+++ b/lib/browser.js
@@ -116,7 +116,7 @@ Browser.create = function create(serviceType, options) {
 
 Browser.defaultResolverSequence = [
   rst.DNSServiceResolve()
-, 'DNSServiceGetAddrInfo' in dns_sd ? rst.DNSServiceGetAddrInfo() : rst.getaddrinfo()
+, 'DNSServiceGetAddrInfo' in dns_sd ? rst.DNSServiceGetAddrInfo() : rst.getaddrinfo({families: [0]})
 , rst.makeAddressesUnique()
 ];
 

With this, it only outputs IPv4 addresses in the former case and both IPv4 and IPv6 addresses in the latter case.

Although maybe it would still be useful to emit an error event so that applications can alert users to fix their nsswitch.conf?

(Only the getaddrinfo case is changed because for DNSServiceGetAddrInfo [0] is the default, and that code path is not taken on Avahi anyway.)

There is a comment // XXX in older versions of node a zero family value is not supported in resolver_sequence_tasks.js, I don’t know which versions these are, but if they are still significant, that could be handled in the same way as the getaddrinfo difference.

cwalther avatar Oct 17 '19 12:10 cwalther