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.

net.h 21KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740
  1. // Copyright (c) 2009-2010 Satoshi Nakamoto
  2. // Copyright (c) 2009-2014 The Bitcoin developers
  3. // Distributed under the MIT/X11 software license, see the accompanying
  4. // file COPYING or http://www.opensource.org/licenses/mit-license.php.
  5. #ifndef BITCOIN_NET_H
  6. #define BITCOIN_NET_H
  7. #include "bloom.h"
  8. #include "compat.h"
  9. #include "hash.h"
  10. #include "limitedmap.h"
  11. #include "mruset.h"
  12. #include "netbase.h"
  13. #include "protocol.h"
  14. #include "sync.h"
  15. #include "uint256.h"
  16. #include "util.h"
  17. #include <deque>
  18. #include <stdint.h>
  19. #ifndef WIN32
  20. #include <arpa/inet.h>
  21. #endif
  22. #include <boost/foreach.hpp>
  23. #include <boost/signals2/signal.hpp>
  24. #include <openssl/rand.h>
  25. class CAddrMan;
  26. class CBlockIndex;
  27. class CNode;
  28. namespace boost {
  29. class thread_group;
  30. } // namespace boost
  31. /** Time between pings automatically sent out for latency probing and keepalive (in seconds). */
  32. static const int PING_INTERVAL = 2 * 60;
  33. /** Time after which to disconnect, after waiting for a ping response (or inactivity). */
  34. static const int TIMEOUT_INTERVAL = 20 * 60;
  35. /** The maximum number of entries in an 'inv' protocol message */
  36. static const unsigned int MAX_INV_SZ = 50000;
  37. /** -listen default */
  38. static const bool DEFAULT_LISTEN = true;
  39. /** -upnp default */
  40. #ifdef USE_UPNP
  41. static const bool DEFAULT_UPNP = USE_UPNP;
  42. #else
  43. static const bool DEFAULT_UPNP = false;
  44. #endif
  45. inline unsigned int ReceiveFloodSize() { return 1000*GetArg("-maxreceivebuffer", 5*1000); }
  46. inline unsigned int SendBufferSize() { return 1000*GetArg("-maxsendbuffer", 1*1000); }
  47. void AddOneShot(std::string strDest);
  48. bool RecvLine(SOCKET hSocket, std::string& strLine);
  49. bool GetMyExternalIP(CNetAddr& ipRet);
  50. void AddressCurrentlyConnected(const CService& addr);
  51. CNode* FindNode(const CNetAddr& ip);
  52. CNode* FindNode(const CService& ip);
  53. CNode* ConnectNode(CAddress addrConnect, const char *pszDest = NULL);
  54. bool OpenNetworkConnection(const CAddress& addrConnect, CSemaphoreGrant *grantOutbound = NULL, const char *strDest = NULL, bool fOneShot = false);
  55. void MapPort(bool fUseUPnP);
  56. unsigned short GetListenPort();
  57. bool BindListenPort(const CService &bindAddr, std::string& strError);
  58. void StartNode(boost::thread_group& threadGroup);
  59. bool StopNode();
  60. void SocketSendData(CNode *pnode);
  61. typedef int NodeId;
  62. // Signals for message handling
  63. struct CNodeSignals
  64. {
  65. boost::signals2::signal<int ()> GetHeight;
  66. boost::signals2::signal<bool (CNode*)> ProcessMessages;
  67. boost::signals2::signal<bool (CNode*, bool)> SendMessages;
  68. boost::signals2::signal<void (NodeId, const CNode*)> InitializeNode;
  69. boost::signals2::signal<void (NodeId)> FinalizeNode;
  70. };
  71. CNodeSignals& GetNodeSignals();
  72. enum
  73. {
  74. LOCAL_NONE, // unknown
  75. LOCAL_IF, // address a local interface listens on
  76. LOCAL_BIND, // address explicit bound to
  77. LOCAL_UPNP, // address reported by UPnP
  78. LOCAL_HTTP, // address reported by whatismyip.com and similar
  79. LOCAL_MANUAL, // address explicitly specified (-externalip=)
  80. LOCAL_MAX
  81. };
  82. void SetLimited(enum Network net, bool fLimited = true);
  83. bool IsLimited(enum Network net);
  84. bool IsLimited(const CNetAddr& addr);
  85. bool AddLocal(const CService& addr, int nScore = LOCAL_NONE);
  86. bool AddLocal(const CNetAddr& addr, int nScore = LOCAL_NONE);
  87. bool SeenLocal(const CService& addr);
  88. bool IsLocal(const CService& addr);
  89. bool GetLocal(CService &addr, const CNetAddr *paddrPeer = NULL);
  90. bool IsReachable(const CNetAddr &addr);
  91. void SetReachable(enum Network net, bool fFlag = true);
  92. CAddress GetLocalAddress(const CNetAddr *paddrPeer = NULL);
  93. extern bool fDiscover;
  94. extern bool fListen;
  95. extern uint64_t nLocalServices;
  96. extern uint64_t nLocalHostNonce;
  97. extern CAddrMan addrman;
  98. extern int nMaxConnections;
  99. extern std::vector<CNode*> vNodes;
  100. extern CCriticalSection cs_vNodes;
  101. extern std::map<CInv, CDataStream> mapRelay;
  102. extern std::deque<std::pair<int64_t, CInv> > vRelayExpiration;
  103. extern CCriticalSection cs_mapRelay;
  104. extern limitedmap<CInv, int64_t> mapAlreadyAskedFor;
  105. extern std::vector<std::string> vAddedNodes;
  106. extern CCriticalSection cs_vAddedNodes;
  107. extern NodeId nLastNodeId;
  108. extern CCriticalSection cs_nLastNodeId;
  109. struct LocalServiceInfo {
  110. int nScore;
  111. int nPort;
  112. };
  113. extern CCriticalSection cs_mapLocalHost;
  114. extern std::map<CNetAddr, LocalServiceInfo> mapLocalHost;
  115. class CNodeStats
  116. {
  117. public:
  118. NodeId nodeid;
  119. uint64_t nServices;
  120. int64_t nLastSend;
  121. int64_t nLastRecv;
  122. int64_t nTimeConnected;
  123. std::string addrName;
  124. int nVersion;
  125. std::string cleanSubVer;
  126. bool fInbound;
  127. int nStartingHeight;
  128. uint64_t nSendBytes;
  129. uint64_t nRecvBytes;
  130. bool fSyncNode;
  131. double dPingTime;
  132. double dPingWait;
  133. std::string addrLocal;
  134. };
  135. class CNetMessage {
  136. public:
  137. bool in_data; // parsing header (false) or data (true)
  138. CDataStream hdrbuf; // partially received header
  139. CMessageHeader hdr; // complete header
  140. unsigned int nHdrPos;
  141. CDataStream vRecv; // received message data
  142. unsigned int nDataPos;
  143. CNetMessage(int nTypeIn, int nVersionIn) : hdrbuf(nTypeIn, nVersionIn), vRecv(nTypeIn, nVersionIn) {
  144. hdrbuf.resize(24);
  145. in_data = false;
  146. nHdrPos = 0;
  147. nDataPos = 0;
  148. }
  149. bool complete() const
  150. {
  151. if (!in_data)
  152. return false;
  153. return (hdr.nMessageSize == nDataPos);
  154. }
  155. void SetVersion(int nVersionIn)
  156. {
  157. hdrbuf.SetVersion(nVersionIn);
  158. vRecv.SetVersion(nVersionIn);
  159. }
  160. int readHeader(const char *pch, unsigned int nBytes);
  161. int readData(const char *pch, unsigned int nBytes);
  162. };
  163. /** Information about a peer */
  164. class CNode
  165. {
  166. public:
  167. // socket
  168. uint64_t nServices;
  169. SOCKET hSocket;
  170. CDataStream ssSend;
  171. size_t nSendSize; // total size of all vSendMsg entries
  172. size_t nSendOffset; // offset inside the first vSendMsg already sent
  173. uint64_t nSendBytes;
  174. std::deque<CSerializeData> vSendMsg;
  175. CCriticalSection cs_vSend;
  176. std::deque<CInv> vRecvGetData;
  177. std::deque<CNetMessage> vRecvMsg;
  178. CCriticalSection cs_vRecvMsg;
  179. uint64_t nRecvBytes;
  180. int nRecvVersion;
  181. int64_t nLastSend;
  182. int64_t nLastRecv;
  183. int64_t nTimeConnected;
  184. CAddress addr;
  185. std::string addrName;
  186. CService addrLocal;
  187. int nVersion;
  188. // strSubVer is whatever byte array we read from the wire. However, this field is intended
  189. // to be printed out, displayed to humans in various forms and so on. So we sanitize it and
  190. // store the sanitized version in cleanSubVer. The original should be used when dealing with
  191. // the network or wire types and the cleaned string used when displayed or logged.
  192. std::string strSubVer, cleanSubVer;
  193. bool fOneShot;
  194. bool fClient;
  195. bool fInbound;
  196. bool fNetworkNode;
  197. bool fSuccessfullyConnected;
  198. bool fDisconnect;
  199. // We use fRelayTxes for two purposes -
  200. // a) it allows us to not relay tx invs before receiving the peer's version message
  201. // b) the peer may tell us in their version message that we should not relay tx invs
  202. // until they have initialized their bloom filter.
  203. bool fRelayTxes;
  204. CSemaphoreGrant grantOutbound;
  205. CCriticalSection cs_filter;
  206. CBloomFilter* pfilter;
  207. int nRefCount;
  208. NodeId id;
  209. protected:
  210. // Denial-of-service detection/prevention
  211. // Key is IP address, value is banned-until-time
  212. static std::map<CNetAddr, int64_t> setBanned;
  213. static CCriticalSection cs_setBanned;
  214. // Basic fuzz-testing
  215. void Fuzz(int nChance); // modifies ssSend
  216. public:
  217. uint256 hashContinue;
  218. CBlockIndex* pindexLastGetBlocksBegin;
  219. uint256 hashLastGetBlocksEnd;
  220. int nStartingHeight;
  221. bool fStartSync;
  222. // flood relay
  223. std::vector<CAddress> vAddrToSend;
  224. mruset<CAddress> setAddrKnown;
  225. bool fGetAddr;
  226. std::set<uint256> setKnown;
  227. // inventory based relay
  228. mruset<CInv> setInventoryKnown;
  229. std::vector<CInv> vInventoryToSend;
  230. CCriticalSection cs_inventory;
  231. std::multimap<int64_t, CInv> mapAskFor;
  232. // Ping time measurement:
  233. // The pong reply we're expecting, or 0 if no pong expected.
  234. uint64_t nPingNonceSent;
  235. // Time (in usec) the last ping was sent, or 0 if no ping was ever sent.
  236. int64_t nPingUsecStart;
  237. // Last measured round-trip time.
  238. int64_t nPingUsecTime;
  239. // Whether a ping is requested.
  240. bool fPingQueued;
  241. CNode(SOCKET hSocketIn, CAddress addrIn, std::string addrNameIn = "", bool fInboundIn=false) : ssSend(SER_NETWORK, INIT_PROTO_VERSION), setAddrKnown(5000)
  242. {
  243. nServices = 0;
  244. hSocket = hSocketIn;
  245. nRecvVersion = INIT_PROTO_VERSION;
  246. nLastSend = 0;
  247. nLastRecv = 0;
  248. nSendBytes = 0;
  249. nRecvBytes = 0;
  250. nTimeConnected = GetTime();
  251. addr = addrIn;
  252. addrName = addrNameIn == "" ? addr.ToStringIPPort() : addrNameIn;
  253. nVersion = 0;
  254. strSubVer = "";
  255. fOneShot = false;
  256. fClient = false; // set by version message
  257. fInbound = fInboundIn;
  258. fNetworkNode = false;
  259. fSuccessfullyConnected = false;
  260. fDisconnect = false;
  261. nRefCount = 0;
  262. nSendSize = 0;
  263. nSendOffset = 0;
  264. hashContinue = 0;
  265. pindexLastGetBlocksBegin = 0;
  266. hashLastGetBlocksEnd = 0;
  267. nStartingHeight = -1;
  268. fStartSync = false;
  269. fGetAddr = false;
  270. fRelayTxes = false;
  271. setInventoryKnown.max_size(SendBufferSize() / 1000);
  272. pfilter = new CBloomFilter();
  273. nPingNonceSent = 0;
  274. nPingUsecStart = 0;
  275. nPingUsecTime = 0;
  276. fPingQueued = false;
  277. {
  278. LOCK(cs_nLastNodeId);
  279. id = nLastNodeId++;
  280. }
  281. // Be shy and don't send version until we hear
  282. if (hSocket != INVALID_SOCKET && !fInbound)
  283. PushVersion();
  284. GetNodeSignals().InitializeNode(GetId(), this);
  285. }
  286. ~CNode()
  287. {
  288. if (hSocket != INVALID_SOCKET)
  289. {
  290. closesocket(hSocket);
  291. hSocket = INVALID_SOCKET;
  292. }
  293. if (pfilter)
  294. delete pfilter;
  295. GetNodeSignals().FinalizeNode(GetId());
  296. }
  297. private:
  298. // Network usage totals
  299. static CCriticalSection cs_totalBytesRecv;
  300. static CCriticalSection cs_totalBytesSent;
  301. static uint64_t nTotalBytesRecv;
  302. static uint64_t nTotalBytesSent;
  303. CNode(const CNode&);
  304. void operator=(const CNode&);
  305. public:
  306. NodeId GetId() const {
  307. return id;
  308. }
  309. int GetRefCount()
  310. {
  311. assert(nRefCount >= 0);
  312. return nRefCount;
  313. }
  314. // requires LOCK(cs_vRecvMsg)
  315. unsigned int GetTotalRecvSize()
  316. {
  317. unsigned int total = 0;
  318. BOOST_FOREACH(const CNetMessage &msg, vRecvMsg)
  319. total += msg.vRecv.size() + 24;
  320. return total;
  321. }
  322. // requires LOCK(cs_vRecvMsg)
  323. bool ReceiveMsgBytes(const char *pch, unsigned int nBytes);
  324. // requires LOCK(cs_vRecvMsg)
  325. void SetRecvVersion(int nVersionIn)
  326. {
  327. nRecvVersion = nVersionIn;
  328. BOOST_FOREACH(CNetMessage &msg, vRecvMsg)
  329. msg.SetVersion(nVersionIn);
  330. }
  331. CNode* AddRef()
  332. {
  333. nRefCount++;
  334. return this;
  335. }
  336. void Release()
  337. {
  338. nRefCount--;
  339. }
  340. void AddAddressKnown(const CAddress& addr)
  341. {
  342. setAddrKnown.insert(addr);
  343. }
  344. void PushAddress(const CAddress& addr)
  345. {
  346. // Known checking here is only to save space from duplicates.
  347. // SendMessages will filter it again for knowns that were added
  348. // after addresses were pushed.
  349. if (addr.IsValid() && !setAddrKnown.count(addr))
  350. vAddrToSend.push_back(addr);
  351. }
  352. void AddInventoryKnown(const CInv& inv)
  353. {
  354. {
  355. LOCK(cs_inventory);
  356. setInventoryKnown.insert(inv);
  357. }
  358. }
  359. void PushInventory(const CInv& inv)
  360. {
  361. {
  362. LOCK(cs_inventory);
  363. if (!setInventoryKnown.count(inv))
  364. vInventoryToSend.push_back(inv);
  365. }
  366. }
  367. void AskFor(const CInv& inv)
  368. {
  369. // We're using mapAskFor as a priority queue,
  370. // the key is the earliest time the request can be sent
  371. int64_t nRequestTime;
  372. limitedmap<CInv, int64_t>::const_iterator it = mapAlreadyAskedFor.find(inv);
  373. if (it != mapAlreadyAskedFor.end())
  374. nRequestTime = it->second;
  375. else
  376. nRequestTime = 0;
  377. LogPrint("net", "askfor %s %d (%s)\n", inv.ToString(), nRequestTime, DateTimeStrFormat("%H:%M:%S", nRequestTime/1000000).c_str());
  378. // Make sure not to reuse time indexes to keep things in the same order
  379. int64_t nNow = GetTimeMicros() - 1000000;
  380. static int64_t nLastTime;
  381. ++nLastTime;
  382. nNow = std::max(nNow, nLastTime);
  383. nLastTime = nNow;
  384. // Each retry is 2 minutes after the last
  385. nRequestTime = std::max(nRequestTime + 2 * 60 * 1000000, nNow);
  386. if (it != mapAlreadyAskedFor.end())
  387. mapAlreadyAskedFor.update(it, nRequestTime);
  388. else
  389. mapAlreadyAskedFor.insert(std::make_pair(inv, nRequestTime));
  390. mapAskFor.insert(std::make_pair(nRequestTime, inv));
  391. }
  392. // TODO: Document the postcondition of this function. Is cs_vSend locked?
  393. void BeginMessage(const char* pszCommand) EXCLUSIVE_LOCK_FUNCTION(cs_vSend)
  394. {
  395. ENTER_CRITICAL_SECTION(cs_vSend);
  396. assert(ssSend.size() == 0);
  397. ssSend << CMessageHeader(pszCommand, 0);
  398. LogPrint("net", "sending: %s ", pszCommand);
  399. }
  400. // TODO: Document the precondition of this function. Is cs_vSend locked?
  401. void AbortMessage() UNLOCK_FUNCTION(cs_vSend)
  402. {
  403. ssSend.clear();
  404. LEAVE_CRITICAL_SECTION(cs_vSend);
  405. LogPrint("net", "(aborted)\n");
  406. }
  407. // TODO: Document the precondition of this function. Is cs_vSend locked?
  408. void EndMessage() UNLOCK_FUNCTION(cs_vSend)
  409. {
  410. // The -*messagestest options are intentionally not documented in the help message,
  411. // since they are only used during development to debug the networking code and are
  412. // not intended for end-users.
  413. if (mapArgs.count("-dropmessagestest") && GetRand(GetArg("-dropmessagestest", 2)) == 0)
  414. {
  415. LogPrint("net", "dropmessages DROPPING SEND MESSAGE\n");
  416. AbortMessage();
  417. return;
  418. }
  419. if (mapArgs.count("-fuzzmessagestest"))
  420. Fuzz(GetArg("-fuzzmessagestest", 10));
  421. if (ssSend.size() == 0)
  422. return;
  423. // Set the size
  424. unsigned int nSize = ssSend.size() - CMessageHeader::HEADER_SIZE;
  425. memcpy((char*)&ssSend[CMessageHeader::MESSAGE_SIZE_OFFSET], &nSize, sizeof(nSize));
  426. // Set the checksum
  427. uint256 hash = Hash(ssSend.begin() + CMessageHeader::HEADER_SIZE, ssSend.end());
  428. unsigned int nChecksum = 0;
  429. memcpy(&nChecksum, &hash, sizeof(nChecksum));
  430. assert(ssSend.size () >= CMessageHeader::CHECKSUM_OFFSET + sizeof(nChecksum));
  431. memcpy((char*)&ssSend[CMessageHeader::CHECKSUM_OFFSET], &nChecksum, sizeof(nChecksum));
  432. LogPrint("net", "(%d bytes)\n", nSize);
  433. std::deque<CSerializeData>::iterator it = vSendMsg.insert(vSendMsg.end(), CSerializeData());
  434. ssSend.GetAndClear(*it);
  435. nSendSize += (*it).size();
  436. // If write queue empty, attempt "optimistic write"
  437. if (it == vSendMsg.begin())
  438. SocketSendData(this);
  439. LEAVE_CRITICAL_SECTION(cs_vSend);
  440. }
  441. void PushVersion();
  442. void PushMessage(const char* pszCommand)
  443. {
  444. try
  445. {
  446. BeginMessage(pszCommand);
  447. EndMessage();
  448. }
  449. catch (...)
  450. {
  451. AbortMessage();
  452. throw;
  453. }
  454. }
  455. template<typename T1>
  456. void PushMessage(const char* pszCommand, const T1& a1)
  457. {
  458. try
  459. {
  460. BeginMessage(pszCommand);
  461. ssSend << a1;
  462. EndMessage();
  463. }
  464. catch (...)
  465. {
  466. AbortMessage();
  467. throw;
  468. }
  469. }
  470. template<typename T1, typename T2>
  471. void PushMessage(const char* pszCommand, const T1& a1, const T2& a2)
  472. {
  473. try
  474. {
  475. BeginMessage(pszCommand);
  476. ssSend << a1 << a2;
  477. EndMessage();
  478. }
  479. catch (...)
  480. {
  481. AbortMessage();
  482. throw;
  483. }
  484. }
  485. template<typename T1, typename T2, typename T3>
  486. void PushMessage(const char* pszCommand, const T1& a1, const T2& a2, const T3& a3)
  487. {
  488. try
  489. {
  490. BeginMessage(pszCommand);
  491. ssSend << a1 << a2 << a3;
  492. EndMessage();
  493. }
  494. catch (...)
  495. {
  496. AbortMessage();
  497. throw;
  498. }
  499. }
  500. template<typename T1, typename T2, typename T3, typename T4>
  501. void PushMessage(const char* pszCommand, const T1& a1, const T2& a2, const T3& a3, const T4& a4)
  502. {
  503. try
  504. {
  505. BeginMessage(pszCommand);
  506. ssSend << a1 << a2 << a3 << a4;
  507. EndMessage();
  508. }
  509. catch (...)
  510. {
  511. AbortMessage();
  512. throw;
  513. }
  514. }
  515. template<typename T1, typename T2, typename T3, typename T4, typename T5>
  516. void PushMessage(const char* pszCommand, const T1& a1, const T2& a2, const T3& a3, const T4& a4, const T5& a5)
  517. {
  518. try
  519. {
  520. BeginMessage(pszCommand);
  521. ssSend << a1 << a2 << a3 << a4 << a5;
  522. EndMessage();
  523. }
  524. catch (...)
  525. {
  526. AbortMessage();
  527. throw;
  528. }
  529. }
  530. template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6>
  531. void PushMessage(const char* pszCommand, const T1& a1, const T2& a2, const T3& a3, const T4& a4, const T5& a5, const T6& a6)
  532. {
  533. try
  534. {
  535. BeginMessage(pszCommand);
  536. ssSend << a1 << a2 << a3 << a4 << a5 << a6;
  537. EndMessage();
  538. }
  539. catch (...)
  540. {
  541. AbortMessage();
  542. throw;
  543. }
  544. }
  545. template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7>
  546. void PushMessage(const char* pszCommand, const T1& a1, const T2& a2, const T3& a3, const T4& a4, const T5& a5, const T6& a6, const T7& a7)
  547. {
  548. try
  549. {
  550. BeginMessage(pszCommand);
  551. ssSend << a1 << a2 << a3 << a4 << a5 << a6 << a7;
  552. EndMessage();
  553. }
  554. catch (...)
  555. {
  556. AbortMessage();
  557. throw;
  558. }
  559. }
  560. template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8>
  561. void PushMessage(const char* pszCommand, const T1& a1, const T2& a2, const T3& a3, const T4& a4, const T5& a5, const T6& a6, const T7& a7, const T8& a8)
  562. {
  563. try
  564. {
  565. BeginMessage(pszCommand);
  566. ssSend << a1 << a2 << a3 << a4 << a5 << a6 << a7 << a8;
  567. EndMessage();
  568. }
  569. catch (...)
  570. {
  571. AbortMessage();
  572. throw;
  573. }
  574. }
  575. template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9>
  576. void PushMessage(const char* pszCommand, const T1& a1, const T2& a2, const T3& a3, const T4& a4, const T5& a5, const T6& a6, const T7& a7, const T8& a8, const T9& a9)
  577. {
  578. try
  579. {
  580. BeginMessage(pszCommand);
  581. ssSend << a1 << a2 << a3 << a4 << a5 << a6 << a7 << a8 << a9;
  582. EndMessage();
  583. }
  584. catch (...)
  585. {
  586. AbortMessage();
  587. throw;
  588. }
  589. }
  590. bool IsSubscribed(unsigned int nChannel);
  591. void Subscribe(unsigned int nChannel, unsigned int nHops=0);
  592. void CancelSubscribe(unsigned int nChannel);
  593. void CloseSocketDisconnect();
  594. // Denial-of-service detection/prevention
  595. // The idea is to detect peers that are behaving
  596. // badly and disconnect/ban them, but do it in a
  597. // one-coding-mistake-won't-shatter-the-entire-network
  598. // way.
  599. // IMPORTANT: There should be nothing I can give a
  600. // node that it will forward on that will make that
  601. // node's peers drop it. If there is, an attacker
  602. // can isolate a node and/or try to split the network.
  603. // Dropping a node for sending stuff that is invalid
  604. // now but might be valid in a later version is also
  605. // dangerous, because it can cause a network split
  606. // between nodes running old code and nodes running
  607. // new code.
  608. static void ClearBanned(); // needed for unit testing
  609. static bool IsBanned(CNetAddr ip);
  610. static bool Ban(const CNetAddr &ip);
  611. void copyStats(CNodeStats &stats);
  612. // Network stats
  613. static void RecordBytesRecv(uint64_t bytes);
  614. static void RecordBytesSent(uint64_t bytes);
  615. static uint64_t GetTotalBytesRecv();
  616. static uint64_t GetTotalBytesSent();
  617. };
  618. class CTransaction;
  619. void RelayTransaction(const CTransaction& tx);
  620. void RelayTransaction(const CTransaction& tx, const CDataStream& ss);
  621. /** Access to the (IP) address database (peers.dat) */
  622. class CAddrDB
  623. {
  624. private:
  625. boost::filesystem::path pathAddr;
  626. public:
  627. CAddrDB();
  628. bool Write(const CAddrMan& addr);
  629. bool Read(CAddrMan& addr);
  630. };
  631. #endif