Repository navigation
DNS lookup should try to avoid IPv6 link-local addresses #51732
Copy link
Copy link
Closed
Labels
dnsIssues and PRs related to the dns subsystem.Issues and PRs related to the dns subsystem.feature requestIssues requesting new Node.js features.Issues requesting new Node.js features.
Description
What is the problem this feature will solve?
Naive calls to createServer happily resolve host names to link-local addresses, which then fail to listen:
$ node -e "net.createServer(c=>console.log).listen(5555,'zen')"
node:events:492
throw er; // Unhandled 'error' event
^
Error: listen EINVAL: invalid argument fe80::2d8:xxxx:xxxx:xxxx:5555
at Server.setupListenHandle [as _listen2] (node:net:1855:21)
at listenInCluster (node:net:1920:12)
at GetAddrInfoReqWrap.doListen [as callback] (node:net:2069:7)
at GetAddrInfoReqWrap.onlookup [as oncomplete] (node:dns:109:8)
Emitted 'error' event on Server instance at:
at emitErrorNT (node:net:1899:8)
at process.processTicksAndRejections (node:internal/process/task_queues:82:21) {
code: 'EINVAL',
errno: -22,
syscall: 'listen',
address: 'fe80::2d8:xxxx:xxxx:xxxx',
port: 5555
}
Node.js v20.10.0
What is the feature you are proposing to solve the problem?
DNS lookup randomly picks the first available entry
> dns.lookup('zen', { verbatim: true }, console.info)
GetAddrInfoReqWrap {
callback: [Function: info],
family: 0,
hostname: 'zen',
oncomplete: [Function: onlookup]
}
> null fe80::2d8:xxxx:xxxx:xxxx 6
if there are multiple addresses returned by getaddrinfo
> dns.lookup('zen', { verbatim: true, all: true }, console.info)
GetAddrInfoReqWrap {
callback: [Function: info],
family: 0,
hostname: 'zen',
oncomplete: [Function: onlookupall]
}
> null [
{ address: 'fe80::2d8:xxxx:xxxx:xxxx', family: 6 },
{ address: '2a02:8109:xxxx:xxxx:2d8:xxxx:xxxx:xxxx', family: 6 },
{ address: '192.168.178.3', family: 4 },
{ address: '192.168.122.1', family: 4 }
Instead, it should pick the first non-link-local address. It is extremely unlikely that you want to listen to a link-local address (starting with fe80::). And in the unlikely case that you do, you certainly would call with options.all to get all resolutions.
What alternatives have you considered?
We could alter all client code to always add options.all and filter, but it seems like node is the correct way to fix this once and for all.
Related issues
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
dnsIssues and PRs related to the dns subsystem.Issues and PRs related to the dns subsystem.feature requestIssues requesting new Node.js features.Issues requesting new Node.js features.
Activity
[-]DNS lookup should try to avoid link-local addresses[/-][+]DNS lookup should try to avoid IPv6 link-local addresses[/+]ryker-uptycs commentedon Feb 13, 2024
I wish to take this up
marco-ippolito commentedon Feb 19, 2024
I guess it can be fixed with something like this:
wathika-eng commentedon Apr 11, 2024
Guess this is my error
puskin commentedon Aug 6, 2024
I am willing to work on this, but I am a little confused about one aspect:
should I remove ALL the local IPV6 links from
addressesinonlookupallor just the first one, if present?vbraun commentedon Aug 6, 2024
You often have more than one ipv6 address, this is pretty normal. So all link-local ones should be skipped, not just the first one.
puskin commentedon Aug 6, 2024
that's what I thought as well, but I got confused by the examples 😄
Thanks!
working on it then
puskin commentedon Aug 6, 2024
I am struggling with automated tests:
the function is working fine, but I noticed that the DNS resolution is actually real and not mocked anywhere (at least I could not find it anywhere in this huge codebase).
Due to this, I would have to create an entry in the runner's
/etc/hostswith a little something like this:and, of course, this is not doeable or even a good idea :)
the test looks something like this:
the best solution would be to mock the call to
const req = new GetAddrInfoReqWrap();but not seeing something similar anywhere else I am wondering if there isn't a better solution?Thanks in advance!
net: exclude ipv6 loopback addresses from server.listen
net: exclude ipv6 loopback addresses from server.listen
net: exclude ipv6 loopback addresses from server.listen