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