Skip to content

Error: bind EADDRINUSE #101

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
Boimb opened this issue Aug 18, 2018 · 47 comments
Closed

Error: bind EADDRINUSE #101

Boimb opened this issue Aug 18, 2018 · 47 comments
Assignees
Labels

Comments

@Boimb
Copy link

Boimb commented Aug 18, 2018

Hi,
Just wanted to try the lib in a sandbox file :

const {discoverGateway} = require('node-tradfri-client')

discoverGateway().then(console.log)

then when I :

node sandbox.js

I get this message :

Error: bind EADDRINUSE fe80::aede:48ff:fe00:1122%en5:5353
at Object._errnoException (util.js:1022:11)
at _exceptionWithHostPort (util.js:1044:20)
at _handle.lookup (dgram.js:266:18)
at _combinedTickCallback (internal/process/next_tick.js:141:11)
at process._tickCallback (internal/process/next_tick.js:180:9)
at Function.Module.runMain (module.js:695:11)
at startup (bootstrap_node.js:188:16)
at bootstrap_node.js:609:3

Ofc, I tried

ps aux | grep node

But no other node process running ...
Any clue ?
Thx for help.

@AlCalzone
Copy link
Owner

You probably have another mDNS client running, which listens on port 5353. I’m not sure if it’s possible to share that port.

@Boimb
Copy link
Author

Boimb commented Aug 18, 2018

Thx for quick reply.
Yep, seems to.
When I

netstat -a -b -n | grep 5353

I get

udp6       0      0  *.5353                 *.*                                     90467      55895
udp4       0      0  *.5353                 *.*                                    106933      53333

Can't find the process to kill :/
I'll keep on searching.

@AlCalzone
Copy link
Owner

Which OS are you using?

@Boimb
Copy link
Author

Boimb commented Aug 19, 2018

MacOS 10.12

I found that :

sudo lsof -iUDP -sTCP:LISTEN -n -P
 ------------ 
mDNSRespo  165 _mdnsresponder    7u  IPv4 0xd1014bae3dc67963      0t0  UDP *:5353
mDNSRespo  165 _mdnsresponder    8u  IPv6 0xd1014bae3dc67703      0t0  UDP *:5353

@Boimb
Copy link
Author

Boimb commented Aug 21, 2018

Everything works fine if I downgrade to 1.2.1.
Maybe it could help to solve this.

@AlCalzone
Copy link
Owner

Ok then it definitely has to do with the package used for mDNS discovery. I previously used bonjour which is a bit buggy on my network. I'll have to see what is different in the socket creation.

@AlCalzone AlCalzone added the bug label Aug 21, 2018
@AlCalzone AlCalzone self-assigned this Aug 21, 2018
@AlCalzone
Copy link
Owner

I just tried the above on my Windows machine where mDNSResponder was also running. The error handling was not correct, so an error during discovery lead to an unhandled exception instead of a promise rejection.

Nonetheless, I only get that error when explicitly setting reuseAddr to false in https://github.com/AlCalzone/node-tradfri-client/blob/master/src/lib/discovery.ts#L31

@AlCalzone
Copy link
Owner

The only difference I could spot between the two modules are IPv6 support. Whenever I use both, I notice that the node process only seems to listen on the unspecified IPv4 address. Can you check if explicitly specifying the IPv4 address helps in your case?
Change:
https://github.com/AlCalzone/node-tradfri-client/blob/master/src/lib/discovery.ts#L30
or the corresponding js-file in ./build to:

const mdns = createMDNSServer({
	reuseAddr: true,
	interfaces: ["your.ipv4.address.here"],
	loopback: false,
});

@Boimb
Copy link
Author

Boimb commented Aug 21, 2018

Thanks for investigating so fast !
I’ll try it when back home. No gateway available at work ;)

@Boimb
Copy link
Author

Boimb commented Aug 21, 2018

Well, I tried, since I could try not to find a gateway but not getting the same err...
Failed 😸

 Error: bind EADDRINUSE 10.0.10.194:5353
    at Object._errnoException (util.js:1022:11)
     at _exceptionWithHostPort (util.js:1044:20)
     at _handle.lookup (dgram.js:266:18)
     at _combinedTickCallback (internal/process/next_tick.js:141:11)
     at process._tickDomainCallback (internal/process/next_tick.js:218:9)

Ofc, 10.0.10.194 is my ip.

// /build/lib/discovery.js
function discoverGateway(timeout = 10000) {
    const mdns = createMDNSServer({
        reuseAddr: true,
        interfaces: ["10.0.10.194"],
        loopback: false,
    });

[edit] Same result when back home. Will stick to 1.2.1 4now ;)[/edit]

@AlCalzone
Copy link
Owner

If you're willing to try a bit more, I have something for you.

Put the following code in a standalone js file and run it with the node CLI.

const dgram = require("dgram");
const os = require("os");

const all = os.networkInterfaces();
const addresses = Object.keys(all)
	.map(key => all[key])
	.reduce((acc, arr) => acc.concat(arr), [])
	.filter(inf => inf.family === 'IPv4' && !inf.internal)
	.map(inf => inf.address)
;

let sock1, sock2;
try {
	sock1 = dgram.createSocket({type: "udp4", reuseAddr: true});
	sock1.bind(5353, addresses[0]);
	sock1.close();
	console.log("binding with reuseAddr works");
} catch (e) {
	console.error("binding with reuseAddr didn't work");
}

try {
	sock2 = dgram.createSocket({type: "udp4", reuseAddr: false});
	sock1.bind(5353, addresses[0]);
	sock2.close();
	console.log("binding without reuseAddr works");
} catch (e) {
	console.error("binding without reuseAddr didn't work");
}

For me it prints

binding with reuseAddr works
binding without reuseAddr didn't work

@Boimb
Copy link
Author

Boimb commented Aug 23, 2018

If you're willing to try a bit more,

Ofc I want :D

I get

binding with reuseAddr works
binding without reuseAddr didn't work

@AlCalzone
Copy link
Owner

binding with reuseAddr works

Ok now I'm confused... Maybe there's a bug in mdns-server. Can you find the module in your node_modules folder and edit index.js:
Before that line https://github.com/bnielsen1965/mdns-server/blob/master/index.js#L101
add a log:

console.dir(iface);
console.dir(mDNS.config);

and try your original sandbox code?

@Boimb
Copy link
Author

Boimb commented Aug 23, 2018

Here you go:

boimb ~/sandbox $ node tradfri.js
import OK
{ name: 'en0',
  address: 'fe80::433:987d:5e93:80ab',
  family: 'IPv6',
  socketSend:
   Socket {
     domain: null,
     _events: { error: [Array], listening: [Function], message: [Function] },
     _eventsCount: 3,
     _maxListeners: undefined,
     _handle:
      UDP {
        lookup: [Function: bound lookup6],
        bind: [Function: bind6],
        send: [Function: send6],
        owner: [Circular],
        onmessage: [Function: onMessage] },
     _receiving: true,
     _bindState: 2,
     type: 'udp6',
     fd: -42,
     _reuseAddr: true,
     _queue: undefined,
     [Symbol(options symbol)]: { recvBufferSize: undefined, sendBufferSize: undefined },
     [Symbol(asyncId)]: 7 } }
{ reuseAddr: true,
  interfaces:
   [ { name: 'en0',
       address: 'fe80::433:987d:5e93:80ab',
       family: 'IPv6',
       socketSend: [Object] },
     { name: 'en0', address: '10.0.10.194', family: 'IPv4' },
     { name: 'awdl0',
       address: 'fe80::1435:9dff:fe95:3e63',
       family: 'IPv6' },
     { name: 'utun0',
       address: 'fe80::c809:9773:f06:ef42',
       family: 'IPv6' },
     { name: 'utun1',
       address: 'fe80::12a1:16de:c31f:2b32',
       family: 'IPv6' },
     { name: 'en5',
       address: 'fe80::aede:48ff:fe00:1122',
       family: 'IPv6' } ],
  ttl: 255,
  loopback: false,
  noInit: false }
events.js:183
      throw er; // Unhandled 'error' event
      ^

Error: bind EADDRINUSE fe80::433:987d:5e93:80ab%en0:5353
// [...]

@AlCalzone
Copy link
Owner

AlCalzone commented Aug 23, 2018

To get rid of the Unhandled 'error' event please update node-tradfri-client to the latest version on github and run the sandbox again. Although you'll probably only get a promise rejection instead of an unhandled error now.

However I still don't get why the error appears despite of reuseAddr: true. Can you please go back to the test code I posted earlier and replace "IPv4" with "IPv6"?
I assume you'll now get a failure with or without reuseAddr.

Once I've figured this out, I'll try to find a way where errors for single interfaces don't break the entire discovery process.

@neophob
Copy link
Contributor

neophob commented Aug 23, 2018

I stumbled over this bug aswell. problem is that in the discovery function theres a unhandled error event:

      mdns.on("error", (err) => {
        console.log('UHHH', err.message);
        reject(err);
});

@neophob
Copy link
Contributor

neophob commented Aug 23, 2018

AH! master contains the code mdns.on("error", reject); which is not part of the last release. So i think releaseing the current master should fix the problem

@AlCalzone
Copy link
Owner

So i think releaseing the current master should fix the problem

However that does not completely fix the discovery. The way it currently is, the internal "error" event just rejects the Promise. I'd rather just skip that one interface and continue with the others. I'll have to investigate if that is possible with the mdns-server module as-is or if that needs changes.

@Boimb
Copy link
Author

Boimb commented Aug 23, 2018

To get rid of the Unhandled 'error' event please update node-tradfri-client to the latest version on github

Don't know if it's the right way, but I changed may package.json like this :

"dependencies": {
    "node-tradfri-client": "git://github.com/AlCalzone/node-tradfri-client.git#master"
  },
"

Then :

npm update
npm i

Now:

boimb ~/sandbox $ node tradfri.js
{ Error: bind EADDRINUSE fe80::433:987d:5e93:80ab%en0:5353
    at Object._errnoException (util.js:1022:11)
    at _exceptionWithHostPort (util.js:1044:20)
    at _handle.lookup (dgram.js:266:18)
    at _combinedTickCallback (internal/process/next_tick.js:141:11)
    at process._tickCallback (internal/process/next_tick.js:180:9)
    at Function.Module.runMain (module.js:695:11)
    at startup (bootstrap_node.js:188:16)
    at bootstrap_node.js:609:3
  code: 'EADDRINUSE',
  errno: 'EADDRINUSE',
  syscall: 'bind',
  address: 'fe80::433:987d:5e93:80ab%en0',
  port: 5353 }

Seems the process is in "standby" as i have to kill it by Ctrl+c.

@neophob
Copy link
Contributor

neophob commented Aug 23, 2018

True, and I remember it worked fine on OSX. So I quickly tested:

  • v1.0.0: works fine
  • v1.1.2: works fine

so that looks like a regression

@AlCalzone
Copy link
Owner

so that looks like a regression

As I wrote earlier, this came from changing the library used for mDNS discovery. The old one didn't use IPv6, the new one does. The weird thing is, binding the sockets on Windows works just fine.

"node-tradfri-client": "git://github.com/AlCalzone/node-tradfri-client.git#master"

That should work. Can you please run the script from #101 (comment) (with "IPv4" changed to "IPv6") using this version?

@neophob
Copy link
Contributor

neophob commented Aug 23, 2018

Sure, here's the output (IPv4)

binding with reuseAddr works
binding without reuseAddr didn't work

debug (IPv4):

> const dgram = require("dgram");
undefined
> const os = require("os");
undefined
>
> const all = os.networkInterfaces();
undefined
> const addresses = Object.keys(all)
undefined
> 	.map(key => all[key])
Invalid REPL keyword
> 	.reduce((acc, arr) => acc.concat(arr), [])
Invalid REPL keyword
> 	.filter(inf => inf.family === 'IPv4' && !inf.internal)
Invalid REPL keyword
> 	.map(inf => inf.address)
Invalid REPL keyword
> ;
undefined
>
> let sock1, sock2;
undefined
> try {
... 	sock1 = dgram.createSocket({type: "udp4", reuseAddr: true});
... 	sock1.bind(5353, addresses[0]);
... 	sock1.close();
... 	console.log("binding with reuseAddr works");
... } catch (e) {
... 	console.error("binding with reuseAddr didn't work");
... }
binding with reuseAddr works
undefined
>
> try {
... 	sock2 = dgram.createSocket({type: "udp4", reuseAddr: false});
... 	sock1.bind(5353, addresses[0]);
... 	sock2.close();
... 	console.log("binding without reuseAddr works");
... } catch (e) {
... 	console.error("binding without reuseAddr didn't work");
... }
binding without reuseAddr didn't work
undefined
> Error: getaddrinfo ENOTFOUND lo0
    at errnoException (dns.js:50:10)
    at GetAddrInfoReqWrap.onlookup [as oncomplete] (dns.js:92:26)

debug (IPv6):

> const dgram = require("dgram");
undefined
> const os = require("os");
undefined
>
> const all = os.networkInterfaces();
undefined
> const addresses = Object.keys(all)
undefined
> 	.map(key => all[key])
Invalid REPL keyword
> 	.reduce((acc, arr) => acc.concat(arr), [])
Invalid REPL keyword
> 	.filter(inf => inf.family === 'IPv6' && !inf.internal)
Invalid REPL keyword
> 	.map(inf => inf.address)
Invalid REPL keyword
> ;
undefined
>
> let sock1, sock2;
undefined
> try {
... 	sock1 = dgram.createSocket({type: "udp6", reuseAddr: true});
... 	sock1.bind(5353, addresses[0]);
... 	sock1.close();
... 	console.log("binding with reuseAddr works");
... } catch (e) {
... 	console.error("binding with reuseAddr didn't work");
... }
binding with reuseAddr works
undefined
>
> try {
... 	sock2 = dgram.createSocket({type: "udp6", reuseAddr: false});
... 	sock1.bind(5353, addresses[0]);
... 	sock2.close();
... 	console.log("binding without reuseAddr works");
... } catch (e) {
... 	console.error("binding without reuseAddr didn't work");
... }
binding without reuseAddr didn't work
undefined
> Error: getaddrinfo ENOTFOUND lo0
    at errnoException (dns.js:50:10)
    at GetAddrInfoReqWrap.onlookup [as oncomplete] (dns.js:92:26)

@Boimb
Copy link
Author

Boimb commented Aug 23, 2018

@AlCalzone

That should work. Can you please run the script from #101 (comment) (with "IPv4" changed to "IPv6") using this version?

// ./test.js
// [...]
const addresses = Object.keys(all)
	.map(key => all[key])
	.reduce((acc, arr) => acc.concat(arr), [])
	.filter(inf => inf.family === 'IPv6' && !inf.internal)
	.map(inf => inf.address)
;
// [...]
boimb ~/sandbox $ node test.js
binding with reuseAddr works
binding without reuseAddr didn't work

I don't see any change.

@AlCalzone
Copy link
Owner

(╯°□°)╯︵ ┻━┻

Ok next try, put this in a sandbox file and run it please (update the IP addresses if they changed):

const dgram = require("dgram");
const ipv6Addr = "fe80::433:987d:5e93:80ab";
const ipv6Suffix = "en0";
const ipv4Addr = "10.0.10.194";

const combinations = [
	{ type: "udp4", addr: ipv4Addr, reuseAddr: true },
	{ type: "udp6", addr: ipv6Addr, reuseAddr: true },
	{ type: "udp6", addr: `${ipv6Addr}%${ipv6Suffix}`, reuseAddr: true },
	{ type: "udp4", addr: ipv4Addr, reuseAddr: false },
	{ type: "udp6", addr: ipv6Addr, reuseAddr: false },
	{ type: "udp6", addr: `${ipv6Addr}%${ipv6Suffix}`, reuseAddr: false },
];

function doit(i) {
	return new Promise((resolve) => {
		const { type, addr, reuseAddr } = combinations[i];
		let success = false;
		const sock = dgram.createSocket({ type, reuseAddr });
		sock.on("error", (e) => {
			success = false;
			console.error(e);
		});
		try {
			sock.bind(5353, addr);
			success = true;
		} catch (e) { console.error(e) }
		setTimeout(() => {
			sock.close();
			console.log(`binding to ${addr} with reuseAddr=${reuseAddr} ${success ? "works" : "didn't work"}`);
			resolve();
		}, 100);
	});
}

doit(0)
	.then(() => doit(1))
	.then(() => doit(2))
	.then(() => doit(3))
	.then(() => doit(4))
	.then(() => doit(5))
;

For me, everything with reuseAddr works, and the rest doesn't.

@Boimb
Copy link
Author

Boimb commented Aug 23, 2018

Arf...
All failed :/

boimb ~/sandbox $ node tradfri-debug.js
{ Error: bind EADDRINUSE 192.168.1.17:5353
    at Object._errnoException (util.js:1022:11)
    at _exceptionWithHostPort (util.js:1044:20)
    at _handle.lookup (dgram.js:266:18)
    at _combinedTickCallback (internal/process/next_tick.js:141:11)
    at process._tickCallback (internal/process/next_tick.js:180:9)
    at Function.Module.runMain (module.js:695:11)
    at startup (bootstrap_node.js:188:16)
    at bootstrap_node.js:609:3
  code: 'EADDRINUSE',
  errno: 'EADDRINUSE',
  syscall: 'bind',
  address: '192.168.1.17',
  port: 5353 }
binding to 192.168.1.17 with reuseAddr=true didn't work
{ Error: bind EADDRNOTAVAIL fe80::433:987d:5e93:80ab:5353
    at Object._errnoException (util.js:1022:11)
    at _exceptionWithHostPort (util.js:1044:20)
    at _handle.lookup (dgram.js:266:18)
    at _combinedTickCallback (internal/process/next_tick.js:141:11)
    at process._tickCallback (internal/process/next_tick.js:180:9)
  code: 'EADDRNOTAVAIL',
  errno: 'EADDRNOTAVAIL',
  syscall: 'bind',
  address: 'fe80::433:987d:5e93:80ab',
  port: 5353 }
binding to fe80::433:987d:5e93:80ab with reuseAddr=true didn't work
{ Error: bind EADDRINUSE fe80::433:987d:5e93:80ab%en0:5353
    at Object._errnoException (util.js:1022:11)
    at _exceptionWithHostPort (util.js:1044:20)
    at _handle.lookup (dgram.js:266:18)
    at _combinedTickCallback (internal/process/next_tick.js:141:11)
    at process._tickCallback (internal/process/next_tick.js:180:9)
  code: 'EADDRINUSE',
  errno: 'EADDRINUSE',
  syscall: 'bind',
  address: 'fe80::433:987d:5e93:80ab%en0',
  port: 5353 }
binding to fe80::433:987d:5e93:80ab%en0 with reuseAddr=true didn't work
{ Error: bind EADDRINUSE 192.168.1.17:5353
    at Object._errnoException (util.js:1022:11)
    at _exceptionWithHostPort (util.js:1044:20)
    at _handle.lookup (dgram.js:266:18)
    at _combinedTickCallback (internal/process/next_tick.js:141:11)
    at process._tickCallback (internal/process/next_tick.js:180:9)
  code: 'EADDRINUSE',
  errno: 'EADDRINUSE',
  syscall: 'bind',
  address: '192.168.1.17',
  port: 5353 }
binding to 192.168.1.17 with reuseAddr=false didn't work
{ Error: bind EADDRNOTAVAIL fe80::433:987d:5e93:80ab:5353
    at Object._errnoException (util.js:1022:11)
    at _exceptionWithHostPort (util.js:1044:20)
    at _handle.lookup (dgram.js:266:18)
    at _combinedTickCallback (internal/process/next_tick.js:141:11)
    at process._tickCallback (internal/process/next_tick.js:180:9)
  code: 'EADDRNOTAVAIL',
  errno: 'EADDRNOTAVAIL',
  syscall: 'bind',
  address: 'fe80::433:987d:5e93:80ab',
  port: 5353 }
binding to fe80::433:987d:5e93:80ab with reuseAddr=false didn't work
{ Error: bind EADDRINUSE fe80::433:987d:5e93:80ab%en0:5353
    at Object._errnoException (util.js:1022:11)
    at _exceptionWithHostPort (util.js:1044:20)
    at _handle.lookup (dgram.js:266:18)
    at _combinedTickCallback (internal/process/next_tick.js:141:11)
    at process._tickCallback (internal/process/next_tick.js:180:9)
  code: 'EADDRINUSE',
  errno: 'EADDRINUSE',
  syscall: 'bind',
  address: 'fe80::433:987d:5e93:80ab%en0',
  port: 5353 }
binding to fe80::433:987d:5e93:80ab%en0 with reuseAddr=false didn't work

@AlCalzone
Copy link
Owner

AlCalzone commented Aug 24, 2018

Ok now I'm genuinely confused... What about

const ipv4Addr = "0.0.0.0";
const ipv6Addr = "::";

?
The previously used multicast-dns module seems to bind to the IPv4 socket to all interfaces (0.0.0.0) instead of a specific one like mdns-server does.

@AlCalzone
Copy link
Owner

AlCalzone commented Aug 24, 2018

Ok I have two more tests for you. You need to install multicast-dns to run them:

IPv4

var mdns = require('multicast-dns')(/*opts*/);

mdns.on('response', function (response) {
	console.log('got a response packet:', response)
})

mdns.on('query', function (query) {
	console.log('got a query packet:', query)
})

const domain = "_coap._udp.local";

mdns.on("ready", () => {
	mdns.query([
		{ name: domain, type: "A" },
	]);
});

IPv6

var opts = {
	interface: '::%en0',
	type: 'udp6',
	ip: 'ff02::1:3'
}
var mdns = require('multicast-dns')(opts);

mdns.on('response', function (response) {
	console.log('got a response packet:', response)
})

mdns.on('query', function (query) {
	console.log('got a query packet:', query)
})

const domain = "_coap._udp.local";

mdns.on("ready", () => {
	mdns.query([
		{ name: domain, type: "A" },
	]);
});

If it works, you get a response packet written to the console (got a response packet: { id: 0, ...). On your network with the gateway it should probably include something related to that gateway.

@Boimb
Copy link
Author

Boimb commented Aug 24, 2018

Really appreciate your tenacity :D
Here you are :

boimb ~/sandbox $ node multi-cast-dns.js
IPV4 VERSION
got a query packet: { id: 0,
  type: 'query',
  flags: 0,
  flag_qr: false,
  opcode: 'QUERY',
  flag_aa: false,
  flag_tc: false,
  flag_rd: false,
  flag_ra: false,
  flag_z: false,
  flag_ad: false,
  flag_cd: false,
  rcode: 'NOERROR',
  questions: [ { name: '_coap._udp.local', type: 'A', class: 'IN' } ],
  answers: [],
  authorities: [],
  additionals: [] }
^C
boimb ~/sandbox $ node multi-cast-dns.js
IPV6 VERSION
got a query packet: { id: 0,
  type: 'query',
  flags: 0,
  flag_qr: false,
  opcode: 'QUERY',
  flag_aa: false,
  flag_tc: false,
  flag_rd: false,
  flag_ra: false,
  flag_z: false,
  flag_ad: false,
  flag_cd: false,
  rcode: 'NOERROR',
  questions: [ { name: '_coap._udp.local', type: 'A', class: 'IN' } ],
  answers: [],
  authorities: [],
  additionals: [] }

Seems really better 👍

@AlCalzone
Copy link
Owner

No response packet, but - hey - no error either. I'll create a branch where I use that package for discovery and let you know when there's something to test.

@neophob
Copy link
Contributor

neophob commented Aug 24, 2018

the ipv4 example seems to work:

got a query packet: { id: 0,
  type: 'query',
  flags: 0,
  flag_qr: false,
  opcode: 'QUERY',
  flag_auth: false,
  flag_trunc: false,
  flag_rd: false,
  flag_ra: false,
  flag_z: false,
  flag_ad: false,
  flag_cd: false,
  rcode: 'NOERROR',
  questions: [ { name: '_coap._udp.local', type: 'A', class: 1 } ],
  answers: [],
  authorities: [],
  additionals: [] }

the ipv6 example did not output anything. some input:

  • the ipv6 widcard ip address is :: (aka 0.0.0.0 in ipv4)
  • ff02::1:3 is "All LLMNR hosts on the local network segment (defined in RFC 4795)"

running osx (Darwin Kernel Version 17.5.0)

@AlCalzone
Copy link
Owner

the ipv6 example did not output anything

Whats the name of your network interface? If its not en0 (as it is appended to the wildcard address), the above code won't work for you.

@neophob
Copy link
Contributor

neophob commented Aug 24, 2018

its en0 as well (wifi nic on osx), but i also try to remove that suffix without any change

@neophob
Copy link
Contributor

neophob commented Sep 3, 2018

Tried current #master branch

"error":"bind EADDRINUSE fe80::14cc:dffe:9a22:1769%en0:5353","stack":"Error: bind EADDRINUSE fe80::14cc:dffe:9a22:1769%en0:5353\n    at Object._errnoException (util.js:992:11)\n    at _exceptionWithHostPort (util.js:1014:20)\n    at _handle.lookup (dgram.js:266:18)\n    at _combinedTickCallback (internal/process/next_tick.js:141:11)\n    at process._tickCallback (internal/process/next_tick.js:180:9)"}

I checked that the reuse flag is already set. I added some debug output in the mdns-server:

here is a log output what happens on my osx machine when i start the tradfri discovery:

en0 createSendSocket fe80::14cc:dffe:9a22:1769 true
en0 createReceiveSocket fe80::14cc:dffe:9a22:1769 true
en0 error bind EADDRINUSE fe80::14cc:dffe:9a22:1769%en0:5353
en0 createSendSocket 192.168.86.217 true
en0 createReceiveSocket 192.168.86.217 true
en0 error bind EADDRINUSE 192.168.86.217:5353
awdl0 createSendSocket fe80::7c70:9dff:fe1b:b1b1 true
awdl0 createReceiveSocket fe80::7c70:9dff:fe1b:b1b1 true
awdl0 error bind EADDRINUSE fe80::7c70:9dff:fe1b:b1b1%awdl0:5353
utun0 createSendSocket fe80::64a5:290b:def:2720 true
utun0 createReceiveSocket fe80::64a5:290b:def:2720 true
utun0 error bind EADDRINUSE fe80::64a5:290b:def:2720%utun0:5353
utun1 createSendSocket fe80::37e7:f9e3:c78f:1342 true
utun1 createReceiveSocket fe80::37e7:f9e3:c78f:1342 true
utun1 error bind EADDRINUSE fe80::37e7:f9e3:c78f:1342%utun1:5353
utun2 createSendSocket fe80::ba7f:fea5:3a19:7bf6 true
utun2 createReceiveSocket fe80::ba7f:fea5:3a19:7bf6 true
utun2 error bind EADDRINUSE fe80::ba7f:fea5:3a19:7bf6%utun2:5353
utun3 createSendSocket fe80::44bd:17de:8fde:5968 true
utun3 createReceiveSocket fe80::44bd:17de:8fde:5968 true
utun3 error bind EADDRINUSE fe80::44bd:17de:8fde:5968%utun3:5353
utun4 createSendSocket fe80::7355:cdb:772b:b72f true
utun4 createReceiveSocket fe80::7355:cdb:772b:b72f true
utun4 error bind EADDRINUSE fe80::7355:cdb:772b:b72f%utun4:5353
utun5 createSendSocket fe80::2350:802c:cd50:80b0 true
utun5 createReceiveSocket fe80::2350:802c:cd50:80b0 true
utun5 error bind EADDRINUSE fe80::2350:802c:cd50:80b0%utun5:5353

fyi, here's the modified part of the mdns-server:

    createReceiveSocket: function (iface) {
      return new Promise((resolve, reject) => {
        console.log(iface.name,'createReceiveSocket', iface.addressm, mDNS.config.reuseAddr);
        iface.socketRecv = dgram.createSocket({
          type: (iface.family === 'IPv4' ? 'udp4' : 'udp6'),
          reuseAddr: mDNS.config.reuseAddr
        })
        .once('error', (err) => {
          console.log(iface.name,'error', err.message);
          emitter.emit('error', err);
          reject();
        })

The same also for createSendSocket. So it looks like creating the send socket works, but then mdns-server fails to create the receiving socket - at leas on osx

@neophob
Copy link
Contributor

neophob commented Sep 3, 2018

I took a look how bonjour dies this, https://github.com/mafintosh/multicast-dns/blob/master/index.js

      if (iface.family === 'IPv4') {
        res.push(iface.address)
        // could only addMembership once per interface (https://nodejs.org/api/dgram.html#dgram_socket_addmembership_multicastaddress_multicastinterface)
        break
      }

Side question: any particular reasons why use mdns-server over bonjour?

@AlCalzone
Copy link
Owner

any particular reasons why use mdns-server over bonjour?

Selfishness, bonjour does not work on my own network ;)
It sends the request using IPv4, but the gateway replies on IPv6 which bonjour (or rather the underlying multicast-dns instance) does not listen on. I'm working on a version that also uses multicast-dns like bonjour does, but with one instance for IPv4 and one per IPv6 interface.

@AlCalzone
Copy link
Owner

Some more info for you guys as you are waiting:
#103 is going (hopefully) solve this issue. I just need to find the time to finish it. I'm going to make the sockets listen on the catch-all addresses 0.0.0.0 (once) and :: (for every interface) and just collect the responses. mdns-server is going to be replaced with multicast-dns.
OSX seems to have a problem binding the socket to specific IP addresses (which mdns-server does) in contrast to the catch-all addresses (which multicast-dns does).

@Boimb
Copy link
Author

Boimb commented Sep 3, 2018

Personally, I’m really happy with 1.2. For sure it’d be great to be able to get latest, but it’s not blocking me for now. “Take your time” ;)
I’ll let you know on #103 when it’ll be ready.

@AlCalzone
Copy link
Owner

Coincidentally, I did have some spare time. Most of the work was already done, I just had to extend it to multiple interfaces. If you like, you can test the version from #103

@neophob
Copy link
Contributor

neophob commented Sep 4, 2018

btw Selfishness is always a VERY good reason ;)

@Boimb
Copy link
Author

Boimb commented Sep 4, 2018

You really rock dude!
Everything ok for me.
DiscoverGateway returns null when not gateway.
Returns gateway when found.
👍 🙌
[EDIT] I let you close this issue when #103 'd be merged. [/EDIT]

@AlCalzone
Copy link
Owner

Glad it works for you. Now it doesn't work for me :D

@AlCalzone
Copy link
Owner

Okay, short update. I seem to be able to detect the gateway now that I'm back mdns-server - but this time with a fix for the receive socket binding.
I provided that version in #104 - can you try it out please?

@Boimb
Copy link
Author

Boimb commented Sep 5, 2018

This works for me too 👍
Seems you achieve it!

@AlCalzone
Copy link
Owner

This will be released in v1.3.3 shortly. Thanks for the help!

@AlCalzone
Copy link
Owner

The original creator of mdns-server has some worries about my change - we'll work on a slightly different fix. Since none of us have access to OSX, would you guys be willing to do a test or two for that?
bnielsen1965/mdns-server#2

@Boimb @neophob

@neophob
Copy link
Contributor

neophob commented Sep 6, 2018

currently not much time from my side, would a os. network interface dump help?

@AlCalzone
Copy link
Owner

We just need someone to test if things still work with the alternative changes. If you don't have time, no problem.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants