Skip to content
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

unable to bind udp6 socket to a specific address #4274

Closed
nickdesaulniers opened this issue Dec 14, 2015 · 10 comments
Closed

unable to bind udp6 socket to a specific address #4274

nickdesaulniers opened this issue Dec 14, 2015 · 10 comments
Labels
dgram Issues and PRs related to the dgram subsystem / UDP. invalid Issues and PRs that are invalid.

Comments

@nickdesaulniers
Copy link

var udp6 = dgram.createSocket('udp6');
udp6.bind(null, 'fe80::e46a:6cff:fe68:a76a');

throws Error: bind EADDRNOTAVAIL fe80::e46a:6cff:fe68:a76a but works for ipv4 addresses listed from os.networkInterfaces().

https://stackoverflow.com/questions/34259279/node-js-cant-bind-a-udp6-socket-to-a-specific-address

@mscdex mscdex added the dgram Issues and PRs related to the dgram subsystem / UDP. label Dec 14, 2015
@mscdex
Copy link
Contributor

mscdex commented Dec 14, 2015

What does strace show when you run that snippet?

@nickdesaulniers
Copy link
Author

I'm on OSX. strace is not available.

@nickdesaulniers
Copy link
Author

let me see if I can attach dtruss to the node process

@nickdesaulniers
Copy link
Author

Running 'sudo dtruss -p pgrep -n node', this is the trace specifically on the execution of udp6.bind(null, 'fe80::2acf:e9ff:fe1f:3939'):

select(0x14, 0x102201F08, 0x102201F0C, 0x0, 0x0)         = 1 0
write(0x9, "\0", 0x1)        = 1 0
kevent(0x5, 0x7FFF5FBF71C0, 0x0)         = 1 0
read(0x8, "\0", 0x400)       = 1 0
read(0x11, "\r\0", 0x10000)      = 1 0
write(0xA, "\r\n\0", 0x2)        = 2 0
write(0xC, "x\0", 0x1)       = 1 0
select(0xE, 0x1022014D8, 0x1022014DC, 0x0, 0x0)      = 1 0
read(0xD, "x\a\0", 0x400)        = 1 0
madvise(0x1015D9000, 0x21000, 0x9)       = 0 0
write(0xA, "Socket {\n  domain: \n   Domain {\n     domain: \033[1mnull\033[22m,\n     _events: { error: \033[36m[Function]\033[39m },\n     _eventsCount: \033[33m1\033[39m,\n     _maxListeners: \033[90mundefined\033[39m,\n     members: [] },\n  _events: {},\n  _eventsCount: \033[33m0\033[39m,\n  _maxListen", 0x273)        = 627 0
write(0xC, "x\0", 0x1)       = 1 0
select(0xE, 0x1022014D8, 0x1022014DC, 0x0, 0x0)      = 1 0
read(0xD, "x\a\0", 0x400)        = 1 0
write(0xA, "\033[1G\0", 0x4)         = 4 0
write(0xC, "x\0", 0x1)       = 1 0
write(0xA, "\033[0J\0", 0x4)         = 4 0
write(0xC, "x\0", 0x1)       = 1 0
select(0xE, 0x1022014D8, 0x1022014DC, 0x0, 0x0)      = 1 0
write(0xA, "> \0", 0x2)      = 2 0
read(0xD, "xx\0", 0x400)         = 2 0
write(0xC, "x\0", 0x1)       = 1 0
select(0xE, 0x1022014D8, 0x1022014DC, 0x0, 0x0)      = 1 0
read(0xD, "x\a\0", 0x400)        = 1 0
write(0xA, "\033[3G\0", 0x4)         = 4 0
write(0xC, "x\0", 0x1)       = 1 0
select(0xE, 0x1022014D8, 0x1022014DC, 0x0, 0x0)      = 1 0
read(0xD, "x\a\0", 0x400)        = 1 0
madvise(0x101783000, 0x41000, 0x9)       = 0 0
madvise(0x1015D9000, 0x21000, 0x9)       = 0 0
madvise(0x101783000, 0x41000, 0x9)       = 0 0
madvise(0x1015D9000, 0x21000, 0x9)       = 0 0
madvise(0x102300000, 0x83000, 0x9)       = 0 0
madvise(0x101783000, 0x41000, 0x9)       = 0 0
madvise(0x1015D9000, 0x21000, 0x9)       = 0 0
socket(0x1E, 0x2, 0x0)       = 21 0
ioctl(0x15, 0x8004667E, 0x7FFF5FBF5EE4)      = 0 0
ioctl(0x15, 0x20006601, 0x0)         = 0 0
setsockopt(0x15, 0xFFFF, 0x1022)         = 0 0
bind(0x15, 0x7FFF5FBF5F90, 0x1C)         = -1 Err#49
close(0x15)      = 0 0
write(0xA, "Error: bind EADDRNOTAVAIL fe80::2acf:e9ff:fe1f:3939\n    at Object.exports._errnoException (util.js:874:11)\n    at exports._exceptionWithHostPort (util.js:897:20)\n    at dgram.js:213:18\n    at doNTCallback3 (node.js:452:9)\n    at process._tickDomainCallback", 0x112)       = 274 0
write(0xC, "x\0", 0x1)       = 1 0
select(0xE, 0x1022014D8, 0x1022014DC, 0x0, 0x0)      = 1 0
read(0xD, "x\0", 0x400)      = 1 0
write(0xA, "\033[1G\0", 0x4)         = 4 0
write(0xC, "x\0", 0x1)       = 1 0
select(0xE, 0x1022014D8, 0x1022014DC, 0x0, 0x0)      = 1 0
read(0xD, "x\0", 0x400)      = 1 0
write(0xA, "\033[0J\0", 0x4)         = 4 0
write(0xC, "x\0", 0x1)       = 1 0
select(0xE, 0x1022014D8, 0x1022014DC, 0x0, 0x0)      = 1 0
read(0xD, "x\0", 0x400)      = 1 0
write(0xA, "> \0", 0x2)      = 2 0
write(0xC, "x\0", 0x1)       = 1 0
select(0xE, 0x1022014D8, 0x1022014DC, 0x0, 0x0)      = 1 0
read(0xD, "x\a\0", 0x400)        = 1 0
write(0xA, "\033[3G\0", 0x4)         = 4 0
write(0xC, "x\0", 0x1)       = 1 0
select(0xE, 0x1022014D8, 0x1022014DC, 0x0, 0x0)      = 1 0
read(0xD, "x\a\0", 0x400)        = 1 0
write(0xC, "x\0", 0x1)       = 1 0
select(0xE, 0x1022014D8, 0x1022014DC, 0x0, 0x0)      = 1 0
kevent(0x5, 0x7FFF5FBF71C0, 0x0)         = 0 0
read(0xD, "x\0", 0x400)      = 1 0
kevent(0x5, 0x7FFF5FBF71C0, 0x0)         = 0 0
mmap(0x2D80B15C4000, 0x200000, 0x0, 0x1042, 0xFF000000, 0x0)         = 0x2D80B15C4000 0
munmap(0x2D80B15C4000, 0x3C000)      = 0 0
munmap(0x2D80B1700000, 0xC4000)      = 0 0
mmap(0x2D80B1600000, 0x100000, 0x3, 0x1012, 0xFF000000, 0x0)         = 0x2D80B1600000 0
mmap(0x154FD3E00000, 0x200000, 0x0, 0x1052, 0xFF000000, 0x0)         = 0x154FD3E00000 0
psynch_cvsignal(0x100E19D00, 0xD0000001100, 0xD00)       = 256 0
psynch_cvwait(0x100E19D00, 0xA0000000E00, 0xA00)         = 0 0
kevent(0x5, 0x7FFF5FBF71C0, 0x0)         = 0 0
pwrite(0x14, "udp6.bind(null, 'fe80::2acf:e9ff:fe1f:3939')\nos.networkInterfaces()\nos = require('os')\nudp6 = dgram.createSocket('udp6')\nudp6.bind(null, 'fe80::2acf:e9ff:fe1f:3939')\ndgram = require('dgram')\nudp6.bind(null, 'fe80::2acf:e9ff:fe1f:3939')\nudp6 = dgram.createS", 0x1145, 0x0)         = 4421 0
write(0x9, "\0", 0x1)        = 1 0
kevent(0x5, 0x7FFF5FBF71C0, 0x0)         = 1 0
read(0x8, "\0", 0x400)       = 1 0

@nickdesaulniers
Copy link
Author

I just tried this on my linux box. Rather than EADDRNOTAVAIL, I got an EINVAL.

man 2 bind says EINVAL means "EINVAL The socket is already bound to an address." What?! udp6._bindState is 0. How could it possibly be already bound?

ipv4 works on my linux box, but ipv6 does not.

@nickdesaulniers
Copy link
Author

oh, so I just tried binding to a non fe80 ipv6 address, and it seemed to work...
ex '2620:101:80fc:224:2acf:e9ff:fe1f:3939'

@nickdesaulniers
Copy link
Author

also, it seems to work if I bind to 'fe80::2acf:e9ff:fe1f:3939%en0' which is the string from ifconfig.

@nickdesaulniers
Copy link
Author

it looks like for network peers to contact me on the fe80 address, they need to specify THEIR interface to contact me on, ex: nc6 -u fe80::2acf:e9ff:fe1f:3939%wlp3s0 65022

@nickdesaulniers
Copy link
Author

ok, my linux buddies just gave me a refresher on link local addresses: https://en.wikipedia.org/wiki/Link-local_address

It seems that the sender will have to specify their networking interface and the receiver also has to specify their listening interface. There may not be any bugs here. Let me think about this over lunch, and when I get back, I'll probably end up closing this bug.

@nickdesaulniers
Copy link
Author

I would mark this bug as invalid.

@mscdex mscdex added the invalid Issues and PRs that are invalid. label Dec 14, 2015
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
dgram Issues and PRs related to the dgram subsystem / UDP. invalid Issues and PRs that are invalid.
Projects
None yet
Development

No branches or pull requests

2 participants