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