Add addr permission flag enabling non-cached addr sharing

This commit is contained in:
Gleb Naumenko
2020-06-03 18:51:34 +03:00
parent acd6135b43
commit cf1569e074
7 changed files with 17 additions and 5 deletions

View File

@@ -258,7 +258,7 @@ public:
/** /**
* Cache is used to minimize topology leaks, so it should * Cache is used to minimize topology leaks, so it should
* be used for all non-trusted calls, for example, p2p. * 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. * call the function without a parameter to avoid using the cache.
*/ */
std::vector<CAddress> GetAddresses(Network requestor_network); std::vector<CAddress> GetAddresses(Network requestor_network);

View File

@@ -15,6 +15,7 @@ const std::vector<std::string> NET_PERMISSIONS_DOC{
"relay (relay even in -blocksonly mode)", "relay (relay even in -blocksonly mode)",
"mempool (allow requesting BIP35 mempool contents)", "mempool (allow requesting BIP35 mempool contents)",
"download (allow getheaders during IBD, no disconnect after maxuploadtarget limit)", "download (allow getheaders during IBD, no disconnect after maxuploadtarget limit)",
"addr (responses to GETADDR avoid hitting the cache and contain random records with the most up-to-date info)"
}; };
namespace { namespace {
@@ -50,6 +51,7 @@ bool TryParsePermissionFlags(const std::string str, NetPermissionFlags& output,
else if (permission == "download") NetPermissions::AddFlag(flags, PF_DOWNLOAD); else if (permission == "download") NetPermissions::AddFlag(flags, PF_DOWNLOAD);
else if (permission == "all") NetPermissions::AddFlag(flags, PF_ALL); else if (permission == "all") NetPermissions::AddFlag(flags, PF_ALL);
else if (permission == "relay") NetPermissions::AddFlag(flags, PF_RELAY); else if (permission == "relay") NetPermissions::AddFlag(flags, PF_RELAY);
else if (permission == "addr") NetPermissions::AddFlag(flags, PF_ADDR);
else if (permission.length() == 0); // Allow empty entries else if (permission.length() == 0); // Allow empty entries
else { else {
error = strprintf(_("Invalid P2P permission: '%s'"), permission); error = strprintf(_("Invalid P2P permission: '%s'"), permission);
@@ -75,6 +77,7 @@ std::vector<std::string> NetPermissions::ToStrings(NetPermissionFlags flags)
if (NetPermissions::HasFlag(flags, PF_RELAY)) strings.push_back("relay"); if (NetPermissions::HasFlag(flags, PF_RELAY)) strings.push_back("relay");
if (NetPermissions::HasFlag(flags, PF_MEMPOOL)) strings.push_back("mempool"); if (NetPermissions::HasFlag(flags, PF_MEMPOOL)) strings.push_back("mempool");
if (NetPermissions::HasFlag(flags, PF_DOWNLOAD)) strings.push_back("download"); if (NetPermissions::HasFlag(flags, PF_DOWNLOAD)) strings.push_back("download");
if (NetPermissions::HasFlag(flags, PF_ADDR)) strings.push_back("addr");
return strings; return strings;
} }

View File

@@ -29,10 +29,12 @@ enum NetPermissionFlags {
PF_NOBAN = (1U << 4) | PF_DOWNLOAD, PF_NOBAN = (1U << 4) | PF_DOWNLOAD,
// Can query the mempool // Can query the mempool
PF_MEMPOOL = (1U << 5), PF_MEMPOOL = (1U << 5),
// Can request addrs without hitting a privacy-preserving cache
PF_ADDR = (1U << 7),
// True if the user did not specifically set fine grained permissions // True if the user did not specifically set fine grained permissions
PF_ISIMPLICIT = (1U << 31), PF_ISIMPLICIT = (1U << 31),
PF_ALL = PF_BLOOMFILTER | PF_FORCERELAY | PF_RELAY | PF_NOBAN | PF_MEMPOOL | PF_DOWNLOAD, PF_ALL = PF_BLOOMFILTER | PF_FORCERELAY | PF_RELAY | PF_NOBAN | PF_MEMPOOL | PF_DOWNLOAD | PF_ADDR,
}; };
class NetPermissions class NetPermissions

View File

@@ -3477,7 +3477,12 @@ void ProcessMessage(
pfrom.fSentAddr = true; pfrom.fSentAddr = true;
pfrom.vAddrToSend.clear(); pfrom.vAddrToSend.clear();
std::vector<CAddress> vAddr = connman.GetAddresses(pfrom.addr.GetNetwork()); std::vector<CAddress> vAddr;
if (pfrom.HasPermission(PF_ADDR)) {
vAddr = connman.GetAddresses();
} else {
vAddr = connman.GetAddresses(pfrom.addr.GetNetwork());
}
FastRandomContext insecure_rand; FastRandomContext insecure_rand;
for (const CAddress &addr : vAddr) { for (const CAddress &addr : vAddr) {
pfrom.PushAddress(addr, insecure_rand); pfrom.PushAddress(addr, insecure_rand);

View File

@@ -24,6 +24,7 @@ void test_one_input(const std::vector<uint8_t>& buffer)
NetPermissionFlags::PF_FORCERELAY, NetPermissionFlags::PF_FORCERELAY,
NetPermissionFlags::PF_NOBAN, NetPermissionFlags::PF_NOBAN,
NetPermissionFlags::PF_MEMPOOL, NetPermissionFlags::PF_MEMPOOL,
NetPermissionFlags::PF_ADDR,
NetPermissionFlags::PF_ISIMPLICIT, NetPermissionFlags::PF_ISIMPLICIT,
NetPermissionFlags::PF_ALL, NetPermissionFlags::PF_ALL,
}) : }) :

View File

@@ -397,13 +397,14 @@ BOOST_AUTO_TEST_CASE(netpermissions_test)
BOOST_CHECK(NetWhitelistPermissions::TryParse("bloom,forcerelay,noban,relay,mempool@1.2.3.4/32", whitelistPermissions, error)); BOOST_CHECK(NetWhitelistPermissions::TryParse("bloom,forcerelay,noban,relay,mempool@1.2.3.4/32", whitelistPermissions, error));
const auto strings = NetPermissions::ToStrings(PF_ALL); const auto strings = NetPermissions::ToStrings(PF_ALL);
BOOST_CHECK_EQUAL(strings.size(), 6U); BOOST_CHECK_EQUAL(strings.size(), 7U);
BOOST_CHECK(std::find(strings.begin(), strings.end(), "bloomfilter") != strings.end()); BOOST_CHECK(std::find(strings.begin(), strings.end(), "bloomfilter") != strings.end());
BOOST_CHECK(std::find(strings.begin(), strings.end(), "forcerelay") != strings.end()); BOOST_CHECK(std::find(strings.begin(), strings.end(), "forcerelay") != strings.end());
BOOST_CHECK(std::find(strings.begin(), strings.end(), "relay") != strings.end()); BOOST_CHECK(std::find(strings.begin(), strings.end(), "relay") != strings.end());
BOOST_CHECK(std::find(strings.begin(), strings.end(), "noban") != strings.end()); BOOST_CHECK(std::find(strings.begin(), strings.end(), "noban") != strings.end());
BOOST_CHECK(std::find(strings.begin(), strings.end(), "mempool") != strings.end()); BOOST_CHECK(std::find(strings.begin(), strings.end(), "mempool") != strings.end());
BOOST_CHECK(std::find(strings.begin(), strings.end(), "download") != 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_AUTO_TEST_CASE(netbase_dont_resolve_strings_with_embedded_nul_characters) BOOST_AUTO_TEST_CASE(netbase_dont_resolve_strings_with_embedded_nul_characters)

View File

@@ -96,7 +96,7 @@ class P2PPermissionsTests(BitcoinTestFramework):
self.checkpermission( self.checkpermission(
# all permission added # all permission added
["-whitelist=all@127.0.0.1"], ["-whitelist=all@127.0.0.1"],
["forcerelay", "noban", "mempool", "bloomfilter", "relay", "download"], ["forcerelay", "noban", "mempool", "bloomfilter", "relay", "download", "addr"],
False) False)
self.stop_node(1) self.stop_node(1)