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