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