aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWladimir J. van der Laan <laanwj@gmail.com>2018-08-10 19:50:59 +0200
committerWladimir J. van der Laan <laanwj@gmail.com>2018-08-10 19:52:13 +0200
commit48bf8ff5b161e77079bf00a7a452b3f2fe511f84 (patch)
treec91bdef18a431cbbdcf8e63040e15578b03892fc
parent71dec5c81fa1e383f4cabe8686ac790288da99d9 (diff)
parente254ff5d53b79bee29203b965fca572f218bff54 (diff)
downloadbitcoin-48bf8ff5b161e77079bf00a7a452b3f2fe511f84.tar.xz
Merge #13907: Introduce a maximum size for locators.
e254ff5d53b79bee29203b965fca572f218bff54 Introduce a maximum size for locators. (Gregory Maxwell) Pull request description: The largest sensible size for a locator is log in the number of blocks. But, as noted by Coinr8d on BCT a maximum size message could encode a hundred thousand locators. If height were used to limit the messages that could open new attacks where peers on long low diff forks would get disconnected and end up stuck. Ideally, nodes first first learn to limit the size of locators they send before limiting what would be processed, but common implementations back off with an exponent of 2 and have an implicit limit of 2^32 blocks, so they already cannot produce locators over some size. Locators are cheap to process so allowing a few more is harmless, so this sets the maximum to 64-- which is enough for blockchains with 2^64 blocks before the get overhead starts increasing. Tree-SHA512: da28df9c46c988980da861046c62e6e7f93d0eaab3083d32e408d1062f45c00316d5e1754127e808c1feb424fa8e00e5a91aea2cc3b80326b71c148696f7cdb3
-rw-r--r--src/net.h2
-rw-r--r--src/net_processing.cpp12
2 files changed, 14 insertions, 0 deletions
diff --git a/src/net.h b/src/net.h
index 5ea4bdeada..f9cfea59b7 100644
--- a/src/net.h
+++ b/src/net.h
@@ -45,6 +45,8 @@ static const int TIMEOUT_INTERVAL = 20 * 60;
static const int FEELER_INTERVAL = 120;
/** The maximum number of entries in an 'inv' protocol message */
static const unsigned int MAX_INV_SZ = 50000;
+/** The maximum number of entries in a locator */
+static const unsigned int MAX_LOCATOR_SZ = 101;
/** The maximum number of new addresses to accumulate before announcing. */
static const unsigned int MAX_ADDR_TO_SEND = 1000;
/** Maximum length of incoming protocol messages (no message over 4 MB is currently acceptable). */
diff --git a/src/net_processing.cpp b/src/net_processing.cpp
index f684698793..88999ba735 100644
--- a/src/net_processing.cpp
+++ b/src/net_processing.cpp
@@ -2018,6 +2018,12 @@ bool static ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStr
uint256 hashStop;
vRecv >> locator >> hashStop;
+ if (locator.vHave.size() > MAX_LOCATOR_SZ) {
+ LogPrint(BCLog::NET, "getblocks locator size %lld > %d, disconnect peer=%d\n", locator.vHave.size(), MAX_LOCATOR_SZ, pfrom->GetId());
+ pfrom->fDisconnect = true;
+ return true;
+ }
+
// We might have announced the currently-being-connected tip using a
// compact block, which resulted in the peer sending a getblocks
// request, which we would otherwise respond to without the new block.
@@ -2131,6 +2137,12 @@ bool static ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStr
uint256 hashStop;
vRecv >> locator >> hashStop;
+ if (locator.vHave.size() > MAX_LOCATOR_SZ) {
+ LogPrint(BCLog::NET, "getheaders locator size %lld > %d, disconnect peer=%d\n", locator.vHave.size(), MAX_LOCATOR_SZ, pfrom->GetId());
+ pfrom->fDisconnect = true;
+ return true;
+ }
+
LOCK(cs_main);
if (IsInitialBlockDownload() && !pfrom->fWhitelisted) {
LogPrint(BCLog::NET, "Ignoring getheaders from peer=%d because node is in initial block download\n", pfrom->GetId());