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.
This commit is contained in:
parent
0b0fc179ab
commit
5029698186
3 changed files with 6 additions and 0 deletions
|
@ -5226,6 +5226,7 @@ bool SendMessages(CNode* pto, bool fSendTrickle)
|
||||||
vGetData.clear();
|
vGetData.clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
pto->setAskFor.erase(inv.hash);
|
||||||
pto->mapAskFor.erase(pto->mapAskFor.begin());
|
pto->mapAskFor.erase(pto->mapAskFor.begin());
|
||||||
}
|
}
|
||||||
if (!vGetData.empty())
|
if (!vGetData.empty())
|
||||||
|
|
|
@ -2410,6 +2410,10 @@ void CNode::AskFor(const CInv& inv)
|
||||||
{
|
{
|
||||||
if (mapAskFor.size() > MAPASKFOR_MAX_SZ)
|
if (mapAskFor.size() > MAPASKFOR_MAX_SZ)
|
||||||
return;
|
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,
|
// We're using mapAskFor as a priority queue,
|
||||||
// the key is the earliest time the request can be sent
|
// the key is the earliest time the request can be sent
|
||||||
int64_t nRequestTime;
|
int64_t nRequestTime;
|
||||||
|
|
|
@ -382,6 +382,7 @@ public:
|
||||||
mruset<CInv> setInventoryKnown;
|
mruset<CInv> setInventoryKnown;
|
||||||
std::vector<CInv> vInventoryToSend;
|
std::vector<CInv> vInventoryToSend;
|
||||||
CCriticalSection cs_inventory;
|
CCriticalSection cs_inventory;
|
||||||
|
std::set<uint256> setAskFor;
|
||||||
std::multimap<int64_t, CInv> mapAskFor;
|
std::multimap<int64_t, CInv> mapAskFor;
|
||||||
|
|
||||||
// Ping time measurement:
|
// Ping time measurement:
|
||||||
|
|
Loading…
Reference in a new issue