aboutsummaryrefslogtreecommitdiff
path: root/src/main.cpp
diff options
context:
space:
mode:
authorGavin Andresen <gavinandresen@gmail.com>2012-02-29 10:14:18 -0500
committerGavin Andresen <gavinandresen@gmail.com>2012-02-29 11:46:46 -0500
commit142e604184e3ab6dcbe02cebcbe08e5623182b81 (patch)
tree0906a390af4ec3314983a62e9fa2ae66dd348ab0 /src/main.cpp
parent722d9387be4b267b689d7b7d78daeb7157bd12d8 (diff)
downloadbitcoin-142e604184e3ab6dcbe02cebcbe08e5623182b81.tar.xz
DoS fix for mapOrphanTransactionsv0.6.0rc2
Diffstat (limited to 'src/main.cpp')
-rw-r--r--src/main.cpp25
1 files changed, 24 insertions, 1 deletions
diff --git a/src/main.cpp b/src/main.cpp
index 5de4b8c3b5..995195289f 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -167,13 +167,14 @@ void static ResendWalletTransactions()
// mapOrphanTransactions
//
-void static AddOrphanTx(const CDataStream& vMsg)
+void AddOrphanTx(const CDataStream& vMsg)
{
CTransaction tx;
CDataStream(vMsg) >> tx;
uint256 hash = tx.GetHash();
if (mapOrphanTransactions.count(hash))
return;
+
CDataStream* pvMsg = mapOrphanTransactions[hash] = new CDataStream(vMsg);
BOOST_FOREACH(const CTxIn& txin, tx.vin)
mapOrphanTransactionsByPrev.insert(make_pair(txin.prevout.hash, pvMsg));
@@ -201,6 +202,23 @@ void static EraseOrphanTx(uint256 hash)
mapOrphanTransactions.erase(hash);
}
+int LimitOrphanTxSize(int nMaxOrphans)
+{
+ int nEvicted = 0;
+ while (mapOrphanTransactions.size() > nMaxOrphans)
+ {
+ // Evict a random orphan:
+ std::vector<unsigned char> randbytes(32);
+ RAND_bytes(&randbytes[0], 32);
+ uint256 randomhash(randbytes);
+ map<uint256, CDataStream*>::iterator it = mapOrphanTransactions.lower_bound(randomhash);
+ if (it == mapOrphanTransactions.end())
+ it = mapOrphanTransactions.begin();
+ EraseOrphanTx(it->first);
+ ++nEvicted;
+ }
+ return nEvicted;
+}
@@ -2473,6 +2491,11 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv)
{
printf("storing orphan tx %s\n", inv.hash.ToString().substr(0,10).c_str());
AddOrphanTx(vMsg);
+
+ // DoS prevention: do not allow mapOrphanTransactions to grow unbounded
+ int nEvicted = LimitOrphanTxSize(MAX_ORPHAN_TRANSACTIONS);
+ if (nEvicted > 0)
+ printf("mapOrphan overflow, removed %d tx\n", nEvicted);
}
if (tx.nDoS) pfrom->Misbehaving(tx.nDoS);
}