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