diff options
author | kazcw <keziahw@gmail.com> | 2014-07-16 14:31:41 -0700 |
---|---|---|
committer | Gregory Maxwell <greg@xiph.org> | 2015-11-23 01:18:54 +0000 |
commit | 5029698186445bf3cd69d0e720f019c472661bff (patch) | |
tree | 7557777e2ca8f70bf5213e81fd9d49ba1993b7ae | |
parent | 0b0fc179ab8795463e0a0f07e989ec6f592a1f90 (diff) | |
download | bitcoin-5029698186445bf3cd69d0e720f019c472661bff.tar.xz |
prevent peer flooding request queue for an inv
mapAlreadyAskedFor does not keep track of which peer has a request queued for a
particular tx. As a result, a peer can blind a node to a tx indefinitely by
sending many invs for the same tx, and then never replying to getdatas for it.
Each inv received will be placed 2 minutes farther back in mapAlreadyAskedFor,
so a short message containing 10 invs would render that tx unavailable for 20
minutes.
This is fixed by disallowing a peer from having more than one entry for a
particular inv in mapAlreadyAskedFor at a time.
-rw-r--r-- | src/main.cpp | 1 | ||||
-rw-r--r-- | src/net.cpp | 4 | ||||
-rw-r--r-- | src/net.h | 1 |
3 files changed, 6 insertions, 0 deletions
diff --git a/src/main.cpp b/src/main.cpp index 2579b642b8..05dedb5631 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -5226,6 +5226,7 @@ bool SendMessages(CNode* pto, bool fSendTrickle) vGetData.clear(); } } + pto->setAskFor.erase(inv.hash); pto->mapAskFor.erase(pto->mapAskFor.begin()); } if (!vGetData.empty()) diff --git a/src/net.cpp b/src/net.cpp index cff4c54505..04119e9ddd 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -2410,6 +2410,10 @@ void CNode::AskFor(const CInv& inv) { if (mapAskFor.size() > MAPASKFOR_MAX_SZ) return; + // a peer may not occupy multiple positions in an inv's request queue + if (!setAskFor.insert(inv.hash).second) + return; + // We're using mapAskFor as a priority queue, // the key is the earliest time the request can be sent int64_t nRequestTime; @@ -382,6 +382,7 @@ public: mruset<CInv> setInventoryKnown; std::vector<CInv> vInventoryToSend; CCriticalSection cs_inventory; + std::set<uint256> setAskFor; std::multimap<int64_t, CInv> mapAskFor; // Ping time measurement: |