Skip to content

Commit

Permalink
prevent peer flooding request queue for an inv
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
kazcw authored and gmaxwell committed Nov 23, 2015
1 parent 0b0fc17 commit 5029698
Show file tree
Hide file tree
Showing 3 changed files with 6 additions and 0 deletions.
1 change: 1 addition & 0 deletions src/main.cpp
Expand Up @@ -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())
Expand Down
4 changes: 4 additions & 0 deletions src/net.cpp
Expand Up @@ -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;
Expand Down
1 change: 1 addition & 0 deletions src/net.h
Expand Up @@ -382,6 +382,7 @@ class CNode
mruset<CInv> setInventoryKnown;
std::vector<CInv> vInventoryToSend;
CCriticalSection cs_inventory;
std::set<uint256> setAskFor;
std::multimap<int64_t, CInv> mapAskFor;

// Ping time measurement:
Expand Down

0 comments on commit 5029698

Please sign in to comment.