34 #include <condition_variable>
37 #include <arpa/inet.h>
114 std::vector<unsigned char>
data;
255 CConnman(uint64_t seed0, uint64_t seed1,
bool network_active =
true);
278 using NodeFn = std::function<void(CNode*)>;
282 for (
auto&& node : vNodes) {
291 for (
auto&& node : vNodes) {
297 template<
typename Callable,
typename CallableAfter>
301 for (
auto&& node : vNodes) {
308 template<
typename Callable,
typename CallableAfter>
312 for (
auto&& node : vNodes) {
323 std::vector<CAddress>
GetAddresses(
size_t max_addresses,
size_t max_pct);
330 std::vector<CAddress>
GetAddresses(
CNode& requestor,
size_t max_addresses,
size_t max_pct);
345 bool AddNode(
const std::string& node);
419 const std::vector<CService>& binds,
420 const std::vector<NetWhitebindPermissions>& whiteBinds,
421 const std::vector<CService>& onion_binds);
432 bool GenerateSelectSet(std::set<SOCKET> &recv_set, std::set<SOCKET> &send_set, std::set<SOCKET> &error_set);
433 void SocketEvents(std::set<SOCKET> &recv_set, std::set<SOCKET> &send_set, std::set<SOCKET> &error_set);
481 uint64_t nMaxOutboundTotalBytesSentInCycle
GUARDED_BY(cs_totalBytesSent);
482 uint64_t nMaxOutboundCycleStartTime
GUARDED_BY(cs_totalBytesSent);
483 uint64_t nMaxOutboundLimit
GUARDED_BY(cs_totalBytesSent);
484 uint64_t nMaxOutboundTimeframe
GUARDED_BY(cs_totalBytesSent);
624 virtual bool ProcessMessages(
CNode* pnode, std::atomic<bool>& interrupt) = 0;
625 virtual bool SendMessages(
CNode* pnode) = 0;
626 virtual void InitializeNode(
CNode* pnode) = 0;
627 virtual void FinalizeNode(
const CNode& node,
bool& update_connection_time) = 0;
683 extern std::map<CNetAddr, LocalServiceInfo> mapLocalHost
GUARDED_BY(cs_mapLocalHost);
737 std::chrono::microseconds m_time{0};
738 uint32_t m_message_size{0};
739 uint32_t m_raw_message_size{0};
757 virtual bool Complete()
const = 0;
759 virtual void SetVersion(
int version) = 0;
761 virtual int Read(
const char *data,
unsigned int bytes) = 0;
781 const uint256& GetMessageHash()
const;
782 int readHeader(
const char *pch,
unsigned int nBytes);
783 int readData(
const char *pch,
unsigned int nBytes);
798 : m_chain_params(chain_params),
800 hdrbuf(nTypeIn, nVersionIn),
801 vRecv(nTypeIn, nVersionIn)
817 int Read(
const char *pch,
unsigned int nBytes)
override {
818 int ret = in_data ? readData(pch, nBytes) : readHeader(pch, nBytes);
819 if (ret < 0) Reset();
822 Optional<CNetMessage> GetMessage(std::chrono::microseconds time, uint32_t& out_err_raw_size)
override;
830 virtual void prepareForTransport(
CSerializedNetMsg& msg, std::vector<unsigned char>& header) = 0;
836 void prepareForTransport(
CSerializedNetMsg& msg, std::vector<unsigned char>& header)
override;
853 size_t nSendOffset{0};
855 std::deque<std::vector<unsigned char>> vSendMsg
GUARDED_BY(cs_vSend);
861 std::list<CNetMessage> vProcessMsg
GUARDED_BY(cs_vProcessMsg);
862 size_t nProcessQueueSize{0};
868 std::atomic<int64_t> nLastSend{0};
869 std::atomic<int64_t> nLastRecv{0};
871 std::atomic<int64_t> nTimeOffset{0};
876 std::atomic<int> nVersion{0};
883 bool m_prefer_evict{
false};
888 bool m_legacyWhitelisted{
false};
890 bool m_limited_node{
false};
895 std::atomic_bool m_wants_addrv2{
false};
896 std::atomic_bool fSuccessfullyConnected{
false};
899 std::atomic_bool fDisconnect{
false};
900 bool fSentAddr{
false};
902 std::atomic<int> nRefCount{0};
905 std::atomic_bool fPauseRecv{
false};
906 std::atomic_bool fPauseSend{
false};
909 switch (m_conn_type) {
954 switch (m_conn_type) {
978 Network ConnectedThroughNetwork()
const;
982 mapMsgCmdSize mapRecvBytesPerMsgCmd
GUARDED_BY(cs_vRecv);
986 std::atomic<int> nStartingHeight{-1};
990 std::unique_ptr<CRollingBloomFilter> m_addr_known{
nullptr};
991 bool fGetAddr{
false};
992 std::chrono::microseconds m_next_addr_send
GUARDED_BY(cs_sendProcessing){0};
993 std::chrono::microseconds m_next_local_addr_send
GUARDED_BY(cs_sendProcessing){0};
998 std::vector<uint256> vInventoryBlockToSend
GUARDED_BY(cs_inventory);
1014 std::set<uint256> setInventoryTxToSend;
1018 std::atomic<std::chrono::seconds> m_last_mempool_req{std::chrono::seconds{0}};
1019 std::chrono::microseconds nNextInvSend{0};
1025 int64_t nextSendTimeFeeFilter{0};
1032 std::vector<uint256> vBlockHashesToAnnounce
GUARDED_BY(cs_inventory);
1039 std::atomic<int64_t> nLastBlockTime{0};
1045 std::atomic<int64_t> nLastTXTime{0};
1049 std::atomic<uint64_t> nPingNonceSent{0};
1051 std::atomic<std::chrono::microseconds> m_ping_start{std::chrono::microseconds{0}};
1053 std::atomic<int64_t> nPingUsecTime{0};
1055 std::atomic<int64_t> nMinPingUsecTime{std::numeric_limits<int64_t>::max()};
1057 std::atomic<bool> fPingQueued{
false};
1059 CNode(
NodeId id,
ServiceFlags nLocalServicesIn,
int nMyStartingHeightIn,
SOCKET hSocketIn,
const CAddress &addrIn, uint64_t nKeyedNetGroupIn, uint64_t nLocalHostNonceIn,
const CAddress &addrBindIn,
const std::string &addrNameIn,
ConnectionType conn_type_in,
bool inbound_onion =
false);
1092 std::string addrName
GUARDED_BY(cs_addrName);
1099 const bool m_inbound_onion{
false};
1108 return nLocalHostNonce;
1112 return nMyStartingHeight;
1117 assert(nRefCount >= 0);
1121 bool ReceiveMsgBytes(
const char *pch,
unsigned int nBytes,
bool& complete);
1125 m_greatest_common_version = greatest_common_version;
1129 return m_greatest_common_version;
1134 void SetAddrLocal(
const CService& addrLocalIn);
1151 assert(m_addr_known);
1152 m_addr_known->insert(_addr.
GetKey());
1165 assert(m_addr_known);
1166 if (_addr.
IsValid() && !m_addr_known->contains(_addr.
GetKey()) && addr_format_supported) {
1168 vAddrToSend[insecure_rand.
randrange(vAddrToSend.size())] = _addr;
1170 vAddrToSend.push_back(_addr);
1178 if (m_tx_relay !=
nullptr) {
1179 LOCK(m_tx_relay->cs_tx_inventory);
1180 m_tx_relay->filterInventoryKnown.insert(hash);
1186 if (m_tx_relay ==
nullptr)
return;
1187 LOCK(m_tx_relay->cs_tx_inventory);
1188 if (!m_tx_relay->filterInventoryKnown.contains(hash)) {
1189 m_tx_relay->setInventoryTxToSend.insert(hash);
1193 void CloseSocketDisconnect();
1195 void copyStats(
CNodeStats &stats,
const std::vector<bool> &m_asmap);
1202 std::string GetAddrName()
const;
1204 void MaybeSetAddrName(
const std::string& addrNameIn);
1206 std::string ConnectionTypeAsString()
const;
1213 inline std::chrono::microseconds
PoissonNextSend(std::chrono::microseconds now, std::chrono::seconds average_interval)
1215 return std::chrono::microseconds{
PoissonNextSend(now.count(), average_interval.count())};
1218 #endif // BITCOIN_NET_H
std::vector< CService > vBinds
int m_max_outbound_full_relay
std::atomic< bool > flagInterruptMsgProc
std::vector< CAddress > m_addrs_response_cache
static const int MAX_BLOCK_RELAY_ONLY_CONNECTIONS
Maximum number of block-relay-only outgoing connections.
uint64_t nTotalBytesSent GUARDED_BY(cs_totalBytesSent)
bool HasPermission(NetPermissionFlags permission) const
std::vector< bool > m_asmap
bool IsReachable(enum Network net)
void ThreadOpenAddedConnections()
static const unsigned int MAX_PROTOCOL_MESSAGE_LENGTH
Maximum length of incoming protocol messages (no message over 4 MB is currently acceptable).
int GetCommonVersion() const
mapMsgCmdSize mapRecvBytesPerMsgCmd
uint64_t CalculateKeyedNetGroup(const CAddress &ad) const
std::atomic< bool > fNetworkActive
uint64_t GetLocalNonce() const
static void AddFlag(NetPermissionFlags &flags, NetPermissionFlags f)
ServiceFlags
nServices flags
static const uint64_t MAX_UPLOAD_TIMEFRAME
The default timeframe for -maxuploadtarget.
std::unique_ptr< TransportSerializer > m_serializer
std::string cleanSubVer GUARDED_BY(cs_SubVer)
cleanSubVer is a sanitized string of the user agent byte array we read from the wire.
unsigned int GetReceiveFloodSize() const
int m_max_outbound_block_relay
We open manual connections to addresses that users explicitly inputted via the addnode RPC...
CNode * FindNode(const CNetAddr &ip)
std::atomic< int > nBestHeight
void WakeMessageHandler()
bool Bind(const CService &addr, unsigned int flags, NetPermissionFlags permissions)
bool fRelayTxes GUARDED_BY(cs_filter)
static bool NodeFullyConnected(const CNode *pnode)
void SetServices(const CService &addr, ServiceFlags nServices)
void SocketEvents(std::set< SOCKET > &recv_set, std::set< SOCKET > &send_set, std::set< SOCKET > &error_set)
const std::string NET_MESSAGE_COMMAND_OTHER
ServiceFlags GetLocalServices() const
Used to convey which local services we are offering peers during node connection. ...
void SetVersion(int nVersionIn) override
void PushTxInventory(const uint256 &hash)
static const bool DEFAULT_FORCEDNSSEED
const uint64_t nKeyedNetGroup
bool SeenLocal(const CService &addr)
mapMsgCmdSize mapSendBytesPerMsgCmd
std::vector< CAddress > GetAddresses(size_t max_addresses, size_t max_pct)
std::vector< unsigned char > data
const ConnectionType m_conn_type
std::vector< NetWhitelistPermissions > vWhitelistedRange
CAmount minFeeFilter GUARDED_BY(cs_feeFilter)
unsigned int nReceiveFloodSize
int m_max_outbound_full_relay
mapMsgCmdSize mapSendBytesPerMsgCmd
CClientUIInterface * uiInterface
void resize(size_type n, value_type c=0)
std::vector< CService > m_onion_binds
A vector of -bind=
:=onion arguments each of which is an address and port that are desi...
void SetAsmap(std::vector< bool > asmap)
bool AlreadyConnectedToAddress(const CAddress &addr)
Determine whether we're already connected to a given address, in order to avoid initiating duplicate ...
void ForEachNodeThen(Callable &&pre, CallableAfter &&post) const
bool GetTryNewOutboundPeer()
std::atomic< int64_t > m_next_send_inv_to_incoming
CDataStream m_recv
received message data
static const bool DEFAULT_LISTEN
-listen default
CNetMessage(CDataStream &&recv_in)
RAII-style semaphore lock.
friend struct CConnmanTest
void SetCommonVersion(int greatest_common_version)
uint64_t GetMaxOutboundTarget()
static const int MAX_ADDNODE_CONNECTIONS
Maximum number of addnode outgoing nodes.
void PushMessage(CNode *pnode, CSerializedNetMsg &&msg)
bool BindListenPort(const CService &bindAddr, bilingual_str &strError, NetPermissionFlags permissions)
RecursiveMutex cs_vProcessMsg
void SetMaxOutboundTimeframe(uint64_t timeframe)
set the timeframe for the max outbound target
Interface for message handling.
void SetVersion(int nVersionIn)
RecursiveMutex cs_addrName
RollingBloomFilter is a probabilistic "keep track of most recently inserted" set. ...
NetEventsInterface * m_msgproc
CSerializedNetMsg()=default
CChainParams defines various tweakable parameters of a given instance of the Bitcoin system...
void AdvertiseLocal(CNode *pnode)
int m_max_outbound_block_relay
Double ended buffer combining vector and stream-like interfaces.
void SetTryNewOutboundPeer(bool flag)
A hasher class for Bitcoin's 256-bit hash (double SHA-256).
std::unique_ptr< TransportDeserializer > m_deserializer
void ThreadSocketHandler()
std::vector< CAddress > vAddrToSend
std::vector< CAddress > GetCurrentBlockRelayOnlyConns() const
Return vector of current BLOCK_RELAY peers.
bool IsBlockOnlyConn() const
size_t GetNodeCount(NumConnections num)
bool IsFeelerConn() const
void PushAddress(const CAddress &_addr, FastRandomContext &insecure_rand)
static const int FEELER_INTERVAL
Run the feeler connection loop once every 2 minutes or 120 seconds.
uint64_t nSendBytes GUARDED_BY(cs_vSend)
static const int TIMEOUT_INTERVAL
Time after which to disconnect, after waiting for a ping response (or inactivity).
Signals for UI communication.
std::list< CNetMessage > vRecvMsg
void NotifyNumConnectionsChanged()
void SetMaxOutboundTarget(uint64_t limit)
set the max outbound target in bytes
void RecordBytesSent(uint64_t bytes)
std::map< uint64_t, CachedAddrResponse > m_addr_response_caches
Addr responses stored in different caches per (network, local socket) prevent cross-network node iden...
static const int MAX_FEELER_CONNECTIONS
Maximum number of feeler connections.
uint64_t GetMaxOutboundTimeframe()
virtual ~TransportDeserializer()
bool ForNode(NodeId id, std::function< bool(CNode *pnode)> func)
RecursiveMutex cs_sendProcessing
ServiceFlags nLocalServices
Services this instance offers.
bool DisconnectNode(const std::string &node)
bool RelayAddrsWithConn() const
Stochastical (IP) address manager.
int64_t CAmount
Amount in satoshis (Can be negative)
void RecordBytesRecv(uint64_t bytes)
static const size_t DEFAULT_MAXRECEIVEBUFFER
bool IsAddrFetchConn() const
std::chrono::microseconds m_next_local_addr_send GUARDED_BY(cs_sendProcessing)
bool GetUseAddrmanOutgoing() const
bool IsInboundConn() const
uint64_t GetOutboundTargetBytesLeft()
response the bytes left in the current max outbound cycle in case of no limit, it will always respons...
std::chrono::microseconds m_cache_entry_expiration
void AddAddrFetch(const std::string &strDest)
bool GetLocal(CService &addr, const CNetAddr *paddrPeer=nullptr)
unsigned int nPrevNodeCount
bool AddNode(const std::string &node)
std::condition_variable condMsgProc
bool IsFullOutboundConn() const
RecursiveMutex cs_vAddedNodes
uint64_t GetMaxOutboundTimeLeftInCycle()
response the time in second left in the current max outbound cycle in case of no limit, it will always response 0
void OpenNetworkConnection(const CAddress &addrConnect, bool fCountFailure, CSemaphoreGrant *grantOutbound, const char *strDest, ConnectionType conn_type)
ListenSocket(SOCKET socket_, NetPermissionFlags permissions_)
void InactivityCheck(CNode *pnode)
const uint64_t nSeed0
SipHasher seeds for deterministic randomness.
std::thread threadOpenAddedConnections
RecursiveMutex m_addr_fetches_mutex
bool IsPeerAddrLocalGood(CNode *pnode)
std::function< void(CNode *)> NodeFn
NetEventsInterface * m_msgproc
static const int INIT_PROTO_VERSION
initial proto version, to be increased after version/verack negotiation
A combination of a network address (CNetAddr) and a (TCP) port.
Transport protocol agnostic message container.
std::vector< std::string > vSeedNodes
int64_t PoissonNextSendInbound(int64_t now, int average_interval_seconds)
Attempts to obfuscate tx time through exponentially distributed emitting.
bool OutboundTargetReached(bool historicalBlockServingLimit)
check if the outbound target is reached if param historicalBlockServingLimit is set true...
std::vector< std::string > m_specified_outgoing
int64_t m_peer_connect_timeout
std::unique_ptr< CSemaphore > semOutbound
void ThreadOpenConnections(std::vector< std::string > connect)
std::thread threadMessageHandler
static bool HasFlag(const NetPermissionFlags &flags, NetPermissionFlags f)
void ForEachNodeThen(Callable &&pre, CallableAfter &&post)
friend struct ConnmanTestMsg
A CService with information about it as peer.
bool Start(CScheduler &scheduler, const Options &options)
int Read(const char *pch, unsigned int nBytes) override
uint64_t GetTotalBytesRecv()
RecursiveMutex cs_mapLocalHost
std::atomic_bool m_try_another_outbound_peer
flag for deciding to connect to an extra outbound peer, in excess of m_max_outbound_full_relay This t...
void SetNetworkActive(bool active)
static const unsigned int DEFAULT_MAX_PEER_CONNECTIONS
The maximum number of peer connections to maintain.
CClientUIInterface * clientInterface
void GetNodeStats(std::vector< CNodeStats > &vstats)
bool AddNewAddresses(const std::vector< CAddress > &vAddr, const CAddress &addrFrom, int64_t nTimePenalty=0)
bool InitBinds(const std::vector< CService > &binds, const std::vector< NetWhitebindPermissions > &whiteBinds, const std::vector< CService > &onion_binds)
int GetMyStartingHeight() const
The TransportSerializer prepares messages for the network transport.
ServiceFlags GetLocalServices() const
uint64_t nRecvBytes GUARDED_BY(cs_vRecv)
bool GetNetworkActive() const
Inbound connections are those initiated by a peer.
void DeleteNode(CNode *pnode)
NetPermissionFlags m_permissions
bool CheckIncomingNonce(uint64_t nonce)
bool IsAddrV1Compatible() const
Check if the current object can be serialized in pre-ADDRv2/BIP155 format.
bool Complete() const override
const int64_t nTimeConnected
virtual ~TransportSerializer()
uint64_t nMaxOutboundTimeframe
std::atomic< NodeId > nLastNodeId
bool RemoveAddedNode(const std::string &node)
RecursiveMutex cs_feeFilter
std::list< CNode * > vNodesDisconnected
void RemoveLocal(const CService &addr)
std::vector< NetWhitelistPermissions > vWhitelistedRange
std::vector< CService > onion_binds
bool ExpectServicesFromConn() const
static const bool DEFAULT_WHITELISTFORCERELAY
Default for -whitelistforcerelay.
void AddKnownTx(const uint256 &hash)
BanMan * m_banman
Pointer to this node's banman.
static const size_t DEFAULT_MAXSENDBUFFER
void AddWhitelistPermissionFlags(NetPermissionFlags &flags, const CNetAddr &addr) const
bool fSendMempool GUARDED_BY(cs_tx_inventory)
int GetBestHeight() const
std::thread threadOpenConnections
bool AttemptToEvictConnection()
static const uint64_t DEFAULT_MAX_UPLOAD_TARGET
The default for -maxuploadtarget.
ConnectionType
Different types of connections to a peer.
bool IsOutboundOrBlockRelayConn() const
CSemaphoreGrant grantOutbound
The TransportDeserializer takes care of holding and deserializing the network receive buffer...
const CChainParams & m_chain_params
std::map< std::string, uint64_t > mapMsgCmdSize
Feeler connections are short-lived connections made to check that a node is alive.
static constexpr size_t MAX_ADDR_TO_SEND
The maximum number of addresses from our addrman to return in response to a getaddr message...
bool fAddressesInitialized
std::thread threadDNSAddressSeed
ServiceFlags nLocalServices
uint64_t nMaxOutboundLimit
std::vector< std::string > m_added_nodes
int64_t PoissonNextSend(int64_t now, int average_interval_seconds)
Return a timestamp in the future (in microseconds) for exponentially distributed events.
std::vector< ListenSocket > vhListenSocket
void SetBestHeight(int height)
std::string m_conn_type_string
void ThreadMessageHandler()
These are the default connections that we use to connect with the network.
static const unsigned int MAX_SUBVERSION_LENGTH
Maximum length of the user agent string in version message.
uint64_t nTotalBytesRecv GUARDED_BY(cs_totalBytesRecv)
static const bool DEFAULT_UPNP
-upnp default
static const int64_t DEFAULT_PEER_CONNECT_TIMEOUT
-peertimeout default
unsigned int nSendBufferMaxSize
static const bool DEFAULT_BLOCKSONLY
Default for blocks only.
const uint64_t nLocalHostNonce
unsigned int nSendBufferMaxSize
std::vector< bool > m_asmap
void ForEachNode(const NodeFn &func) const
const ServiceFlags nLocalServices
Services offered to this peer.
int GetExtraOutboundCount()
CSipHasher GetDeterministicRandomizer(uint64_t id) const
Get a unique deterministic randomizer.
static const bool DEFAULT_WHITELISTRELAY
Default for -whitelistrelay.
CNode * ConnectNode(CAddress addrConnect, const char *pszDest, bool fCountFailure, ConnectionType conn_type)
static const int MAX_OUTBOUND_FULL_RELAY_CONNECTIONS
Maximum number of automatic outgoing nodes over which we'll relay everything (blocks, tx, addrs, etc)
uint64_t GetTotalBytesSent()
bool GenerateSelectSet(std::set< SOCKET > &recv_set, std::set< SOCKET > &send_set, std::set< SOCKET > &error_set)
void AcceptConnection(const ListenSocket &hListenSocket)
std::string strSubVersion
Subversion as sent to the P2P network in version messages.
void MarkAddressGood(const CAddress &addr)
boost::optional< T > Optional
Substitute for C++17 std::optional.
Information about a peer.
void ForEachNode(const NodeFn &func)
std::thread threadSocketHandler
Simple class for background tasks that should be run periodically or once "after a while"...
We use block-relay-only connections to help prevent against partition attacks.
RecursiveMutex cs_totalBytesRecv
void SetReachable(enum Network net, bool reachable)
Mark a network as reachable or unreachable (no automatic connects to it)
NetPermissionFlags m_permissionFlags
CConnman(uint64_t seed0, uint64_t seed1, bool network_active=true)
V1TransportDeserializer(const CChainParams &chain_params, const NodeId node_id, int nTypeIn, int nVersionIn)
RecursiveMutex cs_addrLocal
bool IsManualConn() const
std::vector< CAddress > m_anchors
Addresses that were saved during the previous clean shutdown.
AddrFetch connections are short lived connections used to solicit addresses from peers.
void AddAddressKnown(const CAddress &_addr)
CSerializedNetMsg & operator=(CSerializedNetMsg &&)=default
std::unique_ptr< CSemaphore > semAddnode
void Init(const Options &connOptions)
CThreadInterrupt interruptNet
CAddress GetLocalAddress(const CNetAddr *paddrPeer, ServiceFlags nLocalServices)
bool AddLocal(const CService &addr, int nScore=LOCAL_NONE)
bool m_use_addrman_outgoing
std::vector< NetWhitebindPermissions > vWhiteBinds
bool IsLocal(const CService &addr)
size_t SocketSendData(CNode *pnode) const
uint64_t randrange(uint64_t range) noexcept
Generate a random integer in the range [0..range).
void AddSocketPermissionFlags(NetPermissionFlags &flags) const
RecursiveMutex cs_hSocket
const int nMyStartingHeight
bool m_use_addrman_outgoing
Cache responses to addr requests to minimize privacy leak.
std::vector< AddedNodeInfo > GetAddedNodeInfo()
RecursiveMutex cs_totalBytesSent
unsigned int nReceiveFloodSize
std::chrono::microseconds m_next_addr_send GUARDED_BY(cs_sendProcessing)
std::vector< unsigned char > GetKey() const
std::unique_ptr< TxRelay > m_tx_relay
void ThreadDNSAddressSeed()
int64_t m_peer_connect_timeout
std::unique_ptr< CBloomFilter > pfilter PT_GUARDED_BY(cs_filter) GUARDED_BY(cs_filter)