diff options
author | Gavin Andresen <gavinandresen@gmail.com> | 2012-02-29 10:14:18 -0500 |
---|---|---|
committer | Gavin Andresen <gavinandresen@gmail.com> | 2012-02-29 11:46:46 -0500 |
commit | 142e604184e3ab6dcbe02cebcbe08e5623182b81 (patch) | |
tree | 0906a390af4ec3314983a62e9fa2ae66dd348ab0 /src/main.cpp | |
parent | 722d9387be4b267b689d7b7d78daeb7157bd12d8 (diff) |
DoS fix for mapOrphanTransactionsv0.6.0rc2
Diffstat (limited to 'src/main.cpp')
-rw-r--r-- | src/main.cpp | 25 |
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); } |