1 // Copyright (c) 2009-2010 Satoshi Nakamoto
2 // Copyright (c) 2009-2012 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.
12 #include <openssl/rand.h>
21 class CRequestTracker;
24 extern int nBestHeight;
26 const uint16_t nSocksDefault = 9050;
27 const uint16_t nPortZero = 0;
30 inline uint64_t ReceiveBufferSize() { return 1000*GetArg("-maxreceivebuffer", 5*1000); }
31 inline uint64_t SendBufferSize() { return 1000*GetArg("-maxsendbuffer", 1*1000); }
33 void AddOneShot(string strDest);
34 bool RecvLine(SOCKET hSocket, string& strLine);
35 bool GetMyExternalIP(CNetAddr& ipRet);
36 void AddressCurrentlyConnected(const CService& addr);
37 CNode* FindNode(const CNetAddr& ip);
38 CNode* FindNode(const CService& ip);
39 CNode* ConnectNode(CAddress addrConnect, const char *strDest = NULL, int64_t nTimeout=0);
40 bool OpenNetworkConnection(const CAddress& addrConnect, CSemaphoreGrant *grantOutbound = NULL, const char *strDest = NULL, bool fOneShot = false);
42 uint16_t GetListenPort();
43 bool BindListenPort(const CService &bindAddr, string& strError=REF(string()));
44 void StartNode(void* parg);
49 LOCAL_NONE, // unknown
50 LOCAL_IF, // address a local interface listens on
51 LOCAL_BIND, // address explicit bound to
52 LOCAL_IRC, // address reported by IRC (deprecated)
53 LOCAL_HTTP, // address reported by whatismyip.com and similar
54 LOCAL_MANUAL, // address explicitly specified (-externalip=)
60 bool IsPeerAddrLocalGood(CNode *pnode);
61 void AdvertiseLocal(CNode *pnode);
62 void SetLimited(enum Network net, bool fLimited = true);
63 bool IsLimited(enum Network net);
64 bool IsLimited(const CNetAddr& addr);
65 bool AddLocal(const CService& addr, int nScore = LOCAL_NONE);
66 bool AddLocal(const CNetAddr& addr, int nScore = LOCAL_NONE);
67 bool SeenLocal(const CService& addr);
68 bool IsLocal(const CService& addr);
69 bool GetLocal(CService &addr, const CNetAddr *paddrPeer = NULL);
70 bool IsReachable(const CNetAddr &addr);
71 void SetReachable(enum Network net, bool fFlag = true);
72 CAddress GetLocalAddress(const CNetAddr *paddrPeer = NULL);
84 void (*fn)(void*, CDataStream&);
87 explicit CRequestTracker(void (*fnIn)(void*, CDataStream&)=NULL, void* param1In=NULL)
103 THREAD_SOCKETHANDLER,
104 THREAD_OPENCONNECTIONS,
105 THREAD_MESSAGEHANDLER,
108 THREAD_ADDEDCONNECTIONS,
120 extern bool fDiscover;
121 extern bool fNoListen;
123 extern bool fDiscover;
124 extern uint64_t nLocalServices;
125 extern uint64_t nLocalHostNonce;
126 extern CAddress addrSeenByPeer;
127 extern array<int, THREAD_MAX> vnThreadsRunning;
128 extern CAddrMan addrman;
130 extern vector<CNode*> vNodes;
131 extern CCriticalSection cs_vNodes;
132 extern vector<string> vAddedNodes;
133 extern CCriticalSection cs_vAddedNodes;
134 extern map<CInv, CDataStream> mapRelay;
135 extern deque<pair<int64_t, CInv> > vRelayExpiration;
136 extern CCriticalSection cs_mapRelay;
137 extern map<CInv, int64_t> mapAlreadyAskedFor;
148 int64_t nTimeConnected;
153 int64_t nReleaseTime;
154 int32_t nStartingHeight;
155 int32_t nMisbehavior;
165 /** Information about a peer */
176 CCriticalSection cs_vSend;
177 CCriticalSection cs_vRecv;
180 int64_t nLastSendEmpty;
181 int64_t nTimeConnected;
182 int32_t nHeaderStart;
183 uint32_t nMessageStart;
193 bool fSuccessfullyConnected;
195 CSemaphoreGrant grantOutbound;
199 // Denial-of-service detection/prevention
200 // Key is IP address, value is banned-until-time
201 static map<CNetAddr, int64_t> setBanned;
202 static CCriticalSection cs_setBanned;
206 int64_t nReleaseTime;
207 map<uint256, CRequestTracker> mapRequests;
208 CCriticalSection cs_mapRequests;
209 uint256 hashContinue;
210 CBlockIndex* pindexLastGetBlocksBegin;
211 uint256 hashLastGetBlocksEnd;
212 int32_t nStartingHeight;
216 vector<CAddress> vAddrToSend;
217 set<CAddress> setAddrKnown;
219 set<uint256> setKnown;
220 uint256 hashCheckpointKnown; // ppcoin: known sent sync-checkpoint
221 int64_t nNextAddrSend;
222 int64_t nNextLocalAddrSend;
223 int64_t nNextInvSend;
225 // inventory based relay
226 mruset<CInv> setInventoryKnown;
227 vector<CInv> vInventoryToSend;
228 CCriticalSection cs_inventory;
229 multimap<int64_t, CInv> mapAskFor;
231 CNode(SOCKET hSocketIn, CAddress addrIn, string addrNameIn = "", bool fInboundIn=false) : vSend(SER_NETWORK, MIN_PROTO_VERSION), vRecv(SER_NETWORK, MIN_PROTO_VERSION)
239 nLastSendEmpty = GetTime();
240 nTimeConnected = GetTime();
242 nMessageStart = numeric_limits<uint32_t>::max();
244 addrName = addrNameIn.empty() ? addr.ToStringIPPort() : addrNameIn;
248 fClient = false; // set by version message
249 fInbound = fInboundIn;
250 fNetworkNode = false;
251 fSuccessfullyConnected = false;
256 pindexLastGetBlocksBegin = 0;
257 hashLastGetBlocksEnd = 0;
258 nStartingHeight = -1;
259 nNextLocalAddrSend = 0;
265 hashCheckpointKnown = 0;
266 setInventoryKnown.max_size((size_t)SendBufferSize() / 1000);
268 // Be shy and don't send version until we hear
269 if (hSocket != INVALID_SOCKET && !fInbound)
275 if (hSocket != INVALID_SOCKET)
277 CloseSocket(hSocket);
283 // Network usage totals
284 static CCriticalSection cs_totalBytesRecv;
285 static CCriticalSection cs_totalBytesSent;
286 static uint64_t nTotalBytesRecv;
287 static uint64_t nTotalBytesSent;
289 void operator=(const CNode&);
295 return max(nRefCount, 0) + (GetTime() < nReleaseTime ? 1 : 0);
298 CNode* AddRef(int64_t nTimeout=0)
301 nReleaseTime = max(nReleaseTime, GetTime() + nTimeout);
314 void AddAddressKnown(const CAddress& addr)
316 setAddrKnown.insert(addr);
319 void PushAddress(const CAddress& addr)
321 // Known checking here is only to save space from duplicates.
322 // SendMessages will filter it again for knowns that were added
323 // after addresses were pushed.
324 if (addr.IsValid() && !setAddrKnown.count(addr))
325 vAddrToSend.push_back(addr);
329 void AddInventoryKnown(const CInv& inv)
333 setInventoryKnown.insert(inv);
337 void PushInventory(const CInv& inv)
341 if (!setInventoryKnown.count(inv))
342 vInventoryToSend.push_back(inv);
346 void AskFor(const CInv& inv)
348 // We're using mapAskFor as a priority queue,
349 // the key is the earliest time the request can be sent
350 int64_t& nRequestTime = mapAlreadyAskedFor[inv];
352 printf("askfor %s %" PRId64 " (%s)\n", inv.ToString().c_str(), nRequestTime, DateTimeStrFormat("%H:%M:%S", nRequestTime/1000000).c_str());
354 // Make sure not to reuse time indexes to keep things in the same order
355 int64_t nNow = (GetTime() - 1) * 1000000;
356 static int64_t nLastTime;
358 nNow = max(nNow, nLastTime);
361 // Each retry is 2 minutes after the last
362 nRequestTime = max(nRequestTime + 2 * 60 * 1000000, nNow);
363 mapAskFor.insert({ nRequestTime, inv });
368 void BeginMessage(const char* pszCommand)
370 ENTER_CRITICAL_SECTION(cs_vSend);
371 if (nHeaderStart != -1)
373 nHeaderStart = (int32_t)vSend.size();
374 vSend << CMessageHeader(pszCommand, 0);
375 nMessageStart = (uint32_t)vSend.size();
377 printf("sending: %s ", pszCommand);
382 if (nHeaderStart < 0)
384 vSend.resize(nHeaderStart);
386 nMessageStart = numeric_limits<uint32_t>::max();
387 LEAVE_CRITICAL_SECTION(cs_vSend);
390 printf("(aborted)\n");
395 if (mapArgs.count("-dropmessagestest") && GetRand(atoi(mapArgs["-dropmessagestest"])) == 0)
397 printf("dropmessages DROPPING SEND MESSAGE\n");
402 if (nHeaderStart < 0)
406 uint32_t nSize = (uint32_t) vSend.size() - nMessageStart;
407 memcpy((char*)&vSend[nHeaderStart] + CMessageHeader::MESSAGE_SIZE_OFFSET, &nSize, sizeof(nSize));
410 auto hash = Hash(vSend.begin() + nMessageStart, vSend.end());
411 uint32_t nChecksum = 0;
412 memcpy(&nChecksum, &hash, sizeof(nChecksum));
413 assert(nMessageStart - nHeaderStart >= CMessageHeader::CHECKSUM_OFFSET + sizeof(nChecksum));
414 memcpy((char*)&vSend[nHeaderStart] + CMessageHeader::CHECKSUM_OFFSET, &nChecksum, sizeof(nChecksum));
417 printf("(%d bytes)\n", nSize);
421 nMessageStart = numeric_limits<uint32_t>::max();
422 LEAVE_CRITICAL_SECTION(cs_vSend);
425 void EndMessageAbortIfEmpty()
427 if (nHeaderStart < 0)
429 int nSize = (int) vSend.size() - nMessageStart;
441 void PushMessage(const char* pszCommand)
445 BeginMessage(pszCommand);
455 template<typename T1>
456 void PushMessage(const char* pszCommand, const T1& a1)
460 BeginMessage(pszCommand);
471 template<typename T1, typename T2>
472 void PushMessage(const char* pszCommand, const T1& a1, const T2& a2)
476 BeginMessage(pszCommand);
487 template<typename T1, typename T2, typename T3>
488 void PushMessage(const char* pszCommand, const T1& a1, const T2& a2, const T3& a3)
492 BeginMessage(pszCommand);
493 vSend << a1 << a2 << a3;
503 template<typename T1, typename T2, typename T3, typename T4>
504 void PushMessage(const char* pszCommand, const T1& a1, const T2& a2, const T3& a3, const T4& a4)
508 BeginMessage(pszCommand);
509 vSend << a1 << a2 << a3 << a4;
519 template<typename T1, typename T2, typename T3, typename T4, typename T5>
520 void PushMessage(const char* pszCommand, const T1& a1, const T2& a2, const T3& a3, const T4& a4, const T5& a5)
524 BeginMessage(pszCommand);
525 vSend << a1 << a2 << a3 << a4 << a5;
535 template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6>
536 void PushMessage(const char* pszCommand, const T1& a1, const T2& a2, const T3& a3, const T4& a4, const T5& a5, const T6& a6)
540 BeginMessage(pszCommand);
541 vSend << a1 << a2 << a3 << a4 << a5 << a6;
551 template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7>
552 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)
556 BeginMessage(pszCommand);
557 vSend << a1 << a2 << a3 << a4 << a5 << a6 << a7;
567 template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8>
568 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)
572 BeginMessage(pszCommand);
573 vSend << a1 << a2 << a3 << a4 << a5 << a6 << a7 << a8;
583 template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9>
584 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)
588 BeginMessage(pszCommand);
589 vSend << a1 << a2 << a3 << a4 << a5 << a6 << a7 << a8 << a9;
600 void PushRequest(const char* pszCommand,
601 void (*fn)(void*, CDataStream&), void* param1)
604 RAND_bytes((unsigned char*)&hashReply, sizeof(hashReply));
607 LOCK(cs_mapRequests);
608 mapRequests[hashReply] = CRequestTracker(fn, param1);
611 PushMessage(pszCommand, hashReply);
614 template<typename T1>
615 void PushRequest(const char* pszCommand, const T1& a1,
616 void (*fn)(void*, CDataStream&), void* param1)
619 RAND_bytes((unsigned char*)&hashReply, sizeof(hashReply));
622 LOCK(cs_mapRequests);
623 mapRequests[hashReply] = CRequestTracker(fn, param1);
626 PushMessage(pszCommand, hashReply, a1);
629 template<typename T1, typename T2>
630 void PushRequest(const char* pszCommand, const T1& a1, const T2& a2,
631 void (*fn)(void*, CDataStream&), void* param1)
634 RAND_bytes((unsigned char*)&hashReply, sizeof(hashReply));
637 LOCK(cs_mapRequests);
638 mapRequests[hashReply] = CRequestTracker(fn, param1);
641 PushMessage(pszCommand, hashReply, a1, a2);
646 void PushGetBlocks(CBlockIndex* pindexBegin, uint256 hashEnd);
647 bool IsSubscribed(unsigned int nChannel);
648 void Subscribe(unsigned int nChannel, unsigned int nHops=0);
649 void CancelSubscribe(unsigned int nChannel);
650 void CloseSocketDisconnect();
654 // Denial-of-service detection/prevention
655 // The idea is to detect peers that are behaving
656 // badly and disconnect/ban them, but do it in a
657 // one-coding-mistake-won't-shatter-the-entire-network
659 // IMPORTANT: There should be nothing I can give a
660 // node that it will forward on that will make that
661 // node's peers drop it. If there is, an attacker
662 // can isolate a node and/or try to split the network.
663 // Dropping a node for sending stuff that is invalid
664 // now but might be valid in a later version is also
665 // dangerous, because it can cause a network split
666 // between nodes running old code and nodes running
668 static void ClearBanned(); // needed for unit testing
669 static bool IsBanned(CNetAddr ip);
670 bool Misbehaving(int howmuch); // 1 == a little, 100 == a lot
671 void copyStats(CNodeStats &stats);
673 static void RecordBytesRecv(uint64_t bytes);
674 static void RecordBytesSent(uint64_t bytes);
676 static uint64_t GetTotalBytesRecv();
677 static uint64_t GetTotalBytesSent();
680 inline void RelayInventory(const CInv& inv)
682 // Put on lists to offer to the other nodes
685 for(CNode* pnode : vNodes)
686 pnode->PushInventory(inv);
691 void RelayTransaction(const CTransaction& tx, const uint256& hash);
692 void RelayTransaction(const CTransaction& tx, const uint256& hash, const CDataStream& ss);
695 /** Return a timestamp in the future (in microseconds) for exponentially distributed events. */
696 int64_t PoissonNextSend(int64_t nNow, int average_interval_seconds);