diff --git a/src/net.h b/src/net.h --- a/src/net.h +++ b/src/net.h @@ -346,7 +346,7 @@ /** * Cache is used to minimize topology leaks, so it should * be used for all non-trusted calls, for example, p2p. - * A non-malicious call (from RPC) should + * A non-malicious call (from RPC or a peer with addr permission) should * call the function without a parameter to avoid using the cache. */ std::vector GetAddresses(Network requestor_network); diff --git a/src/net_permissions.h b/src/net_permissions.h --- a/src/net_permissions.h +++ b/src/net_permissions.h @@ -32,6 +32,8 @@ PF_NOBAN = (1U << 4) | PF_DOWNLOAD, // Can query the mempool PF_MEMPOOL = (1U << 5), + // Can request addrs without hitting a privacy-preserving cache + PF_ADDR = (1U << 7), // Bypass the limit on how many proof INVs are tracked from this peer as // well as the delay penalty when reaching the the in-flight requests limit PF_BYPASS_PROOF_REQUEST_LIMITS = (1U << 30), @@ -39,7 +41,7 @@ // True if the user did not specifically set fine grained permissions PF_ISIMPLICIT = (1U << 31), PF_ALL = PF_BLOOMFILTER | PF_FORCERELAY | PF_RELAY | PF_NOBAN | PF_MEMPOOL | - PF_DOWNLOAD | PF_BYPASS_PROOF_REQUEST_LIMITS, + PF_DOWNLOAD | PF_BYPASS_PROOF_REQUEST_LIMITS | PF_ADDR, }; class NetPermissions { diff --git a/src/net_permissions.cpp b/src/net_permissions.cpp --- a/src/net_permissions.cpp +++ b/src/net_permissions.cpp @@ -21,7 +21,8 @@ "maxuploadtarget limit)", "bypass_proof_request_limits (experimental, bypass the limits on avalanche " "proof downloads)", -}; + "addr (responses to GETADDR avoid hitting the cache and contain random " + "records with the most up-to-date info)"}; namespace { @@ -71,6 +72,8 @@ NetPermissions::AddFlag(flags, PF_ALL); } else if (permission == "relay") { NetPermissions::AddFlag(flags, PF_RELAY); + } else if (permission == "addr") { + NetPermissions::AddFlag(flags, PF_ADDR); } else if (permission == "bypass_proof_request_limits") { NetPermissions::AddFlag(flags, PF_BYPASS_PROOF_REQUEST_LIMITS); } else if (permission.length() == 0) { @@ -111,6 +114,9 @@ if (NetPermissions::HasFlag(flags, PF_DOWNLOAD)) { strings.push_back("download"); } + if (NetPermissions::HasFlag(flags, PF_ADDR)) { + strings.push_back("addr"); + } if (NetPermissions::HasFlag(flags, PF_BYPASS_PROOF_REQUEST_LIMITS)) { strings.push_back("bypass_proof_request_limits"); } diff --git a/src/net_processing.cpp b/src/net_processing.cpp --- a/src/net_processing.cpp +++ b/src/net_processing.cpp @@ -4472,8 +4472,12 @@ pfrom.fSentAddr = true; pfrom.vAddrToSend.clear(); - std::vector vAddr = - m_connman.GetAddresses(pfrom.addr.GetNetwork()); + std::vector vAddr; + if (pfrom.HasPermission(PF_ADDR)) { + vAddr = m_connman.GetAddresses(); + } else { + vAddr = m_connman.GetAddresses(pfrom.addr.GetNetwork()); + } FastRandomContext insecure_rand; for (const CAddress &addr : vAddr) { pfrom.PushAddress(addr, insecure_rand); diff --git a/src/test/fuzz/net_permissions.cpp b/src/test/fuzz/net_permissions.cpp --- a/src/test/fuzz/net_permissions.cpp +++ b/src/test/fuzz/net_permissions.cpp @@ -27,6 +27,7 @@ NetPermissionFlags::PF_FORCERELAY, NetPermissionFlags::PF_NOBAN, NetPermissionFlags::PF_MEMPOOL, + NetPermissionFlags::PF_ADDR, NetPermissionFlags::PF_BYPASS_PROOF_REQUEST_LIMITS, NetPermissionFlags::PF_ISIMPLICIT, NetPermissionFlags::PF_ALL, diff --git a/src/test/netbase_tests.cpp b/src/test/netbase_tests.cpp --- a/src/test/netbase_tests.cpp +++ b/src/test/netbase_tests.cpp @@ -488,7 +488,7 @@ error)); const auto strings = NetPermissions::ToStrings(PF_ALL); - BOOST_CHECK_EQUAL(strings.size(), 7U); + BOOST_CHECK_EQUAL(strings.size(), 8U); BOOST_CHECK(std::find(strings.begin(), strings.end(), "bloomfilter") != strings.end()); BOOST_CHECK(std::find(strings.begin(), strings.end(), "forcerelay") != @@ -501,6 +501,8 @@ strings.end()); BOOST_CHECK(std::find(strings.begin(), strings.end(), "download") != strings.end()); + BOOST_CHECK(std::find(strings.begin(), strings.end(), "addr") != + strings.end()); BOOST_CHECK(std::find(strings.begin(), strings.end(), "bypass_proof_request_limits") != strings.end()); } diff --git a/test/functional/p2p_permissions.py b/test/functional/p2p_permissions.py --- a/test/functional/p2p_permissions.py +++ b/test/functional/p2p_permissions.py @@ -101,7 +101,7 @@ # all permission added ["-whitelist=all@127.0.0.1"], ["forcerelay", "noban", "mempool", "bloomfilter", - "relay", "download", "bypass_proof_request_limits"], + "relay", "download", "bypass_proof_request_limits", "addr"], False) self.checkpermission(