Skip to content

Commit 45c98d5

Browse files
Merge pull request #536 from aguycalled/header-spam
Check node address in header spam protection
2 parents a4f23ac + 7f6bc68 commit 45c98d5

File tree

3 files changed

+30
-4
lines changed

3 files changed

+30
-4
lines changed

src/init.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -561,6 +561,7 @@ std::string HelpMessage(HelpMessageMode mode)
561561
strUsage += HelpMessageOpt("-headerspamfilter=<n>", strprintf(_("Use header spam filter (default: %u)"), DEFAULT_HEADER_SPAM_FILTER));
562562
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));
563563
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));
564+
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));
564565

565566
return strUsage;
566567
}

src/main.cpp

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -408,8 +408,6 @@ struct CNodeState {
408408
//! Whether this peer can give us witnesses
409409
bool fHaveWitness;
410410

411-
CNodeHeaders headers;
412-
413411
CNodeState() {
414412
fCurrentlyConnected = false;
415413
nMisbehavior = 0;
@@ -434,6 +432,7 @@ struct CNodeState {
434432

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

438437
// Requires cs_main.
439438
CNodeState *State(NodeId pnode) {
@@ -443,6 +442,26 @@ CNodeState *State(NodeId pnode) {
443442
return &it->second;
444443
}
445444

445+
static CNodeHeaders &ServiceHeaders(const CService& address) EXCLUSIVE_LOCKS_REQUIRED(cs_main) {
446+
unsigned short port =
447+
GetBoolArg("-headerspamfilterignoreport", DEFAULT_HEADER_SPAM_FILTER_IGNORE_PORT) ? 0 : address.GetPort();
448+
CService addr(address, port);
449+
return mapServiceHeaders[addr];
450+
}
451+
452+
static void CleanAddressHeaders(const CAddress& addr) EXCLUSIVE_LOCKS_REQUIRED(cs_main) {
453+
CSubNet subNet(addr);
454+
for (std::map<CService, CNodeHeaders>::iterator it=mapServiceHeaders.begin(); it!=mapServiceHeaders.end();){
455+
if(subNet.Match(it->first))
456+
{
457+
it = mapServiceHeaders.erase(it);
458+
}
459+
else{
460+
it++;
461+
}
462+
}
463+
}
464+
446465
int GetHeight()
447466
{
448467
LOCK(cs_main);
@@ -7210,9 +7229,10 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
72107229
LOCK(cs_main);
72117230
CValidationState state;
72127231
CNodeState *nodestate = State(pfrom->GetId());
7213-
nodestate->headers.addHeaders(nFirst, nLast);
7232+
CNodeHeaders& headers = ServiceHeaders(nodestate->address);
7233+
headers.addHeaders(nFirst, nLast);
72147234
int nDoS;
7215-
ret = nodestate->headers.updateState(state, ret);
7235+
ret = headers.updateState(state, ret);
72167236
if (state.IsInvalid(nDoS)) {
72177237
if (nDoS > 0)
72187238
Misbehaving(pfrom->GetId(), nDoS);
@@ -7791,6 +7811,8 @@ bool SendMessages(CNode* pto)
77917811
else
77927812
{
77937813
CNode::Ban(pto->addr, BanReasonNodeMisbehaving);
7814+
// Remove all data from the header spam filter when the address is banned
7815+
CleanAddressHeaders(pto->addr);
77947816
}
77957817
}
77967818
state.fShouldBan = false;

src/main.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,9 @@ static const bool DEFAULT_HEADER_SPAM_FILTER = true;
161161
static const unsigned int DEFAULT_HEADER_SPAM_FILTER_MAX_SIZE = 50;
162162
/** Default for -headerspamfiltermaxavg, maximum average size of an index occurrence in the header spam filter */
163163
static const unsigned int DEFAULT_HEADER_SPAM_FILTER_MAX_AVG = 10;
164+
/** Default for -headerspamfilterignoreport, ignore the port in the ip address when looking for header spam,
165+
multiple nodes on the same ip will be treated as the one when computing the filter*/
166+
static const unsigned int DEFAULT_HEADER_SPAM_FILTER_IGNORE_PORT = true;
164167

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

0 commit comments

Comments
 (0)