Drop some boost deps
[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 "mruset.h"
9 #include "netbase.h"
10 #include "addrman.h"
11 #include "hash.h"
12
13 #include <openssl/rand.h>
14
15 #ifndef WIN32
16 #include <arpa/inet.h>
17 #endif
18
19 #include <limits>
20 #include <deque>
21
22
23 class CRequestTracker;
24 class CNode;
25 class CBlockIndex;
26 extern int nBestHeight;
27
28 const uint16_t nSocksDefault = 9050;
29 const uint16_t nPortZero = 0;
30
31
32 inline uint64_t ReceiveBufferSize() { return 1000*GetArg("-maxreceivebuffer", 5*1000); }
33 inline uint64_t SendBufferSize() { return 1000*GetArg("-maxsendbuffer", 1*1000); }
34
35 void AddOneShot(std::string strDest);
36 bool RecvLine(SOCKET hSocket, std::string& strLine);
37 bool GetMyExternalIP(CNetAddr& ipRet);
38 void AddressCurrentlyConnected(const CService& addr);
39 CNode* FindNode(const CNetAddr& ip);
40 CNode* FindNode(const CService& ip);
41 CNode* ConnectNode(CAddress addrConnect, const char *strDest = NULL, int64_t nTimeout=0);
42 bool OpenNetworkConnection(const CAddress& addrConnect, CSemaphoreGrant *grantOutbound = NULL, const char *strDest = NULL, bool fOneShot = false);
43 void MapPort();
44 unsigned short GetListenPort();
45 bool BindListenPort(const CService &bindAddr, std::string& strError=REF(std::string()));
46 void StartNode(void* parg);
47 bool StopNode();
48
49 enum
50 {
51     LOCAL_NONE,   // unknown
52     LOCAL_IF,     // address a local interface listens on
53     LOCAL_BIND,   // address explicit bound to
54     LOCAL_IRC,    // address reported by IRC (deprecated)
55     LOCAL_HTTP,   // address reported by whatismyip.com and similar
56     LOCAL_MANUAL, // address explicitly specified (-externalip=)
57
58     LOCAL_MAX
59 };
60
61
62 bool IsPeerAddrLocalGood(CNode *pnode);
63 void AdvertiseLocal(CNode *pnode);
64 void SetLimited(enum Network net, bool fLimited = true);
65 bool IsLimited(enum Network net);
66 bool IsLimited(const CNetAddr& addr);
67 bool AddLocal(const CService& addr, int nScore = LOCAL_NONE);
68 bool AddLocal(const CNetAddr& addr, int nScore = LOCAL_NONE);
69 bool SeenLocal(const CService& addr);
70 bool IsLocal(const CService& addr);
71 bool GetLocal(CService &addr, const CNetAddr *paddrPeer = NULL);
72 bool IsReachable(const CNetAddr &addr);
73 void SetReachable(enum Network net, bool fFlag = true);
74 CAddress GetLocalAddress(const CNetAddr *paddrPeer = NULL);
75
76
77 enum
78 {
79     MSG_TX = 1,
80     MSG_BLOCK
81 };
82
83 class CRequestTracker
84 {
85 public:
86     void (*fn)(void*, CDataStream&);
87     void* param1;
88
89     explicit CRequestTracker(void (*fnIn)(void*, CDataStream&)=NULL, void* param1In=NULL)
90     {
91         fn = fnIn;
92         param1 = param1In;
93     }
94
95     bool IsNull()
96     {
97         return fn == NULL;
98     }
99 };
100
101
102 /** Thread types */
103 enum threadId
104 {
105     THREAD_SOCKETHANDLER,
106     THREAD_OPENCONNECTIONS,
107     THREAD_MESSAGEHANDLER,
108     THREAD_RPCLISTENER,
109     THREAD_DNSSEED,
110     THREAD_ADDEDCONNECTIONS,
111     THREAD_DUMPADDRESS,
112     THREAD_RPCHANDLER,
113     THREAD_MINTER,
114     THREAD_SCRIPTCHECK,
115     THREAD_NTP,
116     THREAD_IPCOLLECTOR,
117
118     THREAD_MAX
119 };
120
121 extern bool fClient;
122 extern bool fDiscover;
123 extern bool fNoListen;
124
125 extern bool fDiscover;
126 extern uint64_t nLocalServices;
127 extern uint64_t nLocalHostNonce;
128 extern CAddress addrSeenByPeer;
129 extern std::array<int, THREAD_MAX> vnThreadsRunning;
130 extern CAddrMan addrman;
131
132 extern std::vector<CNode*> vNodes;
133 extern CCriticalSection cs_vNodes;
134 extern std::vector<std::string> vAddedNodes;
135 extern CCriticalSection cs_vAddedNodes;
136 extern std::map<CInv, CDataStream> mapRelay;
137 extern std::deque<std::pair<int64_t, CInv> > vRelayExpiration;
138 extern CCriticalSection cs_mapRelay;
139 extern std::map<CInv, int64_t> mapAlreadyAskedFor;
140
141
142
143
144 class CNodeStats
145 {
146 public:
147     uint64_t nServices;
148     int64_t nLastSend;
149     int64_t nLastRecv;
150     int64_t nTimeConnected;
151     std::string addrName;
152     int32_t nVersion;
153     std::string strSubVer;
154     bool fInbound;
155     int64_t nReleaseTime;
156     int32_t nStartingHeight;
157     int32_t nMisbehavior;
158     uint64_t nSendBytes;
159     uint64_t nRecvBytes;
160     bool fSyncNode;
161 };
162
163
164
165
166
167 /** Information about a peer */
168 class CNode
169 {
170 public:
171     // socket
172     uint64_t nServices;
173     SOCKET hSocket;
174     CDataStream vSend;
175     CDataStream vRecv;
176     uint64_t nSendBytes;
177     uint64_t nRecvBytes;
178     CCriticalSection cs_vSend;
179     CCriticalSection cs_vRecv;
180     int64_t nLastSend;
181     int64_t nLastRecv;
182     int64_t nLastSendEmpty;
183     int64_t nTimeConnected;
184     int32_t nHeaderStart;
185     uint32_t nMessageStart;
186     CAddress addr;
187     std::string addrName;
188     CService addrLocal;
189     int32_t nVersion;
190     std::string strSubVer;
191     bool fOneShot;
192     bool fClient;
193     bool fInbound;
194     bool fNetworkNode;
195     bool fSuccessfullyConnected;
196     bool fDisconnect;
197     CSemaphoreGrant grantOutbound;
198 protected:
199     int nRefCount;
200
201     // Denial-of-service detection/prevention
202     // Key is IP address, value is banned-until-time
203     static std::map<CNetAddr, int64_t> setBanned;
204     static CCriticalSection cs_setBanned;
205     int nMisbehavior;
206
207 public:
208     int64_t nReleaseTime;
209     std::map<uint256, CRequestTracker> mapRequests;
210     CCriticalSection cs_mapRequests;
211     uint256 hashContinue;
212     CBlockIndex* pindexLastGetBlocksBegin;
213     uint256 hashLastGetBlocksEnd;
214     int32_t nStartingHeight;
215     bool fStartSync;
216
217     // flood relay
218     std::vector<CAddress> vAddrToSend;
219     std::set<CAddress> setAddrKnown;
220     bool fGetAddr;
221     std::set<uint256> setKnown;
222     uint256 hashCheckpointKnown; // ppcoin: known sent sync-checkpoint
223     int64_t nNextAddrSend;
224     int64_t nNextLocalAddrSend;
225     int64_t nNextInvSend;
226
227     // inventory based relay
228     mruset<CInv> setInventoryKnown;
229     std::vector<CInv> vInventoryToSend;
230     CCriticalSection cs_inventory;
231     std::multimap<int64_t, CInv> mapAskFor;
232
233     CNode(SOCKET hSocketIn, CAddress addrIn, std::string addrNameIn = "", bool fInboundIn=false) : vSend(SER_NETWORK, MIN_PROTO_VERSION), vRecv(SER_NETWORK, MIN_PROTO_VERSION)
234     {
235         nServices = 0;
236         hSocket = hSocketIn;
237         nLastSend = 0;
238         nLastRecv = 0;
239         nSendBytes = 0;
240         nRecvBytes = 0;
241         nLastSendEmpty = GetTime();
242         nTimeConnected = GetTime();
243         nHeaderStart = -1;
244         nMessageStart = std::numeric_limits<uint32_t>::max();
245         addr = addrIn;
246         addrName = addrNameIn.empty() ? addr.ToStringIPPort() : addrNameIn;
247         nVersion = 0;
248         strSubVer.clear();
249         fOneShot = false;
250         fClient = false; // set by version message
251         fInbound = fInboundIn;
252         fNetworkNode = false;
253         fSuccessfullyConnected = false;
254         fDisconnect = false;
255         nRefCount = 0;
256         nReleaseTime = 0;
257         hashContinue = 0;
258         pindexLastGetBlocksBegin = 0;
259         hashLastGetBlocksEnd = 0;
260         nStartingHeight = -1;
261         nNextLocalAddrSend = 0;
262         nNextAddrSend = 0;
263         nNextInvSend = 0;
264         fStartSync = false;
265         fGetAddr = false;
266         nMisbehavior = 0;
267         hashCheckpointKnown = 0;
268         setInventoryKnown.max_size((size_t)SendBufferSize() / 1000);
269
270         // Be shy and don't send version until we hear
271         if (hSocket != INVALID_SOCKET && !fInbound)
272             PushVersion();
273     }
274
275     ~CNode()
276     {
277         if (hSocket != INVALID_SOCKET)
278         {
279             CloseSocket(hSocket);
280         }
281     }
282
283
284 private:
285     // Network usage totals
286     static CCriticalSection cs_totalBytesRecv;
287     static CCriticalSection cs_totalBytesSent;
288     static uint64_t nTotalBytesRecv;
289     static uint64_t nTotalBytesSent;
290     CNode(const CNode&);
291     void operator=(const CNode&);
292 public:
293
294
295     int GetRefCount()
296     {
297         return std::max(nRefCount, 0) + (GetTime() < nReleaseTime ? 1 : 0);
298     }
299
300     CNode* AddRef(int64_t nTimeout=0)
301     {
302         if (nTimeout != 0)
303             nReleaseTime = std::max(nReleaseTime, GetTime() + nTimeout);
304         else
305             nRefCount++;
306         return this;
307     }
308
309     void Release()
310     {
311         nRefCount--;
312     }
313
314
315
316     void AddAddressKnown(const CAddress& addr)
317     {
318         setAddrKnown.insert(addr);
319     }
320
321     void PushAddress(const CAddress& addr)
322     {
323         // Known checking here is only to save space from duplicates.
324         // SendMessages will filter it again for knowns that were added
325         // after addresses were pushed.
326         if (addr.IsValid() && !setAddrKnown.count(addr))
327             vAddrToSend.push_back(addr);
328     }
329
330
331     void AddInventoryKnown(const CInv& inv)
332     {
333         {
334             LOCK(cs_inventory);
335             setInventoryKnown.insert(inv);
336         }
337     }
338
339     void PushInventory(const CInv& inv)
340     {
341         {
342             LOCK(cs_inventory);
343             if (!setInventoryKnown.count(inv))
344                 vInventoryToSend.push_back(inv);
345         }
346     }
347
348     void AskFor(const CInv& inv)
349     {
350         // We're using mapAskFor as a priority queue,
351         // the key is the earliest time the request can be sent
352         int64_t& nRequestTime = mapAlreadyAskedFor[inv];
353         if (fDebugNet)
354             printf("askfor %s   %" PRId64 " (%s)\n", inv.ToString().c_str(), nRequestTime, DateTimeStrFormat("%H:%M:%S", nRequestTime/1000000).c_str());
355
356         // Make sure not to reuse time indexes to keep things in the same order
357         int64_t nNow = (GetTime() - 1) * 1000000;
358         static int64_t nLastTime;
359         ++nLastTime;
360         nNow = std::max(nNow, nLastTime);
361         nLastTime = nNow;
362
363         // Each retry is 2 minutes after the last
364         nRequestTime = std::max(nRequestTime + 2 * 60 * 1000000, nNow);
365         mapAskFor.insert(std::make_pair(nRequestTime, inv));
366     }
367
368
369
370     void BeginMessage(const char* pszCommand)
371     {
372         ENTER_CRITICAL_SECTION(cs_vSend);
373         if (nHeaderStart != -1)
374             AbortMessage();
375         nHeaderStart = (int32_t)vSend.size();
376         vSend << CMessageHeader(pszCommand, 0);
377         nMessageStart = (uint32_t)vSend.size();
378         if (fDebug)
379             printf("sending: %s ", pszCommand);
380     }
381
382     void AbortMessage()
383     {
384         if (nHeaderStart < 0)
385             return;
386         vSend.resize(nHeaderStart);
387         nHeaderStart = -1;
388         nMessageStart = std::numeric_limits<uint32_t>::max();
389         LEAVE_CRITICAL_SECTION(cs_vSend);
390
391         if (fDebug)
392             printf("(aborted)\n");
393     }
394
395     void EndMessage()
396     {
397         if (mapArgs.count("-dropmessagestest") && GetRand(atoi(mapArgs["-dropmessagestest"])) == 0)
398         {
399             printf("dropmessages DROPPING SEND MESSAGE\n");
400             AbortMessage();
401             return;
402         }
403
404         if (nHeaderStart < 0) {
405             LEAVE_CRITICAL_SECTION(cs_vSend);
406             return;
407         }
408
409         // Set the size
410         uint32_t nSize = (uint32_t) vSend.size() - nMessageStart;
411         memcpy((char*)&vSend[nHeaderStart] + CMessageHeader::MESSAGE_SIZE_OFFSET, &nSize, sizeof(nSize));
412
413         // Set the checksum
414         uint256 hash = Hash(vSend.begin() + nMessageStart, vSend.end());
415         uint32_t nChecksum = 0;
416         memcpy(&nChecksum, &hash, sizeof(nChecksum));
417         assert(nMessageStart - nHeaderStart >= CMessageHeader::CHECKSUM_OFFSET + sizeof(nChecksum));
418         memcpy((char*)&vSend[nHeaderStart] + CMessageHeader::CHECKSUM_OFFSET, &nChecksum, sizeof(nChecksum));
419
420         if (fDebug) {
421             printf("(%d bytes)\n", nSize);
422         }
423
424         nHeaderStart = -1;
425         nMessageStart = std::numeric_limits<uint32_t>::max();
426         LEAVE_CRITICAL_SECTION(cs_vSend);
427     }
428
429     void EndMessageAbortIfEmpty()
430     {
431         if (nHeaderStart < 0)
432             return;
433         int nSize = (int) vSend.size() - nMessageStart;
434         if (nSize > 0)
435             EndMessage();
436         else
437             AbortMessage();
438     }
439
440
441
442     void PushVersion();
443
444
445     void PushMessage(const char* pszCommand)
446     {
447         try
448         {
449             BeginMessage(pszCommand);
450             EndMessage();
451         }
452         catch (...)
453         {
454             AbortMessage();
455             throw;
456         }
457     }
458
459     template<typename ...Args>
460     void PushMessage(const char* pszCommand, const Args&... args)
461     {
462         try
463         {
464             BeginMessage(pszCommand);
465             (vSend << ... << args);
466             EndMessage();
467         }
468         catch (...)
469         {
470             AbortMessage();
471             throw;
472         }
473     }
474
475     void PushRequest(const char* pszCommand,
476                      void (*fn)(void*, CDataStream&), void* param1)
477     {
478         uint256 hashReply;
479         RAND_bytes((unsigned char*)&hashReply, sizeof(hashReply));
480
481         {
482             LOCK(cs_mapRequests);
483             mapRequests[hashReply] = CRequestTracker(fn, param1);
484         }
485
486         PushMessage(pszCommand, hashReply);
487     }
488
489     template<typename T1>
490     void PushRequest(const char* pszCommand, const T1& a1,
491                      void (*fn)(void*, CDataStream&), void* param1)
492     {
493         uint256 hashReply;
494         RAND_bytes((unsigned char*)&hashReply, sizeof(hashReply));
495
496         {
497             LOCK(cs_mapRequests);
498             mapRequests[hashReply] = CRequestTracker(fn, param1);
499         }
500
501         PushMessage(pszCommand, hashReply, a1);
502     }
503
504     template<typename T1, typename T2>
505     void PushRequest(const char* pszCommand, const T1& a1, const T2& a2,
506                      void (*fn)(void*, CDataStream&), void* param1)
507     {
508         uint256 hashReply;
509         RAND_bytes((unsigned char*)&hashReply, sizeof(hashReply));
510
511         {
512             LOCK(cs_mapRequests);
513             mapRequests[hashReply] = CRequestTracker(fn, param1);
514         }
515
516         PushMessage(pszCommand, hashReply, a1, a2);
517     }
518
519
520
521     void PushGetBlocks(CBlockIndex* pindexBegin, uint256 hashEnd);
522     bool IsSubscribed(unsigned int nChannel);
523     void Subscribe(unsigned int nChannel, unsigned int nHops=0);
524     void CancelSubscribe(unsigned int nChannel);
525     void CloseSocketDisconnect();
526     void Cleanup();
527
528
529     // Denial-of-service detection/prevention
530     // The idea is to detect peers that are behaving
531     // badly and disconnect/ban them, but do it in a
532     // one-coding-mistake-won't-shatter-the-entire-network
533     // way.
534     // IMPORTANT:  There should be nothing I can give a
535     // node that it will forward on that will make that
536     // node's peers drop it. If there is, an attacker
537     // can isolate a node and/or try to split the network.
538     // Dropping a node for sending stuff that is invalid
539     // now but might be valid in a later version is also
540     // dangerous, because it can cause a network split
541     // between nodes running old code and nodes running
542     // new code.
543     static void ClearBanned(); // needed for unit testing
544     static bool IsBanned(CNetAddr ip);
545     bool Misbehaving(int howmuch); // 1 == a little, 100 == a lot
546     void copyStats(CNodeStats &stats);
547     // Network stats
548     static void RecordBytesRecv(uint64_t bytes);
549     static void RecordBytesSent(uint64_t bytes);
550
551     static uint64_t GetTotalBytesRecv();
552     static uint64_t GetTotalBytesSent();
553 };
554
555 inline void RelayInventory(const CInv& inv)
556 {
557     // Put on lists to offer to the other nodes
558     {
559         LOCK(cs_vNodes);
560         for (CNode* pnode : vNodes)
561             pnode->PushInventory(inv);
562     }
563 }
564
565 class CTransaction;
566 void RelayTransaction(const CTransaction& tx, const uint256& hash);
567 void RelayTransaction(const CTransaction& tx, const uint256& hash, const CDataStream& ss);
568
569
570 /** Return a timestamp in the future (in microseconds) for exponentially distributed events. */
571 int64_t PoissonNextSend(int64_t nNow, int average_interval_seconds);
572
573 #endif