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