mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-03-05 14:06:27 -05:00
Merge #19316: [net] Cleanup logic around connection types
01e283068b
[net] Remove unnecessary default args on CNode constructor (Amiti Uttarwar)bc5d65b3ca
[refactor] Remove IsOutboundDisconnectionCandidate (Amiti Uttarwar)2f2e13b6c2
[net/refactor] Simplify multiple-connection checks (Amiti Uttarwar)7f7b83deb2
[net/refactor] Rework ThreadOpenConnections logic (Amiti Uttarwar)35839e963b
[net] Fix bug where AddrFetch connections would be counted as outbound full relay (Amiti Uttarwar)4972c21b67
[net/refactor] Clarify logic for selecting connections in ThreadOpenConnections (Amiti Uttarwar)60156f5fc4
[net/refactor] Remove fInbound flag from CNode (Amiti Uttarwar)7b322df629
[net/refactor] Remove m_addr_fetch member var from CNode (Amiti Uttarwar)14923422b0
[net/refactor] Remove fFeeler flag from CNode (Amiti Uttarwar)49efac5cae
[net/refactor] Remove m_manual_connection flag from CNode (Amiti Uttarwar)d3698b5ee3
[net/refactor] Add connection type as a member var to CNode (Amiti Uttarwar)46578c03e9
[doc] Describe different connection types (Amiti Uttarwar)442abae2ba
[net/refactor] Add AddrFetch connections to ConnectionType enum (Amiti Uttarwar)af59feb052
[net/refactor] Extract m_addr_known logic from initializer list (Amiti Uttarwar)e1bc29812d
[net/refactor] Add block relay only connections to ConnectionType enum (Amiti Uttarwar)0e52a659a2
[net/refactor] Add feeler connections to ConnectionType enum (Amiti Uttarwar)1521c47438
[net/refactor] Add manual connections to ConnectionType enum (Amiti Uttarwar)26304b4100
[net/refactor] Introduce an enum to distinguish type of connection (Amiti Uttarwar)3f1b7140e9
scripted-diff: Rename OneShot to AddrFetch (Amiti Uttarwar) Pull request description: **This is part 1 of #19315, which enables the ability to test `outbound` and `block-relay-only` connections from the functional tests.** Please see that PR for more information of overall functionality. **This PR simplifies how we manage different connection types.** It introduces an enum with the various types of connections so we can explicitly define the connection type. The existing system relies on a series of independent flags, then has asserts scattered around to ensure that conflicting flags are not enabled at the same time. I find this approach to be both brittle and confusing. While making these changes, I found a small bug due to the silent assumptions. This PR also proposes a rename from `OneShot` to `AddrFetch`. I find the name `OneShot` to be very confusing, especially when we also have `onetry` manual connections. Everyone I've talked to offline has agreed that the name is confusing, so I propose a potential alternative. I think this is a good opportunity for a rename since I'm creating an enum to explicitly define the connection types. (some context for the unfamiliar: `oneshot` or `addrfetch` connections are short-lived connections created on startup. They connect to the seed peers, send a `getaddr` to solicit addresses, then close the connection.) Overview of this PR: * rename `oneshot` to `addrfetch` * introduce `ConnectionType` enum * one by one, add different connection types to the enum * expose the `conn_type` on CNode, and use this to reduce reliance on flags (& asserts) * fix the bug in counting different type of connections * some additional cleanup to simplify logic and make expectations explicit/inclusive rather than implicit/exclusive. ACKs for top commit: jnewbery: utACK01e283068b
laanwj: Code review ACK01e283068b
, the commits are pretty straightforward to follow, and I think this is a move in the right direction overall vasild: ACK01e283068
sdaftuar: ACK01e283068b
. fanquake: ACK01e283068b
- I don't have as much experience with the networking code but these changes look fairly straight forward, the new code seems more robust/understandable and the additional documentation is great. I'm glad that a followup branch is already underway. There might be some more review comments here later today, so keep an eye on the discussion, however I'm going to merge this now. jb55: wow this code was messy before... ACK01e283068b
Tree-SHA512: 7bb644a6ed5849913d777ebc2ff89133ca0fbef680355a9a344e07496a979e6f9ff21a958e8eea93dcd7d5c343682b0c7174b1a3de380a4247eaae73da436e15
This commit is contained in:
commit
ce3bdd0ed1
9 changed files with 186 additions and 140 deletions
|
@ -110,7 +110,7 @@ public:
|
|||
|
||||
// Note that of those which support the service bits prefix, most only support a subset of
|
||||
// possible options.
|
||||
// This is fine at runtime as we'll fall back to using them as a oneshot if they don't support the
|
||||
// This is fine at runtime as we'll fall back to using them as an addrfetch if they don't support the
|
||||
// service bits we want, but we should get them updated to support all service bits wanted by any
|
||||
// release ASAP to avoid it where possible.
|
||||
vSeeds.emplace_back("seed.bitcoin.sipa.be"); // Pieter Wuille, only supports x1, x5, x9, and xd
|
||||
|
|
156
src/net.cpp
156
src/net.cpp
|
@ -105,10 +105,10 @@ std::map<CNetAddr, LocalServiceInfo> mapLocalHost GUARDED_BY(cs_mapLocalHost);
|
|||
static bool vfLimited[NET_MAX] GUARDED_BY(cs_mapLocalHost) = {};
|
||||
std::string strSubVersion;
|
||||
|
||||
void CConnman::AddOneShot(const std::string& strDest)
|
||||
void CConnman::AddAddrFetch(const std::string& strDest)
|
||||
{
|
||||
LOCK(cs_vOneShots);
|
||||
vOneShots.push_back(strDest);
|
||||
LOCK(m_addr_fetches_mutex);
|
||||
m_addr_fetches.push_back(strDest);
|
||||
}
|
||||
|
||||
uint16_t GetListenPort()
|
||||
|
@ -346,7 +346,7 @@ bool CConnman::CheckIncomingNonce(uint64_t nonce)
|
|||
{
|
||||
LOCK(cs_vNodes);
|
||||
for (const CNode* pnode : vNodes) {
|
||||
if (!pnode->fSuccessfullyConnected && !pnode->fInbound && pnode->GetLocalNonce() == nonce)
|
||||
if (!pnode->fSuccessfullyConnected && !pnode->IsInboundConn() && pnode->GetLocalNonce() == nonce)
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
@ -368,8 +368,10 @@ static CAddress GetBindAddress(SOCKET sock)
|
|||
return addr_bind;
|
||||
}
|
||||
|
||||
CNode* CConnman::ConnectNode(CAddress addrConnect, const char *pszDest, bool fCountFailure, bool manual_connection, bool block_relay_only)
|
||||
CNode* CConnman::ConnectNode(CAddress addrConnect, const char *pszDest, bool fCountFailure, ConnectionType conn_type)
|
||||
{
|
||||
assert(conn_type != ConnectionType::INBOUND);
|
||||
|
||||
if (pszDest == nullptr) {
|
||||
if (IsLocal(addrConnect))
|
||||
return nullptr;
|
||||
|
@ -432,7 +434,7 @@ CNode* CConnman::ConnectNode(CAddress addrConnect, const char *pszDest, bool fCo
|
|||
if (hSocket == INVALID_SOCKET) {
|
||||
return nullptr;
|
||||
}
|
||||
connected = ConnectSocketDirectly(addrConnect, hSocket, nConnectTimeout, manual_connection);
|
||||
connected = ConnectSocketDirectly(addrConnect, hSocket, nConnectTimeout, conn_type == ConnectionType::MANUAL);
|
||||
}
|
||||
if (!proxyConnectionFailed) {
|
||||
// If a connection to the node was attempted, and failure (if any) is not caused by a problem connecting to
|
||||
|
@ -459,7 +461,7 @@ CNode* CConnman::ConnectNode(CAddress addrConnect, const char *pszDest, bool fCo
|
|||
NodeId id = GetNewNodeId();
|
||||
uint64_t nonce = GetDeterministicRandomizer(RANDOMIZER_ID_LOCALHOSTNONCE).Write(id).Finalize();
|
||||
CAddress addr_bind = GetBindAddress(hSocket);
|
||||
CNode* pnode = new CNode(id, nLocalServices, GetBestHeight(), hSocket, addrConnect, CalculateKeyedNetGroup(addrConnect), nonce, addr_bind, pszDest ? pszDest : "", false, block_relay_only);
|
||||
CNode* pnode = new CNode(id, nLocalServices, GetBestHeight(), hSocket, addrConnect, CalculateKeyedNetGroup(addrConnect), nonce, addr_bind, pszDest ? pszDest : "", conn_type);
|
||||
pnode->AddRef();
|
||||
|
||||
// We're making a new connection, harvest entropy from the time (and our peer count)
|
||||
|
@ -536,8 +538,8 @@ void CNode::copyStats(CNodeStats &stats, const std::vector<bool> &m_asmap)
|
|||
LOCK(cs_SubVer);
|
||||
X(cleanSubVer);
|
||||
}
|
||||
X(fInbound);
|
||||
X(m_manual_connection);
|
||||
stats.fInbound = IsInboundConn();
|
||||
stats.m_manual_connection = IsManualConn();
|
||||
X(nStartingHeight);
|
||||
{
|
||||
LOCK(cs_vSend);
|
||||
|
@ -872,7 +874,7 @@ bool CConnman::AttemptToEvictConnection()
|
|||
for (const CNode* node : vNodes) {
|
||||
if (node->HasPermission(PF_NOBAN))
|
||||
continue;
|
||||
if (!node->fInbound)
|
||||
if (!node->IsInboundConn())
|
||||
continue;
|
||||
if (node->fDisconnect)
|
||||
continue;
|
||||
|
@ -983,7 +985,7 @@ void CConnman::AcceptConnection(const ListenSocket& hListenSocket) {
|
|||
{
|
||||
LOCK(cs_vNodes);
|
||||
for (const CNode* pnode : vNodes) {
|
||||
if (pnode->fInbound) nInbound++;
|
||||
if (pnode->IsInboundConn()) nInbound++;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1048,7 +1050,7 @@ void CConnman::AcceptConnection(const ListenSocket& hListenSocket) {
|
|||
if (NetPermissions::HasFlag(permissionFlags, PF_BLOOMFILTER)) {
|
||||
nodeServices = static_cast<ServiceFlags>(nodeServices | NODE_BLOOM);
|
||||
}
|
||||
CNode* pnode = new CNode(id, nodeServices, GetBestHeight(), hSocket, addr, CalculateKeyedNetGroup(addr), nonce, addr_bind, "", true);
|
||||
CNode* pnode = new CNode(id, nodeServices, GetBestHeight(), hSocket, addr, CalculateKeyedNetGroup(addr), nonce, addr_bind, "", ConnectionType::INBOUND);
|
||||
pnode->AddRef();
|
||||
pnode->m_permissionFlags = permissionFlags;
|
||||
// If this flag is present, the user probably expect that RPC and QT report it as whitelisted (backward compatibility)
|
||||
|
@ -1646,7 +1648,7 @@ void CConnman::ThreadDNSAddressSeed()
|
|||
{
|
||||
LOCK(cs_vNodes);
|
||||
for (const CNode* pnode : vNodes) {
|
||||
nRelevant += pnode->fSuccessfullyConnected && !pnode->fFeeler && !pnode->fOneShot && !pnode->m_manual_connection && !pnode->fInbound;
|
||||
if (pnode->fSuccessfullyConnected && pnode->IsOutboundOrBlockRelayConn()) ++nRelevant;
|
||||
}
|
||||
}
|
||||
if (nRelevant >= 2) {
|
||||
|
@ -1674,7 +1676,7 @@ void CConnman::ThreadDNSAddressSeed()
|
|||
|
||||
LogPrintf("Loading addresses from DNS seed %s\n", seed);
|
||||
if (HaveNameProxy()) {
|
||||
AddOneShot(seed);
|
||||
AddAddrFetch(seed);
|
||||
} else {
|
||||
std::vector<CNetAddr> vIPs;
|
||||
std::vector<CAddress> vAdd;
|
||||
|
@ -1696,8 +1698,8 @@ void CConnman::ThreadDNSAddressSeed()
|
|||
addrman.Add(vAdd, resolveSource);
|
||||
} else {
|
||||
// We now avoid directly using results from DNS Seeds which do not support service bit filtering,
|
||||
// instead using them as a oneshot to get nodes with our desired service bits.
|
||||
AddOneShot(seed);
|
||||
// instead using them as a addrfetch to get nodes with our desired service bits.
|
||||
AddAddrFetch(seed);
|
||||
}
|
||||
}
|
||||
--seeds_right_now;
|
||||
|
@ -1705,17 +1707,6 @@ void CConnman::ThreadDNSAddressSeed()
|
|||
LogPrintf("%d addresses found from DNS seeds\n", found);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void CConnman::DumpAddresses()
|
||||
{
|
||||
int64_t nStart = GetTimeMillis();
|
||||
|
@ -1727,20 +1718,20 @@ void CConnman::DumpAddresses()
|
|||
addrman.size(), GetTimeMillis() - nStart);
|
||||
}
|
||||
|
||||
void CConnman::ProcessOneShot()
|
||||
void CConnman::ProcessAddrFetch()
|
||||
{
|
||||
std::string strDest;
|
||||
{
|
||||
LOCK(cs_vOneShots);
|
||||
if (vOneShots.empty())
|
||||
LOCK(m_addr_fetches_mutex);
|
||||
if (m_addr_fetches.empty())
|
||||
return;
|
||||
strDest = vOneShots.front();
|
||||
vOneShots.pop_front();
|
||||
strDest = m_addr_fetches.front();
|
||||
m_addr_fetches.pop_front();
|
||||
}
|
||||
CAddress addr;
|
||||
CSemaphoreGrant grant(*semOutbound, true);
|
||||
if (grant) {
|
||||
OpenNetworkConnection(addr, false, &grant, strDest.c_str(), true);
|
||||
OpenNetworkConnection(addr, false, &grant, strDest.c_str(), ConnectionType::ADDR_FETCH);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1767,7 +1758,7 @@ int CConnman::GetExtraOutboundCount()
|
|||
{
|
||||
LOCK(cs_vNodes);
|
||||
for (const CNode* pnode : vNodes) {
|
||||
if (!pnode->fInbound && !pnode->m_manual_connection && !pnode->fFeeler && !pnode->fDisconnect && !pnode->fOneShot && pnode->fSuccessfullyConnected) {
|
||||
if (pnode->fSuccessfullyConnected && !pnode->fDisconnect && pnode->IsOutboundOrBlockRelayConn()) {
|
||||
++nOutbound;
|
||||
}
|
||||
}
|
||||
|
@ -1782,11 +1773,11 @@ void CConnman::ThreadOpenConnections(const std::vector<std::string> connect)
|
|||
{
|
||||
for (int64_t nLoop = 0;; nLoop++)
|
||||
{
|
||||
ProcessOneShot();
|
||||
ProcessAddrFetch();
|
||||
for (const std::string& strAddr : connect)
|
||||
{
|
||||
CAddress addr(CService(), NODE_NONE);
|
||||
OpenNetworkConnection(addr, false, nullptr, strAddr.c_str(), false, false, true);
|
||||
OpenNetworkConnection(addr, false, nullptr, strAddr.c_str(), ConnectionType::MANUAL);
|
||||
for (int i = 0; i < 10 && i < nLoop; i++)
|
||||
{
|
||||
if (!interruptNet.sleep_for(std::chrono::milliseconds(500)))
|
||||
|
@ -1805,7 +1796,7 @@ void CConnman::ThreadOpenConnections(const std::vector<std::string> connect)
|
|||
int64_t nNextFeeler = PoissonNextSend(nStart*1000*1000, FEELER_INTERVAL);
|
||||
while (!interruptNet)
|
||||
{
|
||||
ProcessOneShot();
|
||||
ProcessAddrFetch();
|
||||
|
||||
if (!interruptNet.sleep_for(std::chrono::milliseconds(500)))
|
||||
return;
|
||||
|
@ -1838,21 +1829,27 @@ void CConnman::ThreadOpenConnections(const std::vector<std::string> connect)
|
|||
int nOutboundFullRelay = 0;
|
||||
int nOutboundBlockRelay = 0;
|
||||
std::set<std::vector<unsigned char> > setConnected;
|
||||
|
||||
{
|
||||
LOCK(cs_vNodes);
|
||||
for (const CNode* pnode : vNodes) {
|
||||
if (!pnode->fInbound && !pnode->m_manual_connection) {
|
||||
// Netgroups for inbound and addnode peers are not excluded because our goal here
|
||||
// is to not use multiple of our limited outbound slots on a single netgroup
|
||||
// but inbound and addnode peers do not use our outbound slots. Inbound peers
|
||||
// also have the added issue that they're attacker controlled and could be used
|
||||
// to prevent us from connecting to particular hosts if we used them here.
|
||||
setConnected.insert(pnode->addr.GetGroup(addrman.m_asmap));
|
||||
if (pnode->m_tx_relay == nullptr) {
|
||||
nOutboundBlockRelay++;
|
||||
} else if (!pnode->fFeeler) {
|
||||
nOutboundFullRelay++;
|
||||
}
|
||||
if (pnode->IsFullOutboundConn()) nOutboundFullRelay++;
|
||||
if (pnode->IsBlockOnlyConn()) nOutboundBlockRelay++;
|
||||
|
||||
// Netgroups for inbound and manual peers are not excluded because our goal here
|
||||
// is to not use multiple of our limited outbound slots on a single netgroup
|
||||
// but inbound and manual peers do not use our outbound slots. Inbound peers
|
||||
// also have the added issue that they could be attacker controlled and used
|
||||
// to prevent us from connecting to particular hosts if we used them here.
|
||||
switch(pnode->m_conn_type){
|
||||
case ConnectionType::INBOUND:
|
||||
case ConnectionType::MANUAL:
|
||||
break;
|
||||
case ConnectionType::OUTBOUND:
|
||||
case ConnectionType::BLOCK_RELAY:
|
||||
case ConnectionType::ADDR_FETCH:
|
||||
case ConnectionType::FEELER:
|
||||
setConnected.insert(pnode->addr.GetGroup(addrman.m_asmap));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1945,14 +1942,24 @@ void CConnman::ThreadOpenConnections(const std::vector<std::string> connect)
|
|||
LogPrint(BCLog::NET, "Making feeler connection to %s\n", addrConnect.ToString());
|
||||
}
|
||||
|
||||
// Open this connection as block-relay-only if we're already at our
|
||||
// full-relay capacity, but not yet at our block-relay peer limit.
|
||||
// (It should not be possible for fFeeler to be set if we're not
|
||||
// also at our block-relay peer limit, but check against that as
|
||||
// well for sanity.)
|
||||
bool block_relay_only = nOutboundBlockRelay < m_max_outbound_block_relay && !fFeeler && nOutboundFullRelay >= m_max_outbound_full_relay;
|
||||
ConnectionType conn_type;
|
||||
// Determine what type of connection to open. If fFeeler is not
|
||||
// set, open OUTBOUND connections until we meet our full-relay
|
||||
// capacity. Then open BLOCK_RELAY connections until we hit our
|
||||
// block-relay peer limit. Otherwise, default to opening an
|
||||
// OUTBOUND connection.
|
||||
if (fFeeler) {
|
||||
conn_type = ConnectionType::FEELER;
|
||||
} else if (nOutboundFullRelay < m_max_outbound_full_relay) {
|
||||
conn_type = ConnectionType::OUTBOUND;
|
||||
} else if (nOutboundBlockRelay < m_max_outbound_block_relay) {
|
||||
conn_type = ConnectionType::BLOCK_RELAY;
|
||||
} else {
|
||||
// GetTryNewOutboundPeer() is true
|
||||
conn_type = ConnectionType::OUTBOUND;
|
||||
}
|
||||
|
||||
OpenNetworkConnection(addrConnect, (int)setConnected.size() >= std::min(nMaxConnections - 1, 2), &grant, nullptr, false, fFeeler, false, block_relay_only);
|
||||
OpenNetworkConnection(addrConnect, (int)setConnected.size() >= std::min(nMaxConnections - 1, 2), &grant, nullptr, conn_type);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1976,11 +1983,11 @@ std::vector<AddedNodeInfo> CConnman::GetAddedNodeInfo()
|
|||
LOCK(cs_vNodes);
|
||||
for (const CNode* pnode : vNodes) {
|
||||
if (pnode->addr.IsValid()) {
|
||||
mapConnected[pnode->addr] = pnode->fInbound;
|
||||
mapConnected[pnode->addr] = pnode->IsInboundConn();
|
||||
}
|
||||
std::string addrName = pnode->GetAddrName();
|
||||
if (!addrName.empty()) {
|
||||
mapConnectedByName[std::move(addrName)] = std::make_pair(pnode->fInbound, static_cast<const CService&>(pnode->addr));
|
||||
mapConnectedByName[std::move(addrName)] = std::make_pair(pnode->IsInboundConn(), static_cast<const CService&>(pnode->addr));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2027,7 +2034,7 @@ void CConnman::ThreadOpenAddedConnections()
|
|||
}
|
||||
tried = true;
|
||||
CAddress addr(CService(), NODE_NONE);
|
||||
OpenNetworkConnection(addr, false, &grant, info.strAddedNode.c_str(), false, false, true);
|
||||
OpenNetworkConnection(addr, false, &grant, info.strAddedNode.c_str(), ConnectionType::MANUAL);
|
||||
if (!interruptNet.sleep_for(std::chrono::milliseconds(500)))
|
||||
return;
|
||||
}
|
||||
|
@ -2039,8 +2046,10 @@ void CConnman::ThreadOpenAddedConnections()
|
|||
}
|
||||
|
||||
// if successful, this moves the passed grant to the constructed node
|
||||
void CConnman::OpenNetworkConnection(const CAddress& addrConnect, bool fCountFailure, CSemaphoreGrant *grantOutbound, const char *pszDest, bool fOneShot, bool fFeeler, bool manual_connection, bool block_relay_only)
|
||||
void CConnman::OpenNetworkConnection(const CAddress& addrConnect, bool fCountFailure, CSemaphoreGrant *grantOutbound, const char *pszDest, ConnectionType conn_type)
|
||||
{
|
||||
assert(conn_type != ConnectionType::INBOUND);
|
||||
|
||||
//
|
||||
// Initiate outbound network connection
|
||||
//
|
||||
|
@ -2058,18 +2067,12 @@ void CConnman::OpenNetworkConnection(const CAddress& addrConnect, bool fCountFai
|
|||
} else if (FindNode(std::string(pszDest)))
|
||||
return;
|
||||
|
||||
CNode* pnode = ConnectNode(addrConnect, pszDest, fCountFailure, manual_connection, block_relay_only);
|
||||
CNode* pnode = ConnectNode(addrConnect, pszDest, fCountFailure, conn_type);
|
||||
|
||||
if (!pnode)
|
||||
return;
|
||||
if (grantOutbound)
|
||||
grantOutbound->MoveTo(pnode->grantOutbound);
|
||||
if (fOneShot)
|
||||
pnode->fOneShot = true;
|
||||
if (fFeeler)
|
||||
pnode->fFeeler = true;
|
||||
if (manual_connection)
|
||||
pnode->m_manual_connection = true;
|
||||
|
||||
m_msgproc->InitializeNode(pnode);
|
||||
{
|
||||
|
@ -2127,11 +2130,6 @@ void CConnman::ThreadMessageHandler()
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
bool CConnman::BindListenPort(const CService& addrBind, bilingual_str& strError, NetPermissionFlags permissions)
|
||||
{
|
||||
int nOne = 1;
|
||||
|
@ -2337,7 +2335,7 @@ bool CConnman::Start(CScheduler& scheduler, const Options& connOptions)
|
|||
}
|
||||
|
||||
for (const auto& strDest : connOptions.vSeedNodes) {
|
||||
AddOneShot(strDest);
|
||||
AddAddrFetch(strDest);
|
||||
}
|
||||
|
||||
if (clientInterface) {
|
||||
|
@ -2390,7 +2388,7 @@ bool CConnman::Start(CScheduler& scheduler, const Options& connOptions)
|
|||
else
|
||||
threadDNSAddressSeed = std::thread(&TraceThread<std::function<void()> >, "dnsseed", std::function<void()>(std::bind(&CConnman::ThreadDNSAddressSeed, this)));
|
||||
|
||||
// Initiate outbound connections from -addnode
|
||||
// Initiate manual connections
|
||||
threadOpenAddedConnections = std::thread(&TraceThread<std::function<void()> >, "addcon", std::function<void()>(std::bind(&CConnman::ThreadOpenAddedConnections, this)));
|
||||
|
||||
if (connOptions.m_use_addrman_outgoing && !connOptions.m_specified_outgoing.empty()) {
|
||||
|
@ -2581,7 +2579,7 @@ size_t CConnman::GetNodeCount(NumConnections flags)
|
|||
|
||||
int nNum = 0;
|
||||
for (const auto& pnode : vNodes) {
|
||||
if (flags & (pnode->fInbound ? CONNECTIONS_IN : CONNECTIONS_OUT)) {
|
||||
if (flags & (pnode->IsInboundConn() ? CONNECTIONS_IN : CONNECTIONS_OUT)) {
|
||||
nNum++;
|
||||
}
|
||||
}
|
||||
|
@ -2765,26 +2763,26 @@ int CConnman::GetBestHeight() const
|
|||
|
||||
unsigned int CConnman::GetReceiveFloodSize() const { return nReceiveFloodSize; }
|
||||
|
||||
CNode::CNode(NodeId idIn, ServiceFlags nLocalServicesIn, int nMyStartingHeightIn, SOCKET hSocketIn, const CAddress& addrIn, uint64_t nKeyedNetGroupIn, uint64_t nLocalHostNonceIn, const CAddress& addrBindIn, const std::string& addrNameIn, bool fInboundIn, bool block_relay_only)
|
||||
CNode::CNode(NodeId idIn, 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)
|
||||
: nTimeConnected(GetSystemTimeInSeconds()),
|
||||
addr(addrIn),
|
||||
addrBind(addrBindIn),
|
||||
fInbound(fInboundIn),
|
||||
nKeyedNetGroup(nKeyedNetGroupIn),
|
||||
// Don't relay addr messages to peers that we connect to as block-relay-only
|
||||
// peers (to prevent adversaries from inferring these links from addr
|
||||
// traffic).
|
||||
m_addr_known{block_relay_only ? nullptr : MakeUnique<CRollingBloomFilter>(5000, 0.001)},
|
||||
id(idIn),
|
||||
nLocalHostNonce(nLocalHostNonceIn),
|
||||
m_conn_type(conn_type_in),
|
||||
nLocalServices(nLocalServicesIn),
|
||||
nMyStartingHeight(nMyStartingHeightIn)
|
||||
{
|
||||
hSocket = hSocketIn;
|
||||
addrName = addrNameIn == "" ? addr.ToStringIPPort() : addrNameIn;
|
||||
hashContinue = uint256();
|
||||
if (!block_relay_only) {
|
||||
if (conn_type_in != ConnectionType::BLOCK_RELAY) {
|
||||
m_tx_relay = MakeUnique<TxRelay>();
|
||||
m_addr_known = MakeUnique<CRollingBloomFilter>(5000, 0.001);
|
||||
}
|
||||
|
||||
for (const std::string &msg : getAllNetMessageTypes())
|
||||
|
|
86
src/net.h
86
src/net.h
|
@ -117,6 +117,17 @@ struct CSerializedNetMsg
|
|||
std::string m_type;
|
||||
};
|
||||
|
||||
/** Different types of connections to a peer. This enum encapsulates the
|
||||
* information we have available at the time of opening or accepting the
|
||||
* connection. Aside from INBOUND, all types are initiated by us. */
|
||||
enum class ConnectionType {
|
||||
INBOUND, /**< peer initiated connections */
|
||||
OUTBOUND, /**< full relay connections (blocks, addrs, txns) made automatically. Addresses selected from AddrMan. */
|
||||
MANUAL, /**< connections to addresses added via addnode or the connect command line argument */
|
||||
FEELER, /**< short lived connections used to test address validity */
|
||||
BLOCK_RELAY, /**< only relay blocks to these automatic outbound connections. Addresses selected from AddrMan. */
|
||||
ADDR_FETCH, /**< short lived connections used to solicit addrs when starting the node without a populated AddrMan */
|
||||
};
|
||||
|
||||
class NetEventsInterface;
|
||||
class CConnman
|
||||
|
@ -201,7 +212,7 @@ public:
|
|||
bool GetNetworkActive() const { return fNetworkActive; };
|
||||
bool GetUseAddrmanOutgoing() const { return m_use_addrman_outgoing; };
|
||||
void SetNetworkActive(bool active);
|
||||
void OpenNetworkConnection(const CAddress& addrConnect, bool fCountFailure, CSemaphoreGrant *grantOutbound = nullptr, const char *strDest = nullptr, bool fOneShot = false, bool fFeeler = false, bool manual_connection = false, bool block_relay_only = false);
|
||||
void OpenNetworkConnection(const CAddress& addrConnect, bool fCountFailure, CSemaphoreGrant *grantOutbound = nullptr, const char *strDest = nullptr, ConnectionType conn_type = ConnectionType::OUTBOUND);
|
||||
bool CheckIncomingNonce(uint64_t nonce);
|
||||
|
||||
bool ForNode(NodeId id, std::function<bool(CNode* pnode)> func);
|
||||
|
@ -351,8 +362,8 @@ private:
|
|||
bool Bind(const CService& addr, unsigned int flags, NetPermissionFlags permissions);
|
||||
bool InitBinds(const std::vector<CService>& binds, const std::vector<NetWhitebindPermissions>& whiteBinds);
|
||||
void ThreadOpenAddedConnections();
|
||||
void AddOneShot(const std::string& strDest);
|
||||
void ProcessOneShot();
|
||||
void AddAddrFetch(const std::string& strDest);
|
||||
void ProcessAddrFetch();
|
||||
void ThreadOpenConnections(std::vector<std::string> connect);
|
||||
void ThreadMessageHandler();
|
||||
void AcceptConnection(const ListenSocket& hListenSocket);
|
||||
|
@ -373,7 +384,7 @@ private:
|
|||
CNode* FindNode(const CService& addr);
|
||||
|
||||
bool AttemptToEvictConnection();
|
||||
CNode* ConnectNode(CAddress addrConnect, const char *pszDest, bool fCountFailure, bool manual_connection, bool block_relay_only);
|
||||
CNode* ConnectNode(CAddress addrConnect, const char *pszDest, bool fCountFailure, ConnectionType conn_type);
|
||||
void AddWhitelistPermissionFlags(NetPermissionFlags& flags, const CNetAddr &addr) const;
|
||||
|
||||
void DeleteNode(CNode* pnode);
|
||||
|
@ -416,8 +427,8 @@ private:
|
|||
std::atomic<bool> fNetworkActive{true};
|
||||
bool fAddressesInitialized{false};
|
||||
CAddrMan addrman;
|
||||
std::deque<std::string> vOneShots GUARDED_BY(cs_vOneShots);
|
||||
RecursiveMutex cs_vOneShots;
|
||||
std::deque<std::string> m_addr_fetches GUARDED_BY(m_addr_fetches_mutex);
|
||||
RecursiveMutex m_addr_fetches_mutex;
|
||||
std::vector<std::string> vAddedNodes GUARDED_BY(cs_vAddedNodes);
|
||||
RecursiveMutex cs_vAddedNodes;
|
||||
std::vector<CNode*> vNodes GUARDED_BY(cs_vNodes);
|
||||
|
@ -798,12 +809,8 @@ public:
|
|||
}
|
||||
// This boolean is unusued in actual processing, only present for backward compatibility at RPC/QT level
|
||||
bool m_legacyWhitelisted{false};
|
||||
bool fFeeler{false}; // If true this node is being used as a short lived feeler.
|
||||
bool fOneShot{false};
|
||||
bool m_manual_connection{false};
|
||||
bool fClient{false}; // set by version message
|
||||
bool m_limited_node{false}; //after BIP159, set by version message
|
||||
const bool fInbound;
|
||||
std::atomic_bool fSuccessfullyConnected{false};
|
||||
// Setting fDisconnect to true will cause the node to be disconnected the
|
||||
// next time DisconnectNodes() runs
|
||||
|
@ -816,6 +823,60 @@ public:
|
|||
std::atomic_bool fPauseRecv{false};
|
||||
std::atomic_bool fPauseSend{false};
|
||||
|
||||
bool IsOutboundOrBlockRelayConn() const {
|
||||
switch(m_conn_type) {
|
||||
case ConnectionType::OUTBOUND:
|
||||
case ConnectionType::BLOCK_RELAY:
|
||||
return true;
|
||||
case ConnectionType::INBOUND:
|
||||
case ConnectionType::MANUAL:
|
||||
case ConnectionType::ADDR_FETCH:
|
||||
case ConnectionType::FEELER:
|
||||
return false;
|
||||
}
|
||||
|
||||
assert(false);
|
||||
}
|
||||
|
||||
bool IsFullOutboundConn() const {
|
||||
return m_conn_type == ConnectionType::OUTBOUND;
|
||||
}
|
||||
|
||||
bool IsManualConn() const {
|
||||
return m_conn_type == ConnectionType::MANUAL;
|
||||
}
|
||||
|
||||
bool IsBlockOnlyConn() const {
|
||||
return m_conn_type == ConnectionType::BLOCK_RELAY;
|
||||
}
|
||||
|
||||
bool IsFeelerConn() const {
|
||||
return m_conn_type == ConnectionType::FEELER;
|
||||
}
|
||||
|
||||
bool IsAddrFetchConn() const {
|
||||
return m_conn_type == ConnectionType::ADDR_FETCH;
|
||||
}
|
||||
|
||||
bool IsInboundConn() const {
|
||||
return m_conn_type == ConnectionType::INBOUND;
|
||||
}
|
||||
|
||||
bool ExpectServicesFromConn() const {
|
||||
switch(m_conn_type) {
|
||||
case ConnectionType::INBOUND:
|
||||
case ConnectionType::MANUAL:
|
||||
case ConnectionType::FEELER:
|
||||
return false;
|
||||
case ConnectionType::OUTBOUND:
|
||||
case ConnectionType::BLOCK_RELAY:
|
||||
case ConnectionType::ADDR_FETCH:
|
||||
return true;
|
||||
}
|
||||
|
||||
assert(false);
|
||||
}
|
||||
|
||||
protected:
|
||||
mapMsgCmdSize mapSendBytesPerMsgCmd;
|
||||
mapMsgCmdSize mapRecvBytesPerMsgCmd GUARDED_BY(cs_vRecv);
|
||||
|
@ -826,7 +887,7 @@ public:
|
|||
|
||||
// flood relay
|
||||
std::vector<CAddress> vAddrToSend;
|
||||
const std::unique_ptr<CRollingBloomFilter> m_addr_known;
|
||||
std::unique_ptr<CRollingBloomFilter> m_addr_known = nullptr;
|
||||
bool fGetAddr{false};
|
||||
std::chrono::microseconds m_next_addr_send GUARDED_BY(cs_sendProcessing){0};
|
||||
std::chrono::microseconds m_next_local_addr_send GUARDED_BY(cs_sendProcessing){0};
|
||||
|
@ -890,7 +951,7 @@ public:
|
|||
|
||||
std::set<uint256> orphan_work_set;
|
||||
|
||||
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 = "", bool fInboundIn = false, bool block_relay_only = false);
|
||||
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);
|
||||
~CNode();
|
||||
CNode(const CNode&) = delete;
|
||||
CNode& operator=(const CNode&) = delete;
|
||||
|
@ -898,6 +959,7 @@ public:
|
|||
private:
|
||||
const NodeId id;
|
||||
const uint64_t nLocalHostNonce;
|
||||
const ConnectionType m_conn_type;
|
||||
|
||||
//! Services offered to this peer.
|
||||
//!
|
||||
|
|
|
@ -479,7 +479,7 @@ static void UpdatePreferredDownload(const CNode& node, CNodeState* state) EXCLUS
|
|||
nPreferredDownload -= state->fPreferredDownload;
|
||||
|
||||
// Whether this node should be marked as a preferred download node.
|
||||
state->fPreferredDownload = (!node.fInbound || node.HasPermission(PF_NOBAN)) && !node.fOneShot && !node.fClient;
|
||||
state->fPreferredDownload = (!node.IsInboundConn() || node.HasPermission(PF_NOBAN)) && !node.IsAddrFetchConn() && !node.fClient;
|
||||
|
||||
nPreferredDownload += state->fPreferredDownload;
|
||||
}
|
||||
|
@ -833,22 +833,15 @@ void UpdateLastBlockAnnounceTime(NodeId node, int64_t time_in_seconds)
|
|||
if (state) state->m_last_block_announcement = time_in_seconds;
|
||||
}
|
||||
|
||||
// Returns true for outbound peers, excluding manual connections, feelers, and
|
||||
// one-shots.
|
||||
static bool IsOutboundDisconnectionCandidate(const CNode& node)
|
||||
{
|
||||
return !(node.fInbound || node.m_manual_connection || node.fFeeler || node.fOneShot);
|
||||
}
|
||||
|
||||
void PeerLogicValidation::InitializeNode(CNode *pnode) {
|
||||
CAddress addr = pnode->addr;
|
||||
std::string addrName = pnode->GetAddrName();
|
||||
NodeId nodeid = pnode->GetId();
|
||||
{
|
||||
LOCK(cs_main);
|
||||
mapNodeState.emplace_hint(mapNodeState.end(), std::piecewise_construct, std::forward_as_tuple(nodeid), std::forward_as_tuple(addr, std::move(addrName), pnode->fInbound, pnode->m_manual_connection));
|
||||
mapNodeState.emplace_hint(mapNodeState.end(), std::piecewise_construct, std::forward_as_tuple(nodeid), std::forward_as_tuple(addr, std::move(addrName), pnode->IsInboundConn(), pnode->IsManualConn()));
|
||||
}
|
||||
if(!pnode->fInbound)
|
||||
if(!pnode->IsInboundConn())
|
||||
PushNodeVersion(*pnode, *connman, GetTime());
|
||||
}
|
||||
|
||||
|
@ -1982,14 +1975,14 @@ static void ProcessHeadersMessage(CNode& pfrom, CConnman& connman, ChainstateMan
|
|||
// until we have a headers chain that has at least
|
||||
// nMinimumChainWork, even if a peer has a chain past our tip,
|
||||
// as an anti-DoS measure.
|
||||
if (IsOutboundDisconnectionCandidate(pfrom)) {
|
||||
if (pfrom.IsOutboundOrBlockRelayConn()) {
|
||||
LogPrintf("Disconnecting outbound peer %d -- headers chain has insufficient work\n", pfrom.GetId());
|
||||
pfrom.fDisconnect = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!pfrom.fDisconnect && IsOutboundDisconnectionCandidate(pfrom) && nodestate->pindexBestKnownBlock != nullptr && pfrom.m_tx_relay != nullptr) {
|
||||
if (!pfrom.fDisconnect && pfrom.IsOutboundOrBlockRelayConn() && nodestate->pindexBestKnownBlock != nullptr && pfrom.m_tx_relay != nullptr) {
|
||||
// If this is an outbound full-relay peer, check to see if we should protect
|
||||
// it from the bad/lagging chain logic.
|
||||
// Note that block-relay-only peers are already implicitly protected, so we
|
||||
|
@ -2352,11 +2345,11 @@ void ProcessMessage(
|
|||
vRecv >> nVersion >> nServiceInt >> nTime >> addrMe;
|
||||
nSendVersion = std::min(nVersion, PROTOCOL_VERSION);
|
||||
nServices = ServiceFlags(nServiceInt);
|
||||
if (!pfrom.fInbound)
|
||||
if (!pfrom.IsInboundConn())
|
||||
{
|
||||
connman.SetServices(pfrom.addr, nServices);
|
||||
}
|
||||
if (!pfrom.fInbound && !pfrom.fFeeler && !pfrom.m_manual_connection && !HasAllDesirableServiceFlags(nServices))
|
||||
if (pfrom.ExpectServicesFromConn() && !HasAllDesirableServiceFlags(nServices))
|
||||
{
|
||||
LogPrint(BCLog::NET, "peer=%d does not offer the expected services (%08x offered, %08x expected); disconnecting\n", pfrom.GetId(), nServices, GetDesirableServiceFlags(nServices));
|
||||
pfrom.fDisconnect = true;
|
||||
|
@ -2383,20 +2376,20 @@ void ProcessMessage(
|
|||
if (!vRecv.empty())
|
||||
vRecv >> fRelay;
|
||||
// Disconnect if we connected to ourself
|
||||
if (pfrom.fInbound && !connman.CheckIncomingNonce(nNonce))
|
||||
if (pfrom.IsInboundConn() && !connman.CheckIncomingNonce(nNonce))
|
||||
{
|
||||
LogPrintf("connected to self at %s, disconnecting\n", pfrom.addr.ToString());
|
||||
pfrom.fDisconnect = true;
|
||||
return;
|
||||
}
|
||||
|
||||
if (pfrom.fInbound && addrMe.IsRoutable())
|
||||
if (pfrom.IsInboundConn() && addrMe.IsRoutable())
|
||||
{
|
||||
SeenLocal(addrMe);
|
||||
}
|
||||
|
||||
// Be shy and don't send version until we hear
|
||||
if (pfrom.fInbound)
|
||||
if (pfrom.IsInboundConn())
|
||||
PushNodeVersion(pfrom, connman, GetAdjustedTime());
|
||||
|
||||
if (nVersion >= WTXID_RELAY_VERSION) {
|
||||
|
@ -2440,7 +2433,7 @@ void ProcessMessage(
|
|||
UpdatePreferredDownload(pfrom, State(pfrom.GetId()));
|
||||
}
|
||||
|
||||
if (!pfrom.fInbound && pfrom.IsAddrRelayPeer())
|
||||
if (!pfrom.IsInboundConn() && pfrom.IsAddrRelayPeer())
|
||||
{
|
||||
// Advertise our address
|
||||
if (fListen && !::ChainstateActive().IsInitialBlockDownload())
|
||||
|
@ -2484,8 +2477,7 @@ void ProcessMessage(
|
|||
}
|
||||
|
||||
// Feeler connections exist only to verify if address is online.
|
||||
if (pfrom.fFeeler) {
|
||||
assert(pfrom.fInbound == false);
|
||||
if (pfrom.IsFeelerConn()) {
|
||||
pfrom.fDisconnect = true;
|
||||
}
|
||||
return;
|
||||
|
@ -2505,7 +2497,7 @@ void ProcessMessage(
|
|||
{
|
||||
pfrom.SetRecvVersion(std::min(pfrom.nVersion.load(), PROTOCOL_VERSION));
|
||||
|
||||
if (!pfrom.fInbound) {
|
||||
if (!pfrom.IsInboundConn()) {
|
||||
// Mark this node as currently connected, so we update its timestamp later.
|
||||
LOCK(cs_main);
|
||||
State(pfrom.GetId())->fCurrentlyConnected = true;
|
||||
|
@ -2614,7 +2606,7 @@ void ProcessMessage(
|
|||
connman.AddNewAddresses(vAddrOk, pfrom.addr, 2 * 60 * 60);
|
||||
if (vAddr.size() < 1000)
|
||||
pfrom.fGetAddr = false;
|
||||
if (pfrom.fOneShot)
|
||||
if (pfrom.IsAddrFetchConn())
|
||||
pfrom.fDisconnect = true;
|
||||
return;
|
||||
}
|
||||
|
@ -3509,7 +3501,7 @@ void ProcessMessage(
|
|||
// to users' AddrMan and later request them by sending getaddr messages.
|
||||
// Making nodes which are behind NAT and can only make outgoing connections ignore
|
||||
// the getaddr message mitigates the attack.
|
||||
if (!pfrom.fInbound) {
|
||||
if (!pfrom.IsInboundConn()) {
|
||||
LogPrint(BCLog::NET, "Ignoring \"getaddr\" from outbound connection. peer=%d\n", pfrom.GetId());
|
||||
return;
|
||||
}
|
||||
|
@ -3792,7 +3784,7 @@ bool PeerLogicValidation::MaybeDiscourageAndDisconnect(CNode& pnode)
|
|||
return false;
|
||||
}
|
||||
|
||||
if (pnode.m_manual_connection) {
|
||||
if (pnode.IsManualConn()) {
|
||||
// We never disconnect or discourage manual peers for bad behavior
|
||||
LogPrintf("Warning: not punishing manually connected peer %d!\n", peer_id);
|
||||
return false;
|
||||
|
@ -3913,7 +3905,7 @@ void PeerLogicValidation::ConsiderEviction(CNode& pto, int64_t time_in_seconds)
|
|||
CNodeState &state = *State(pto.GetId());
|
||||
const CNetMsgMaker msgMaker(pto.GetSendVersion());
|
||||
|
||||
if (!state.m_chain_sync.m_protect && IsOutboundDisconnectionCandidate(pto) && state.fSyncStarted) {
|
||||
if (!state.m_chain_sync.m_protect && pto.IsOutboundOrBlockRelayConn() && state.fSyncStarted) {
|
||||
// This is an outbound peer subject to disconnection if they don't
|
||||
// announce a block with as much work as the current tip within
|
||||
// CHAIN_SYNC_TIMEOUT + HEADERS_RESPONSE_TIME seconds (note: if
|
||||
|
@ -3975,7 +3967,7 @@ void PeerLogicValidation::EvictExtraOutboundPeers(int64_t time_in_seconds)
|
|||
AssertLockHeld(cs_main);
|
||||
|
||||
// Ignore non-outbound peers, or nodes marked for disconnect already
|
||||
if (!IsOutboundDisconnectionCandidate(*pnode) || pnode->fDisconnect) return;
|
||||
if (!pnode->IsOutboundOrBlockRelayConn() || pnode->fDisconnect) return;
|
||||
CNodeState *state = State(pnode->GetId());
|
||||
if (state == nullptr) return; // shouldn't be possible, but just in case
|
||||
// Don't evict our protected peers
|
||||
|
@ -4153,7 +4145,7 @@ bool PeerLogicValidation::SendMessages(CNode* pto)
|
|||
// Start block sync
|
||||
if (pindexBestHeader == nullptr)
|
||||
pindexBestHeader = ::ChainActive().Tip();
|
||||
bool fFetch = state.fPreferredDownload || (nPreferredDownload == 0 && !pto->fClient && !pto->fOneShot); // Download if this is a nice peer, or we have no nice peers and this one might do.
|
||||
bool fFetch = state.fPreferredDownload || (nPreferredDownload == 0 && !pto->fClient && !pto->IsAddrFetchConn()); // Download if this is a nice peer, or we have no nice peers and this one might do.
|
||||
if (!state.fSyncStarted && !pto->fClient && !fImporting && !fReindex) {
|
||||
// Only actively request headers from a single peer, unless we're close to today.
|
||||
if ((nSyncStarted == 0 && fFetch) || pindexBestHeader->GetBlockTime() > GetAdjustedTime() - 24 * 60 * 60) {
|
||||
|
@ -4338,7 +4330,7 @@ bool PeerLogicValidation::SendMessages(CNode* pto)
|
|||
bool fSendTrickle = pto->HasPermission(PF_NOBAN);
|
||||
if (pto->m_tx_relay->nNextInvSend < current_time) {
|
||||
fSendTrickle = true;
|
||||
if (pto->fInbound) {
|
||||
if (pto->IsInboundConn()) {
|
||||
pto->m_tx_relay->nNextInvSend = std::chrono::microseconds{connman->PoissonNextSendInbound(nNow, INVENTORY_BROADCAST_INTERVAL)};
|
||||
} else {
|
||||
// Use half the delay for outbound peers, as there is less privacy concern for them.
|
||||
|
|
|
@ -264,7 +264,7 @@ static UniValue addnode(const JSONRPCRequest& request)
|
|||
if (strCommand == "onetry")
|
||||
{
|
||||
CAddress addr;
|
||||
node.connman->OpenNetworkConnection(addr, false, nullptr, strNode.c_str(), false, false, true);
|
||||
node.connman->OpenNetworkConnection(addr, false, nullptr, strNode.c_str(), ConnectionType::MANUAL);
|
||||
return NullUniValue;
|
||||
}
|
||||
|
||||
|
|
|
@ -84,7 +84,7 @@ BOOST_AUTO_TEST_CASE(outbound_slow_chain_eviction)
|
|||
|
||||
// Mock an outbound peer
|
||||
CAddress addr1(ip(0xa0b0c001), NODE_NONE);
|
||||
CNode dummyNode1(id++, ServiceFlags(NODE_NETWORK|NODE_WITNESS), 0, INVALID_SOCKET, addr1, 0, 0, CAddress(), "", /*fInboundIn=*/ false);
|
||||
CNode dummyNode1(id++, ServiceFlags(NODE_NETWORK|NODE_WITNESS), 0, INVALID_SOCKET, addr1, 0, 0, CAddress(), "", ConnectionType::OUTBOUND);
|
||||
dummyNode1.SetSendVersion(PROTOCOL_VERSION);
|
||||
|
||||
peerLogic->InitializeNode(&dummyNode1);
|
||||
|
@ -136,7 +136,7 @@ BOOST_AUTO_TEST_CASE(outbound_slow_chain_eviction)
|
|||
static void AddRandomOutboundPeer(std::vector<CNode *> &vNodes, PeerLogicValidation &peerLogic, CConnmanTest* connman)
|
||||
{
|
||||
CAddress addr(ip(g_insecure_rand_ctx.randbits(32)), NODE_NONE);
|
||||
vNodes.emplace_back(new CNode(id++, ServiceFlags(NODE_NETWORK|NODE_WITNESS), 0, INVALID_SOCKET, addr, 0, 0, CAddress(), "", /*fInboundIn=*/ false));
|
||||
vNodes.emplace_back(new CNode(id++, ServiceFlags(NODE_NETWORK|NODE_WITNESS), 0, INVALID_SOCKET, addr, 0, 0, CAddress(), "", ConnectionType::OUTBOUND));
|
||||
CNode &node = *vNodes.back();
|
||||
node.SetSendVersion(PROTOCOL_VERSION);
|
||||
|
||||
|
@ -227,7 +227,7 @@ BOOST_AUTO_TEST_CASE(peer_discouragement)
|
|||
|
||||
banman->ClearBanned();
|
||||
CAddress addr1(ip(0xa0b0c001), NODE_NONE);
|
||||
CNode dummyNode1(id++, NODE_NETWORK, 0, INVALID_SOCKET, addr1, 0, 0, CAddress(), "", true);
|
||||
CNode dummyNode1(id++, NODE_NETWORK, 0, INVALID_SOCKET, addr1, 0, 0, CAddress(), "", ConnectionType::INBOUND);
|
||||
dummyNode1.SetSendVersion(PROTOCOL_VERSION);
|
||||
peerLogic->InitializeNode(&dummyNode1);
|
||||
dummyNode1.nVersion = 1;
|
||||
|
@ -244,7 +244,7 @@ BOOST_AUTO_TEST_CASE(peer_discouragement)
|
|||
BOOST_CHECK(!banman->IsDiscouraged(ip(0xa0b0c001|0x0000ff00))); // Different IP, not discouraged
|
||||
|
||||
CAddress addr2(ip(0xa0b0c002), NODE_NONE);
|
||||
CNode dummyNode2(id++, NODE_NETWORK, 0, INVALID_SOCKET, addr2, 1, 1, CAddress(), "", true);
|
||||
CNode dummyNode2(id++, NODE_NETWORK, 0, INVALID_SOCKET, addr2, 1, 1, CAddress(), "", ConnectionType::INBOUND);
|
||||
dummyNode2.SetSendVersion(PROTOCOL_VERSION);
|
||||
peerLogic->InitializeNode(&dummyNode2);
|
||||
dummyNode2.nVersion = 1;
|
||||
|
@ -286,7 +286,7 @@ BOOST_AUTO_TEST_CASE(DoS_bantime)
|
|||
SetMockTime(nStartTime); // Overrides future calls to GetTime()
|
||||
|
||||
CAddress addr(ip(0xa0b0c001), NODE_NONE);
|
||||
CNode dummyNode(id++, NODE_NETWORK, 0, INVALID_SOCKET, addr, 4, 4, CAddress(), "", true);
|
||||
CNode dummyNode(id++, NODE_NETWORK, 0, INVALID_SOCKET, addr, 4, 4, CAddress(), "", ConnectionType::INBOUND);
|
||||
dummyNode.SetSendVersion(PROTOCOL_VERSION);
|
||||
peerLogic->InitializeNode(&dummyNode);
|
||||
dummyNode.nVersion = 1;
|
||||
|
|
|
@ -80,7 +80,7 @@ void test_one_input(const std::vector<uint8_t>& buffer)
|
|||
return;
|
||||
}
|
||||
CDataStream random_bytes_data_stream{fuzzed_data_provider.ConsumeRemainingBytes<unsigned char>(), SER_NETWORK, PROTOCOL_VERSION};
|
||||
CNode& p2p_node = *MakeUnique<CNode>(0, ServiceFlags(NODE_NETWORK | NODE_WITNESS | NODE_BLOOM), 0, INVALID_SOCKET, CAddress{CService{in_addr{0x0100007f}, 7777}, NODE_NETWORK}, 0, 0, CAddress{}, std::string{}, false).release();
|
||||
CNode& p2p_node = *MakeUnique<CNode>(0, ServiceFlags(NODE_NETWORK | NODE_WITNESS | NODE_BLOOM), 0, INVALID_SOCKET, CAddress{CService{in_addr{0x0100007f}, 7777}, NODE_NETWORK}, 0, 0, CAddress{}, std::string{}, ConnectionType::OUTBOUND).release();
|
||||
p2p_node.fSuccessfullyConnected = true;
|
||||
p2p_node.nVersion = PROTOCOL_VERSION;
|
||||
p2p_node.SetSendVersion(PROTOCOL_VERSION);
|
||||
|
|
|
@ -44,9 +44,8 @@ void test_one_input(const std::vector<uint8_t>& buffer)
|
|||
const auto num_peers_to_add = fuzzed_data_provider.ConsumeIntegralInRange(1, 3);
|
||||
for (int i = 0; i < num_peers_to_add; ++i) {
|
||||
const ServiceFlags service_flags = ServiceFlags(fuzzed_data_provider.ConsumeIntegral<uint64_t>());
|
||||
const bool inbound{fuzzed_data_provider.ConsumeBool()};
|
||||
const bool block_relay_only{fuzzed_data_provider.ConsumeBool()};
|
||||
peers.push_back(MakeUnique<CNode>(i, service_flags, 0, INVALID_SOCKET, CAddress{CService{in_addr{0x0100007f}, 7777}, NODE_NETWORK}, 0, 0, CAddress{}, std::string{}, inbound, block_relay_only).release());
|
||||
const ConnectionType conn_type = fuzzed_data_provider.PickValueInArray({ConnectionType::INBOUND, ConnectionType::OUTBOUND, ConnectionType::MANUAL, ConnectionType::FEELER, ConnectionType::BLOCK_RELAY, ConnectionType::ADDR_FETCH});
|
||||
peers.push_back(MakeUnique<CNode>(i, service_flags, 0, INVALID_SOCKET, CAddress{CService{in_addr{0x0100007f}, 7777}, NODE_NETWORK}, 0, 0, CAddress{}, std::string{}, conn_type).release());
|
||||
CNode& p2p_node = *peers.back();
|
||||
|
||||
p2p_node.fSuccessfullyConnected = true;
|
||||
|
|
|
@ -180,17 +180,12 @@ BOOST_AUTO_TEST_CASE(cnode_simple_test)
|
|||
|
||||
CAddress addr = CAddress(CService(ipv4Addr, 7777), NODE_NETWORK);
|
||||
std::string pszDest;
|
||||
bool fInboundIn = false;
|
||||
|
||||
// Test that fFeeler is false by default.
|
||||
std::unique_ptr<CNode> pnode1 = MakeUnique<CNode>(id++, NODE_NETWORK, height, hSocket, addr, 0, 0, CAddress(), pszDest, fInboundIn);
|
||||
BOOST_CHECK(pnode1->fInbound == false);
|
||||
BOOST_CHECK(pnode1->fFeeler == false);
|
||||
std::unique_ptr<CNode> pnode1 = MakeUnique<CNode>(id++, NODE_NETWORK, height, hSocket, addr, 0, 0, CAddress(), pszDest, ConnectionType::OUTBOUND);
|
||||
BOOST_CHECK(pnode1->IsInboundConn() == false);
|
||||
|
||||
fInboundIn = true;
|
||||
std::unique_ptr<CNode> pnode2 = MakeUnique<CNode>(id++, NODE_NETWORK, height, hSocket, addr, 1, 1, CAddress(), pszDest, fInboundIn);
|
||||
BOOST_CHECK(pnode2->fInbound == true);
|
||||
BOOST_CHECK(pnode2->fFeeler == false);
|
||||
std::unique_ptr<CNode> pnode2 = MakeUnique<CNode>(id++, NODE_NETWORK, height, hSocket, addr, 1, 1, CAddress(), pszDest, ConnectionType::INBOUND);
|
||||
BOOST_CHECK(pnode2->IsInboundConn() == true);
|
||||
}
|
||||
|
||||
// prior to PR #14728, this test triggers an undefined behavior
|
||||
|
@ -214,7 +209,7 @@ BOOST_AUTO_TEST_CASE(ipv4_peer_with_ipv6_addrMe_test)
|
|||
in_addr ipv4AddrPeer;
|
||||
ipv4AddrPeer.s_addr = 0xa0b0c001;
|
||||
CAddress addr = CAddress(CService(ipv4AddrPeer, 7777), NODE_NETWORK);
|
||||
std::unique_ptr<CNode> pnode = MakeUnique<CNode>(0, NODE_NETWORK, 0, INVALID_SOCKET, addr, 0, 0, CAddress{}, std::string{}, false);
|
||||
std::unique_ptr<CNode> pnode = MakeUnique<CNode>(0, NODE_NETWORK, 0, INVALID_SOCKET, addr, 0, 0, CAddress{}, std::string{}, ConnectionType::OUTBOUND);
|
||||
pnode->fSuccessfullyConnected.store(true);
|
||||
|
||||
// the peer claims to be reaching us via IPv6
|
||||
|
|
Loading…
Add table
Reference in a new issue