net.h 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656
  1. // ECOin - Copyright (c) - 2014/2022 - GPLv3 - epsylon@riseup.net (https://03c8.net)
  2. #ifndef ECOIN_NET_H
  3. #define ECOIN_NET_H
  4. #include <deque>
  5. #include <boost/array.hpp>
  6. #include <boost/foreach.hpp>
  7. #include <openssl/rand.h>
  8. #ifndef WIN32
  9. #include <arpa/inet.h>
  10. #endif
  11. #include "mruset.h"
  12. #include "netbase.h"
  13. #include "protocol.h"
  14. #include "addrman.h"
  15. class CRequestTracker;
  16. class CNode;
  17. class CBlockIndex;
  18. extern int nBestHeight;
  19. inline unsigned int ReceiveBufferSize() { return 1000*GetArg("-maxreceivebuffer", 5*1000); }
  20. inline unsigned int SendBufferSize() { return 1000*GetArg("-maxsendbuffer", 1*1000); }
  21. void AddOneShot(std::string strDest);
  22. bool RecvLine(SOCKET hSocket, std::string& strLine);
  23. bool GetMyExternalIP(CNetAddr& ipRet);
  24. void AddressCurrentlyConnected(const CService& addr);
  25. CNode* FindNode(const CNetAddr& ip);
  26. CNode* FindNode(const CService& ip);
  27. CNode* ConnectNode(CAddress addrConnect, const char *strDest = NULL, int64 nTimeout=0);
  28. void MapPort();
  29. unsigned short GetListenPort();
  30. bool BindListenPort(const CService &bindAddr, std::string& strError=REF(std::string()));
  31. void StartNode(void* parg);
  32. bool StopNode();
  33. enum
  34. {
  35. LOCAL_NONE, // unknown
  36. LOCAL_IF, // address a local interface listens on
  37. LOCAL_BIND, // address explicit bound to
  38. LOCAL_UPNP, // address reported by UPnP
  39. LOCAL_IRC, // address reported by IRC (deprecated)
  40. LOCAL_HTTP, // address reported by whatismyip.com and similar
  41. LOCAL_MANUAL, // address explicitly specified (-externalip=)
  42. LOCAL_MAX
  43. };
  44. void SetLimited(enum Network net, bool fLimited = true);
  45. bool IsLimited(enum Network net);
  46. bool IsLimited(const CNetAddr& addr);
  47. bool AddLocal(const CService& addr, int nScore = LOCAL_NONE);
  48. bool AddLocal(const CNetAddr& addr, int nScore = LOCAL_NONE);
  49. bool SeenLocal(const CService& addr);
  50. bool IsLocal(const CService& addr);
  51. bool GetLocal(CService &addr, const CNetAddr *paddrPeer = NULL);
  52. bool IsReachable(const CNetAddr &addr);
  53. void SetReachable(enum Network net, bool fFlag = true);
  54. CAddress GetLocalAddress(const CNetAddr *paddrPeer = NULL);
  55. enum
  56. {
  57. MSG_TX = 1,
  58. MSG_BLOCK,
  59. };
  60. class CRequestTracker
  61. {
  62. public:
  63. void (*fn)(void*, CDataStream&);
  64. void* param1;
  65. explicit CRequestTracker(void (*fnIn)(void*, CDataStream&)=NULL, void* param1In=NULL)
  66. {
  67. fn = fnIn;
  68. param1 = param1In;
  69. }
  70. bool IsNull()
  71. {
  72. return fn == NULL;
  73. }
  74. };
  75. /** Thread types */
  76. enum threadId
  77. {
  78. THREAD_SOCKETHANDLER,
  79. THREAD_OPENCONNECTIONS,
  80. THREAD_MESSAGEHANDLER,
  81. THREAD_RPCLISTENER,
  82. THREAD_UPNP,
  83. THREAD_DNSSEED,
  84. THREAD_ADDEDCONNECTIONS,
  85. THREAD_DUMPADDRESS,
  86. THREAD_RPCHANDLER,
  87. THREAD_MINTER,
  88. THREAD_MAX
  89. };
  90. extern bool fClient;
  91. extern bool fDiscover;
  92. extern bool fUseUPnP;
  93. extern uint64 nLocalServices;
  94. extern uint64 nLocalHostNonce;
  95. extern CAddress addrSeenByPeer;
  96. extern boost::array<int, THREAD_MAX> vnThreadsRunning;
  97. extern CAddrMan addrman;
  98. extern std::vector<CNode*> vNodes;
  99. extern CCriticalSection cs_vNodes;
  100. extern std::map<CInv, CDataStream> mapRelay;
  101. extern std::deque<std::pair<int64, CInv> > vRelayExpiration;
  102. extern CCriticalSection cs_mapRelay;
  103. extern std::map<CInv, int64> mapAlreadyAskedFor;
  104. class CNodeStats
  105. {
  106. public:
  107. uint64 nServices;
  108. int64 nLastSend;
  109. int64 nLastRecv;
  110. int64 nTimeConnected;
  111. std::string addrName;
  112. int nVersion;
  113. std::string strSubVer;
  114. bool fInbound;
  115. int64 nReleaseTime;
  116. int nStartingHeight;
  117. int nMisbehavior;
  118. };
  119. /** Information about a peer */
  120. class CNode
  121. {
  122. public:
  123. // socket
  124. uint64 nServices;
  125. SOCKET hSocket;
  126. CDataStream vSend;
  127. CDataStream vRecv;
  128. CCriticalSection cs_vSend;
  129. CCriticalSection cs_vRecv;
  130. int64 nLastSend;
  131. int64 nLastRecv;
  132. int64 nLastSendEmpty;
  133. int64 nTimeConnected;
  134. int nHeaderStart;
  135. unsigned int nMessageStart;
  136. CAddress addr;
  137. std::string addrName;
  138. CService addrLocal;
  139. int nVersion;
  140. std::string strSubVer;
  141. bool fOneShot;
  142. bool fClient;
  143. bool fInbound;
  144. bool fNetworkNode;
  145. bool fSuccessfullyConnected;
  146. bool fDisconnect;
  147. CSemaphoreGrant grantOutbound;
  148. protected:
  149. int nRefCount;
  150. // Denial-of-service detection/prevention
  151. // Key is IP address, value is banned-until-time
  152. static std::map<CNetAddr, int64> setBanned;
  153. static CCriticalSection cs_setBanned;
  154. int nMisbehavior;
  155. public:
  156. int64 nReleaseTime;
  157. std::map<uint256, CRequestTracker> mapRequests;
  158. CCriticalSection cs_mapRequests;
  159. uint256 hashContinue;
  160. CBlockIndex* pindexLastGetBlocksBegin;
  161. uint256 hashLastGetBlocksEnd;
  162. int nStartingHeight;
  163. // flood relay
  164. std::vector<CAddress> vAddrToSend;
  165. std::set<CAddress> setAddrKnown;
  166. bool fGetAddr;
  167. std::set<uint256> setKnown;
  168. uint256 hashCheckpointKnown; // ecoin: known sent sync-checkpoint
  169. // inventory based relay
  170. mruset<CInv> setInventoryKnown;
  171. std::vector<CInv> vInventoryToSend;
  172. CCriticalSection cs_inventory;
  173. std::multimap<int64, CInv> mapAskFor;
  174. CNode(SOCKET hSocketIn, CAddress addrIn, std::string addrNameIn = "", bool fInboundIn=false) : vSend(SER_NETWORK, MIN_PROTO_VERSION), vRecv(SER_NETWORK, MIN_PROTO_VERSION)
  175. {
  176. nServices = 0;
  177. hSocket = hSocketIn;
  178. nLastSend = 0;
  179. nLastRecv = 0;
  180. nLastSendEmpty = GetTime();
  181. nTimeConnected = GetTime();
  182. nHeaderStart = -1;
  183. nMessageStart = -1;
  184. addr = addrIn;
  185. addrName = addrNameIn == "" ? addr.ToStringIPPort() : addrNameIn;
  186. nVersion = 0;
  187. strSubVer = "";
  188. fOneShot = false;
  189. fClient = false; // set by version message
  190. fInbound = fInboundIn;
  191. fNetworkNode = false;
  192. fSuccessfullyConnected = false;
  193. fDisconnect = false;
  194. nRefCount = 0;
  195. nReleaseTime = 0;
  196. hashContinue = 0;
  197. pindexLastGetBlocksBegin = 0;
  198. hashLastGetBlocksEnd = 0;
  199. nStartingHeight = -1;
  200. fGetAddr = false;
  201. nMisbehavior = 0;
  202. hashCheckpointKnown = 0;
  203. setInventoryKnown.max_size(SendBufferSize() / 1000);
  204. // Be shy and don't send version until we hear
  205. if (hSocket != INVALID_SOCKET && !fInbound)
  206. PushVersion();
  207. }
  208. ~CNode()
  209. {
  210. if (hSocket != INVALID_SOCKET)
  211. {
  212. closesocket(hSocket);
  213. hSocket = INVALID_SOCKET;
  214. }
  215. }
  216. private:
  217. CNode(const CNode&);
  218. void operator=(const CNode&);
  219. public:
  220. int GetRefCount()
  221. {
  222. return std::max(nRefCount, 0) + (GetTime() < nReleaseTime ? 1 : 0);
  223. }
  224. CNode* AddRef(int64 nTimeout=0)
  225. {
  226. if (nTimeout != 0)
  227. nReleaseTime = std::max(nReleaseTime, GetTime() + nTimeout);
  228. else
  229. nRefCount++;
  230. return this;
  231. }
  232. void Release()
  233. {
  234. nRefCount--;
  235. }
  236. void AddAddressKnown(const CAddress& addr)
  237. {
  238. setAddrKnown.insert(addr);
  239. }
  240. void PushAddress(const CAddress& addr)
  241. {
  242. // Known checking here is only to save space from duplicates.
  243. // SendMessages will filter it again for knowns that were added
  244. // after addresses were pushed.
  245. if (addr.IsValid() && !setAddrKnown.count(addr))
  246. vAddrToSend.push_back(addr);
  247. }
  248. void AddInventoryKnown(const CInv& inv)
  249. {
  250. {
  251. LOCK(cs_inventory);
  252. setInventoryKnown.insert(inv);
  253. }
  254. }
  255. void PushInventory(const CInv& inv)
  256. {
  257. {
  258. LOCK(cs_inventory);
  259. if (!setInventoryKnown.count(inv))
  260. vInventoryToSend.push_back(inv);
  261. }
  262. }
  263. void AskFor(const CInv& inv)
  264. {
  265. // We're using mapAskFor as a priority queue,
  266. // the key is the earliest time the request can be sent
  267. int64& nRequestTime = mapAlreadyAskedFor[inv];
  268. if (fDebugNet)
  269. printf("askfor %s %" PRI64d" (%s)\n", inv.ToString().c_str(), nRequestTime, DateTimeStrFormat("%H:%M:%S", nRequestTime/1000000).c_str());
  270. // Make sure not to reuse time indexes to keep things in the same order
  271. int64 nNow = (GetTime() - 1) * 1000000;
  272. static int64 nLastTime;
  273. ++nLastTime;
  274. nNow = std::max(nNow, nLastTime);
  275. nLastTime = nNow;
  276. // Each retry is 2 minutes after the last
  277. nRequestTime = std::max(nRequestTime + 2 * 60 * 1000000, nNow);
  278. mapAskFor.insert(std::make_pair(nRequestTime, inv));
  279. }
  280. void BeginMessage(const char* pszCommand)
  281. {
  282. ENTER_CRITICAL_SECTION(cs_vSend);
  283. if (nHeaderStart != -1)
  284. AbortMessage();
  285. nHeaderStart = vSend.size();
  286. vSend << CMessageHeader(pszCommand, 0);
  287. nMessageStart = vSend.size();
  288. if (fDebug)
  289. printf("sending: %s ", pszCommand);
  290. }
  291. void AbortMessage()
  292. {
  293. if (nHeaderStart < 0)
  294. return;
  295. vSend.resize(nHeaderStart);
  296. nHeaderStart = -1;
  297. nMessageStart = -1;
  298. LEAVE_CRITICAL_SECTION(cs_vSend);
  299. if (fDebug)
  300. printf("(aborted)\n");
  301. }
  302. void EndMessage()
  303. {
  304. if (mapArgs.count("-dropmessagestest") && GetRand(atoi(mapArgs["-dropmessagestest"])) == 0)
  305. {
  306. printf("dropmessages DROPPING SEND MESSAGE\n");
  307. AbortMessage();
  308. return;
  309. }
  310. if (nHeaderStart < 0)
  311. return;
  312. // Set the size
  313. unsigned int nSize = vSend.size() - nMessageStart;
  314. memcpy((char*)&vSend[nHeaderStart] + CMessageHeader::MESSAGE_SIZE_OFFSET, &nSize, sizeof(nSize));
  315. // Set the checksum
  316. uint256 hash = Hash(vSend.begin() + nMessageStart, vSend.end());
  317. unsigned int nChecksum = 0;
  318. memcpy(&nChecksum, &hash, sizeof(nChecksum));
  319. assert(nMessageStart - nHeaderStart >= CMessageHeader::CHECKSUM_OFFSET + sizeof(nChecksum));
  320. memcpy((char*)&vSend[nHeaderStart] + CMessageHeader::CHECKSUM_OFFSET, &nChecksum, sizeof(nChecksum));
  321. if (fDebug) {
  322. printf("(%d bytes)\n", nSize);
  323. }
  324. nHeaderStart = -1;
  325. nMessageStart = -1;
  326. LEAVE_CRITICAL_SECTION(cs_vSend);
  327. }
  328. void EndMessageAbortIfEmpty()
  329. {
  330. if (nHeaderStart < 0)
  331. return;
  332. int nSize = vSend.size() - nMessageStart;
  333. if (nSize > 0)
  334. EndMessage();
  335. else
  336. AbortMessage();
  337. }
  338. void PushVersion();
  339. void PushMessage(const char* pszCommand)
  340. {
  341. try
  342. {
  343. BeginMessage(pszCommand);
  344. EndMessage();
  345. }
  346. catch (...)
  347. {
  348. AbortMessage();
  349. throw;
  350. }
  351. }
  352. template<typename T1>
  353. void PushMessage(const char* pszCommand, const T1& a1)
  354. {
  355. try
  356. {
  357. BeginMessage(pszCommand);
  358. vSend << a1;
  359. EndMessage();
  360. }
  361. catch (...)
  362. {
  363. AbortMessage();
  364. throw;
  365. }
  366. }
  367. template<typename T1, typename T2>
  368. void PushMessage(const char* pszCommand, const T1& a1, const T2& a2)
  369. {
  370. try
  371. {
  372. BeginMessage(pszCommand);
  373. vSend << a1 << a2;
  374. EndMessage();
  375. }
  376. catch (...)
  377. {
  378. AbortMessage();
  379. throw;
  380. }
  381. }
  382. template<typename T1, typename T2, typename T3>
  383. void PushMessage(const char* pszCommand, const T1& a1, const T2& a2, const T3& a3)
  384. {
  385. try
  386. {
  387. BeginMessage(pszCommand);
  388. vSend << a1 << a2 << a3;
  389. EndMessage();
  390. }
  391. catch (...)
  392. {
  393. AbortMessage();
  394. throw;
  395. }
  396. }
  397. template<typename T1, typename T2, typename T3, typename T4>
  398. void PushMessage(const char* pszCommand, const T1& a1, const T2& a2, const T3& a3, const T4& a4)
  399. {
  400. try
  401. {
  402. BeginMessage(pszCommand);
  403. vSend << a1 << a2 << a3 << a4;
  404. EndMessage();
  405. }
  406. catch (...)
  407. {
  408. AbortMessage();
  409. throw;
  410. }
  411. }
  412. template<typename T1, typename T2, typename T3, typename T4, typename T5>
  413. void PushMessage(const char* pszCommand, const T1& a1, const T2& a2, const T3& a3, const T4& a4, const T5& a5)
  414. {
  415. try
  416. {
  417. BeginMessage(pszCommand);
  418. vSend << a1 << a2 << a3 << a4 << a5;
  419. EndMessage();
  420. }
  421. catch (...)
  422. {
  423. AbortMessage();
  424. throw;
  425. }
  426. }
  427. template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6>
  428. void PushMessage(const char* pszCommand, const T1& a1, const T2& a2, const T3& a3, const T4& a4, const T5& a5, const T6& a6)
  429. {
  430. try
  431. {
  432. BeginMessage(pszCommand);
  433. vSend << a1 << a2 << a3 << a4 << a5 << a6;
  434. EndMessage();
  435. }
  436. catch (...)
  437. {
  438. AbortMessage();
  439. throw;
  440. }
  441. }
  442. template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7>
  443. 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)
  444. {
  445. try
  446. {
  447. BeginMessage(pszCommand);
  448. vSend << a1 << a2 << a3 << a4 << a5 << a6 << a7;
  449. EndMessage();
  450. }
  451. catch (...)
  452. {
  453. AbortMessage();
  454. throw;
  455. }
  456. }
  457. template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8>
  458. 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)
  459. {
  460. try
  461. {
  462. BeginMessage(pszCommand);
  463. vSend << a1 << a2 << a3 << a4 << a5 << a6 << a7 << a8;
  464. EndMessage();
  465. }
  466. catch (...)
  467. {
  468. AbortMessage();
  469. throw;
  470. }
  471. }
  472. template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9>
  473. 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)
  474. {
  475. try
  476. {
  477. BeginMessage(pszCommand);
  478. vSend << a1 << a2 << a3 << a4 << a5 << a6 << a7 << a8 << a9;
  479. EndMessage();
  480. }
  481. catch (...)
  482. {
  483. AbortMessage();
  484. throw;
  485. }
  486. }
  487. void PushRequest(const char* pszCommand,
  488. void (*fn)(void*, CDataStream&), void* param1)
  489. {
  490. uint256 hashReply;
  491. RAND_bytes((unsigned char*)&hashReply, sizeof(hashReply));
  492. {
  493. LOCK(cs_mapRequests);
  494. mapRequests[hashReply] = CRequestTracker(fn, param1);
  495. }
  496. PushMessage(pszCommand, hashReply);
  497. }
  498. template<typename T1>
  499. void PushRequest(const char* pszCommand, const T1& a1,
  500. void (*fn)(void*, CDataStream&), void* param1)
  501. {
  502. uint256 hashReply;
  503. RAND_bytes((unsigned char*)&hashReply, sizeof(hashReply));
  504. {
  505. LOCK(cs_mapRequests);
  506. mapRequests[hashReply] = CRequestTracker(fn, param1);
  507. }
  508. PushMessage(pszCommand, hashReply, a1);
  509. }
  510. template<typename T1, typename T2>
  511. void PushRequest(const char* pszCommand, const T1& a1, const T2& a2,
  512. void (*fn)(void*, CDataStream&), void* param1)
  513. {
  514. uint256 hashReply;
  515. RAND_bytes((unsigned char*)&hashReply, sizeof(hashReply));
  516. {
  517. LOCK(cs_mapRequests);
  518. mapRequests[hashReply] = CRequestTracker(fn, param1);
  519. }
  520. PushMessage(pszCommand, hashReply, a1, a2);
  521. }
  522. void PushGetBlocks(CBlockIndex* pindexBegin, uint256 hashEnd);
  523. bool IsSubscribed(unsigned int nChannel);
  524. void Subscribe(unsigned int nChannel, unsigned int nHops=0);
  525. void CancelSubscribe(unsigned int nChannel);
  526. void CloseSocketDisconnect();
  527. void Cleanup();
  528. // Denial-of-service detection/prevention
  529. // The idea is to detect peers that are behaving
  530. // badly and disconnect/ban them, but do it in a
  531. // one-coding-mistake-won't-shatter-the-entire-network
  532. // way.
  533. // IMPORTANT: There should be nothing I can give a
  534. // node that it will forward on that will make that
  535. // node's peers drop it. If there is, an attacker
  536. // can isolate a node and/or try to split the network.
  537. // Dropping a node for sending stuff that is invalid
  538. // now but might be valid in a later version is also
  539. // dangerous, because it can cause a network split
  540. // between nodes running old code and nodes running
  541. // new code.
  542. static void ClearBanned(); // needed for unit testing
  543. static bool IsBanned(CNetAddr ip);
  544. bool Misbehaving(int howmuch); // 1 == a little, 100 == a lot
  545. void copyStats(CNodeStats &stats);
  546. };
  547. inline void RelayInventory(const CInv& inv)
  548. {
  549. // Put on lists to offer to the other nodes
  550. {
  551. LOCK(cs_vNodes);
  552. BOOST_FOREACH(CNode* pnode, vNodes)
  553. pnode->PushInventory(inv);
  554. }
  555. }
  556. class CTransaction;
  557. void RelayTransaction(const CTransaction& tx, const uint256& hash);
  558. void RelayTransaction(const CTransaction& tx, const uint256& hash, const CDataStream& ss);
  559. #endif