rpc: add getnetworkinfo
[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 #endif
12 #include <openssl/rand.h>
13
14 #include "mruset.h"
15 #include "netbase.h"
16 #include "addrman.h"
17 #include "hash.h"
18
19
20 class CRequestTracker;
21 class CNode;
22 class CBlockIndex;
23 extern int nBestHeight;
24
25 const uint16_t nSocksDefault = 9050;
26 const uint16_t nPortZero = 0;
27
28
29 inline uint64_t ReceiveBufferSize() { return 1000*GetArg("-maxreceivebuffer", 5*1000); }
30 inline uint64_t 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_t nTimeout=0);
39 bool OpenNetworkConnection(const CAddress& addrConnect, CSemaphoreGrant *grantOutbound = NULL, const char *strDest = NULL, bool fOneShot = false);
40 uint16_t 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_IRC,    // address reported by IRC (deprecated)
51     LOCAL_HTTP,   // address reported by whatismyip.com and similar
52     LOCAL_MANUAL, // address explicitly specified (-externalip=)
53
54     LOCAL_MAX
55 };
56
57
58 bool IsPeerAddrLocalGood(CNode *pnode);
59 void AdvertiseLocal(CNode *pnode);
60 void SetLimited(enum Network net, bool fLimited = true);
61 bool IsLimited(enum Network net);
62 bool IsLimited(const CNetAddr& addr);
63 bool AddLocal(const CService& addr, int nScore = LOCAL_NONE);
64 bool AddLocal(const CNetAddr& addr, int nScore = LOCAL_NONE);
65 bool SeenLocal(const CService& addr);
66 bool IsLocal(const CService& addr);
67 bool GetLocal(CService &addr, const CNetAddr *paddrPeer = NULL);
68 bool IsReachable(const CNetAddr &addr);
69 void SetReachable(enum Network net, bool fFlag = true);
70 CAddress GetLocalAddress(const CNetAddr *paddrPeer = NULL);
71
72
73 enum
74 {
75     MSG_TX = 1,
76     MSG_BLOCK
77 };
78
79 class CRequestTracker
80 {
81 public:
82     void (*fn)(void*, CDataStream&);
83     void* param1;
84
85     explicit CRequestTracker(void (*fnIn)(void*, CDataStream&)=NULL, void* param1In=NULL)
86     {
87         fn = fnIn;
88         param1 = param1In;
89     }
90
91     bool IsNull()
92     {
93         return fn == NULL;
94     }
95 };
96
97
98 /** Thread types */
99 enum threadId
100 {
101     THREAD_SOCKETHANDLER,
102     THREAD_OPENCONNECTIONS,
103     THREAD_MESSAGEHANDLER,
104     THREAD_RPCLISTENER,
105     THREAD_DNSSEED,
106     THREAD_ADDEDCONNECTIONS,
107     THREAD_DUMPADDRESS,
108     THREAD_RPCHANDLER,
109     THREAD_MINTER,
110     THREAD_SCRIPTCHECK,
111     THREAD_NTP,
112     THREAD_IPCOLLECTOR,
113
114     THREAD_MAX
115 };
116
117 extern bool fClient;
118 extern bool fDiscover;
119 extern bool fNoListen;
120
121 extern bool fDiscover;
122 extern uint64_t nLocalServices;
123 extern uint64_t nLocalHostNonce;
124 extern CAddress addrSeenByPeer;
125 extern std::array<int, THREAD_MAX> vnThreadsRunning;
126 extern CAddrMan addrman;
127
128 extern std::vector<CNode*> vNodes;
129 extern CCriticalSection cs_vNodes;
130 extern std::vector<std::string> vAddedNodes;
131 extern CCriticalSection cs_vAddedNodes;
132 extern std::map<CInv, CDataStream> mapRelay;
133 extern std::deque<std::pair<int64_t, CInv> > vRelayExpiration;
134 extern CCriticalSection cs_mapRelay;
135 extern std::map<CInv, int64_t> mapAlreadyAskedFor;
136
137 struct LocalServiceInfo {
138     int nScore;
139     uint16_t nPort;
140 };
141
142 extern CCriticalSection cs_mapLocalHost;
143 extern std::map<CNetAddr, LocalServiceInfo> mapLocalHost;
144
145 class CNodeStats
146 {
147 public:
148     uint64_t nServices;
149     int64_t nLastSend;
150     int64_t nLastRecv;
151     int64_t nTimeConnected;
152     std::string addrName;
153     int32_t nVersion;
154     std::string strSubVer;
155     bool fInbound;
156     int64_t nReleaseTime;
157     int32_t nStartingHeight;
158     int32_t nMisbehavior;
159     uint64_t nSendBytes;
160     uint64_t nRecvBytes;
161     bool fSyncNode;
162 };
163
164
165 // Information about a peer
166 class CNode
167 {
168 public:
169     // socket
170     uint64_t nServices;
171     SOCKET hSocket;
172     CDataStream vSend;
173     CDataStream vRecv;
174     uint64_t nSendBytes;
175     uint64_t nRecvBytes;
176     CCriticalSection cs_vSend;
177     CCriticalSection cs_vRecv;
178     int64_t nLastSend;
179     int64_t nLastRecv;
180     int64_t nLastSendEmpty;
181     int64_t nTimeConnected;
182     int32_t nHeaderStart;
183     uint32_t nMessageStart;
184     CAddress addr;
185     std::string addrName;
186     CService addrLocal;
187     int32_t nVersion;
188     std::string strSubVer;
189     bool fOneShot;
190     bool fClient;
191     bool fInbound;
192     bool fNetworkNode;
193     bool fSuccessfullyConnected;
194     bool fDisconnect;
195     CSemaphoreGrant grantOutbound;
196 protected:
197     int nRefCount;
198
199     // Denial-of-service detection/prevention
200     // Key is IP address, value is banned-until-time
201     static std::map<CNetAddr, int64_t> setBanned;
202     static CCriticalSection cs_setBanned;
203     int nMisbehavior;
204
205 public:
206     int64_t nReleaseTime;
207     std::map<uint256, CRequestTracker> mapRequests;
208     CCriticalSection cs_mapRequests;
209     uint256 hashContinue;
210     CBlockIndex* pindexLastGetBlocksBegin;
211     uint256 hashLastGetBlocksEnd;
212     int32_t nStartingHeight;
213     bool fStartSync;
214
215     // flood relay
216     std::vector<CAddress> vAddrToSend;
217     std::set<CAddress> setAddrKnown;
218     bool fGetAddr;
219     std::set<uint256> setKnown;
220     uint256 hashCheckpointKnown; // ppcoin: known sent sync-checkpoint
221     int64_t nNextAddrSend;
222     int64_t nNextLocalAddrSend;
223     int64_t nNextInvSend;
224
225     // inventory based relay
226     mruset<CInv> setInventoryKnown;
227     std::vector<CInv> vInventoryToSend;
228     CCriticalSection cs_inventory;
229     std::multimap<int64_t, CInv> mapAskFor;
230
231     CNode(SOCKET hSocketIn, CAddress addrIn, std::string addrNameIn = "", bool fInboundIn=false);
232     ~CNode();
233
234 private:
235     // Network usage totals
236     static CCriticalSection cs_totalBytesRecv;
237     static CCriticalSection cs_totalBytesSent;
238     static uint64_t nTotalBytesRecv;
239     static uint64_t nTotalBytesSent;
240     CNode(const CNode&);
241     void operator=(const CNode&);
242
243 public:
244
245     int GetRefCount();
246     CNode* AddRef(int64_t nTimeout=0);
247     void Release();
248     void AddAddressKnown(const CAddress& addr);
249     void PushAddress(const CAddress& addr);
250     void AddInventoryKnown(const CInv& inv);
251     void PushInventory(const CInv& inv);
252     void AskFor(const CInv& inv);
253     void BeginMessage(const char* pszCommand);
254     void AbortMessage();
255     void EndMessage();
256     void EndMessageAbortIfEmpty();
257     void PushVersion();
258
259     void PushMessage(const char* pszCommand)
260     {
261         try
262         {
263             BeginMessage(pszCommand);
264             EndMessage();
265         }
266         catch (...)
267         {
268             AbortMessage();
269             throw;
270         }
271     }
272
273     template<typename T1>
274     void PushMessage(const char* pszCommand, const T1& a1)
275     {
276         try
277         {
278             BeginMessage(pszCommand);
279             vSend << a1;
280             EndMessage();
281         }
282         catch (...)
283         {
284             AbortMessage();
285             throw;
286         }
287     }
288
289     template<typename T1, typename T2>
290     void PushMessage(const char* pszCommand, const T1& a1, const T2& a2)
291     {
292         try
293         {
294             BeginMessage(pszCommand);
295             vSend << a1 << a2;
296             EndMessage();
297         }
298         catch (...)
299         {
300             AbortMessage();
301             throw;
302         }
303     }
304
305     template<typename T1, typename T2, typename T3>
306     void PushMessage(const char* pszCommand, const T1& a1, const T2& a2, const T3& a3)
307     {
308         try
309         {
310             BeginMessage(pszCommand);
311             vSend << a1 << a2 << a3;
312             EndMessage();
313         }
314         catch (...)
315         {
316             AbortMessage();
317             throw;
318         }
319     }
320
321     template<typename T1, typename T2, typename T3, typename T4>
322     void PushMessage(const char* pszCommand, const T1& a1, const T2& a2, const T3& a3, const T4& a4)
323     {
324         try
325         {
326             BeginMessage(pszCommand);
327             vSend << a1 << a2 << a3 << a4;
328             EndMessage();
329         }
330         catch (...)
331         {
332             AbortMessage();
333             throw;
334         }
335     }
336
337     template<typename T1, typename T2, typename T3, typename T4, typename T5>
338     void PushMessage(const char* pszCommand, const T1& a1, const T2& a2, const T3& a3, const T4& a4, const T5& a5)
339     {
340         try
341         {
342             BeginMessage(pszCommand);
343             vSend << a1 << a2 << a3 << a4 << a5;
344             EndMessage();
345         }
346         catch (...)
347         {
348             AbortMessage();
349             throw;
350         }
351     }
352
353     template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6>
354     void PushMessage(const char* pszCommand, const T1& a1, const T2& a2, const T3& a3, const T4& a4, const T5& a5, const T6& a6)
355     {
356         try
357         {
358             BeginMessage(pszCommand);
359             vSend << a1 << a2 << a3 << a4 << a5 << a6;
360             EndMessage();
361         }
362         catch (...)
363         {
364             AbortMessage();
365             throw;
366         }
367     }
368
369     template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7>
370     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)
371     {
372         try
373         {
374             BeginMessage(pszCommand);
375             vSend << a1 << a2 << a3 << a4 << a5 << a6 << a7;
376             EndMessage();
377         }
378         catch (...)
379         {
380             AbortMessage();
381             throw;
382         }
383     }
384
385     template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8>
386     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)
387     {
388         try
389         {
390             BeginMessage(pszCommand);
391             vSend << a1 << a2 << a3 << a4 << a5 << a6 << a7 << a8;
392             EndMessage();
393         }
394         catch (...)
395         {
396             AbortMessage();
397             throw;
398         }
399     }
400
401     template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9>
402     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)
403     {
404         try
405         {
406             BeginMessage(pszCommand);
407             vSend << a1 << a2 << a3 << a4 << a5 << a6 << a7 << a8 << a9;
408             EndMessage();
409         }
410         catch (...)
411         {
412             AbortMessage();
413             throw;
414         }
415     }
416
417
418     void PushRequest(const char* pszCommand,
419                      void (*fn)(void*, CDataStream&), void* param1)
420     {
421         uint256 hashReply;
422         RAND_bytes((unsigned char*)&hashReply, sizeof(hashReply));
423
424         {
425             LOCK(cs_mapRequests);
426             mapRequests[hashReply] = CRequestTracker(fn, param1);
427         }
428
429         PushMessage(pszCommand, hashReply);
430     }
431
432     template<typename T1>
433     void PushRequest(const char* pszCommand, const T1& a1,
434                      void (*fn)(void*, CDataStream&), void* param1)
435     {
436         uint256 hashReply;
437         RAND_bytes((unsigned char*)&hashReply, sizeof(hashReply));
438
439         {
440             LOCK(cs_mapRequests);
441             mapRequests[hashReply] = CRequestTracker(fn, param1);
442         }
443
444         PushMessage(pszCommand, hashReply, a1);
445     }
446
447     template<typename T1, typename T2>
448     void PushRequest(const char* pszCommand, const T1& a1, const T2& a2,
449                      void (*fn)(void*, CDataStream&), void* param1)
450     {
451         uint256 hashReply;
452         RAND_bytes((unsigned char*)&hashReply, sizeof(hashReply));
453
454         {
455             LOCK(cs_mapRequests);
456             mapRequests[hashReply] = CRequestTracker(fn, param1);
457         }
458
459         PushMessage(pszCommand, hashReply, a1, a2);
460     }
461
462
463
464     void PushGetBlocks(CBlockIndex* pindexBegin, uint256 hashEnd);
465     bool IsSubscribed(unsigned int nChannel);
466     void Subscribe(unsigned int nChannel, unsigned int nHops=0);
467     void CancelSubscribe(unsigned int nChannel);
468     void CloseSocketDisconnect();
469     void Cleanup();
470
471
472     // Denial-of-service detection/prevention
473     // The idea is to detect peers that are behaving
474     // badly and disconnect/ban them, but do it in a
475     // one-coding-mistake-won't-shatter-the-entire-network
476     // way.
477     // IMPORTANT:  There should be nothing I can give a
478     // node that it will forward on that will make that
479     // node's peers drop it. If there is, an attacker
480     // can isolate a node and/or try to split the network.
481     // Dropping a node for sending stuff that is invalid
482     // now but might be valid in a later version is also
483     // dangerous, because it can cause a network split
484     // between nodes running old code and nodes running
485     // new code.
486     static void ClearBanned(); // needed for unit testing
487     static bool IsBanned(const CNetAddr& ip);
488     bool Misbehaving(int howmuch); // 1 == a little, 100 == a lot
489     void copyStats(CNodeStats &stats);
490     // Network stats
491     static void RecordBytesRecv(uint64_t bytes);
492     static void RecordBytesSent(uint64_t bytes);
493
494     static uint64_t GetTotalBytesRecv();
495     static uint64_t GetTotalBytesSent();
496 };
497
498 class CTransaction;
499 void RelayTransaction(const CTransaction& tx, const uint256& hash);
500 void RelayTransaction(const CTransaction& tx, const uint256& hash, const CDataStream& ss);
501
502
503 /** Return a timestamp in the future (in microseconds) for exponentially distributed events. */
504 int64_t PoissonNextSend(int64_t nNow, int average_interval_seconds);
505
506 #endif