LCOV - code coverage report
Current view: top level - src - net.h (source / functions) Hit Total Coverage
Test: total_coverage.info Lines: 80 124 64.5 %
Date: 2015-10-12 22:39:14 Functions: 27 49 55.1 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : // Copyright (c) 2009-2010 Satoshi Nakamoto
       2             : // Copyright (c) 2009-2014 The Bitcoin Core developers
       3             : // Distributed under the MIT 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 "limitedmap.h"
      12             : #include "mruset.h"
      13             : #include "netbase.h"
      14             : #include "protocol.h"
      15             : #include "random.h"
      16             : #include "streams.h"
      17             : #include "sync.h"
      18             : #include "uint256.h"
      19             : 
      20             : #include <deque>
      21             : #include <stdint.h>
      22             : 
      23             : #ifndef WIN32
      24             : #include <arpa/inet.h>
      25             : #endif
      26             : 
      27             : #include <boost/filesystem/path.hpp>
      28             : #include <boost/foreach.hpp>
      29             : #include <boost/signals2/signal.hpp>
      30             : 
      31             : class CAddrMan;
      32             : class CScheduler;
      33             : class CNode;
      34             : 
      35             : namespace boost {
      36             :     class thread_group;
      37             : } // namespace boost
      38             : 
      39             : /** Time between pings automatically sent out for latency probing and keepalive (in seconds). */
      40             : static const int PING_INTERVAL = 2 * 60;
      41             : /** Time after which to disconnect, after waiting for a ping response (or inactivity). */
      42             : static const int TIMEOUT_INTERVAL = 20 * 60;
      43             : /** The maximum number of entries in an 'inv' protocol message */
      44             : static const unsigned int MAX_INV_SZ = 50000;
      45             : /** The maximum number of new addresses to accumulate before announcing. */
      46             : static const unsigned int MAX_ADDR_TO_SEND = 1000;
      47             : /** Maximum length of incoming protocol messages (no message over 2 MiB is currently acceptable). */
      48             : static const unsigned int MAX_PROTOCOL_MESSAGE_LENGTH = 2 * 1024 * 1024;
      49             : /** Maximum length of strSubVer in `version` message */
      50             : static const unsigned int MAX_SUBVERSION_LENGTH = 256;
      51             : /** -listen default */
      52             : static const bool DEFAULT_LISTEN = true;
      53             : /** -upnp default */
      54             : #ifdef USE_UPNP
      55             : static const bool DEFAULT_UPNP = USE_UPNP;
      56             : #else
      57             : static const bool DEFAULT_UPNP = false;
      58             : #endif
      59             : /** The maximum number of entries in mapAskFor */
      60             : static const size_t MAPASKFOR_MAX_SZ = MAX_INV_SZ;
      61             : /** The maximum number of peer connections to maintain. */
      62             : static const unsigned int DEFAULT_MAX_PEER_CONNECTIONS = 125;
      63             : 
      64             : unsigned int ReceiveFloodSize();
      65             : unsigned int SendBufferSize();
      66             : 
      67             : void AddOneShot(const std::string& strDest);
      68             : void AddressCurrentlyConnected(const CService& addr);
      69             : CNode* FindNode(const CNetAddr& ip);
      70             : CNode* FindNode(const CSubNet& subNet);
      71             : CNode* FindNode(const std::string& addrName);
      72             : CNode* FindNode(const CService& ip);
      73             : CNode* ConnectNode(CAddress addrConnect, const char *pszDest = NULL);
      74             : bool OpenNetworkConnection(const CAddress& addrConnect, CSemaphoreGrant *grantOutbound = NULL, const char *strDest = NULL, bool fOneShot = false);
      75             : void MapPort(bool fUseUPnP);
      76             : unsigned short GetListenPort();
      77             : bool BindListenPort(const CService &bindAddr, std::string& strError, bool fWhitelisted = false);
      78             : void StartNode(boost::thread_group& threadGroup, CScheduler& scheduler);
      79             : bool StopNode();
      80             : void SocketSendData(CNode *pnode);
      81             : 
      82             : typedef int NodeId;
      83             : 
      84             : struct CombinerAll
      85             : {
      86             :     typedef bool result_type;
      87             : 
      88             :     template<typename I>
      89      118431 :     bool operator()(I first, I last) const
      90             :     {
      91      236858 :         while (first != last) {
      92      118429 :             if (!(*first)) return false;
      93             :             ++first;
      94             :         }
      95             :         return true;
      96             :     }
      97             : };
      98             : 
      99             : // Signals for message handling
     100        1152 : struct CNodeSignals
     101             : {
     102             :     boost::signals2::signal<int ()> GetHeight;
     103             :     boost::signals2::signal<bool (CNode*), CombinerAll> ProcessMessages;
     104             :     boost::signals2::signal<bool (CNode*, bool), CombinerAll> SendMessages;
     105             :     boost::signals2::signal<void (NodeId, const CNode*)> InitializeNode;
     106             :     boost::signals2::signal<void (NodeId)> FinalizeNode;
     107             : };
     108             : 
     109             : 
     110             : CNodeSignals& GetNodeSignals();
     111             : 
     112             : 
     113             : enum
     114             : {
     115             :     LOCAL_NONE,   // unknown
     116             :     LOCAL_IF,     // address a local interface listens on
     117             :     LOCAL_BIND,   // address explicit bound to
     118             :     LOCAL_UPNP,   // address reported by UPnP
     119             :     LOCAL_MANUAL, // address explicitly specified (-externalip=)
     120             : 
     121             :     LOCAL_MAX
     122             : };
     123             : 
     124             : bool IsPeerAddrLocalGood(CNode *pnode);
     125             : void AdvertizeLocal(CNode *pnode);
     126             : void SetLimited(enum Network net, bool fLimited = true);
     127             : bool IsLimited(enum Network net);
     128             : bool IsLimited(const CNetAddr& addr);
     129             : bool AddLocal(const CService& addr, int nScore = LOCAL_NONE);
     130             : bool AddLocal(const CNetAddr& addr, int nScore = LOCAL_NONE);
     131             : bool SeenLocal(const CService& addr);
     132             : bool IsLocal(const CService& addr);
     133             : bool GetLocal(CService &addr, const CNetAddr *paddrPeer = NULL);
     134             : bool IsReachable(enum Network net);
     135             : bool IsReachable(const CNetAddr &addr);
     136             : void SetReachable(enum Network net, bool fFlag = true);
     137             : CAddress GetLocalAddress(const CNetAddr *paddrPeer = NULL);
     138             : 
     139             : 
     140             : extern bool fDiscover;
     141             : extern bool fListen;
     142             : extern uint64_t nLocalServices;
     143             : extern uint64_t nLocalHostNonce;
     144             : extern CAddrMan addrman;
     145             : 
     146             : /** Maximum number of connections to simultaneously allow (aka connection slots) */
     147             : extern int nMaxConnections;
     148             : 
     149             : extern std::vector<CNode*> vNodes;
     150             : extern CCriticalSection cs_vNodes;
     151             : extern std::map<CInv, CDataStream> mapRelay;
     152             : extern std::deque<std::pair<int64_t, CInv> > vRelayExpiration;
     153             : extern CCriticalSection cs_mapRelay;
     154             : extern limitedmap<CInv, int64_t> mapAlreadyAskedFor;
     155             : 
     156             : extern std::vector<std::string> vAddedNodes;
     157             : extern CCriticalSection cs_vAddedNodes;
     158             : 
     159             : extern NodeId nLastNodeId;
     160             : extern CCriticalSection cs_nLastNodeId;
     161             : 
     162             : /** Subversion as sent to the P2P network in `version` messages */
     163             : extern std::string strSubVersion;
     164             : 
     165             : struct LocalServiceInfo {
     166             :     int nScore;
     167             :     int nPort;
     168             : };
     169             : 
     170             : extern CCriticalSection cs_mapLocalHost;
     171             : extern std::map<CNetAddr, LocalServiceInfo> mapLocalHost;
     172             : 
     173        6456 : class CNodeStats
     174             : {
     175             : public:
     176             :     NodeId nodeid;
     177             :     uint64_t nServices;
     178             :     int64_t nLastSend;
     179             :     int64_t nLastRecv;
     180             :     int64_t nTimeConnected;
     181             :     int64_t nTimeOffset;
     182             :     std::string addrName;
     183             :     int nVersion;
     184             :     std::string cleanSubVer;
     185             :     bool fInbound;
     186             :     int nStartingHeight;
     187             :     uint64_t nSendBytes;
     188             :     uint64_t nRecvBytes;
     189             :     bool fWhitelisted;
     190             :     double dPingTime;
     191             :     double dPingWait;
     192             :     double dPingMin;
     193             :     std::string addrLocal;
     194             : };
     195             : 
     196             : 
     197             : 
     198             : 
     199      190853 : class CNetMessage {
     200             : public:
     201             :     bool in_data;                   // parsing header (false) or data (true)
     202             : 
     203             :     CDataStream hdrbuf;             // partially received header
     204             :     CMessageHeader hdr;             // complete header
     205             :     unsigned int nHdrPos;
     206             : 
     207             :     CDataStream vRecv;              // received message data
     208             :     unsigned int nDataPos;
     209             : 
     210             :     int64_t nTime;                  // time (in microseconds) of message receipt.
     211             : 
     212       42412 :     CNetMessage(const CMessageHeader::MessageStartChars& pchMessageStartIn, int nTypeIn, int nVersionIn) : hdrbuf(nTypeIn, nVersionIn), hdr(pchMessageStartIn), vRecv(nTypeIn, nVersionIn) {
     213       21206 :         hdrbuf.resize(24);
     214       21206 :         in_data = false;
     215       21206 :         nHdrPos = 0;
     216       21206 :         nDataPos = 0;
     217       21206 :         nTime = 0;
     218       21206 :     }
     219             : 
     220             :     bool complete() const
     221             :     {
     222      126001 :         if (!in_data)
     223             :             return false;
     224      126001 :         return (hdr.nMessageSize == nDataPos);
     225             :     }
     226             : 
     227             :     void SetVersion(int nVersionIn)
     228             :     {
     229         448 :         hdrbuf.SetVersion(nVersionIn);
     230         448 :         vRecv.SetVersion(nVersionIn);
     231             :     }
     232             : 
     233             :     int readHeader(const char *pch, unsigned int nBytes);
     234             :     int readData(const char *pch, unsigned int nBytes);
     235             : };
     236             : 
     237             : 
     238             : typedef enum BanReason
     239             : {
     240             :     BanReasonUnknown          = 0,
     241             :     BanReasonNodeMisbehaving  = 1,
     242             :     BanReasonManuallyAdded    = 2
     243             : } BanReason;
     244             : 
     245             : class CBanEntry
     246             : {
     247             : public:
     248             :     static const int CURRENT_VERSION=1;
     249             :     int nVersion;
     250             :     int64_t nCreateTime;
     251             :     int64_t nBanUntil;
     252             :     uint8_t banReason;
     253             : 
     254           0 :     CBanEntry()
     255             :     {
     256             :         SetNull();
     257           0 :     }
     258             : 
     259           0 :     CBanEntry(int64_t nCreateTimeIn)
     260             :     {
     261             :         SetNull();
     262          17 :         nCreateTime = nCreateTimeIn;
     263           0 :     }
     264             : 
     265          25 :     ADD_SERIALIZE_METHODS;
     266             : 
     267             :     template <typename Stream, typename Operation>
     268          25 :     inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) {
     269          25 :         READWRITE(this->nVersion);
     270          25 :         nVersion = this->nVersion;
     271          25 :         READWRITE(nCreateTime);
     272          25 :         READWRITE(nBanUntil);
     273          25 :         READWRITE(banReason);
     274          25 :     }
     275             : 
     276             :     void SetNull()
     277             :     {
     278          20 :         nVersion = CBanEntry::CURRENT_VERSION;
     279          20 :         nCreateTime = 0;
     280          20 :         nBanUntil = 0;
     281          20 :         banReason = BanReasonUnknown;
     282             :     }
     283             : 
     284          17 :     std::string banReasonToString()
     285             :     {
     286          17 :         switch (banReason) {
     287             :         case BanReasonNodeMisbehaving:
     288           0 :             return "node misbehabing";
     289             :         case BanReasonManuallyAdded:
     290          34 :             return "manually added";
     291             :         default:
     292           0 :             return "unknown";
     293             :         }
     294             :     }
     295             : };
     296             : 
     297             : typedef std::map<CSubNet, CBanEntry> banmap_t;
     298             : 
     299             : /** Information about a peer */
     300             : class CNode
     301             : {
     302             : public:
     303             :     // socket
     304             :     uint64_t nServices;
     305             :     SOCKET hSocket;
     306             :     CDataStream ssSend;
     307             :     size_t nSendSize; // total size of all vSendMsg entries
     308             :     size_t nSendOffset; // offset inside the first vSendMsg already sent
     309             :     uint64_t nSendBytes;
     310             :     std::deque<CSerializeData> vSendMsg;
     311             :     CCriticalSection cs_vSend;
     312             : 
     313             :     std::deque<CInv> vRecvGetData;
     314             :     std::deque<CNetMessage> vRecvMsg;
     315             :     CCriticalSection cs_vRecvMsg;
     316             :     uint64_t nRecvBytes;
     317             :     int nRecvVersion;
     318             : 
     319             :     int64_t nLastSend;
     320             :     int64_t nLastRecv;
     321             :     int64_t nTimeConnected;
     322             :     int64_t nTimeOffset;
     323             :     CAddress addr;
     324             :     std::string addrName;
     325             :     CService addrLocal;
     326             :     int nVersion;
     327             :     // strSubVer is whatever byte array we read from the wire. However, this field is intended
     328             :     // to be printed out, displayed to humans in various forms and so on. So we sanitize it and
     329             :     // store the sanitized version in cleanSubVer. The original should be used when dealing with
     330             :     // the network or wire types and the cleaned string used when displayed or logged.
     331             :     std::string strSubVer, cleanSubVer;
     332             :     bool fWhitelisted; // This peer can bypass DoS banning.
     333             :     bool fOneShot;
     334             :     bool fClient;
     335             :     bool fInbound;
     336             :     bool fNetworkNode;
     337             :     bool fSuccessfullyConnected;
     338             :     bool fDisconnect;
     339             :     // We use fRelayTxes for two purposes -
     340             :     // a) it allows us to not relay tx invs before receiving the peer's version message
     341             :     // b) the peer may tell us in its version message that we should not relay tx invs
     342             :     //    until it has initialized its bloom filter.
     343             :     bool fRelayTxes;
     344             :     CSemaphoreGrant grantOutbound;
     345             :     CCriticalSection cs_filter;
     346             :     CBloomFilter* pfilter;
     347             :     int nRefCount;
     348             :     NodeId id;
     349             : protected:
     350             : 
     351             :     // Denial-of-service detection/prevention
     352             :     // Key is IP address, value is banned-until-time
     353             :     static banmap_t setBanned;
     354             :     static CCriticalSection cs_setBanned;
     355             :     static bool setBannedIsDirty;
     356             : 
     357             :     // Whitelisted ranges. Any node connecting from these is automatically
     358             :     // whitelisted (as well as those connecting to whitelisted binds).
     359             :     static std::vector<CSubNet> vWhitelistedRange;
     360             :     static CCriticalSection cs_vWhitelistedRange;
     361             : 
     362             :     // Basic fuzz-testing
     363             :     void Fuzz(int nChance); // modifies ssSend
     364             : 
     365             : public:
     366             :     uint256 hashContinue;
     367             :     int nStartingHeight;
     368             : 
     369             :     // flood relay
     370             :     std::vector<CAddress> vAddrToSend;
     371             :     CRollingBloomFilter addrKnown;
     372             :     bool fGetAddr;
     373             :     std::set<uint256> setKnown;
     374             : 
     375             :     // inventory based relay
     376             :     mruset<CInv> setInventoryKnown;
     377             :     std::vector<CInv> vInventoryToSend;
     378             :     CCriticalSection cs_inventory;
     379             :     std::multimap<int64_t, CInv> mapAskFor;
     380             : 
     381             :     // Ping time measurement:
     382             :     // The pong reply we're expecting, or 0 if no pong expected.
     383             :     uint64_t nPingNonceSent;
     384             :     // Time (in usec) the last ping was sent, or 0 if no ping was ever sent.
     385             :     int64_t nPingUsecStart;
     386             :     // Last measured round-trip time.
     387             :     int64_t nPingUsecTime;
     388             :     // Best measured round-trip time.
     389             :     int64_t nMinPingUsecTime;
     390             :     // Whether a ping is requested.
     391             :     bool fPingQueued;
     392             : 
     393             :     CNode(SOCKET hSocketIn, const CAddress &addrIn, const std::string &addrNameIn = "", bool fInboundIn = false);
     394             :     ~CNode();
     395             : 
     396             : private:
     397             :     // Network usage totals
     398             :     static CCriticalSection cs_totalBytesRecv;
     399             :     static CCriticalSection cs_totalBytesSent;
     400             :     static uint64_t nTotalBytesRecv;
     401             :     static uint64_t nTotalBytesSent;
     402             : 
     403             :     CNode(const CNode&);
     404             :     void operator=(const CNode&);
     405             : 
     406             : public:
     407             : 
     408           0 :     NodeId GetId() const {
     409           0 :       return id;
     410             :     }
     411             : 
     412           0 :     int GetRefCount()
     413             :     {
     414       59305 :         assert(nRefCount >= 0);
     415           0 :         return nRefCount;
     416             :     }
     417             : 
     418             :     // requires LOCK(cs_vRecvMsg)
     419       11580 :     unsigned int GetTotalRecvSize()
     420             :     {
     421       11580 :         unsigned int total = 0;
     422      466000 :         BOOST_FOREACH(const CNetMessage &msg, vRecvMsg)
     423      198260 :             total += msg.vRecv.size() + 24;
     424       11580 :         return total;
     425             :     }
     426             : 
     427             :     // requires LOCK(cs_vRecvMsg)
     428             :     bool ReceiveMsgBytes(const char *pch, unsigned int nBytes);
     429             : 
     430             :     // requires LOCK(cs_vRecvMsg)
     431         250 :     void SetRecvVersion(int nVersionIn)
     432             :     {
     433         250 :         nRecvVersion = nVersionIn;
     434        3740 :         BOOST_FOREACH(CNetMessage &msg, vRecvMsg)
     435             :             msg.SetVersion(nVersionIn);
     436         250 :     }
     437             : 
     438             :     CNode* AddRef()
     439             :     {
     440      118931 :         nRefCount++;
     441             :         return this;
     442             :     }
     443             : 
     444           0 :     void Release()
     445             :     {
     446      118705 :         nRefCount--;
     447           0 :     }
     448             : 
     449             : 
     450             : 
     451           0 :     void AddAddressKnown(const CAddress& addr)
     452             :     {
     453           0 :         addrKnown.insert(addr.GetKey());
     454           0 :     }
     455             : 
     456           0 :     void PushAddress(const CAddress& addr)
     457             :     {
     458             :         // Known checking here is only to save space from duplicates.
     459             :         // SendMessages will filter it again for knowns that were added
     460             :         // after addresses were pushed.
     461           0 :         if (addr.IsValid() && !addrKnown.contains(addr.GetKey())) {
     462           0 :             if (vAddrToSend.size() >= MAX_ADDR_TO_SEND) {
     463           0 :                 vAddrToSend[insecure_rand() % vAddrToSend.size()] = addr;
     464             :             } else {
     465           0 :                 vAddrToSend.push_back(addr);
     466             :             }
     467             :         }
     468           0 :     }
     469             : 
     470             : 
     471       12769 :     void AddInventoryKnown(const CInv& inv)
     472             :     {
     473             :         {
     474       12769 :             LOCK(cs_inventory);
     475       12769 :             setInventoryKnown.insert(inv);
     476             :         }
     477       12769 :     }
     478             : 
     479       14989 :     void PushInventory(const CInv& inv)
     480             :     {
     481             :         {
     482       14989 :             LOCK(cs_inventory);
     483       29978 :             if (!setInventoryKnown.count(inv))
     484        8339 :                 vInventoryToSend.push_back(inv);
     485             :         }
     486       14989 :     }
     487             : 
     488             :     void AskFor(const CInv& inv);
     489             : 
     490             :     // TODO: Document the postcondition of this function.  Is cs_vSend locked?
     491             :     void BeginMessage(const char* pszCommand) EXCLUSIVE_LOCK_FUNCTION(cs_vSend);
     492             : 
     493             :     // TODO: Document the precondition of this function.  Is cs_vSend locked?
     494             :     void AbortMessage() UNLOCK_FUNCTION(cs_vSend);
     495             : 
     496             :     // TODO: Document the precondition of this function.  Is cs_vSend locked?
     497             :     void EndMessage() UNLOCK_FUNCTION(cs_vSend);
     498             : 
     499             :     void PushVersion();
     500             : 
     501             : 
     502         378 :     void PushMessage(const char* pszCommand)
     503             :     {
     504             :         try
     505             :         {
     506         378 :             BeginMessage(pszCommand);
     507         378 :             EndMessage();
     508             :         }
     509           0 :         catch (...)
     510             :         {
     511           0 :             AbortMessage();
     512           0 :             throw;
     513             :         }
     514         378 :     }
     515             : 
     516             :     template<typename T1>
     517       15526 :     void PushMessage(const char* pszCommand, const T1& a1)
     518             :     {
     519             :         try
     520             :         {
     521       15526 :             BeginMessage(pszCommand);
     522       15526 :             ssSend << a1;
     523       15526 :             EndMessage();
     524             :         }
     525           0 :         catch (...)
     526             :         {
     527           0 :             AbortMessage();
     528           0 :             throw;
     529             :         }
     530       15526 :     }
     531             : 
     532             :     template<typename T1, typename T2>
     533        4752 :     void PushMessage(const char* pszCommand, const T1& a1, const T2& a2)
     534             :     {
     535             :         try
     536             :         {
     537        4752 :             BeginMessage(pszCommand);
     538        9504 :             ssSend << a1 << a2;
     539        4752 :             EndMessage();
     540             :         }
     541           0 :         catch (...)
     542             :         {
     543           0 :             AbortMessage();
     544           0 :             throw;
     545             :         }
     546        4752 :     }
     547             : 
     548             :     template<typename T1, typename T2, typename T3>
     549           0 :     void PushMessage(const char* pszCommand, const T1& a1, const T2& a2, const T3& a3)
     550             :     {
     551             :         try
     552             :         {
     553           0 :             BeginMessage(pszCommand);
     554           0 :             ssSend << a1 << a2 << a3;
     555           0 :             EndMessage();
     556             :         }
     557           0 :         catch (...)
     558             :         {
     559           0 :             AbortMessage();
     560           0 :             throw;
     561             :         }
     562           0 :     }
     563             : 
     564             :     template<typename T1, typename T2, typename T3, typename T4>
     565          53 :     void PushMessage(const char* pszCommand, const T1& a1, const T2& a2, const T3& a3, const T4& a4)
     566             :     {
     567             :         try
     568             :         {
     569          53 :             BeginMessage(pszCommand);
     570         212 :             ssSend << a1 << a2 << a3 << a4;
     571          53 :             EndMessage();
     572             :         }
     573           0 :         catch (...)
     574             :         {
     575           0 :             AbortMessage();
     576           0 :             throw;
     577             :         }
     578          53 :     }
     579             : 
     580             :     template<typename T1, typename T2, typename T3, typename T4, typename T5>
     581             :     void PushMessage(const char* pszCommand, const T1& a1, const T2& a2, const T3& a3, const T4& a4, const T5& a5)
     582             :     {
     583             :         try
     584             :         {
     585             :             BeginMessage(pszCommand);
     586             :             ssSend << a1 << a2 << a3 << a4 << a5;
     587             :             EndMessage();
     588             :         }
     589             :         catch (...)
     590             :         {
     591             :             AbortMessage();
     592             :             throw;
     593             :         }
     594             :     }
     595             : 
     596             :     template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6>
     597             :     void PushMessage(const char* pszCommand, const T1& a1, const T2& a2, const T3& a3, const T4& a4, const T5& a5, const T6& a6)
     598             :     {
     599             :         try
     600             :         {
     601             :             BeginMessage(pszCommand);
     602             :             ssSend << a1 << a2 << a3 << a4 << a5 << a6;
     603             :             EndMessage();
     604             :         }
     605             :         catch (...)
     606             :         {
     607             :             AbortMessage();
     608             :             throw;
     609             :         }
     610             :     }
     611             : 
     612             :     template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7>
     613             :     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)
     614             :     {
     615             :         try
     616             :         {
     617             :             BeginMessage(pszCommand);
     618             :             ssSend << a1 << a2 << a3 << a4 << a5 << a6 << a7;
     619             :             EndMessage();
     620             :         }
     621             :         catch (...)
     622             :         {
     623             :             AbortMessage();
     624             :             throw;
     625             :         }
     626             :     }
     627             : 
     628             :     template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8>
     629             :     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)
     630             :     {
     631             :         try
     632             :         {
     633             :             BeginMessage(pszCommand);
     634             :             ssSend << a1 << a2 << a3 << a4 << a5 << a6 << a7 << a8;
     635             :             EndMessage();
     636             :         }
     637             :         catch (...)
     638             :         {
     639             :             AbortMessage();
     640             :             throw;
     641             :         }
     642             :     }
     643             : 
     644             :     template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9>
     645         265 :     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)
     646             :     {
     647             :         try
     648             :         {
     649         265 :             BeginMessage(pszCommand);
     650        2385 :             ssSend << a1 << a2 << a3 << a4 << a5 << a6 << a7 << a8 << a9;
     651         265 :             EndMessage();
     652             :         }
     653           0 :         catch (...)
     654             :         {
     655           0 :             AbortMessage();
     656           0 :             throw;
     657             :         }
     658         265 :     }
     659             : 
     660             :     void CloseSocketDisconnect();
     661             : 
     662             :     // Denial-of-service detection/prevention
     663             :     // The idea is to detect peers that are behaving
     664             :     // badly and disconnect/ban them, but do it in a
     665             :     // one-coding-mistake-won't-shatter-the-entire-network
     666             :     // way.
     667             :     // IMPORTANT:  There should be nothing I can give a
     668             :     // node that it will forward on that will make that
     669             :     // node's peers drop it. If there is, an attacker
     670             :     // can isolate a node and/or try to split the network.
     671             :     // Dropping a node for sending stuff that is invalid
     672             :     // now but might be valid in a later version is also
     673             :     // dangerous, because it can cause a network split
     674             :     // between nodes running old code and nodes running
     675             :     // new code.
     676             :     static void ClearBanned(); // needed for unit testing
     677             :     static bool IsBanned(CNetAddr ip);
     678             :     static bool IsBanned(CSubNet subnet);
     679             :     static void Ban(const CNetAddr &ip, const BanReason &banReason, int64_t bantimeoffset = 0, bool sinceUnixEpoch = false);
     680             :     static void Ban(const CSubNet &subNet, const BanReason &banReason, int64_t bantimeoffset = 0, bool sinceUnixEpoch = false);
     681             :     static bool Unban(const CNetAddr &ip);
     682             :     static bool Unban(const CSubNet &ip);
     683             :     static void GetBanned(banmap_t &banmap);
     684             :     static void SetBanned(const banmap_t &banmap);
     685             : 
     686             :     //!check is the banlist has unwritten changes
     687             :     static bool BannedSetIsDirty();
     688             :     //!set the "dirty" flag for the banlist
     689             :     static void SetBannedSetDirty(bool dirty=true);
     690             :     //!clean unused entries (if bantime has expired)
     691             :     static void SweepBanned();
     692             : 
     693             :     void copyStats(CNodeStats &stats);
     694             : 
     695             :     static bool IsWhitelistedRange(const CNetAddr &ip);
     696             :     static void AddWhitelistedRange(const CSubNet &subnet);
     697             : 
     698             :     // Network stats
     699             :     static void RecordBytesRecv(uint64_t bytes);
     700             :     static void RecordBytesSent(uint64_t bytes);
     701             : 
     702             :     static uint64_t GetTotalBytesRecv();
     703             :     static uint64_t GetTotalBytesSent();
     704             : };
     705             : 
     706             : 
     707             : 
     708             : class CTransaction;
     709             : void RelayTransaction(const CTransaction& tx);
     710             : void RelayTransaction(const CTransaction& tx, const CDataStream& ss);
     711             : 
     712             : /** Access to the (IP) address database (peers.dat) */
     713         376 : class CAddrDB
     714             : {
     715             : private:
     716             :     boost::filesystem::path pathAddr;
     717             : public:
     718             :     CAddrDB();
     719             :     bool Write(const CAddrMan& addr);
     720             :     bool Read(CAddrMan& addr);
     721             : };
     722             : 
     723             : /** Access to the banlist database (banlist.dat) */
     724         236 : class CBanDB
     725             : {
     726             : private:
     727             :     boost::filesystem::path pathBanlist;
     728             : public:
     729             :     CBanDB();
     730             :     bool Write(const banmap_t& banSet);
     731             :     bool Read(banmap_t& banSet);
     732             : };
     733             : 
     734             : void DumpBanlist();
     735             : 
     736             : #endif // BITCOIN_NET_H

Generated by: LCOV version 1.11