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