2e5ac228dee80213fe8f4da59cd2352b9e005259
[novacoin.git] / src / net.h
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.
5 #ifndef BITCOIN_NET_H
6 #define BITCOIN_NET_H
7
8 #include <limits>
9 #include <deque>
10 #ifndef Q_MOC_RUN
11 #endif
12 #include <openssl/rand.h>
13
14 #include "mruset.h"
15 #include "netbase.h"
16 #include "addrman.h"
17 #include "hash.h"
18
19 using namespace std;
20
21 class CRequestTracker;
22 class CNode;
23 class CBlockIndex;
24 extern int nBestHeight;
25
26 const uint16_t nSocksDefault = 9050;
27 const uint16_t nPortZero = 0;
28
29
30 inline uint64_t ReceiveBufferSize() { return 1000*GetArg("-maxreceivebuffer", 5*1000); }
31 inline uint64_t SendBufferSize() { return 1000*GetArg("-maxsendbuffer", 1*1000); }
32
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);
41 void MapPort();
42 uint16_t GetListenPort();
43 bool BindListenPort(const CService &bindAddr, string& strError=REF(string()));
44 void StartNode(void* parg);
45 bool StopNode();
46
47 enum
48 {
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=)
55
56     LOCAL_MAX
57 };
58
59
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);
73
74
75 enum
76 {
77     MSG_TX = 1,
78     MSG_BLOCK
79 };
80
81 class CRequestTracker
82 {
83 public:
84     void (*fn)(void*, CDataStream&);
85     void* param1;
86
87     explicit CRequestTracker(void (*fnIn)(void*, CDataStream&)=NULL, void* param1In=NULL)
88     {
89         fn = fnIn;
90         param1 = param1In;
91     }
92
93     bool IsNull()
94     {
95         return fn == NULL;
96     }
97 };
98
99
100 /** Thread types */
101 enum threadId
102 {
103     THREAD_SOCKETHANDLER,
104     THREAD_OPENCONNECTIONS,
105     THREAD_MESSAGEHANDLER,
106     THREAD_RPCLISTENER,
107     THREAD_DNSSEED,
108     THREAD_ADDEDCONNECTIONS,
109     THREAD_DUMPADDRESS,
110     THREAD_RPCHANDLER,
111     THREAD_MINTER,
112     THREAD_SCRIPTCHECK,
113     THREAD_NTP,
114     THREAD_IPCOLLECTOR,
115
116     THREAD_MAX
117 };
118
119 extern bool fClient;
120 extern bool fDiscover;
121 extern bool fNoListen;
122
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;
129
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;
138
139
140
141
142 class CNodeStats
143 {
144 public:
145     uint64_t nServices;
146     int64_t nLastSend;
147     int64_t nLastRecv;
148     int64_t nTimeConnected;
149     string addrName;
150     int32_t nVersion;
151     string strSubVer;
152     bool fInbound;
153     int64_t nReleaseTime;
154     int32_t nStartingHeight;
155     int32_t nMisbehavior;
156     uint64_t nSendBytes;
157     uint64_t nRecvBytes;
158     bool fSyncNode;
159 };
160
161
162
163
164
165 /** Information about a peer */
166 class CNode
167 {
168 public:
169     // socket
170     uint64_t nServices;
171     SOCKET hSocket;
172     CDataStream vSend;
173     CDataStream vRecv;
174     uint64_t nSendBytes;
175     uint64_t nRecvBytes;
176     CCriticalSection cs_vSend;
177     CCriticalSection cs_vRecv;
178     int64_t nLastSend;
179     int64_t nLastRecv;
180     int64_t nLastSendEmpty;
181     int64_t nTimeConnected;
182     int32_t nHeaderStart;
183     uint32_t nMessageStart;
184     CAddress addr;
185     string addrName;
186     CService addrLocal;
187     int32_t nVersion;
188     string strSubVer;
189     bool fOneShot;
190     bool fClient;
191     bool fInbound;
192     bool fNetworkNode;
193     bool fSuccessfullyConnected;
194     bool fDisconnect;
195     CSemaphoreGrant grantOutbound;
196 protected:
197     int nRefCount;
198
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;
203     int nMisbehavior;
204
205 public:
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;
213     bool fStartSync;
214
215     // flood relay
216     vector<CAddress> vAddrToSend;
217     set<CAddress> setAddrKnown;
218     bool fGetAddr;
219     set<uint256> setKnown;
220     uint256 hashCheckpointKnown; // ppcoin: known sent sync-checkpoint
221     int64_t nNextAddrSend;
222     int64_t nNextLocalAddrSend;
223     int64_t nNextInvSend;
224
225     // inventory based relay
226     mruset<CInv> setInventoryKnown;
227     vector<CInv> vInventoryToSend;
228     CCriticalSection cs_inventory;
229     multimap<int64_t, CInv> mapAskFor;
230
231     CNode(SOCKET hSocketIn, CAddress addrIn, string addrNameIn = "", bool fInboundIn=false) : vSend(SER_NETWORK, MIN_PROTO_VERSION), vRecv(SER_NETWORK, MIN_PROTO_VERSION)
232     {
233         nServices = 0;
234         hSocket = hSocketIn;
235         nLastSend = 0;
236         nLastRecv = 0;
237         nSendBytes = 0;
238         nRecvBytes = 0;
239         nLastSendEmpty = GetTime();
240         nTimeConnected = GetTime();
241         nHeaderStart = -1;
242         nMessageStart = numeric_limits<uint32_t>::max();
243         addr = addrIn;
244         addrName = addrNameIn.empty() ? addr.ToStringIPPort() : addrNameIn;
245         nVersion = 0;
246         strSubVer.clear();
247         fOneShot = false;
248         fClient = false; // set by version message
249         fInbound = fInboundIn;
250         fNetworkNode = false;
251         fSuccessfullyConnected = false;
252         fDisconnect = false;
253         nRefCount = 0;
254         nReleaseTime = 0;
255         hashContinue = 0;
256         pindexLastGetBlocksBegin = 0;
257         hashLastGetBlocksEnd = 0;
258         nStartingHeight = -1;
259         nNextLocalAddrSend = 0;
260         nNextAddrSend = 0;
261         nNextInvSend = 0;
262         fStartSync = false;
263         fGetAddr = false;
264         nMisbehavior = 0;
265         hashCheckpointKnown = 0;
266         setInventoryKnown.max_size((size_t)SendBufferSize() / 1000);
267
268         // Be shy and don't send version until we hear
269         if (hSocket != INVALID_SOCKET && !fInbound)
270             PushVersion();
271     }
272
273     ~CNode()
274     {
275         if (hSocket != INVALID_SOCKET)
276         {
277             CloseSocket(hSocket);
278         }
279     }
280
281
282 private:
283     // Network usage totals
284     static CCriticalSection cs_totalBytesRecv;
285     static CCriticalSection cs_totalBytesSent;
286     static uint64_t nTotalBytesRecv;
287     static uint64_t nTotalBytesSent;
288     CNode(const CNode&);
289     void operator=(const CNode&);
290 public:
291
292
293     int GetRefCount()
294     {
295         return max(nRefCount, 0) + (GetTime() < nReleaseTime ? 1 : 0);
296     }
297
298     CNode* AddRef(int64_t nTimeout=0)
299     {
300         if (nTimeout != 0)
301             nReleaseTime = max(nReleaseTime, GetTime() + nTimeout);
302         else
303             nRefCount++;
304         return this;
305     }
306
307     void Release()
308     {
309         nRefCount--;
310     }
311
312
313
314     void AddAddressKnown(const CAddress& addr)
315     {
316         setAddrKnown.insert(addr);
317     }
318
319     void PushAddress(const CAddress& addr)
320     {
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);
326     }
327
328
329     void AddInventoryKnown(const CInv& inv)
330     {
331         {
332             LOCK(cs_inventory);
333             setInventoryKnown.insert(inv);
334         }
335     }
336
337     void PushInventory(const CInv& inv)
338     {
339         {
340             LOCK(cs_inventory);
341             if (!setInventoryKnown.count(inv))
342                 vInventoryToSend.push_back(inv);
343         }
344     }
345
346     void AskFor(const CInv& inv)
347     {
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];
351         if (fDebugNet)
352             printf("askfor %s   %" PRId64 " (%s)\n", inv.ToString().c_str(), nRequestTime, DateTimeStrFormat("%H:%M:%S", nRequestTime/1000000).c_str());
353
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;
357         ++nLastTime;
358         nNow = max(nNow, nLastTime);
359         nLastTime = nNow;
360
361         // Each retry is 2 minutes after the last
362         nRequestTime = max(nRequestTime + 2 * 60 * 1000000, nNow);
363         mapAskFor.insert({ nRequestTime, inv });
364     }
365
366
367
368     void BeginMessage(const char* pszCommand)
369     {
370         ENTER_CRITICAL_SECTION(cs_vSend);
371         if (nHeaderStart != -1)
372             AbortMessage();
373         nHeaderStart = (int32_t)vSend.size();
374         vSend << CMessageHeader(pszCommand, 0);
375         nMessageStart = (uint32_t)vSend.size();
376         if (fDebug)
377             printf("sending: %s ", pszCommand);
378     }
379
380     void AbortMessage()
381     {
382         if (nHeaderStart < 0)
383             return;
384         vSend.resize(nHeaderStart);
385         nHeaderStart = -1;
386         nMessageStart = numeric_limits<uint32_t>::max();
387         LEAVE_CRITICAL_SECTION(cs_vSend);
388
389         if (fDebug)
390             printf("(aborted)\n");
391     }
392
393     void EndMessage()
394     {
395         if (mapArgs.count("-dropmessagestest") && GetRand(atoi(mapArgs["-dropmessagestest"])) == 0)
396         {
397             printf("dropmessages DROPPING SEND MESSAGE\n");
398             AbortMessage();
399             return;
400         }
401
402         if (nHeaderStart < 0)
403             return;
404
405         // Set the size
406         uint32_t nSize = (uint32_t) vSend.size() - nMessageStart;
407         memcpy((char*)&vSend[nHeaderStart] + CMessageHeader::MESSAGE_SIZE_OFFSET, &nSize, sizeof(nSize));
408
409         // Set the checksum
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));
415
416         if (fDebug) {
417             printf("(%d bytes)\n", nSize);
418         }
419
420         nHeaderStart = -1;
421         nMessageStart = numeric_limits<uint32_t>::max();
422         LEAVE_CRITICAL_SECTION(cs_vSend);
423     }
424
425     void EndMessageAbortIfEmpty()
426     {
427         if (nHeaderStart < 0)
428             return;
429         int nSize = (int) vSend.size() - nMessageStart;
430         if (nSize > 0)
431             EndMessage();
432         else
433             AbortMessage();
434     }
435
436
437
438     void PushVersion();
439
440
441     void PushMessage(const char* pszCommand)
442     {
443         try
444         {
445             BeginMessage(pszCommand);
446             EndMessage();
447         }
448         catch (...)
449         {
450             AbortMessage();
451             throw;
452         }
453     }
454
455     template<typename T1>
456     void PushMessage(const char* pszCommand, const T1& a1)
457     {
458         try
459         {
460             BeginMessage(pszCommand);
461             vSend << a1;
462             EndMessage();
463         }
464         catch (...)
465         {
466             AbortMessage();
467             throw;
468         }
469     }
470
471     template<typename T1, typename T2>
472     void PushMessage(const char* pszCommand, const T1& a1, const T2& a2)
473     {
474         try
475         {
476             BeginMessage(pszCommand);
477             vSend << a1 << a2;
478             EndMessage();
479         }
480         catch (...)
481         {
482             AbortMessage();
483             throw;
484         }
485     }
486
487     template<typename T1, typename T2, typename T3>
488     void PushMessage(const char* pszCommand, const T1& a1, const T2& a2, const T3& a3)
489     {
490         try
491         {
492             BeginMessage(pszCommand);
493             vSend << a1 << a2 << a3;
494             EndMessage();
495         }
496         catch (...)
497         {
498             AbortMessage();
499             throw;
500         }
501     }
502
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)
505     {
506         try
507         {
508             BeginMessage(pszCommand);
509             vSend << a1 << a2 << a3 << a4;
510             EndMessage();
511         }
512         catch (...)
513         {
514             AbortMessage();
515             throw;
516         }
517     }
518
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)
521     {
522         try
523         {
524             BeginMessage(pszCommand);
525             vSend << a1 << a2 << a3 << a4 << a5;
526             EndMessage();
527         }
528         catch (...)
529         {
530             AbortMessage();
531             throw;
532         }
533     }
534
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)
537     {
538         try
539         {
540             BeginMessage(pszCommand);
541             vSend << a1 << a2 << a3 << a4 << a5 << a6;
542             EndMessage();
543         }
544         catch (...)
545         {
546             AbortMessage();
547             throw;
548         }
549     }
550
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)
553     {
554         try
555         {
556             BeginMessage(pszCommand);
557             vSend << a1 << a2 << a3 << a4 << a5 << a6 << a7;
558             EndMessage();
559         }
560         catch (...)
561         {
562             AbortMessage();
563             throw;
564         }
565     }
566
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)
569     {
570         try
571         {
572             BeginMessage(pszCommand);
573             vSend << a1 << a2 << a3 << a4 << a5 << a6 << a7 << a8;
574             EndMessage();
575         }
576         catch (...)
577         {
578             AbortMessage();
579             throw;
580         }
581     }
582
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)
585     {
586         try
587         {
588             BeginMessage(pszCommand);
589             vSend << a1 << a2 << a3 << a4 << a5 << a6 << a7 << a8 << a9;
590             EndMessage();
591         }
592         catch (...)
593         {
594             AbortMessage();
595             throw;
596         }
597     }
598
599
600     void PushRequest(const char* pszCommand,
601                      void (*fn)(void*, CDataStream&), void* param1)
602     {
603         uint256 hashReply;
604         RAND_bytes((unsigned char*)&hashReply, sizeof(hashReply));
605
606         {
607             LOCK(cs_mapRequests);
608             mapRequests[hashReply] = CRequestTracker(fn, param1);
609         }
610
611         PushMessage(pszCommand, hashReply);
612     }
613
614     template<typename T1>
615     void PushRequest(const char* pszCommand, const T1& a1,
616                      void (*fn)(void*, CDataStream&), void* param1)
617     {
618         uint256 hashReply;
619         RAND_bytes((unsigned char*)&hashReply, sizeof(hashReply));
620
621         {
622             LOCK(cs_mapRequests);
623             mapRequests[hashReply] = CRequestTracker(fn, param1);
624         }
625
626         PushMessage(pszCommand, hashReply, a1);
627     }
628
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)
632     {
633         uint256 hashReply;
634         RAND_bytes((unsigned char*)&hashReply, sizeof(hashReply));
635
636         {
637             LOCK(cs_mapRequests);
638             mapRequests[hashReply] = CRequestTracker(fn, param1);
639         }
640
641         PushMessage(pszCommand, hashReply, a1, a2);
642     }
643
644
645
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();
651     void Cleanup();
652
653
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
658     // way.
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
667     // new code.
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);
672     // Network stats
673     static void RecordBytesRecv(uint64_t bytes);
674     static void RecordBytesSent(uint64_t bytes);
675
676     static uint64_t GetTotalBytesRecv();
677     static uint64_t GetTotalBytesSent();
678 };
679
680 inline void RelayInventory(const CInv& inv)
681 {
682     // Put on lists to offer to the other nodes
683     {
684         LOCK(cs_vNodes);
685         for(CNode* pnode :  vNodes)
686             pnode->PushInventory(inv);
687     }
688 }
689
690 class CTransaction;
691 void RelayTransaction(const CTransaction& tx, const uint256& hash);
692 void RelayTransaction(const CTransaction& tx, const uint256& hash, const CDataStream& ss);
693
694
695 /** Return a timestamp in the future (in microseconds) for exponentially distributed events. */
696 int64_t PoissonNextSend(int64_t nNow, int average_interval_seconds);
697
698 #endif