You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

DoS_tests.cpp 7.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215
  1. // Copyright (c) 2011-2016 The Bitcoin Core developers
  2. // Distributed under the MIT software license, see the accompanying
  3. // file COPYING or http://www.opensource.org/licenses/mit-license.php.
  4. // Unit tests for denial-of-service detection/prevention code
  5. #include "chainparams.h"
  6. #include "keystore.h"
  7. #include "net.h"
  8. #include "net_processing.h"
  9. #include "pow.h"
  10. #include "script/sign.h"
  11. #include "serialize.h"
  12. #include "util.h"
  13. #include "validation.h"
  14. #include "test/test_bitcoin.h"
  15. #include <stdint.h>
  16. #include <boost/test/unit_test.hpp>
  17. // Tests these internal-to-net_processing.cpp methods:
  18. extern bool AddOrphanTx(const CTransactionRef& tx, NodeId peer);
  19. extern void EraseOrphansFor(NodeId peer);
  20. extern unsigned int LimitOrphanTxSize(unsigned int nMaxOrphans);
  21. struct COrphanTx {
  22. CTransactionRef tx;
  23. NodeId fromPeer;
  24. int64_t nTimeExpire;
  25. };
  26. extern std::map<uint256, COrphanTx> mapOrphanTransactions;
  27. CService ip(uint32_t i)
  28. {
  29. struct in_addr s;
  30. s.s_addr = i;
  31. return CService(CNetAddr(s), Params().GetDefaultPort());
  32. }
  33. static NodeId id = 0;
  34. BOOST_FIXTURE_TEST_SUITE(DoS_tests, TestingSetup)
  35. BOOST_AUTO_TEST_CASE(DoS_banning)
  36. {
  37. std::atomic<bool> interruptDummy(false);
  38. connman->ClearBanned();
  39. CAddress addr1(ip(0xa0b0c001), NODE_NONE);
  40. CNode dummyNode1(id++, NODE_NETWORK, 0, INVALID_SOCKET, addr1, 0, 0, CAddress(), "", true);
  41. dummyNode1.SetSendVersion(PROTOCOL_VERSION);
  42. peerLogic->InitializeNode(&dummyNode1);
  43. dummyNode1.nVersion = 1;
  44. dummyNode1.fSuccessfullyConnected = true;
  45. Misbehaving(dummyNode1.GetId(), 100); // Should get banned
  46. peerLogic->SendMessages(&dummyNode1, interruptDummy);
  47. BOOST_CHECK(connman->IsBanned(addr1));
  48. BOOST_CHECK(!connman->IsBanned(ip(0xa0b0c001|0x0000ff00))); // Different IP, not banned
  49. CAddress addr2(ip(0xa0b0c002), NODE_NONE);
  50. CNode dummyNode2(id++, NODE_NETWORK, 0, INVALID_SOCKET, addr2, 1, 1, CAddress(), "", true);
  51. dummyNode2.SetSendVersion(PROTOCOL_VERSION);
  52. peerLogic->InitializeNode(&dummyNode2);
  53. dummyNode2.nVersion = 1;
  54. dummyNode2.fSuccessfullyConnected = true;
  55. Misbehaving(dummyNode2.GetId(), 50);
  56. peerLogic->SendMessages(&dummyNode2, interruptDummy);
  57. BOOST_CHECK(!connman->IsBanned(addr2)); // 2 not banned yet...
  58. BOOST_CHECK(connman->IsBanned(addr1)); // ... but 1 still should be
  59. Misbehaving(dummyNode2.GetId(), 50);
  60. peerLogic->SendMessages(&dummyNode2, interruptDummy);
  61. BOOST_CHECK(connman->IsBanned(addr2));
  62. }
  63. BOOST_AUTO_TEST_CASE(DoS_banscore)
  64. {
  65. std::atomic<bool> interruptDummy(false);
  66. connman->ClearBanned();
  67. gArgs.ForceSetArg("-banscore", "111"); // because 11 is my favorite number
  68. CAddress addr1(ip(0xa0b0c001), NODE_NONE);
  69. CNode dummyNode1(id++, NODE_NETWORK, 0, INVALID_SOCKET, addr1, 3, 1, CAddress(), "", true);
  70. dummyNode1.SetSendVersion(PROTOCOL_VERSION);
  71. peerLogic->InitializeNode(&dummyNode1);
  72. dummyNode1.nVersion = 1;
  73. dummyNode1.fSuccessfullyConnected = true;
  74. Misbehaving(dummyNode1.GetId(), 100);
  75. peerLogic->SendMessages(&dummyNode1, interruptDummy);
  76. BOOST_CHECK(!connman->IsBanned(addr1));
  77. Misbehaving(dummyNode1.GetId(), 10);
  78. peerLogic->SendMessages(&dummyNode1, interruptDummy);
  79. BOOST_CHECK(!connman->IsBanned(addr1));
  80. Misbehaving(dummyNode1.GetId(), 1);
  81. peerLogic->SendMessages(&dummyNode1, interruptDummy);
  82. BOOST_CHECK(connman->IsBanned(addr1));
  83. gArgs.ForceSetArg("-banscore", std::to_string(DEFAULT_BANSCORE_THRESHOLD));
  84. }
  85. BOOST_AUTO_TEST_CASE(DoS_bantime)
  86. {
  87. std::atomic<bool> interruptDummy(false);
  88. connman->ClearBanned();
  89. int64_t nStartTime = GetTime();
  90. SetMockTime(nStartTime); // Overrides future calls to GetTime()
  91. CAddress addr(ip(0xa0b0c001), NODE_NONE);
  92. CNode dummyNode(id++, NODE_NETWORK, 0, INVALID_SOCKET, addr, 4, 4, CAddress(), "", true);
  93. dummyNode.SetSendVersion(PROTOCOL_VERSION);
  94. peerLogic->InitializeNode(&dummyNode);
  95. dummyNode.nVersion = 1;
  96. dummyNode.fSuccessfullyConnected = true;
  97. Misbehaving(dummyNode.GetId(), 100);
  98. peerLogic->SendMessages(&dummyNode, interruptDummy);
  99. BOOST_CHECK(connman->IsBanned(addr));
  100. SetMockTime(nStartTime+60*60);
  101. BOOST_CHECK(connman->IsBanned(addr));
  102. SetMockTime(nStartTime+60*60*24+1);
  103. BOOST_CHECK(!connman->IsBanned(addr));
  104. }
  105. CTransactionRef RandomOrphan()
  106. {
  107. std::map<uint256, COrphanTx>::iterator it;
  108. it = mapOrphanTransactions.lower_bound(InsecureRand256());
  109. if (it == mapOrphanTransactions.end())
  110. it = mapOrphanTransactions.begin();
  111. return it->second.tx;
  112. }
  113. BOOST_AUTO_TEST_CASE(DoS_mapOrphans)
  114. {
  115. CKey key;
  116. key.MakeNewKey(true);
  117. CBasicKeyStore keystore;
  118. keystore.AddKey(key);
  119. // 50 orphan transactions:
  120. for (int i = 0; i < 50; i++)
  121. {
  122. CMutableTransaction tx;
  123. tx.vin.resize(1);
  124. tx.vin[0].prevout.n = 0;
  125. tx.vin[0].prevout.hash = InsecureRand256();
  126. tx.vin[0].scriptSig << OP_1;
  127. tx.vout.resize(1);
  128. tx.vout[0].nValue = 1*CENT;
  129. tx.vout[0].scriptPubKey = GetScriptForDestination(key.GetPubKey().GetID());
  130. AddOrphanTx(MakeTransactionRef(tx), i);
  131. }
  132. // ... and 50 that depend on other orphans:
  133. for (int i = 0; i < 50; i++)
  134. {
  135. CTransactionRef txPrev = RandomOrphan();
  136. CMutableTransaction tx;
  137. tx.vin.resize(1);
  138. tx.vin[0].prevout.n = 0;
  139. tx.vin[0].prevout.hash = txPrev->GetHash();
  140. tx.vout.resize(1);
  141. tx.vout[0].nValue = 1*CENT;
  142. tx.vout[0].scriptPubKey = GetScriptForDestination(key.GetPubKey().GetID());
  143. SignSignature(keystore, *txPrev, tx, 0, SIGHASH_ALL);
  144. AddOrphanTx(MakeTransactionRef(tx), i);
  145. }
  146. // This really-big orphan should be ignored:
  147. for (int i = 0; i < 10; i++)
  148. {
  149. CTransactionRef txPrev = RandomOrphan();
  150. CMutableTransaction tx;
  151. tx.vout.resize(1);
  152. tx.vout[0].nValue = 1*CENT;
  153. tx.vout[0].scriptPubKey = GetScriptForDestination(key.GetPubKey().GetID());
  154. tx.vin.resize(2777);
  155. for (unsigned int j = 0; j < tx.vin.size(); j++)
  156. {
  157. tx.vin[j].prevout.n = j;
  158. tx.vin[j].prevout.hash = txPrev->GetHash();
  159. }
  160. SignSignature(keystore, *txPrev, tx, 0, SIGHASH_ALL);
  161. // Re-use same signature for other inputs
  162. // (they don't have to be valid for this test)
  163. for (unsigned int j = 1; j < tx.vin.size(); j++)
  164. tx.vin[j].scriptSig = tx.vin[0].scriptSig;
  165. BOOST_CHECK(!AddOrphanTx(MakeTransactionRef(tx), i));
  166. }
  167. // Test EraseOrphansFor:
  168. for (NodeId i = 0; i < 3; i++)
  169. {
  170. size_t sizeBefore = mapOrphanTransactions.size();
  171. EraseOrphansFor(i);
  172. BOOST_CHECK(mapOrphanTransactions.size() < sizeBefore);
  173. }
  174. // Test LimitOrphanTxSize() function:
  175. LimitOrphanTxSize(40);
  176. BOOST_CHECK(mapOrphanTransactions.size() <= 40);
  177. LimitOrphanTxSize(10);
  178. BOOST_CHECK(mapOrphanTransactions.size() <= 10);
  179. LimitOrphanTxSize(0);
  180. BOOST_CHECK(mapOrphanTransactions.empty());
  181. }
  182. BOOST_AUTO_TEST_SUITE_END()