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