Skip to content

Commit

Permalink
Merge pull request #536 from aguycalled/header-spam
Browse files Browse the repository at this point in the history
Check node address in header spam protection
  • Loading branch information
proletesseract authored Jun 29, 2019
2 parents a4f23ac + 7f6bc68 commit 45c98d5
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 4 deletions.
1 change: 1 addition & 0 deletions src/init.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -561,6 +561,7 @@ std::string HelpMessage(HelpMessageMode mode)
strUsage += HelpMessageOpt("-headerspamfilter=<n>", strprintf(_("Use header spam filter (default: %u)"), DEFAULT_HEADER_SPAM_FILTER));
strUsage += HelpMessageOpt("-headerspamfiltermaxsize=<n>", strprintf(_("Maximum size of the list of indexes in the header spam filter (default: %u)"), DEFAULT_HEADER_SPAM_FILTER_MAX_SIZE));
strUsage += HelpMessageOpt("-headerspamfiltermaxavg=<n>", strprintf(_("Maximum average size of an index occurrence in the header spam filter (default: %u)"), DEFAULT_HEADER_SPAM_FILTER_MAX_AVG));
strUsage += HelpMessageOpt("-headerspamfilterignoreport=<n>", strprintf("Ignore the port in the ip address when looking for header spam, determine whether or not multiple nodes can be on the same IP (default: %u)", DEFAULT_HEADER_SPAM_FILTER_IGNORE_PORT));

return strUsage;
}
Expand Down
30 changes: 26 additions & 4 deletions src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -408,8 +408,6 @@ struct CNodeState {
//! Whether this peer can give us witnesses
bool fHaveWitness;

CNodeHeaders headers;

CNodeState() {
fCurrentlyConnected = false;
nMisbehavior = 0;
Expand All @@ -434,6 +432,7 @@ struct CNodeState {

/** Map maintaining per-node state. Requires cs_main. */
map<NodeId, CNodeState> mapNodeState;
map<CService, CNodeHeaders> mapServiceHeaders;

// Requires cs_main.
CNodeState *State(NodeId pnode) {
Expand All @@ -443,6 +442,26 @@ CNodeState *State(NodeId pnode) {
return &it->second;
}

static CNodeHeaders &ServiceHeaders(const CService& address) EXCLUSIVE_LOCKS_REQUIRED(cs_main) {
unsigned short port =
GetBoolArg("-headerspamfilterignoreport", DEFAULT_HEADER_SPAM_FILTER_IGNORE_PORT) ? 0 : address.GetPort();
CService addr(address, port);
return mapServiceHeaders[addr];
}

static void CleanAddressHeaders(const CAddress& addr) EXCLUSIVE_LOCKS_REQUIRED(cs_main) {
CSubNet subNet(addr);
for (std::map<CService, CNodeHeaders>::iterator it=mapServiceHeaders.begin(); it!=mapServiceHeaders.end();){
if(subNet.Match(it->first))
{
it = mapServiceHeaders.erase(it);
}
else{
it++;
}
}
}

int GetHeight()
{
LOCK(cs_main);
Expand Down Expand Up @@ -7210,9 +7229,10 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
LOCK(cs_main);
CValidationState state;
CNodeState *nodestate = State(pfrom->GetId());
nodestate->headers.addHeaders(nFirst, nLast);
CNodeHeaders& headers = ServiceHeaders(nodestate->address);
headers.addHeaders(nFirst, nLast);
int nDoS;
ret = nodestate->headers.updateState(state, ret);
ret = headers.updateState(state, ret);
if (state.IsInvalid(nDoS)) {
if (nDoS > 0)
Misbehaving(pfrom->GetId(), nDoS);
Expand Down Expand Up @@ -7791,6 +7811,8 @@ bool SendMessages(CNode* pto)
else
{
CNode::Ban(pto->addr, BanReasonNodeMisbehaving);
// Remove all data from the header spam filter when the address is banned
CleanAddressHeaders(pto->addr);
}
}
state.fShouldBan = false;
Expand Down
3 changes: 3 additions & 0 deletions src/main.h
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,9 @@ static const bool DEFAULT_HEADER_SPAM_FILTER = true;
static const unsigned int DEFAULT_HEADER_SPAM_FILTER_MAX_SIZE = 50;
/** Default for -headerspamfiltermaxavg, maximum average size of an index occurrence in the header spam filter */
static const unsigned int DEFAULT_HEADER_SPAM_FILTER_MAX_AVG = 10;
/** Default for -headerspamfilterignoreport, ignore the port in the ip address when looking for header spam,
multiple nodes on the same ip will be treated as the one when computing the filter*/
static const unsigned int DEFAULT_HEADER_SPAM_FILTER_IGNORE_PORT = true;

/** Maximum number of headers to announce when relaying blocks with headers message.*/
static const unsigned int MAX_BLOCKS_TO_ANNOUNCE = 8;
Expand Down

0 comments on commit 45c98d5

Please sign in to comment.