2010-08-29 18:58:15 +02:00
|
|
|
// Copyright (c) 2009-2010 Satoshi Nakamoto
|
2015-12-13 17:58:29 +01:00
|
|
|
// Copyright (c) 2009-2015 The Bitcoin Core developers
|
2014-12-13 05:09:33 +01:00
|
|
|
// Distributed under the MIT software license, see the accompanying
|
2012-05-18 16:02:28 +02:00
|
|
|
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
2013-04-13 07:13:08 +02:00
|
|
|
|
2011-05-15 09:11:04 +02:00
|
|
|
#ifndef BITCOIN_NET_H
|
|
|
|
#define BITCOIN_NET_H
|
|
|
|
|
2016-04-16 06:13:15 +02:00
|
|
|
#include "addrdb.h"
|
2016-04-16 23:43:11 +02:00
|
|
|
#include "addrman.h"
|
2016-02-12 21:57:15 +01:00
|
|
|
#include "amount.h"
|
2013-04-13 07:13:08 +02:00
|
|
|
#include "bloom.h"
|
|
|
|
#include "compat.h"
|
|
|
|
#include "limitedmap.h"
|
2016-05-31 23:42:38 +02:00
|
|
|
#include "netaddress.h"
|
2013-04-13 07:13:08 +02:00
|
|
|
#include "protocol.h"
|
2014-06-26 14:41:53 +02:00
|
|
|
#include "random.h"
|
2014-10-22 21:08:30 +02:00
|
|
|
#include "streams.h"
|
2013-04-13 07:13:08 +02:00
|
|
|
#include "sync.h"
|
|
|
|
#include "uint256.h"
|
|
|
|
|
2016-05-20 18:19:26 +02:00
|
|
|
#include <atomic>
|
2011-05-15 09:11:04 +02:00
|
|
|
#include <deque>
|
2013-04-13 07:13:08 +02:00
|
|
|
#include <stdint.h>
|
2016-04-16 20:47:18 +02:00
|
|
|
#include <memory>
|
2011-05-15 09:11:04 +02:00
|
|
|
|
2011-10-07 17:02:21 +02:00
|
|
|
#ifndef WIN32
|
2011-05-15 09:11:04 +02:00
|
|
|
#include <arpa/inet.h>
|
|
|
|
#endif
|
2010-08-29 18:58:15 +02:00
|
|
|
|
Split up util.cpp/h
Split up util.cpp/h into:
- string utilities (hex, base32, base64): no internal dependencies, no dependency on boost (apart from foreach)
- money utilities (parsesmoney, formatmoney)
- time utilities (gettime*, sleep, format date):
- and the rest (logging, argument parsing, config file parsing)
The latter is basically the environment and OS handling,
and is stripped of all utility functions, so we may want to
rename it to something else than util.cpp/h for clarity (Matt suggested
osinterface).
Breaks dependency of sha256.cpp on all the things pulled in by util.
2014-08-21 16:11:09 +02:00
|
|
|
#include <boost/filesystem/path.hpp>
|
2013-04-13 07:13:08 +02:00
|
|
|
#include <boost/foreach.hpp>
|
|
|
|
#include <boost/signals2/signal.hpp>
|
2013-06-06 09:04:33 +02:00
|
|
|
|
2013-04-13 07:13:08 +02:00
|
|
|
class CAddrMan;
|
2015-04-02 18:04:59 +02:00
|
|
|
class CScheduler;
|
2013-04-13 07:13:08 +02:00
|
|
|
class CNode;
|
2010-08-29 18:58:15 +02:00
|
|
|
|
2013-04-13 07:13:08 +02:00
|
|
|
namespace boost {
|
|
|
|
class thread_group;
|
2014-06-24 14:17:43 +02:00
|
|
|
} // namespace boost
|
2010-08-29 18:58:15 +02:00
|
|
|
|
2013-10-15 00:34:20 +02:00
|
|
|
/** Time between pings automatically sent out for latency probing and keepalive (in seconds). */
|
|
|
|
static const int PING_INTERVAL = 2 * 60;
|
|
|
|
/** Time after which to disconnect, after waiting for a ping response (or inactivity). */
|
|
|
|
static const int TIMEOUT_INTERVAL = 20 * 60;
|
2016-06-17 06:10:07 +02:00
|
|
|
/** Run the feeler connection loop once every 2 minutes or 120 seconds. **/
|
|
|
|
static const int FEELER_INTERVAL = 120;
|
2013-04-13 07:13:08 +02:00
|
|
|
/** The maximum number of entries in an 'inv' protocol message */
|
|
|
|
static const unsigned int MAX_INV_SZ = 50000;
|
2014-11-21 12:22:11 +01:00
|
|
|
/** The maximum number of new addresses to accumulate before announcing. */
|
|
|
|
static const unsigned int MAX_ADDR_TO_SEND = 1000;
|
2016-01-03 18:54:50 +01:00
|
|
|
/** Maximum length of incoming protocol messages (no message over 4 MB is currently acceptable). */
|
|
|
|
static const unsigned int MAX_PROTOCOL_MESSAGE_LENGTH = 4 * 1000 * 1000;
|
2015-07-31 18:05:42 +02:00
|
|
|
/** Maximum length of strSubVer in `version` message */
|
|
|
|
static const unsigned int MAX_SUBVERSION_LENGTH = 256;
|
2014-05-29 13:02:22 +02:00
|
|
|
/** -listen default */
|
|
|
|
static const bool DEFAULT_LISTEN = true;
|
2014-05-05 21:06:14 +02:00
|
|
|
/** -upnp default */
|
|
|
|
#ifdef USE_UPNP
|
|
|
|
static const bool DEFAULT_UPNP = USE_UPNP;
|
|
|
|
#else
|
|
|
|
static const bool DEFAULT_UPNP = false;
|
|
|
|
#endif
|
2014-09-09 09:18:05 +02:00
|
|
|
/** The maximum number of entries in mapAskFor */
|
|
|
|
static const size_t MAPASKFOR_MAX_SZ = MAX_INV_SZ;
|
2015-11-23 02:54:23 +01:00
|
|
|
/** The maximum number of entries in setAskFor (larger due to getdata latency)*/
|
|
|
|
static const size_t SETASKFOR_MAX_SZ = 2 * MAX_INV_SZ;
|
2015-08-01 19:41:21 +02:00
|
|
|
/** The maximum number of peer connections to maintain. */
|
|
|
|
static const unsigned int DEFAULT_MAX_PEER_CONNECTIONS = 125;
|
2015-11-06 00:05:06 +01:00
|
|
|
/** The default for -maxuploadtarget. 0 = Unlimited */
|
|
|
|
static const uint64_t DEFAULT_MAX_UPLOAD_TARGET = 0;
|
2015-11-14 13:47:53 +01:00
|
|
|
/** Default for blocks only*/
|
|
|
|
static const bool DEFAULT_BLOCKSONLY = false;
|
2010-08-29 18:58:15 +02:00
|
|
|
|
2015-06-27 21:21:41 +02:00
|
|
|
static const bool DEFAULT_FORCEDNSSEED = false;
|
|
|
|
static const size_t DEFAULT_MAXRECEIVEBUFFER = 5 * 1000;
|
|
|
|
static const size_t DEFAULT_MAXSENDBUFFER = 1 * 1000;
|
|
|
|
|
2016-06-13 16:01:21 +02:00
|
|
|
static const ServiceFlags REQUIRED_SERVICES = NODE_NETWORK;
|
|
|
|
|
2015-06-27 21:21:41 +02:00
|
|
|
// NOTE: When adjusting this, update rpcnet:setban's help ("24h")
|
|
|
|
static const unsigned int DEFAULT_MISBEHAVING_BANTIME = 60 * 60 * 24; // Default 24-hour ban
|
|
|
|
|
2014-08-21 05:17:21 +02:00
|
|
|
unsigned int ReceiveFloodSize();
|
|
|
|
unsigned int SendBufferSize();
|
2010-08-29 18:58:15 +02:00
|
|
|
|
2016-05-06 20:50:24 +02:00
|
|
|
typedef int NodeId;
|
|
|
|
|
2016-04-17 00:12:58 +02:00
|
|
|
struct AddedNodeInfo
|
|
|
|
{
|
|
|
|
std::string strAddedNode;
|
|
|
|
CService resolvedAddress;
|
|
|
|
bool fConnected;
|
|
|
|
bool fInbound;
|
|
|
|
};
|
|
|
|
|
2016-04-17 01:13:12 +02:00
|
|
|
class CTransaction;
|
2016-04-17 00:30:03 +02:00
|
|
|
class CNodeStats;
|
2016-04-16 20:47:18 +02:00
|
|
|
class CConnman
|
|
|
|
{
|
|
|
|
public:
|
2016-04-17 00:30:03 +02:00
|
|
|
|
|
|
|
enum NumConnections {
|
|
|
|
CONNECTIONS_NONE = 0,
|
|
|
|
CONNECTIONS_IN = (1U << 0),
|
|
|
|
CONNECTIONS_OUT = (1U << 1),
|
|
|
|
CONNECTIONS_ALL = (CONNECTIONS_IN | CONNECTIONS_OUT),
|
|
|
|
};
|
|
|
|
|
2016-04-16 20:47:18 +02:00
|
|
|
CConnman();
|
|
|
|
~CConnman();
|
2016-04-16 23:43:11 +02:00
|
|
|
bool Start(boost::thread_group& threadGroup, CScheduler& scheduler, std::string& strNodeError);
|
2016-04-16 20:47:18 +02:00
|
|
|
void Stop();
|
2016-04-16 21:46:00 +02:00
|
|
|
bool BindListenPort(const CService &bindAddr, std::string& strError, bool fWhitelisted = false);
|
2016-04-16 21:59:10 +02:00
|
|
|
bool OpenNetworkConnection(const CAddress& addrConnect, bool fCountFailure, CSemaphoreGrant *grantOutbound = NULL, const char *strDest = NULL, bool fOneShot = false, bool fFeeler = false);
|
2016-04-18 02:21:58 +02:00
|
|
|
bool CheckIncomingNonce(uint64_t nonce);
|
2016-04-16 21:46:00 +02:00
|
|
|
|
2016-04-17 01:13:12 +02:00
|
|
|
bool ForNode(NodeId id, std::function<bool(CNode* pnode)> func);
|
|
|
|
bool ForEachNode(std::function<bool(CNode* pnode)> func);
|
|
|
|
bool ForEachNode(std::function<bool(const CNode* pnode)> func) const;
|
|
|
|
bool ForEachNodeThen(std::function<bool(CNode* pnode)> pre, std::function<void()> post);
|
|
|
|
bool ForEachNodeThen(std::function<bool(const CNode* pnode)> pre, std::function<void()> post) const;
|
|
|
|
|
|
|
|
void RelayTransaction(const CTransaction& tx);
|
|
|
|
|
2016-04-16 23:43:11 +02:00
|
|
|
// Addrman functions
|
|
|
|
size_t GetAddressCount() const;
|
|
|
|
void SetServices(const CService &addr, ServiceFlags nServices);
|
|
|
|
void MarkAddressGood(const CAddress& addr);
|
|
|
|
void AddNewAddress(const CAddress& addr, const CAddress& addrFrom, int64_t nTimePenalty = 0);
|
|
|
|
void AddNewAddresses(const std::vector<CAddress>& vAddr, const CAddress& addrFrom, int64_t nTimePenalty = 0);
|
|
|
|
std::vector<CAddress> GetAddresses();
|
|
|
|
void AddressCurrentlyConnected(const CService& addr);
|
|
|
|
|
|
|
|
// Denial-of-service detection/prevention
|
|
|
|
// The idea is to detect peers that are behaving
|
|
|
|
// badly and disconnect/ban them, but do it in a
|
|
|
|
// one-coding-mistake-won't-shatter-the-entire-network
|
|
|
|
// way.
|
|
|
|
// IMPORTANT: There should be nothing I can give a
|
|
|
|
// node that it will forward on that will make that
|
|
|
|
// node's peers drop it. If there is, an attacker
|
|
|
|
// can isolate a node and/or try to split the network.
|
|
|
|
// Dropping a node for sending stuff that is invalid
|
|
|
|
// now but might be valid in a later version is also
|
|
|
|
// dangerous, because it can cause a network split
|
|
|
|
// between nodes running old code and nodes running
|
|
|
|
// new code.
|
|
|
|
void Ban(const CNetAddr& netAddr, const BanReason& reason, int64_t bantimeoffset = 0, bool sinceUnixEpoch = false);
|
|
|
|
void Ban(const CSubNet& subNet, const BanReason& reason, int64_t bantimeoffset = 0, bool sinceUnixEpoch = false);
|
|
|
|
void ClearBanned(); // needed for unit testing
|
|
|
|
bool IsBanned(CNetAddr ip);
|
|
|
|
bool IsBanned(CSubNet subnet);
|
|
|
|
bool Unban(const CNetAddr &ip);
|
|
|
|
bool Unban(const CSubNet &ip);
|
|
|
|
void GetBanned(banmap_t &banmap);
|
|
|
|
void SetBanned(const banmap_t &banmap);
|
|
|
|
|
2016-04-16 23:51:01 +02:00
|
|
|
void AddOneShot(const std::string& strDest);
|
2016-04-17 00:12:58 +02:00
|
|
|
|
|
|
|
bool AddNode(const std::string& node);
|
|
|
|
bool RemoveAddedNode(const std::string& node);
|
|
|
|
std::vector<AddedNodeInfo> GetAddedNodeInfo();
|
|
|
|
|
2016-04-17 00:30:03 +02:00
|
|
|
size_t GetNodeCount(NumConnections num);
|
|
|
|
void GetNodeStats(std::vector<CNodeStats>& vstats);
|
|
|
|
bool DisconnectAddress(const CNetAddr& addr);
|
|
|
|
bool DisconnectNode(const std::string& node);
|
|
|
|
bool DisconnectNode(NodeId id);
|
|
|
|
bool DisconnectSubnet(const CSubNet& subnet);
|
|
|
|
|
2016-04-18 00:34:32 +02:00
|
|
|
void AddWhitelistedRange(const CSubNet &subnet);
|
2016-04-16 20:47:18 +02:00
|
|
|
private:
|
2016-04-16 21:46:00 +02:00
|
|
|
struct ListenSocket {
|
|
|
|
SOCKET socket;
|
|
|
|
bool whitelisted;
|
|
|
|
|
|
|
|
ListenSocket(SOCKET socket_, bool whitelisted_) : socket(socket_), whitelisted(whitelisted_) {}
|
|
|
|
};
|
|
|
|
|
2016-04-16 20:47:18 +02:00
|
|
|
void ThreadOpenAddedConnections();
|
|
|
|
void ProcessOneShot();
|
|
|
|
void ThreadOpenConnections();
|
|
|
|
void ThreadMessageHandler();
|
|
|
|
void AcceptConnection(const ListenSocket& hListenSocket);
|
|
|
|
void ThreadSocketHandler();
|
|
|
|
void ThreadDNSAddressSeed();
|
2016-04-16 21:46:00 +02:00
|
|
|
|
2016-04-17 01:13:12 +02:00
|
|
|
CNode* FindNode(const CNetAddr& ip);
|
|
|
|
CNode* FindNode(const CSubNet& subNet);
|
|
|
|
CNode* FindNode(const std::string& addrName);
|
|
|
|
CNode* FindNode(const CService& addr);
|
|
|
|
|
|
|
|
bool AttemptToEvictConnection();
|
2016-04-16 21:59:10 +02:00
|
|
|
CNode* ConnectNode(CAddress addrConnect, const char *pszDest, bool fCountFailure);
|
2016-04-18 00:34:32 +02:00
|
|
|
bool IsWhitelistedRange(const CNetAddr &addr);
|
|
|
|
|
2016-05-25 00:59:16 +02:00
|
|
|
void DeleteNode(CNode* pnode);
|
2016-04-18 02:20:34 +02:00
|
|
|
|
|
|
|
NodeId GetNewNodeId();
|
|
|
|
|
2016-04-16 23:43:11 +02:00
|
|
|
//!check is the banlist has unwritten changes
|
|
|
|
bool BannedSetIsDirty();
|
|
|
|
//!set the "dirty" flag for the banlist
|
|
|
|
void SetBannedSetDirty(bool dirty=true);
|
|
|
|
//!clean unused entries (if bantime has expired)
|
|
|
|
void SweepBanned();
|
|
|
|
void DumpAddresses();
|
|
|
|
void DumpData();
|
|
|
|
void DumpBanlist();
|
2016-04-16 21:59:10 +02:00
|
|
|
|
2016-04-18 00:34:32 +02:00
|
|
|
// Whitelisted ranges. Any node connecting from these is automatically
|
|
|
|
// whitelisted (as well as those connecting to whitelisted binds).
|
|
|
|
std::vector<CSubNet> vWhitelistedRange;
|
|
|
|
CCriticalSection cs_vWhitelistedRange;
|
|
|
|
|
2016-04-16 21:46:00 +02:00
|
|
|
std::vector<ListenSocket> vhListenSocket;
|
2016-04-16 23:43:11 +02:00
|
|
|
banmap_t setBanned;
|
|
|
|
CCriticalSection cs_setBanned;
|
|
|
|
bool setBannedIsDirty;
|
|
|
|
bool fAddressesInitialized;
|
|
|
|
CAddrMan addrman;
|
2016-04-16 23:51:01 +02:00
|
|
|
std::deque<std::string> vOneShots;
|
|
|
|
CCriticalSection cs_vOneShots;
|
2016-04-17 00:12:58 +02:00
|
|
|
std::vector<std::string> vAddedNodes;
|
|
|
|
CCriticalSection cs_vAddedNodes;
|
2016-04-17 01:13:12 +02:00
|
|
|
std::vector<CNode*> vNodes;
|
|
|
|
mutable CCriticalSection cs_vNodes;
|
2016-04-18 02:20:34 +02:00
|
|
|
std::atomic<NodeId> nLastNodeId;
|
2016-04-19 03:33:54 +02:00
|
|
|
boost::condition_variable messageHandlerCondition;
|
2016-04-16 20:47:18 +02:00
|
|
|
};
|
|
|
|
extern std::unique_ptr<CConnman> g_connman;
|
2013-03-07 04:31:26 +01:00
|
|
|
void MapPort(bool fUseUPnP);
|
2012-05-13 01:26:14 +02:00
|
|
|
unsigned short GetListenPort();
|
2014-06-21 13:34:36 +02:00
|
|
|
bool BindListenPort(const CService &bindAddr, std::string& strError, bool fWhitelisted = false);
|
2016-04-16 20:47:18 +02:00
|
|
|
bool StartNode(CConnman& connman, boost::thread_group& threadGroup, CScheduler& scheduler, std::string& strNodeError);
|
|
|
|
bool StopNode(CConnman& connman);
|
2012-11-16 00:20:26 +01:00
|
|
|
void SocketSendData(CNode *pnode);
|
2010-08-29 18:58:15 +02:00
|
|
|
|
2015-03-05 13:01:01 +01:00
|
|
|
struct CombinerAll
|
|
|
|
{
|
|
|
|
typedef bool result_type;
|
|
|
|
|
|
|
|
template<typename I>
|
|
|
|
bool operator()(I first, I last) const
|
|
|
|
{
|
|
|
|
while (first != last) {
|
|
|
|
if (!(*first)) return false;
|
|
|
|
++first;
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2013-06-06 05:21:41 +02:00
|
|
|
// Signals for message handling
|
|
|
|
struct CNodeSignals
|
|
|
|
{
|
2013-10-10 23:07:44 +02:00
|
|
|
boost::signals2::signal<int ()> GetHeight;
|
2016-05-26 20:26:01 +02:00
|
|
|
boost::signals2::signal<bool (CNode*, CConnman&), CombinerAll> ProcessMessages;
|
|
|
|
boost::signals2::signal<bool (CNode*, CConnman&), CombinerAll> SendMessages;
|
2013-11-18 01:25:17 +01:00
|
|
|
boost::signals2::signal<void (NodeId, const CNode*)> InitializeNode;
|
2016-05-25 00:59:16 +02:00
|
|
|
boost::signals2::signal<void (NodeId, bool&)> FinalizeNode;
|
2013-06-06 05:21:41 +02:00
|
|
|
};
|
|
|
|
|
2013-11-18 01:25:17 +01:00
|
|
|
|
2013-06-06 05:21:41 +02:00
|
|
|
CNodeSignals& GetNodeSignals();
|
2013-01-07 17:07:51 +01:00
|
|
|
|
|
|
|
|
2012-02-12 13:45:24 +01:00
|
|
|
enum
|
|
|
|
{
|
2012-05-10 20:35:13 +02:00
|
|
|
LOCAL_NONE, // unknown
|
|
|
|
LOCAL_IF, // address a local interface listens on
|
2012-05-11 15:28:59 +02:00
|
|
|
LOCAL_BIND, // address explicit bound to
|
2012-05-10 20:35:13 +02:00
|
|
|
LOCAL_UPNP, // address reported by UPnP
|
|
|
|
LOCAL_MANUAL, // address explicitly specified (-externalip=)
|
2012-02-19 20:44:35 +01:00
|
|
|
|
|
|
|
LOCAL_MAX
|
2012-02-12 13:45:24 +01:00
|
|
|
};
|
|
|
|
|
2014-07-21 08:32:25 +02:00
|
|
|
bool IsPeerAddrLocalGood(CNode *pnode);
|
2016-02-12 19:35:32 +01:00
|
|
|
void AdvertiseLocal(CNode *pnode);
|
2012-05-04 16:46:22 +02:00
|
|
|
void SetLimited(enum Network net, bool fLimited = true);
|
2012-05-14 17:15:58 +02:00
|
|
|
bool IsLimited(enum Network net);
|
2012-05-04 16:46:22 +02:00
|
|
|
bool IsLimited(const CNetAddr& addr);
|
2012-05-10 20:35:13 +02:00
|
|
|
bool AddLocal(const CService& addr, int nScore = LOCAL_NONE);
|
2012-05-13 01:26:14 +02:00
|
|
|
bool AddLocal(const CNetAddr& addr, int nScore = LOCAL_NONE);
|
2015-09-08 17:48:45 +02:00
|
|
|
bool RemoveLocal(const CService& addr);
|
2012-05-10 20:35:13 +02:00
|
|
|
bool SeenLocal(const CService& addr);
|
|
|
|
bool IsLocal(const CService& addr);
|
|
|
|
bool GetLocal(CService &addr, const CNetAddr *paddrPeer = NULL);
|
2014-07-30 15:31:36 +02:00
|
|
|
bool IsReachable(enum Network net);
|
2012-04-10 20:22:04 +02:00
|
|
|
bool IsReachable(const CNetAddr &addr);
|
2012-02-12 13:45:24 +01:00
|
|
|
CAddress GetLocalAddress(const CNetAddr *paddrPeer = NULL);
|
|
|
|
|
2012-04-10 20:22:04 +02:00
|
|
|
|
2012-05-24 19:02:21 +02:00
|
|
|
extern bool fDiscover;
|
2014-05-29 12:33:17 +02:00
|
|
|
extern bool fListen;
|
2016-06-08 19:12:22 +02:00
|
|
|
extern ServiceFlags nLocalServices;
|
2015-11-17 00:20:49 +01:00
|
|
|
extern ServiceFlags nRelevantServices;
|
2016-05-12 14:00:22 +02:00
|
|
|
extern bool fRelayTxes;
|
2014-11-16 12:19:23 +01:00
|
|
|
|
|
|
|
/** Maximum number of connections to simultaneously allow (aka connection slots) */
|
2013-04-26 00:46:47 +02:00
|
|
|
extern int nMaxConnections;
|
2010-08-29 18:58:15 +02:00
|
|
|
|
2016-04-11 18:52:29 +02:00
|
|
|
extern limitedmap<uint256, int64_t> mapAlreadyAskedFor;
|
2010-08-29 18:58:15 +02:00
|
|
|
|
2015-07-31 18:05:42 +02:00
|
|
|
/** Subversion as sent to the P2P network in `version` messages */
|
|
|
|
extern std::string strSubVersion;
|
|
|
|
|
2014-05-05 13:22:28 +02:00
|
|
|
struct LocalServiceInfo {
|
|
|
|
int nScore;
|
|
|
|
int nPort;
|
|
|
|
};
|
|
|
|
|
|
|
|
extern CCriticalSection cs_mapLocalHost;
|
2014-06-04 12:52:15 +02:00
|
|
|
extern std::map<CNetAddr, LocalServiceInfo> mapLocalHost;
|
2015-08-25 16:30:31 +02:00
|
|
|
typedef std::map<std::string, uint64_t> mapMsgCmdSize; //command, total bytes
|
2010-08-29 18:58:15 +02:00
|
|
|
|
2012-06-29 23:24:53 +02:00
|
|
|
class CNodeStats
|
|
|
|
{
|
|
|
|
public:
|
2013-11-18 01:25:17 +01:00
|
|
|
NodeId nodeid;
|
2016-06-08 19:12:22 +02:00
|
|
|
ServiceFlags nServices;
|
2015-11-21 00:51:44 +01:00
|
|
|
bool fRelayTxes;
|
2013-04-13 07:13:08 +02:00
|
|
|
int64_t nLastSend;
|
|
|
|
int64_t nLastRecv;
|
|
|
|
int64_t nTimeConnected;
|
2014-12-15 11:06:15 +01:00
|
|
|
int64_t nTimeOffset;
|
2012-06-29 23:24:53 +02:00
|
|
|
std::string addrName;
|
|
|
|
int nVersion;
|
2013-11-26 12:52:21 +01:00
|
|
|
std::string cleanSubVer;
|
2012-06-29 23:24:53 +02:00
|
|
|
bool fInbound;
|
|
|
|
int nStartingHeight;
|
2013-04-13 07:13:08 +02:00
|
|
|
uint64_t nSendBytes;
|
2015-08-25 16:30:31 +02:00
|
|
|
mapMsgCmdSize mapSendBytesPerMsgCmd;
|
2013-04-13 07:13:08 +02:00
|
|
|
uint64_t nRecvBytes;
|
2015-08-25 16:30:31 +02:00
|
|
|
mapMsgCmdSize mapRecvBytesPerMsgCmd;
|
2014-06-21 13:34:36 +02:00
|
|
|
bool fWhitelisted;
|
2013-08-22 13:34:33 +02:00
|
|
|
double dPingTime;
|
|
|
|
double dPingWait;
|
2015-09-03 22:06:13 +02:00
|
|
|
double dPingMin;
|
2013-08-22 07:50:19 +02:00
|
|
|
std::string addrLocal;
|
2012-06-29 23:24:53 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
2010-08-29 18:58:15 +02:00
|
|
|
|
2012-11-16 01:41:12 +01:00
|
|
|
class CNetMessage {
|
|
|
|
public:
|
|
|
|
bool in_data; // parsing header (false) or data (true)
|
|
|
|
|
|
|
|
CDataStream hdrbuf; // partially received header
|
|
|
|
CMessageHeader hdr; // complete header
|
|
|
|
unsigned int nHdrPos;
|
|
|
|
|
|
|
|
CDataStream vRecv; // received message data
|
|
|
|
unsigned int nDataPos;
|
|
|
|
|
2014-07-06 16:06:46 +02:00
|
|
|
int64_t nTime; // time (in microseconds) of message receipt.
|
|
|
|
|
2014-10-28 01:24:31 +01:00
|
|
|
CNetMessage(const CMessageHeader::MessageStartChars& pchMessageStartIn, int nTypeIn, int nVersionIn) : hdrbuf(nTypeIn, nVersionIn), hdr(pchMessageStartIn), vRecv(nTypeIn, nVersionIn) {
|
2012-11-16 01:41:12 +01:00
|
|
|
hdrbuf.resize(24);
|
|
|
|
in_data = false;
|
|
|
|
nHdrPos = 0;
|
|
|
|
nDataPos = 0;
|
2014-07-06 16:06:46 +02:00
|
|
|
nTime = 0;
|
2012-11-16 01:41:12 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
bool complete() const
|
|
|
|
{
|
|
|
|
if (!in_data)
|
|
|
|
return false;
|
|
|
|
return (hdr.nMessageSize == nDataPos);
|
|
|
|
}
|
|
|
|
|
|
|
|
void SetVersion(int nVersionIn)
|
|
|
|
{
|
|
|
|
hdrbuf.SetVersion(nVersionIn);
|
|
|
|
vRecv.SetVersion(nVersionIn);
|
|
|
|
}
|
|
|
|
|
|
|
|
int readHeader(const char *pch, unsigned int nBytes);
|
|
|
|
int readData(const char *pch, unsigned int nBytes);
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2012-03-26 16:48:23 +02:00
|
|
|
/** Information about a peer */
|
2010-08-29 18:58:15 +02:00
|
|
|
class CNode
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
// socket
|
2016-06-08 19:12:22 +02:00
|
|
|
ServiceFlags nServices;
|
|
|
|
ServiceFlags nServicesExpected;
|
2010-08-29 18:58:15 +02:00
|
|
|
SOCKET hSocket;
|
2013-03-24 16:52:24 +01:00
|
|
|
CDataStream ssSend;
|
|
|
|
size_t nSendSize; // total size of all vSendMsg entries
|
|
|
|
size_t nSendOffset; // offset inside the first vSendMsg already sent
|
2013-04-13 07:13:08 +02:00
|
|
|
uint64_t nSendBytes;
|
2013-03-24 16:52:24 +01:00
|
|
|
std::deque<CSerializeData> vSendMsg;
|
2010-08-29 18:58:15 +02:00
|
|
|
CCriticalSection cs_vSend;
|
2012-11-16 01:41:12 +01:00
|
|
|
|
2013-03-29 23:49:38 +01:00
|
|
|
std::deque<CInv> vRecvGetData;
|
2013-03-01 01:41:28 +01:00
|
|
|
std::deque<CNetMessage> vRecvMsg;
|
2012-11-16 01:41:12 +01:00
|
|
|
CCriticalSection cs_vRecvMsg;
|
2013-04-13 07:13:08 +02:00
|
|
|
uint64_t nRecvBytes;
|
2012-11-16 01:41:12 +01:00
|
|
|
int nRecvVersion;
|
|
|
|
|
2013-04-13 07:13:08 +02:00
|
|
|
int64_t nLastSend;
|
|
|
|
int64_t nLastRecv;
|
|
|
|
int64_t nTimeConnected;
|
2014-12-15 11:06:15 +01:00
|
|
|
int64_t nTimeOffset;
|
2016-05-25 15:38:32 +02:00
|
|
|
const CAddress addr;
|
2012-04-19 17:38:03 +02:00
|
|
|
std::string addrName;
|
2012-05-10 20:35:13 +02:00
|
|
|
CService addrLocal;
|
2010-08-29 18:58:15 +02:00
|
|
|
int nVersion;
|
2014-01-11 18:14:29 +01:00
|
|
|
// strSubVer is whatever byte array we read from the wire. However, this field is intended
|
2013-11-26 12:52:21 +01:00
|
|
|
// to be printed out, displayed to humans in various forms and so on. So we sanitize it and
|
|
|
|
// store the sanitized version in cleanSubVer. The original should be used when dealing with
|
|
|
|
// the network or wire types and the cleaned string used when displayed or logged.
|
|
|
|
std::string strSubVer, cleanSubVer;
|
2014-06-21 13:34:36 +02:00
|
|
|
bool fWhitelisted; // This peer can bypass DoS banning.
|
2016-06-17 06:10:07 +02:00
|
|
|
bool fFeeler; // If true this node is being used as a short lived feeler.
|
2012-04-24 02:15:00 +02:00
|
|
|
bool fOneShot;
|
2010-08-29 18:58:15 +02:00
|
|
|
bool fClient;
|
|
|
|
bool fInbound;
|
|
|
|
bool fNetworkNode;
|
|
|
|
bool fSuccessfullyConnected;
|
|
|
|
bool fDisconnect;
|
2012-08-21 03:10:25 +02:00
|
|
|
// We use fRelayTxes for two purposes -
|
|
|
|
// a) it allows us to not relay tx invs before receiving the peer's version message
|
2015-04-28 16:48:28 +02:00
|
|
|
// b) the peer may tell us in its version message that we should not relay tx invs
|
2015-11-14 14:12:31 +01:00
|
|
|
// unless it loads a bloom filter.
|
2016-04-20 09:05:23 +02:00
|
|
|
bool fRelayTxes; //protected by cs_filter
|
2016-04-11 03:09:34 +02:00
|
|
|
bool fSentAddr;
|
2012-05-10 18:44:07 +02:00
|
|
|
CSemaphoreGrant grantOutbound;
|
2012-08-13 05:26:29 +02:00
|
|
|
CCriticalSection cs_filter;
|
|
|
|
CBloomFilter* pfilter;
|
2010-08-29 18:58:15 +02:00
|
|
|
int nRefCount;
|
2013-11-18 01:25:17 +01:00
|
|
|
NodeId id;
|
2016-05-23 09:21:05 +02:00
|
|
|
|
2016-05-25 15:38:32 +02:00
|
|
|
const uint64_t nKeyedNetGroup;
|
2013-03-29 00:43:31 +01:00
|
|
|
protected:
|
2011-09-06 22:09:04 +02:00
|
|
|
|
2015-08-25 16:30:31 +02:00
|
|
|
mapMsgCmdSize mapSendBytesPerMsgCmd;
|
|
|
|
mapMsgCmdSize mapRecvBytesPerMsgCmd;
|
|
|
|
|
2013-10-28 07:28:00 +01:00
|
|
|
// Basic fuzz-testing
|
|
|
|
void Fuzz(int nChance); // modifies ssSend
|
|
|
|
|
2010-08-29 18:58:15 +02:00
|
|
|
public:
|
|
|
|
uint256 hashContinue;
|
|
|
|
int nStartingHeight;
|
|
|
|
|
|
|
|
// flood relay
|
2011-05-15 09:11:04 +02:00
|
|
|
std::vector<CAddress> vAddrToSend;
|
2015-04-25 22:25:44 +02:00
|
|
|
CRollingBloomFilter addrKnown;
|
2010-08-29 18:58:15 +02:00
|
|
|
bool fGetAddr;
|
2011-05-15 09:11:04 +02:00
|
|
|
std::set<uint256> setKnown;
|
2015-04-08 20:20:00 +02:00
|
|
|
int64_t nNextAddrSend;
|
|
|
|
int64_t nNextLocalAddrSend;
|
2010-08-29 18:58:15 +02:00
|
|
|
|
|
|
|
// inventory based relay
|
2015-11-29 10:52:51 +01:00
|
|
|
CRollingBloomFilter filterInventoryKnown;
|
2016-04-07 13:57:36 +02:00
|
|
|
// Set of transaction ids we still have to announce.
|
|
|
|
// They are sorted by the mempool before relay, so the order is not important.
|
|
|
|
std::set<uint256> setInventoryTxToSend;
|
|
|
|
// List of block ids we still have announce.
|
|
|
|
// There is no final sorting before sending, as they are always sent immediately
|
|
|
|
// and in the order requested.
|
|
|
|
std::vector<uint256> vInventoryBlockToSend;
|
2010-08-29 18:58:15 +02:00
|
|
|
CCriticalSection cs_inventory;
|
2014-07-16 23:31:41 +02:00
|
|
|
std::set<uint256> setAskFor;
|
2013-04-13 07:13:08 +02:00
|
|
|
std::multimap<int64_t, CInv> mapAskFor;
|
2015-04-08 20:20:00 +02:00
|
|
|
int64_t nNextInvSend;
|
2014-11-18 22:16:32 +01:00
|
|
|
// Used for headers announcements - unfiltered blocks to relay
|
|
|
|
// Also protected by cs_inventory
|
|
|
|
std::vector<uint256> vBlockHashesToAnnounce;
|
2016-04-08 16:26:41 +02:00
|
|
|
// Used for BIP35 mempool sending, also protected by cs_inventory
|
|
|
|
bool fSendMempool;
|
2010-08-29 18:58:15 +02:00
|
|
|
|
2016-05-20 18:19:26 +02:00
|
|
|
// Last time a "MEMPOOL" request was serviced.
|
|
|
|
std::atomic<int64_t> timeLastMempoolReq;
|
2016-05-22 07:55:15 +02:00
|
|
|
|
|
|
|
// Block and TXN accept times
|
|
|
|
std::atomic<int64_t> nLastBlockTime;
|
|
|
|
std::atomic<int64_t> nLastTXTime;
|
|
|
|
|
2013-10-15 00:34:20 +02:00
|
|
|
// Ping time measurement:
|
|
|
|
// The pong reply we're expecting, or 0 if no pong expected.
|
2013-04-13 07:13:08 +02:00
|
|
|
uint64_t nPingNonceSent;
|
2013-10-15 00:34:20 +02:00
|
|
|
// Time (in usec) the last ping was sent, or 0 if no ping was ever sent.
|
2013-04-13 07:13:08 +02:00
|
|
|
int64_t nPingUsecStart;
|
2013-10-15 00:34:20 +02:00
|
|
|
// Last measured round-trip time.
|
2013-04-13 07:13:08 +02:00
|
|
|
int64_t nPingUsecTime;
|
2015-08-13 11:31:46 +02:00
|
|
|
// Best measured round-trip time.
|
|
|
|
int64_t nMinPingUsecTime;
|
2013-10-15 00:34:20 +02:00
|
|
|
// Whether a ping is requested.
|
2013-08-22 13:34:33 +02:00
|
|
|
bool fPingQueued;
|
2016-02-12 21:57:15 +01:00
|
|
|
// Minimum fee rate with which to filter inv's to this node
|
|
|
|
CAmount minFeeFilter;
|
|
|
|
CCriticalSection cs_feeFilter;
|
|
|
|
CAmount lastSentFeeFilter;
|
|
|
|
int64_t nextSendTimeFeeFilter;
|
2014-01-11 18:14:29 +01:00
|
|
|
|
2016-04-18 02:20:34 +02:00
|
|
|
CNode(NodeId id, SOCKET hSocketIn, const CAddress &addrIn, const std::string &addrNameIn = "", bool fInboundIn = false);
|
2014-08-21 05:17:21 +02:00
|
|
|
~CNode();
|
2010-08-29 18:58:15 +02:00
|
|
|
|
|
|
|
private:
|
2013-08-22 18:09:32 +02:00
|
|
|
// Network usage totals
|
|
|
|
static CCriticalSection cs_totalBytesRecv;
|
|
|
|
static CCriticalSection cs_totalBytesSent;
|
2013-04-13 07:13:08 +02:00
|
|
|
static uint64_t nTotalBytesRecv;
|
|
|
|
static uint64_t nTotalBytesSent;
|
2013-08-22 18:09:32 +02:00
|
|
|
|
2015-09-02 17:03:27 +02:00
|
|
|
// outbound limit & stats
|
|
|
|
static uint64_t nMaxOutboundTotalBytesSentInCycle;
|
|
|
|
static uint64_t nMaxOutboundCycleStartTime;
|
|
|
|
static uint64_t nMaxOutboundLimit;
|
|
|
|
static uint64_t nMaxOutboundTimeframe;
|
|
|
|
|
2010-08-29 18:58:15 +02:00
|
|
|
CNode(const CNode&);
|
|
|
|
void operator=(const CNode&);
|
2013-08-22 18:09:32 +02:00
|
|
|
|
2016-05-25 15:38:32 +02:00
|
|
|
static uint64_t CalculateKeyedNetGroup(const CAddress& ad);
|
2016-05-23 09:21:05 +02:00
|
|
|
|
2016-04-18 02:21:58 +02:00
|
|
|
uint64_t nLocalHostNonce;
|
2010-08-29 18:58:15 +02:00
|
|
|
public:
|
|
|
|
|
2013-11-18 01:25:17 +01:00
|
|
|
NodeId GetId() const {
|
|
|
|
return id;
|
|
|
|
}
|
2010-08-29 18:58:15 +02:00
|
|
|
|
2016-04-18 02:21:58 +02:00
|
|
|
uint64_t GetLocalNonce() const {
|
|
|
|
return nLocalHostNonce;
|
|
|
|
}
|
|
|
|
|
2010-08-29 18:58:15 +02:00
|
|
|
int GetRefCount()
|
|
|
|
{
|
2013-03-29 00:43:31 +01:00
|
|
|
assert(nRefCount >= 0);
|
|
|
|
return nRefCount;
|
2010-08-29 18:58:15 +02:00
|
|
|
}
|
|
|
|
|
2012-11-16 01:41:12 +01:00
|
|
|
// requires LOCK(cs_vRecvMsg)
|
|
|
|
unsigned int GetTotalRecvSize()
|
|
|
|
{
|
|
|
|
unsigned int total = 0;
|
2013-10-15 12:13:54 +02:00
|
|
|
BOOST_FOREACH(const CNetMessage &msg, vRecvMsg)
|
2013-03-01 01:41:28 +01:00
|
|
|
total += msg.vRecv.size() + 24;
|
2012-11-16 01:41:12 +01:00
|
|
|
return total;
|
|
|
|
}
|
|
|
|
|
|
|
|
// requires LOCK(cs_vRecvMsg)
|
2016-04-19 03:33:54 +02:00
|
|
|
bool ReceiveMsgBytes(const char *pch, unsigned int nBytes, bool& complete);
|
2012-11-16 01:41:12 +01:00
|
|
|
|
|
|
|
// requires LOCK(cs_vRecvMsg)
|
|
|
|
void SetRecvVersion(int nVersionIn)
|
|
|
|
{
|
|
|
|
nRecvVersion = nVersionIn;
|
2013-03-01 01:41:28 +01:00
|
|
|
BOOST_FOREACH(CNetMessage &msg, vRecvMsg)
|
|
|
|
msg.SetVersion(nVersionIn);
|
2012-11-16 01:41:12 +01:00
|
|
|
}
|
|
|
|
|
2013-03-29 00:43:31 +01:00
|
|
|
CNode* AddRef()
|
2010-08-29 18:58:15 +02:00
|
|
|
{
|
2013-03-29 00:43:31 +01:00
|
|
|
nRefCount++;
|
2010-08-29 18:58:15 +02:00
|
|
|
return this;
|
|
|
|
}
|
|
|
|
|
|
|
|
void Release()
|
|
|
|
{
|
|
|
|
nRefCount--;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
2016-08-15 14:10:07 +02:00
|
|
|
void AddAddressKnown(const CAddress& _addr)
|
2010-08-29 18:58:15 +02:00
|
|
|
{
|
2016-08-15 14:10:07 +02:00
|
|
|
addrKnown.insert(_addr.GetKey());
|
2010-08-29 18:58:15 +02:00
|
|
|
}
|
|
|
|
|
2016-08-15 14:10:07 +02:00
|
|
|
void PushAddress(const CAddress& _addr)
|
2010-08-29 18:58:15 +02:00
|
|
|
{
|
|
|
|
// Known checking here is only to save space from duplicates.
|
|
|
|
// SendMessages will filter it again for knowns that were added
|
|
|
|
// after addresses were pushed.
|
2016-08-15 14:10:07 +02:00
|
|
|
if (_addr.IsValid() && !addrKnown.contains(_addr.GetKey())) {
|
2014-11-21 12:22:11 +01:00
|
|
|
if (vAddrToSend.size() >= MAX_ADDR_TO_SEND) {
|
2016-08-15 14:10:07 +02:00
|
|
|
vAddrToSend[insecure_rand() % vAddrToSend.size()] = _addr;
|
2014-11-21 12:22:11 +01:00
|
|
|
} else {
|
2016-08-15 14:10:07 +02:00
|
|
|
vAddrToSend.push_back(_addr);
|
2014-11-21 12:22:11 +01:00
|
|
|
}
|
|
|
|
}
|
2010-08-29 18:58:15 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void AddInventoryKnown(const CInv& inv)
|
|
|
|
{
|
2012-04-06 18:39:12 +02:00
|
|
|
{
|
|
|
|
LOCK(cs_inventory);
|
2015-11-29 10:52:51 +01:00
|
|
|
filterInventoryKnown.insert(inv.hash);
|
2012-04-06 18:39:12 +02:00
|
|
|
}
|
2010-08-29 18:58:15 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void PushInventory(const CInv& inv)
|
|
|
|
{
|
2016-04-07 13:57:36 +02:00
|
|
|
LOCK(cs_inventory);
|
|
|
|
if (inv.type == MSG_TX) {
|
|
|
|
if (!filterInventoryKnown.contains(inv.hash)) {
|
|
|
|
setInventoryTxToSend.insert(inv.hash);
|
|
|
|
}
|
|
|
|
} else if (inv.type == MSG_BLOCK) {
|
|
|
|
vInventoryBlockToSend.push_back(inv.hash);
|
2012-04-06 18:39:12 +02:00
|
|
|
}
|
2010-08-29 18:58:15 +02:00
|
|
|
}
|
|
|
|
|
2014-11-18 22:16:32 +01:00
|
|
|
void PushBlockHash(const uint256 &hash)
|
|
|
|
{
|
|
|
|
LOCK(cs_inventory);
|
|
|
|
vBlockHashesToAnnounce.push_back(hash);
|
|
|
|
}
|
|
|
|
|
2014-08-21 05:17:21 +02:00
|
|
|
void AskFor(const CInv& inv);
|
2010-08-29 18:58:15 +02:00
|
|
|
|
2012-11-11 03:51:50 +01:00
|
|
|
// TODO: Document the postcondition of this function. Is cs_vSend locked?
|
2014-08-21 05:17:21 +02:00
|
|
|
void BeginMessage(const char* pszCommand) EXCLUSIVE_LOCK_FUNCTION(cs_vSend);
|
2010-08-29 18:58:15 +02:00
|
|
|
|
2012-11-11 03:51:50 +01:00
|
|
|
// TODO: Document the precondition of this function. Is cs_vSend locked?
|
2014-08-21 05:17:21 +02:00
|
|
|
void AbortMessage() UNLOCK_FUNCTION(cs_vSend);
|
2010-08-29 18:58:15 +02:00
|
|
|
|
2012-11-11 03:51:50 +01:00
|
|
|
// TODO: Document the precondition of this function. Is cs_vSend locked?
|
2015-08-25 16:30:31 +02:00
|
|
|
void EndMessage(const char* pszCommand) UNLOCK_FUNCTION(cs_vSend);
|
2010-08-29 18:58:15 +02:00
|
|
|
|
2011-12-16 22:26:14 +01:00
|
|
|
void PushVersion();
|
2011-01-24 16:42:17 +01:00
|
|
|
|
2010-08-29 18:58:15 +02:00
|
|
|
|
|
|
|
void PushMessage(const char* pszCommand)
|
|
|
|
{
|
|
|
|
try
|
|
|
|
{
|
|
|
|
BeginMessage(pszCommand);
|
2015-08-25 16:30:31 +02:00
|
|
|
EndMessage(pszCommand);
|
2010-08-29 18:58:15 +02:00
|
|
|
}
|
|
|
|
catch (...)
|
|
|
|
{
|
|
|
|
AbortMessage();
|
|
|
|
throw;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
template<typename T1>
|
|
|
|
void PushMessage(const char* pszCommand, const T1& a1)
|
|
|
|
{
|
|
|
|
try
|
|
|
|
{
|
|
|
|
BeginMessage(pszCommand);
|
2013-03-24 16:52:24 +01:00
|
|
|
ssSend << a1;
|
2015-08-25 16:30:31 +02:00
|
|
|
EndMessage(pszCommand);
|
2010-08-29 18:58:15 +02:00
|
|
|
}
|
|
|
|
catch (...)
|
|
|
|
{
|
|
|
|
AbortMessage();
|
|
|
|
throw;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-11-06 01:32:04 +01:00
|
|
|
/** Send a message containing a1, serialized with flag flag. */
|
|
|
|
template<typename T1>
|
|
|
|
void PushMessageWithFlag(int flag, const char* pszCommand, const T1& a1)
|
|
|
|
{
|
|
|
|
try
|
|
|
|
{
|
|
|
|
BeginMessage(pszCommand);
|
|
|
|
WithOrVersion(&ssSend, flag) << a1;
|
|
|
|
EndMessage(pszCommand);
|
|
|
|
}
|
|
|
|
catch (...)
|
|
|
|
{
|
|
|
|
AbortMessage();
|
|
|
|
throw;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-08-29 18:58:15 +02:00
|
|
|
template<typename T1, typename T2>
|
|
|
|
void PushMessage(const char* pszCommand, const T1& a1, const T2& a2)
|
|
|
|
{
|
|
|
|
try
|
|
|
|
{
|
|
|
|
BeginMessage(pszCommand);
|
2013-03-24 16:52:24 +01:00
|
|
|
ssSend << a1 << a2;
|
2015-08-25 16:30:31 +02:00
|
|
|
EndMessage(pszCommand);
|
2010-08-29 18:58:15 +02:00
|
|
|
}
|
|
|
|
catch (...)
|
|
|
|
{
|
|
|
|
AbortMessage();
|
|
|
|
throw;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
template<typename T1, typename T2, typename T3>
|
|
|
|
void PushMessage(const char* pszCommand, const T1& a1, const T2& a2, const T3& a3)
|
|
|
|
{
|
|
|
|
try
|
|
|
|
{
|
|
|
|
BeginMessage(pszCommand);
|
2013-03-24 16:52:24 +01:00
|
|
|
ssSend << a1 << a2 << a3;
|
2015-08-25 16:30:31 +02:00
|
|
|
EndMessage(pszCommand);
|
2010-08-29 18:58:15 +02:00
|
|
|
}
|
|
|
|
catch (...)
|
|
|
|
{
|
|
|
|
AbortMessage();
|
|
|
|
throw;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
template<typename T1, typename T2, typename T3, typename T4>
|
|
|
|
void PushMessage(const char* pszCommand, const T1& a1, const T2& a2, const T3& a3, const T4& a4)
|
|
|
|
{
|
|
|
|
try
|
|
|
|
{
|
|
|
|
BeginMessage(pszCommand);
|
2013-03-24 16:52:24 +01:00
|
|
|
ssSend << a1 << a2 << a3 << a4;
|
2015-08-25 16:30:31 +02:00
|
|
|
EndMessage(pszCommand);
|
2010-08-29 18:58:15 +02:00
|
|
|
}
|
|
|
|
catch (...)
|
|
|
|
{
|
|
|
|
AbortMessage();
|
|
|
|
throw;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
template<typename T1, typename T2, typename T3, typename T4, typename T5>
|
|
|
|
void PushMessage(const char* pszCommand, const T1& a1, const T2& a2, const T3& a3, const T4& a4, const T5& a5)
|
|
|
|
{
|
|
|
|
try
|
|
|
|
{
|
|
|
|
BeginMessage(pszCommand);
|
2013-03-24 16:52:24 +01:00
|
|
|
ssSend << a1 << a2 << a3 << a4 << a5;
|
2015-08-25 16:30:31 +02:00
|
|
|
EndMessage(pszCommand);
|
2010-08-29 18:58:15 +02:00
|
|
|
}
|
|
|
|
catch (...)
|
|
|
|
{
|
|
|
|
AbortMessage();
|
|
|
|
throw;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6>
|
|
|
|
void PushMessage(const char* pszCommand, const T1& a1, const T2& a2, const T3& a3, const T4& a4, const T5& a5, const T6& a6)
|
|
|
|
{
|
|
|
|
try
|
|
|
|
{
|
|
|
|
BeginMessage(pszCommand);
|
2013-03-24 16:52:24 +01:00
|
|
|
ssSend << a1 << a2 << a3 << a4 << a5 << a6;
|
2015-08-25 16:30:31 +02:00
|
|
|
EndMessage(pszCommand);
|
2010-08-29 18:58:15 +02:00
|
|
|
}
|
|
|
|
catch (...)
|
|
|
|
{
|
|
|
|
AbortMessage();
|
|
|
|
throw;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7>
|
|
|
|
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)
|
|
|
|
{
|
|
|
|
try
|
|
|
|
{
|
|
|
|
BeginMessage(pszCommand);
|
2013-03-24 16:52:24 +01:00
|
|
|
ssSend << a1 << a2 << a3 << a4 << a5 << a6 << a7;
|
2015-08-25 16:30:31 +02:00
|
|
|
EndMessage(pszCommand);
|
2010-08-29 18:58:15 +02:00
|
|
|
}
|
|
|
|
catch (...)
|
|
|
|
{
|
|
|
|
AbortMessage();
|
|
|
|
throw;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8>
|
|
|
|
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)
|
|
|
|
{
|
|
|
|
try
|
|
|
|
{
|
|
|
|
BeginMessage(pszCommand);
|
2013-03-24 16:52:24 +01:00
|
|
|
ssSend << a1 << a2 << a3 << a4 << a5 << a6 << a7 << a8;
|
2015-08-25 16:30:31 +02:00
|
|
|
EndMessage(pszCommand);
|
2010-08-29 18:58:15 +02:00
|
|
|
}
|
|
|
|
catch (...)
|
|
|
|
{
|
|
|
|
AbortMessage();
|
|
|
|
throw;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9>
|
|
|
|
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)
|
|
|
|
{
|
|
|
|
try
|
|
|
|
{
|
|
|
|
BeginMessage(pszCommand);
|
2013-03-24 16:52:24 +01:00
|
|
|
ssSend << a1 << a2 << a3 << a4 << a5 << a6 << a7 << a8 << a9;
|
2015-08-25 16:30:31 +02:00
|
|
|
EndMessage(pszCommand);
|
2010-08-29 18:58:15 +02:00
|
|
|
}
|
|
|
|
catch (...)
|
|
|
|
{
|
|
|
|
AbortMessage();
|
|
|
|
throw;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void CloseSocketDisconnect();
|
2011-09-06 22:09:04 +02:00
|
|
|
|
2012-06-29 23:24:53 +02:00
|
|
|
void copyStats(CNodeStats &stats);
|
2013-08-22 18:09:32 +02:00
|
|
|
|
|
|
|
// Network stats
|
2013-04-13 07:13:08 +02:00
|
|
|
static void RecordBytesRecv(uint64_t bytes);
|
|
|
|
static void RecordBytesSent(uint64_t bytes);
|
2013-08-22 18:09:32 +02:00
|
|
|
|
2013-04-13 07:13:08 +02:00
|
|
|
static uint64_t GetTotalBytesRecv();
|
|
|
|
static uint64_t GetTotalBytesSent();
|
2015-09-02 17:03:27 +02:00
|
|
|
|
|
|
|
//!set the max outbound target in bytes
|
|
|
|
static void SetMaxOutboundTarget(uint64_t limit);
|
|
|
|
static uint64_t GetMaxOutboundTarget();
|
|
|
|
|
|
|
|
//!set the timeframe for the max outbound target
|
|
|
|
static void SetMaxOutboundTimeframe(uint64_t timeframe);
|
|
|
|
static uint64_t GetMaxOutboundTimeframe();
|
|
|
|
|
|
|
|
//!check if the outbound target is reached
|
|
|
|
// if param historicalBlockServingLimit is set true, the function will
|
|
|
|
// response true if the limit for serving historical blocks has been reached
|
|
|
|
static bool OutboundTargetReached(bool historicalBlockServingLimit);
|
|
|
|
|
|
|
|
//!response the bytes left in the current max outbound cycle
|
|
|
|
// in case of no limit, it will always response 0
|
|
|
|
static uint64_t GetOutboundTargetBytesLeft();
|
|
|
|
|
|
|
|
//!response the time in second left in the current max outbound cycle
|
|
|
|
// in case of no limit, it will always response 0
|
|
|
|
static uint64_t GetMaxOutboundTimeLeftInCycle();
|
2010-08-29 18:58:15 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2015-06-19 15:27:37 +02:00
|
|
|
|
2015-04-08 20:20:00 +02:00
|
|
|
/** Return a timestamp in the future (in microseconds) for exponentially distributed events. */
|
|
|
|
int64_t PoissonNextSend(int64_t nNow, int average_interval_seconds);
|
|
|
|
|
2014-08-28 22:21:03 +02:00
|
|
|
#endif // BITCOIN_NET_H
|