Add bytessent, bytesrecv and syncnode to getpeerinfo
[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     uint64 nSendBytes;
149     uint64 nRecvBytes;
150     bool fSyncNode;
151 };
152
153
154
155
156
157 /** Information about a peer */
158 class CNode
159 {
160 public:
161     // socket
162     uint64 nServices;
163     SOCKET hSocket;
164     CDataStream vSend;
165     CDataStream vRecv;
166     uint64 nSendBytes;
167     uint64 nRecvBytes;
168     CCriticalSection cs_vSend;
169     CCriticalSection cs_vRecv;
170     int64 nLastSend;
171     int64 nLastRecv;
172     int64 nLastSendEmpty;
173     int64 nTimeConnected;
174     int nHeaderStart;
175     unsigned int nMessageStart;
176     CAddress addr;
177     std::string addrName;
178     CService addrLocal;
179     int nVersion;
180     std::string strSubVer;
181     bool fOneShot;
182     bool fClient;
183     bool fInbound;
184     bool fNetworkNode;
185     bool fSuccessfullyConnected;
186     bool fDisconnect;
187     CSemaphoreGrant grantOutbound;
188 protected:
189     int nRefCount;
190
191     // Denial-of-service detection/prevention
192     // Key is IP address, value is banned-until-time
193     static std::map<CNetAddr, int64> setBanned;
194     static CCriticalSection cs_setBanned;
195     int nMisbehavior;
196
197 public:
198     int64 nReleaseTime;
199     std::map<uint256, CRequestTracker> mapRequests;
200     CCriticalSection cs_mapRequests;
201     uint256 hashContinue;
202     CBlockIndex* pindexLastGetBlocksBegin;
203     uint256 hashLastGetBlocksEnd;
204     int nStartingHeight;
205     bool fStartSync;
206
207     // flood relay
208     std::vector<CAddress> vAddrToSend;
209     std::set<CAddress> setAddrKnown;
210     bool fGetAddr;
211     std::set<uint256> setKnown;
212     uint256 hashCheckpointKnown; // ppcoin: known sent sync-checkpoint
213
214     // inventory based relay
215     mruset<CInv> setInventoryKnown;
216     std::vector<CInv> vInventoryToSend;
217     CCriticalSection cs_inventory;
218     std::multimap<int64, CInv> mapAskFor;
219
220     CNode(SOCKET hSocketIn, CAddress addrIn, std::string addrNameIn = "", bool fInboundIn=false) : vSend(SER_NETWORK, MIN_PROTO_VERSION), vRecv(SER_NETWORK, MIN_PROTO_VERSION)
221     {
222         nServices = 0;
223         hSocket = hSocketIn;
224         nLastSend = 0;
225         nLastRecv = 0;
226         nSendBytes = 0;
227         nRecvBytes = 0;
228         nLastSendEmpty = GetTime();
229         nTimeConnected = GetTime();
230         nHeaderStart = -1;
231         nMessageStart = -1;
232         addr = addrIn;
233         addrName = addrNameIn == "" ? addr.ToStringIPPort() : addrNameIn;
234         nVersion = 0;
235         strSubVer = "";
236         fOneShot = false;
237         fClient = false; // set by version message
238         fInbound = fInboundIn;
239         fNetworkNode = false;
240         fSuccessfullyConnected = false;
241         fDisconnect = false;
242         nRefCount = 0;
243         nReleaseTime = 0;
244         hashContinue = 0;
245         pindexLastGetBlocksBegin = 0;
246         hashLastGetBlocksEnd = 0;
247         nStartingHeight = -1;
248         fStartSync = false;
249         fGetAddr = false;
250         nMisbehavior = 0;
251         hashCheckpointKnown = 0;
252         setInventoryKnown.max_size(SendBufferSize() / 1000);
253
254         // Be shy and don't send version until we hear
255         if (hSocket != INVALID_SOCKET && !fInbound)
256             PushVersion();
257     }
258
259     ~CNode()
260     {
261         if (hSocket != INVALID_SOCKET)
262         {
263             closesocket(hSocket);
264             hSocket = INVALID_SOCKET;
265         }
266     }
267
268 private:
269     CNode(const CNode&);
270     void operator=(const CNode&);
271 public:
272
273
274     int GetRefCount()
275     {
276         return std::max(nRefCount, 0) + (GetTime() < nReleaseTime ? 1 : 0);
277     }
278
279     CNode* AddRef(int64 nTimeout=0)
280     {
281         if (nTimeout != 0)
282             nReleaseTime = std::max(nReleaseTime, GetTime() + nTimeout);
283         else
284             nRefCount++;
285         return this;
286     }
287
288     void Release()
289     {
290         nRefCount--;
291     }
292
293
294
295     void AddAddressKnown(const CAddress& addr)
296     {
297         setAddrKnown.insert(addr);
298     }
299
300     void PushAddress(const CAddress& addr)
301     {
302         // Known checking here is only to save space from duplicates.
303         // SendMessages will filter it again for knowns that were added
304         // after addresses were pushed.
305         if (addr.IsValid() && !setAddrKnown.count(addr))
306             vAddrToSend.push_back(addr);
307     }
308
309
310     void AddInventoryKnown(const CInv& inv)
311     {
312         {
313             LOCK(cs_inventory);
314             setInventoryKnown.insert(inv);
315         }
316     }
317
318     void PushInventory(const CInv& inv)
319     {
320         {
321             LOCK(cs_inventory);
322             if (!setInventoryKnown.count(inv))
323                 vInventoryToSend.push_back(inv);
324         }
325     }
326
327     void AskFor(const CInv& inv)
328     {
329         // We're using mapAskFor as a priority queue,
330         // the key is the earliest time the request can be sent
331         int64& nRequestTime = mapAlreadyAskedFor[inv];
332         if (fDebugNet)
333             printf("askfor %s   %"PRI64d" (%s)\n", inv.ToString().c_str(), nRequestTime, DateTimeStrFormat("%H:%M:%S", nRequestTime/1000000).c_str());
334
335         // Make sure not to reuse time indexes to keep things in the same order
336         int64 nNow = (GetTime() - 1) * 1000000;
337         static int64 nLastTime;
338         ++nLastTime;
339         nNow = std::max(nNow, nLastTime);
340         nLastTime = nNow;
341
342         // Each retry is 2 minutes after the last
343         nRequestTime = std::max(nRequestTime + 2 * 60 * 1000000, nNow);
344         mapAskFor.insert(std::make_pair(nRequestTime, inv));
345     }
346
347
348
349     void BeginMessage(const char* pszCommand)
350     {
351         ENTER_CRITICAL_SECTION(cs_vSend);
352         if (nHeaderStart != -1)
353             AbortMessage();
354         nHeaderStart = vSend.size();
355         vSend << CMessageHeader(pszCommand, 0);
356         nMessageStart = vSend.size();
357         if (fDebug)
358             printf("sending: %s ", pszCommand);
359     }
360
361     void AbortMessage()
362     {
363         if (nHeaderStart < 0)
364             return;
365         vSend.resize(nHeaderStart);
366         nHeaderStart = -1;
367         nMessageStart = -1;
368         LEAVE_CRITICAL_SECTION(cs_vSend);
369
370         if (fDebug)
371             printf("(aborted)\n");
372     }
373
374     void EndMessage()
375     {
376         if (mapArgs.count("-dropmessagestest") && GetRand(atoi(mapArgs["-dropmessagestest"])) == 0)
377         {
378             printf("dropmessages DROPPING SEND MESSAGE\n");
379             AbortMessage();
380             return;
381         }
382
383         if (nHeaderStart < 0)
384             return;
385
386         // Set the size
387         unsigned int nSize = vSend.size() - nMessageStart;
388         memcpy((char*)&vSend[nHeaderStart] + CMessageHeader::MESSAGE_SIZE_OFFSET, &nSize, sizeof(nSize));
389
390         // Set the checksum
391         uint256 hash = Hash(vSend.begin() + nMessageStart, vSend.end());
392         unsigned int nChecksum = 0;
393         memcpy(&nChecksum, &hash, sizeof(nChecksum));
394         assert(nMessageStart - nHeaderStart >= CMessageHeader::CHECKSUM_OFFSET + sizeof(nChecksum));
395         memcpy((char*)&vSend[nHeaderStart] + CMessageHeader::CHECKSUM_OFFSET, &nChecksum, sizeof(nChecksum));
396
397         if (fDebug) {
398             printf("(%d bytes)\n", nSize);
399         }
400
401         nHeaderStart = -1;
402         nMessageStart = -1;
403         LEAVE_CRITICAL_SECTION(cs_vSend);
404     }
405
406     void EndMessageAbortIfEmpty()
407     {
408         if (nHeaderStart < 0)
409             return;
410         int nSize = vSend.size() - nMessageStart;
411         if (nSize > 0)
412             EndMessage();
413         else
414             AbortMessage();
415     }
416
417
418
419     void PushVersion();
420
421
422     void PushMessage(const char* pszCommand)
423     {
424         try
425         {
426             BeginMessage(pszCommand);
427             EndMessage();
428         }
429         catch (...)
430         {
431             AbortMessage();
432             throw;
433         }
434     }
435
436     template<typename T1>
437     void PushMessage(const char* pszCommand, const T1& a1)
438     {
439         try
440         {
441             BeginMessage(pszCommand);
442             vSend << a1;
443             EndMessage();
444         }
445         catch (...)
446         {
447             AbortMessage();
448             throw;
449         }
450     }
451
452     template<typename T1, typename T2>
453     void PushMessage(const char* pszCommand, const T1& a1, const T2& a2)
454     {
455         try
456         {
457             BeginMessage(pszCommand);
458             vSend << a1 << a2;
459             EndMessage();
460         }
461         catch (...)
462         {
463             AbortMessage();
464             throw;
465         }
466     }
467
468     template<typename T1, typename T2, typename T3>
469     void PushMessage(const char* pszCommand, const T1& a1, const T2& a2, const T3& a3)
470     {
471         try
472         {
473             BeginMessage(pszCommand);
474             vSend << a1 << a2 << a3;
475             EndMessage();
476         }
477         catch (...)
478         {
479             AbortMessage();
480             throw;
481         }
482     }
483
484     template<typename T1, typename T2, typename T3, typename T4>
485     void PushMessage(const char* pszCommand, const T1& a1, const T2& a2, const T3& a3, const T4& a4)
486     {
487         try
488         {
489             BeginMessage(pszCommand);
490             vSend << a1 << a2 << a3 << a4;
491             EndMessage();
492         }
493         catch (...)
494         {
495             AbortMessage();
496             throw;
497         }
498     }
499
500     template<typename T1, typename T2, typename T3, typename T4, typename T5>
501     void PushMessage(const char* pszCommand, const T1& a1, const T2& a2, const T3& a3, const T4& a4, const T5& a5)
502     {
503         try
504         {
505             BeginMessage(pszCommand);
506             vSend << a1 << a2 << a3 << a4 << a5;
507             EndMessage();
508         }
509         catch (...)
510         {
511             AbortMessage();
512             throw;
513         }
514     }
515
516     template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6>
517     void PushMessage(const char* pszCommand, const T1& a1, const T2& a2, const T3& a3, const T4& a4, const T5& a5, const T6& a6)
518     {
519         try
520         {
521             BeginMessage(pszCommand);
522             vSend << a1 << a2 << a3 << a4 << a5 << a6;
523             EndMessage();
524         }
525         catch (...)
526         {
527             AbortMessage();
528             throw;
529         }
530     }
531
532     template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7>
533     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)
534     {
535         try
536         {
537             BeginMessage(pszCommand);
538             vSend << a1 << a2 << a3 << a4 << a5 << a6 << a7;
539             EndMessage();
540         }
541         catch (...)
542         {
543             AbortMessage();
544             throw;
545         }
546     }
547
548     template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8>
549     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)
550     {
551         try
552         {
553             BeginMessage(pszCommand);
554             vSend << a1 << a2 << a3 << a4 << a5 << a6 << a7 << a8;
555             EndMessage();
556         }
557         catch (...)
558         {
559             AbortMessage();
560             throw;
561         }
562     }
563
564     template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9>
565     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)
566     {
567         try
568         {
569             BeginMessage(pszCommand);
570             vSend << a1 << a2 << a3 << a4 << a5 << a6 << a7 << a8 << a9;
571             EndMessage();
572         }
573         catch (...)
574         {
575             AbortMessage();
576             throw;
577         }
578     }
579
580
581     void PushRequest(const char* pszCommand,
582                      void (*fn)(void*, CDataStream&), void* param1)
583     {
584         uint256 hashReply;
585         RAND_bytes((unsigned char*)&hashReply, sizeof(hashReply));
586
587         {
588             LOCK(cs_mapRequests);
589             mapRequests[hashReply] = CRequestTracker(fn, param1);
590         }
591
592         PushMessage(pszCommand, hashReply);
593     }
594
595     template<typename T1>
596     void PushRequest(const char* pszCommand, const T1& a1,
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, a1);
608     }
609
610     template<typename T1, typename T2>
611     void PushRequest(const char* pszCommand, const T1& a1, const T2& a2,
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, a2);
623     }
624
625
626
627     void PushGetBlocks(CBlockIndex* pindexBegin, uint256 hashEnd);
628     bool IsSubscribed(unsigned int nChannel);
629     void Subscribe(unsigned int nChannel, unsigned int nHops=0);
630     void CancelSubscribe(unsigned int nChannel);
631     void CloseSocketDisconnect();
632     void Cleanup();
633
634
635     // Denial-of-service detection/prevention
636     // The idea is to detect peers that are behaving
637     // badly and disconnect/ban them, but do it in a
638     // one-coding-mistake-won't-shatter-the-entire-network
639     // way.
640     // IMPORTANT:  There should be nothing I can give a
641     // node that it will forward on that will make that
642     // node's peers drop it. If there is, an attacker
643     // can isolate a node and/or try to split the network.
644     // Dropping a node for sending stuff that is invalid
645     // now but might be valid in a later version is also
646     // dangerous, because it can cause a network split
647     // between nodes running old code and nodes running
648     // new code.
649     static void ClearBanned(); // needed for unit testing
650     static bool IsBanned(CNetAddr ip);
651     bool Misbehaving(int howmuch); // 1 == a little, 100 == a lot
652     void copyStats(CNodeStats &stats);
653 };
654
655 inline void RelayInventory(const CInv& inv)
656 {
657     // Put on lists to offer to the other nodes
658     {
659         LOCK(cs_vNodes);
660         BOOST_FOREACH(CNode* pnode, vNodes)
661             pnode->PushInventory(inv);
662     }
663 }
664
665 class CTransaction;
666 void RelayTransaction(const CTransaction& tx, const uint256& hash);
667 void RelayTransaction(const CTransaction& tx, const uint256& hash, const CDataStream& ss);
668
669
670 #endif