-
Notifications
You must be signed in to change notification settings - Fork 30.2k
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
dns: exclude loopback link from the single lookup resolution #54249
Conversation
…ult is a loopback link Fixes: nodejs#51732
Review requested:
|
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #54249 +/- ##
==========================================
- Coverage 87.10% 87.10% -0.01%
==========================================
Files 647 647
Lines 181739 181758 +19
Branches 34887 34889 +2
==========================================
+ Hits 158310 158318 +8
- Misses 16738 16741 +3
- Partials 6691 6699 +8
|
How is the new API different from |
if the result of the single lookup is a loopback address: before: const response = await dnsPromises.lookup('ipv6_loopback', { verbatim: true });
console.log(response); // { address: 'fe80::1', family: 6 }
util.promisify(dns.lookup)('ipv6_loopback').then(response => {
console.log(response); // { address: 'fe80::1', family: 6 }
}); after: const response = await dnsPromises.lookup('ipv6_loopback', { verbatim: true });
console.log(response); // { }
util.promisify(dns.lookup)('ipv6_loopback').then(response => {
console.log(response); // { }
}); to be honest, considering we are completely filtering out any loopback address in this case, and the result being empty, I would be more in favor of returning a |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the explanation and for working on this @puskin94. I don't think this is the correct behaviour quite yet though. This technically solves #51732, but it will cause lots of other issues, as it seems to make it impossible to look up DNS names for link-local addresses.
There's two specific things I think we should still support:
- If there is a hostname that resolves to a single link-local IPv6 IP then it should still be possible to resolve that.
- If there is a hostname that resolves to multiple IPs including some link-local results, it should definitely still be possible to get the full list when passing
all: true
, including those results.
This PR currently breaks both of those I think. A hostname resolving to these IPs is unusual, but AFAICT it's not invalid in any sense from a DNS perspective, so we shouldn't pretend it doesn't exist. We shouldn't return ENOTFOUND either - it should be possible to still look up these addresses for other use cases.
To resolve #51732, we just need to ensure that that when you call server.listen(port, hostname)
the server prefers non-link-local addresses for the hostname somehow, if there is one available. Blocking all those addresses from lookups technically works, but there are better approaches. I can see two plausible options:
- If you call
dns.lookup
(withoutall: true
, to get just one value) and there are multiple values, maybe the selection logic should change to prefer non-link-local IPs. - Alternatively, maybe we shouldn't change DNS at all, and instead this should just be a change within
net.listen
to look up all addresses for the given hostname and prefer non-link-local IPs when there is one available (probably best to still try to use the link-local IP if it's the only IP returned, I think? Just because it makes the error message in the failure case a little clearer).
That first option is very likely a breaking change (although it's a bit unclear how consistent the current DNS result selection is anyway) and the latter is probably not (since it sounds like this currently always fails anyway?) but both will need some thought to check there's no other consequences. Changing the server listen logic is the cleaner/preferable choice I think, assuming there's no issues with that, unless we have a good reason to be sure that this preference would be useful in DNS lookup selection in most other contexts.
Does that make sense?
Hi @pimterry ! Thanks for the super detailed explaination 😃
All this said, I agree with both your domain analysis and implementation specs 😄 Thanks again 😃 |
Yes, it's not totally clear, it does need some thought & testing. If That's just if listening on link-local addresses does indeed always fail. I haven't intentionally ever used them in practice myself though, so that needs confirmation. If there are practical cases in Node where it does work today, then we can still make the change if it's clearly what most people would expect (for a hostname with a public + link-local IP, I think that's true) but in that case it's definitely a breaking change.
True - I just don't think that DNS returning that address is necessarily wrong. In some use cases it's weird and won't work, but it's not entirely invalid, and the world of computers contains plenty of weird software that might want to actually use these addresses 😄. The server.listen case however seems to be the underlying motivation, and that case does seem relatively clear cut - if you specify a hostname to listen on, and it has both a public and a link-local address, then I think you do almost certainly want to listen on the public address (@vbraun feel free to chime in with more context if you have thoughts on this). |
@pimterry amazing! thanks for being so thorough with your answers :) The PR is almost ready, the code is working and new (and old) automated tests are passing, just refining a couple of things and then I will sumbmit it. I will close this one in favor of the other one because the scope (and how it is achieved) is completely different. Btw, about your
It looks like it is the case, and this new test confirms it: |
closing in favor of #54264 |
dns: the lookup of a single address should not be returned if the result is a loopback link
Fixes: #51732
As described in the original issue, I am having problems writing working automated tests:
if
/etc/hosts
is modified to have this entryfe80::1 ipv6_loopback
tests are working just fine, but of course it is not a valid solution. I tried to mock the inner workings of the actual dns resolved but I was not able to make it work fine for my test case.two questions: