]> Git Repo - VerusCoin.git/blob - src/net.h
Merge pull request #5076
[VerusCoin.git] / src / net.h
1 // Copyright (c) 2009-2010 Satoshi Nakamoto
2 // Copyright (c) 2009-2014 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
6 #ifndef BITCOIN_NET_H
7 #define BITCOIN_NET_H
8
9 #include "bloom.h"
10 #include "compat.h"
11 #include "hash.h"
12 #include "limitedmap.h"
13 #include "mruset.h"
14 #include "netbase.h"
15 #include "protocol.h"
16 #include "random.h"
17 #include "sync.h"
18 #include "uint256.h"
19 #include "utilstrencodings.h"
20
21 #include <deque>
22 #include <stdint.h>
23
24 #ifndef WIN32
25 #include <arpa/inet.h>
26 #endif
27
28 #include <boost/filesystem/path.hpp>
29 #include <boost/foreach.hpp>
30 #include <boost/signals2/signal.hpp>
31
32 class CAddrMan;
33 class CBlockIndex;
34 class CNode;
35
36 namespace boost {
37     class thread_group;
38 } // namespace boost
39
40 /** Time between pings automatically sent out for latency probing and keepalive (in seconds). */
41 static const int PING_INTERVAL = 2 * 60;
42 /** Time after which to disconnect, after waiting for a ping response (or inactivity). */
43 static const int TIMEOUT_INTERVAL = 20 * 60;
44 /** The maximum number of entries in an 'inv' protocol message */
45 static const unsigned int MAX_INV_SZ = 50000;
46 /** -listen default */
47 static const bool DEFAULT_LISTEN = true;
48 /** -upnp default */
49 #ifdef USE_UPNP
50 static const bool DEFAULT_UPNP = USE_UPNP;
51 #else
52 static const bool DEFAULT_UPNP = false;
53 #endif
54 /** The maximum number of entries in mapAskFor */
55 static const size_t MAPASKFOR_MAX_SZ = MAX_INV_SZ;
56
57 unsigned int ReceiveFloodSize();
58 unsigned int SendBufferSize();
59
60 void AddOneShot(std::string strDest);
61 bool RecvLine(SOCKET hSocket, std::string& strLine);
62 bool GetMyExternalIP(CNetAddr& ipRet);
63 void AddressCurrentlyConnected(const CService& addr);
64 CNode* FindNode(const CNetAddr& ip);
65 CNode* FindNode(const std::string& addrName);
66 CNode* FindNode(const CService& ip);
67 CNode* ConnectNode(CAddress addrConnect, const char *pszDest = NULL);
68 bool OpenNetworkConnection(const CAddress& addrConnect, CSemaphoreGrant *grantOutbound = NULL, const char *strDest = NULL, bool fOneShot = false);
69 void MapPort(bool fUseUPnP);
70 unsigned short GetListenPort();
71 bool BindListenPort(const CService &bindAddr, std::string& strError, bool fWhitelisted = false);
72 void StartNode(boost::thread_group& threadGroup);
73 bool StopNode();
74 void SocketSendData(CNode *pnode);
75
76 typedef int NodeId;
77
78 // Signals for message handling
79 struct CNodeSignals
80 {
81     boost::signals2::signal<int ()> GetHeight;
82     boost::signals2::signal<bool (CNode*)> ProcessMessages;
83     boost::signals2::signal<bool (CNode*, bool)> SendMessages;
84     boost::signals2::signal<void (NodeId, const CNode*)> InitializeNode;
85     boost::signals2::signal<void (NodeId)> FinalizeNode;
86 };
87
88
89 CNodeSignals& GetNodeSignals();
90
91
92 enum
93 {
94     LOCAL_NONE,   // unknown
95     LOCAL_IF,     // address a local interface listens on
96     LOCAL_BIND,   // address explicit bound to
97     LOCAL_UPNP,   // address reported by UPnP
98     LOCAL_HTTP,   // address reported by whatismyip.com and similar
99     LOCAL_MANUAL, // address explicitly specified (-externalip=)
100
101     LOCAL_MAX
102 };
103
104 void SetLimited(enum Network net, bool fLimited = true);
105 bool IsLimited(enum Network net);
106 bool IsLimited(const CNetAddr& addr);
107 bool AddLocal(const CService& addr, int nScore = LOCAL_NONE);
108 bool AddLocal(const CNetAddr& addr, int nScore = LOCAL_NONE);
109 bool SeenLocal(const CService& addr);
110 bool IsLocal(const CService& addr);
111 bool GetLocal(CService &addr, const CNetAddr *paddrPeer = NULL);
112 bool IsReachable(enum Network net);
113 bool IsReachable(const CNetAddr &addr);
114 void SetReachable(enum Network net, bool fFlag = true);
115 CAddress GetLocalAddress(const CNetAddr *paddrPeer = NULL);
116
117
118 extern bool fDiscover;
119 extern bool fListen;
120 extern uint64_t nLocalServices;
121 extern uint64_t nLocalHostNonce;
122 extern CAddrMan addrman;
123 extern int nMaxConnections;
124
125 extern std::vector<CNode*> vNodes;
126 extern CCriticalSection cs_vNodes;
127 extern std::map<CInv, CDataStream> mapRelay;
128 extern std::deque<std::pair<int64_t, CInv> > vRelayExpiration;
129 extern CCriticalSection cs_mapRelay;
130 extern limitedmap<CInv, int64_t> mapAlreadyAskedFor;
131
132 extern std::vector<std::string> vAddedNodes;
133 extern CCriticalSection cs_vAddedNodes;
134
135 extern NodeId nLastNodeId;
136 extern CCriticalSection cs_nLastNodeId;
137
138 struct LocalServiceInfo {
139     int nScore;
140     int nPort;
141 };
142
143 extern CCriticalSection cs_mapLocalHost;
144 extern std::map<CNetAddr, LocalServiceInfo> mapLocalHost;
145
146 class CNodeStats
147 {
148 public:
149     NodeId nodeid;
150     uint64_t nServices;
151     int64_t nLastSend;
152     int64_t nLastRecv;
153     int64_t nTimeConnected;
154     std::string addrName;
155     int nVersion;
156     std::string cleanSubVer;
157     bool fInbound;
158     int nStartingHeight;
159     uint64_t nSendBytes;
160     uint64_t nRecvBytes;
161     bool fWhitelisted;
162     double dPingTime;
163     double dPingWait;
164     std::string addrLocal;
165 };
166
167
168
169
170 class CNetMessage {
171 public:
172     bool in_data;                   // parsing header (false) or data (true)
173
174     CDataStream hdrbuf;             // partially received header
175     CMessageHeader hdr;             // complete header
176     unsigned int nHdrPos;
177
178     CDataStream vRecv;              // received message data
179     unsigned int nDataPos;
180
181     int64_t nTime;                  // time (in microseconds) of message receipt.
182
183     CNetMessage(int nTypeIn, int nVersionIn) : hdrbuf(nTypeIn, nVersionIn), vRecv(nTypeIn, nVersionIn) {
184         hdrbuf.resize(24);
185         in_data = false;
186         nHdrPos = 0;
187         nDataPos = 0;
188         nTime = 0;
189     }
190
191     bool complete() const
192     {
193         if (!in_data)
194             return false;
195         return (hdr.nMessageSize == nDataPos);
196     }
197
198     void SetVersion(int nVersionIn)
199     {
200         hdrbuf.SetVersion(nVersionIn);
201         vRecv.SetVersion(nVersionIn);
202     }
203
204     int readHeader(const char *pch, unsigned int nBytes);
205     int readData(const char *pch, unsigned int nBytes);
206 };
207
208
209
210
211
212 /** Information about a peer */
213 class CNode
214 {
215 public:
216     // socket
217     uint64_t nServices;
218     SOCKET hSocket;
219     CDataStream ssSend;
220     size_t nSendSize; // total size of all vSendMsg entries
221     size_t nSendOffset; // offset inside the first vSendMsg already sent
222     uint64_t nSendBytes;
223     std::deque<CSerializeData> vSendMsg;
224     CCriticalSection cs_vSend;
225
226     std::deque<CInv> vRecvGetData;
227     std::deque<CNetMessage> vRecvMsg;
228     CCriticalSection cs_vRecvMsg;
229     uint64_t nRecvBytes;
230     int nRecvVersion;
231
232     int64_t nLastSend;
233     int64_t nLastRecv;
234     int64_t nTimeConnected;
235     CAddress addr;
236     std::string addrName;
237     CService addrLocal;
238     int nVersion;
239     // strSubVer is whatever byte array we read from the wire. However, this field is intended
240     // to be printed out, displayed to humans in various forms and so on. So we sanitize it and
241     // store the sanitized version in cleanSubVer. The original should be used when dealing with
242     // the network or wire types and the cleaned string used when displayed or logged.
243     std::string strSubVer, cleanSubVer;
244     bool fWhitelisted; // This peer can bypass DoS banning.
245     bool fOneShot;
246     bool fClient;
247     bool fInbound;
248     bool fNetworkNode;
249     bool fSuccessfullyConnected;
250     bool fDisconnect;
251     // We use fRelayTxes for two purposes -
252     // a) it allows us to not relay tx invs before receiving the peer's version message
253     // b) the peer may tell us in their version message that we should not relay tx invs
254     //    until they have initialized their bloom filter.
255     bool fRelayTxes;
256     CSemaphoreGrant grantOutbound;
257     CCriticalSection cs_filter;
258     CBloomFilter* pfilter;
259     int nRefCount;
260     NodeId id;
261 protected:
262
263     // Denial-of-service detection/prevention
264     // Key is IP address, value is banned-until-time
265     static std::map<CNetAddr, int64_t> setBanned;
266     static CCriticalSection cs_setBanned;
267
268     // Whitelisted ranges. Any node connecting from these is automatically
269     // whitelisted (as well as those connecting to whitelisted binds).
270     static std::vector<CSubNet> vWhitelistedRange;
271     static CCriticalSection cs_vWhitelistedRange;
272
273     // Basic fuzz-testing
274     void Fuzz(int nChance); // modifies ssSend
275
276 public:
277     uint256 hashContinue;
278     int nStartingHeight;
279
280     // flood relay
281     std::vector<CAddress> vAddrToSend;
282     mruset<CAddress> setAddrKnown;
283     bool fGetAddr;
284     std::set<uint256> setKnown;
285
286     // inventory based relay
287     mruset<CInv> setInventoryKnown;
288     std::vector<CInv> vInventoryToSend;
289     CCriticalSection cs_inventory;
290     std::multimap<int64_t, CInv> mapAskFor;
291
292     // Ping time measurement:
293     // The pong reply we're expecting, or 0 if no pong expected.
294     uint64_t nPingNonceSent;
295     // Time (in usec) the last ping was sent, or 0 if no ping was ever sent.
296     int64_t nPingUsecStart;
297     // Last measured round-trip time.
298     int64_t nPingUsecTime;
299     // Whether a ping is requested.
300     bool fPingQueued;
301
302     CNode(SOCKET hSocketIn, CAddress addrIn, std::string addrNameIn = "", bool fInboundIn=false);
303     ~CNode();
304
305 private:
306     // Network usage totals
307     static CCriticalSection cs_totalBytesRecv;
308     static CCriticalSection cs_totalBytesSent;
309     static uint64_t nTotalBytesRecv;
310     static uint64_t nTotalBytesSent;
311
312     CNode(const CNode&);
313     void operator=(const CNode&);
314
315 public:
316
317     NodeId GetId() const {
318       return id;
319     }
320
321     int GetRefCount()
322     {
323         assert(nRefCount >= 0);
324         return nRefCount;
325     }
326
327     // requires LOCK(cs_vRecvMsg)
328     unsigned int GetTotalRecvSize()
329     {
330         unsigned int total = 0;
331         BOOST_FOREACH(const CNetMessage &msg, vRecvMsg)
332             total += msg.vRecv.size() + 24;
333         return total;
334     }
335
336     // requires LOCK(cs_vRecvMsg)
337     bool ReceiveMsgBytes(const char *pch, unsigned int nBytes);
338
339     // requires LOCK(cs_vRecvMsg)
340     void SetRecvVersion(int nVersionIn)
341     {
342         nRecvVersion = nVersionIn;
343         BOOST_FOREACH(CNetMessage &msg, vRecvMsg)
344             msg.SetVersion(nVersionIn);
345     }
346
347     CNode* AddRef()
348     {
349         nRefCount++;
350         return this;
351     }
352
353     void Release()
354     {
355         nRefCount--;
356     }
357
358
359
360     void AddAddressKnown(const CAddress& addr)
361     {
362         setAddrKnown.insert(addr);
363     }
364
365     void PushAddress(const CAddress& addr)
366     {
367         // Known checking here is only to save space from duplicates.
368         // SendMessages will filter it again for knowns that were added
369         // after addresses were pushed.
370         if (addr.IsValid() && !setAddrKnown.count(addr))
371             vAddrToSend.push_back(addr);
372     }
373
374
375     void AddInventoryKnown(const CInv& inv)
376     {
377         {
378             LOCK(cs_inventory);
379             setInventoryKnown.insert(inv);
380         }
381     }
382
383     void PushInventory(const CInv& inv)
384     {
385         {
386             LOCK(cs_inventory);
387             if (!setInventoryKnown.count(inv))
388                 vInventoryToSend.push_back(inv);
389         }
390     }
391
392     void AskFor(const CInv& inv);
393
394     // TODO: Document the postcondition of this function.  Is cs_vSend locked?
395     void BeginMessage(const char* pszCommand) EXCLUSIVE_LOCK_FUNCTION(cs_vSend);
396
397     // TODO: Document the precondition of this function.  Is cs_vSend locked?
398     void AbortMessage() UNLOCK_FUNCTION(cs_vSend);
399
400     // TODO: Document the precondition of this function.  Is cs_vSend locked?
401     void EndMessage() UNLOCK_FUNCTION(cs_vSend);
402
403     void PushVersion();
404
405
406     void PushMessage(const char* pszCommand)
407     {
408         try
409         {
410             BeginMessage(pszCommand);
411             EndMessage();
412         }
413         catch (...)
414         {
415             AbortMessage();
416             throw;
417         }
418     }
419
420     template<typename T1>
421     void PushMessage(const char* pszCommand, const T1& a1)
422     {
423         try
424         {
425             BeginMessage(pszCommand);
426             ssSend << a1;
427             EndMessage();
428         }
429         catch (...)
430         {
431             AbortMessage();
432             throw;
433         }
434     }
435
436     template<typename T1, typename T2>
437     void PushMessage(const char* pszCommand, const T1& a1, const T2& a2)
438     {
439         try
440         {
441             BeginMessage(pszCommand);
442             ssSend << a1 << a2;
443             EndMessage();
444         }
445         catch (...)
446         {
447             AbortMessage();
448             throw;
449         }
450     }
451
452     template<typename T1, typename T2, typename T3>
453     void PushMessage(const char* pszCommand, const T1& a1, const T2& a2, const T3& a3)
454     {
455         try
456         {
457             BeginMessage(pszCommand);
458             ssSend << a1 << a2 << a3;
459             EndMessage();
460         }
461         catch (...)
462         {
463             AbortMessage();
464             throw;
465         }
466     }
467
468     template<typename T1, typename T2, typename T3, typename T4>
469     void PushMessage(const char* pszCommand, const T1& a1, const T2& a2, const T3& a3, const T4& a4)
470     {
471         try
472         {
473             BeginMessage(pszCommand);
474             ssSend << a1 << a2 << a3 << a4;
475             EndMessage();
476         }
477         catch (...)
478         {
479             AbortMessage();
480             throw;
481         }
482     }
483
484     template<typename T1, typename T2, typename T3, typename T4, typename T5>
485     void PushMessage(const char* pszCommand, const T1& a1, const T2& a2, const T3& a3, const T4& a4, const T5& a5)
486     {
487         try
488         {
489             BeginMessage(pszCommand);
490             ssSend << a1 << a2 << a3 << a4 << a5;
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, typename T6>
501     void PushMessage(const char* pszCommand, const T1& a1, const T2& a2, const T3& a3, const T4& a4, const T5& a5, const T6& a6)
502     {
503         try
504         {
505             BeginMessage(pszCommand);
506             ssSend << a1 << a2 << a3 << a4 << a5 << a6;
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, typename T7>
517     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)
518     {
519         try
520         {
521             BeginMessage(pszCommand);
522             ssSend << a1 << a2 << a3 << a4 << a5 << a6 << a7;
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, typename T8>
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, const T8& a8)
534     {
535         try
536         {
537             BeginMessage(pszCommand);
538             ssSend << a1 << a2 << a3 << a4 << a5 << a6 << a7 << a8;
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, typename T9>
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, const T9& a9)
550     {
551         try
552         {
553             BeginMessage(pszCommand);
554             ssSend << a1 << a2 << a3 << a4 << a5 << a6 << a7 << a8 << a9;
555             EndMessage();
556         }
557         catch (...)
558         {
559             AbortMessage();
560             throw;
561         }
562     }
563
564     bool IsSubscribed(unsigned int nChannel);
565     void Subscribe(unsigned int nChannel, unsigned int nHops=0);
566     void CancelSubscribe(unsigned int nChannel);
567     void CloseSocketDisconnect();
568
569     // Denial-of-service detection/prevention
570     // The idea is to detect peers that are behaving
571     // badly and disconnect/ban them, but do it in a
572     // one-coding-mistake-won't-shatter-the-entire-network
573     // way.
574     // IMPORTANT:  There should be nothing I can give a
575     // node that it will forward on that will make that
576     // node's peers drop it. If there is, an attacker
577     // can isolate a node and/or try to split the network.
578     // Dropping a node for sending stuff that is invalid
579     // now but might be valid in a later version is also
580     // dangerous, because it can cause a network split
581     // between nodes running old code and nodes running
582     // new code.
583     static void ClearBanned(); // needed for unit testing
584     static bool IsBanned(CNetAddr ip);
585     static bool Ban(const CNetAddr &ip);
586     void copyStats(CNodeStats &stats);
587
588     static bool IsWhitelistedRange(const CNetAddr &ip);
589     static void AddWhitelistedRange(const CSubNet &subnet);
590
591     // Network stats
592     static void RecordBytesRecv(uint64_t bytes);
593     static void RecordBytesSent(uint64_t bytes);
594
595     static uint64_t GetTotalBytesRecv();
596     static uint64_t GetTotalBytesSent();
597 };
598
599
600
601 class CTransaction;
602 void RelayTransaction(const CTransaction& tx);
603 void RelayTransaction(const CTransaction& tx, const CDataStream& ss);
604
605 /** Access to the (IP) address database (peers.dat) */
606 class CAddrDB
607 {
608 private:
609     boost::filesystem::path pathAddr;
610 public:
611     CAddrDB();
612     bool Write(const CAddrMan& addr);
613     bool Read(CAddrMan& addr);
614 };
615
616 #endif // BITCOIN_NET_H
This page took 0.057633 seconds and 4 git commands to generate.