-
Notifications
You must be signed in to change notification settings - Fork 37.7k
p2p: skip querying dns seeds if -onlynet
disables IPv4 and IPv6
#25678
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
Conversation
45ed3f7
to
09384fc
Compare
The following sections might be updated with supplementary metadata relevant to reviewers and maintainers. ConflictsReviewers, this pull request conflicts with the following ones:
If you consider this pull request important, please also help to review the conflicting pull requests. Ideally, start with the one that should be merged first. |
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.
Strong concept ACK
Concept ACK, Approach ACK. This was asked about in this StackExchange question. |
Concept ACK on (at least by default) not using DNS seed lookups (incl. addrfetch based ones) with Orthogonal idea (not for this PR): would it make sense, when using the hardcoded seeds (for whatever reason, onlynot or not), to only make addrfetch connections to them? Their point is getting us an entrypoint to the network, and using them directly as fully-featured nodes probably places an undue burden on them. This would get worse with a change like this PR. |
09384fc
to
1e039d1
Compare
09384fc to 1e039d1: Addressed feedback, some refactoring/rewording. The current PR is not specific to
Yes, I agree that this could makes sense. While in principle, the maximum inbound limit together with the inbound eviction logic should keep the number of connections under control, hardcoded peers will receive connections from a lot of new nodes which require IBD, so it would be nice to reduce their traffic burden. |
Concept ACK
Well, unlike Tor and I2P addresses, CJDNS addresses could be returned by the DNS seeds, e.g. this could happen:
But we would still need to open a connection to the DNS server itself. If that is from the CJDNS network, then we are perfectly good (e.g. I guess, given the above, it is best and easiest to treat CJDNS like Tor and I2P and have |
ACK 1e039d1 |
utACK 1e039d1 |
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.
ACK 1e039d1
This would leave gArgs.GetBoolArg("-dnsseed")
to true
but would effectively disable DNS seeds if e.g. -onlynet=onion
is given. The existent code is already capable of disabling DNS seeds - it does so if dnsseed=0
.
Given that we want to disable DNS seeds, would it be simpler to flip (soft set) -dnsseed
to false
in InitParameterInteraction()
and not touch any of the code in net.{cpp.h}
(no need to add new member to CConnman
)?
Would require something like this in InitParameterInteraction().
bool clearnet_reachable = true;
if (args.IsArgSet("-onlynet")) {
const auto onlynets = args.GetArgs("-onlynet");
clearnet_reachable = std::any_of(onlynets.begin(), onlynets.end(), [](const auto& net) {
const auto n = ParseNetwork(net);
return n == NET_IPV4 || n == NET_IPV6;
});
}
src/init.cpp
Outdated
if (args.GetBoolArg("-dnsseed") == true && !IsReachable(NET_IPV4) && !IsReachable(NET_IPV6)) { | ||
return InitError(strprintf(_("Incompatible options: -dnsseed was explicitly specified, but -onlynet forbids connections to IPv4/IPv6"))); | ||
}; |
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.
Should this also cover -forcednsseed
? Its help reads: "Always query for peer addresses via DNS lookup", seems to contradict with -onlynet=onion
, just like -dnsseed
does. In other words, should this give an init error too: bitcoind -onlynet=onion -forcednsseed=1
?
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.
There is already an interaction between -forcednsseed
and -dnsseed
which gives an InitError if -dnsseed
is not set.
With the latest push (taking your suggestion to use InitParameterInteraction()
) that should hit.
1e039d1
to
c21bd3d
Compare
Thanks - I agree that it would be simpler and more similar to other parameter interactions to do that and took your suggestion with the latest push (added you as coauthor). |
c21bd3d
to
7dab719
Compare
ACK 7dab719 |
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.
ACK 7dab719
@naumenkogs's suggestions above make sense, would be happy to re-ACK.
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.
Approach ACK, agree with @naumenkogs' suggestions as well
@@ -1630,15 +1633,20 @@ void CConnman::ThreadOpenConnections(const std::vector<std::string> connect) | |||
LOCK2(m_addr_fetches_mutex, m_added_nodes_mutex); | |||
if (m_addr_fetches.empty() && m_added_nodes.empty()) { | |||
add_fixed_seeds_now = true; | |||
LogPrintf("Adding fixed seeds as -dnsseed=0, -addnode is not provided and all -seednode(s) attempted\n"); | |||
LogPrintf("Adding fixed seeds as -dnsseed=0 (or IPv4/IPv6 connections are disabled via -onlynet), -addnode is not provided and all -seednode(s) attempted\n"); |
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.
while touching this, could use severity-based logging (info is always logged, like LogPrintf), feel free to ignore
LogPrintf("Adding fixed seeds as -dnsseed=0 (or IPv4/IPv6 connections are disabled via -onlynet), -addnode is not provided and all -seednode(s) attempted\n"); | |
LogPrintLevel(BCLog::ADDRMAN, BCLog::Level::Info, "Adding fixed seeds as -dnsseed=0 (or IPv4/IPv6 connections are disabled via -onlynet), -addnode is not provided and all -seednode(s) attempted\n"); |
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.
I think I would prefer to have this done in a dedicated PR that switches it everywhere per module (for 25.0 - no idea whether this qualifies as a bugfix and should still go into 24.0, at least it still has the label), so that hopefully there wouldn't be too much of a mix for an extended time.
Also, how about a short heads-up in the weekly IRC meeting or so summarizing the recent changes? While logging is used by / affects everyone, I think most contributors who didn't follow the recent developments have internalized something like "With LogPrintf be careful about disk-filling attacks - with category-based logging no need to think about that much" which is going to change.
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.
Yes agree, was about to update my comment to say never mind. (Am about to propose renaming the LogPrintLevel macro to simply Log or something before converting to more of them, as it is likely to subsume most of the other logging.)
7dab719
to
626ad77
Compare
626ad77
to
37b2b5b
Compare
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.
ACK 37b2b5b
Concept ACK 37b2b5b ("don't query seeds...") makes sense to me, but e91e3ef ("add only reachable addresses to addrman") less so. This commit seems to assume that the node is always started with the same IIUC we only ever load the fixed seed nodes if |
src/net.cpp
Outdated
@@ -1475,6 +1475,9 @@ void CConnman::ThreadDNSAddressSeed() | |||
vAdd.push_back(addr); | |||
found++; | |||
} | |||
vAdd.erase(std::remove_if(vAdd.begin(), vAdd.end(), | |||
[](const CAddress& addr) { return !IsReachable(addr); }), |
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.
e91e3ef: why not just check this condition before calling vAdd.push_back(addr)
? We should probably not increment found
either when we don't use an address.
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.
Good point. On second thought, the filtering seems unnecessary in the DNS seed case, because with the second commit, we will skip querying the DNS seeds if IPv4 and IPv6 are unreachable, while DNS seeds only return IPv4 and IPv6 addresses. So I removed it.
Yes, so we will never load them more than once for a given
The general idea is to make the behavior consistent with the behavior towards peers (don't accept addrs into our addrman we can't or don't want to connect to). I think if a user decides to just more additional networks (at least for a transitional period), there shouldn't be a problem: Both It's more complicated if the user makes an abrupt change from I think that switching from What this PR may make more difficult is a situation where we switch between privacy networks, e.g. from Maybe it would be better to change the criterion for querying hardcoded seeds from |
We will not make outgoing connection to peers that are unreachable (e.g. because of -onlynet configuration). Therefore, it makes no sense to add them to addrman in the first place. While this is already the case for addresses received via p2p addr messages, this commit does the same for addresses received from fixed seeds.
This happens, for example, if the user specified -onlynet=onion or -onlynet=i2p. DNS seeds only resolve to IPv4 / IPv6 addresses, making their answers useless to us, since we don't want to make connections to these. If, within the DNS seed thread, we'd instead do fallback AddrFetch connections to one of the clearnet addresses the DNS seed resolves to, we might get usable addresses from other networks if lucky, but would be violating our -onlynet user preference in doing so. Therefore, in this case it is better to rely on fixed seeds for networks we want to connect to. Co-authored-by: Vasil Dimov <vd@FreeBSD.org>
37b2b5b
to
385f5a4
Compare
|
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.
utACK 91f0a7f modulo using hardcoded seeds when we have nothing reachable
utACK 385f5a4 |
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.
Ok, so now the "modulo" part of my review is at least documented in #26035. |
…es to addrman" ce42570 doc: comment "add only reachable addresses to addrman" (Kristaps Kaupe) Pull request description: Proposed by Sjors during review of #25678, was likely just missed, as it also for me looks a code where comment will not hurt. bitcoin/bitcoin#25678 (comment) ACKs for top commit: mzumsande: ACK ce42570 vasild: ACK ce42570 Zero-1729: re-ACK ce42570 Tree-SHA512: ef085d527349de07c1b43ed39e55e34b29cb0137c9509bd14a1af88206f7d4aa7dfec1dca53a9deaed67a2d0f32fa21e0b1a04d4d5d7f8a265dfab3b62bf8c54
…drman" ce42570 doc: comment "add only reachable addresses to addrman" (Kristaps Kaupe) Pull request description: Proposed by Sjors during review of bitcoin#25678, was likely just missed, as it also for me looks a code where comment will not hurt. bitcoin#25678 (comment) ACKs for top commit: mzumsande: ACK ce42570 vasild: ACK ce42570 Zero-1729: re-ACK ce42570 Tree-SHA512: ef085d527349de07c1b43ed39e55e34b29cb0137c9509bd14a1af88206f7d4aa7dfec1dca53a9deaed67a2d0f32fa21e0b1a04d4d5d7f8a265dfab3b62bf8c54
Currently,
-onlynet
does not work well in connection with initial peer discovery, because DNS seeds only resolve to IPv6 and IPv4 adresses:With
-onlynet=i2p
, we would load clearnet addresses from DNS seeds into addrman, be content our addrman isn't empty so we don't try to query hardcoded seeds (although these exist for i2p!), and never attempt to make an automatic outbound connection.With
-onlynet=onion
and-proxy
set, we wouldn't load addresses via DNS, but will make AddrFetch connections (through a tor exit node) to a random clearnet peer the DNS seed resolves to (see #6808 (comment)), thus breaching the-onlynet
preference of the user - this has been reported in the two issues listed below.This PR proposes two changes:
1.) Don't load addresses that are unreachable (so that we wouldn't connect to them) into addrman. This is already the case for addresses received via p2p addr messages, this PR implements the same for addresses received from DNS seeds and fixed seeds. This means that in the case of
-onlynet=onion
, we wouldn't load fixed seed IPv4 addresses into addrman, only the onion ones.2.) Skip trying the DNS seeds if neither IPv4 nor IPv6 are reachable and move directly to adding the hardcoded seeds from networks we can connect to. This is done by soft-setting
-dnsseed
to 0 in this case, unless-dnsseed=1
was explicitly specified, in which case we abort with anInitError
.Fixes #6808
Fixes #12344