Browse Source

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.
0.13
kazcw 10 years ago committed by Gregory Maxwell
parent
commit
5029698186
  1. 1
      src/main.cpp
  2. 4
      src/net.cpp
  3. 1
      src/net.h

1
src/main.cpp

@ -5226,6 +5226,7 @@ bool SendMessages(CNode* pto, bool fSendTrickle) @@ -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())

4
src/net.cpp

@ -2410,6 +2410,10 @@ void CNode::AskFor(const CInv& inv) @@ -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;

1
src/net.h

@ -382,6 +382,7 @@ public: @@ -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:

Loading…
Cancel
Save