From 01e5c97ac6490a34fe43e069dc41b846f2b14557 Mon Sep 17 00:00:00 2001 From: Rhett Creighton Date: Fri, 5 Jun 2026 23:40:19 +0000 Subject: [PATCH] =?UTF-8?q?beta7:=20beta7:=20P2P=20DoS=20hardening=20?= =?UTF-8?q?=E2=80=94=20blocklocator=20bound,=20mempool=20rate-limit,=20get?= =?UTF-8?q?data=20cap?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Opus 4.8 (1M context) --- src/main.cpp | 22 ++++++++++++++++++++++ src/net.cpp | 1 + src/net.h | 1 + 3 files changed, 24 insertions(+) diff --git a/src/main.cpp b/src/main.cpp index eb98a68c72d..c088e88af71 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -6486,6 +6486,12 @@ bool ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, int64_t if ((fDebug && vInv.size() > 0) || (vInv.size() == 1)) LogPrint("net", "received getdata for: %s peer=%d\n", vInv[0].ToString(), pfrom->id); + if (pfrom->vRecvGetData.size() + vInv.size() > 100000) { + Misbehaving(pfrom->GetId(), 20); + pfrom->fDisconnect = true; + return true; + } + pfrom->vRecvGetData.insert(pfrom->vRecvGetData.end(), vInv.begin(), vInv.end()); ProcessGetData(pfrom); } @@ -6497,6 +6503,11 @@ bool ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, int64_t uint256 hashStop; vRecv >> locator >> hashStop; + if (locator.vHave.size() > 64) { + Misbehaving(pfrom->GetId(), 20); + return true; + } + LOCK(cs_main); // Find the last block the caller has in the main chain @@ -6541,6 +6552,11 @@ bool ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, int64_t uint256 hashStop; vRecv >> locator >> hashStop; + if (locator.vHave.size() > 64) { + Misbehaving(pfrom->GetId(), 20); + return true; + } + LOCK(cs_main); if (IsInitialBlockDownload()) @@ -6821,6 +6837,11 @@ bool ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, int64_t else if (strCommand == "mempool") { + if (pfrom->fSentMempool) { + LogPrint("net", "Ignoring repeated \"mempool\" from peer=%d\n", pfrom->id); + return true; + } + int currentHeight = GetHeight(); LOCK2(cs_main, pfrom->cs_filter); @@ -6848,6 +6869,7 @@ bool ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, int64_t } if (vInv.size() > 0) pfrom->PushMessage("inv", vInv); + pfrom->fSentMempool = true; } diff --git a/src/net.cpp b/src/net.cpp index 4aab7bda1c0..85876957354 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -2102,6 +2102,7 @@ CNode::CNode(SOCKET hSocketIn, const CAddress& addrIn, const std::string& addrNa fGetAddr = false; fRelayTxes = false; fSentAddr = false; + fSentMempool = false; fBootstrapManifestSent = false; fBootstrapParamManifestSent = false; pfilter = new CBloomFilter(); diff --git a/src/net.h b/src/net.h index 3ed577d37e4..759e4211e98 100644 --- a/src/net.h +++ b/src/net.h @@ -287,6 +287,7 @@ class CNode // until it has initialized its bloom filter. bool fRelayTxes; bool fSentAddr; + bool fSentMempool; CSemaphoreGrant grantOutbound; CCriticalSection cs_filter; CBloomFilter* pfilter;