diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/net.cpp | 21 | ||||
-rw-r--r-- | src/net.h | 1 | ||||
-rw-r--r-- | src/net_processing.cpp | 10 | ||||
-rw-r--r-- | src/rpc/net.cpp | 4 |
4 files changed, 30 insertions, 6 deletions
diff --git a/src/net.cpp b/src/net.cpp index 70ba875c4b..3a1bb138ab 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -1212,16 +1212,29 @@ void CConnman::CreateNodeFromAcceptedSocket(SOCKET hSocket, bool CConnman::AddConnection(const std::string& address, ConnectionType conn_type) { - if (conn_type != ConnectionType::OUTBOUND_FULL_RELAY && conn_type != ConnectionType::BLOCK_RELAY) return false; - - const int max_connections = conn_type == ConnectionType::OUTBOUND_FULL_RELAY ? m_max_outbound_full_relay : m_max_outbound_block_relay; + std::optional<int> max_connections; + switch (conn_type) { + case ConnectionType::INBOUND: + case ConnectionType::MANUAL: + case ConnectionType::FEELER: + return false; + case ConnectionType::OUTBOUND_FULL_RELAY: + max_connections = m_max_outbound_full_relay; + break; + case ConnectionType::BLOCK_RELAY: + max_connections = m_max_outbound_block_relay; + break; + // no limit for ADDR_FETCH because -seednode has no limit either + case ConnectionType::ADDR_FETCH: + break; + } // no default case, so the compiler can warn about missing cases // Count existing connections int existing_connections = WITH_LOCK(cs_vNodes, return std::count_if(vNodes.begin(), vNodes.end(), [conn_type](CNode* node) { return node->m_conn_type == conn_type; });); // Max connections of specified type already exist - if (existing_connections >= max_connections) return false; + if (max_connections != std::nullopt && existing_connections >= max_connections) return false; // Max total outbound connections already exist CSemaphoreGrant grant(*semOutbound, true); @@ -893,6 +893,7 @@ public: * * @param[in] address Address of node to try connecting to * @param[in] conn_type ConnectionType::OUTBOUND or ConnectionType::BLOCK_RELAY + * or ConnectionType::ADDR_FETCH * @return bool Returns false if there are no available * slots for this connection: * - conn_type not a supported ConnectionType diff --git a/src/net_processing.cpp b/src/net_processing.cpp index 9c4544df21..44f9879a23 100644 --- a/src/net_processing.cpp +++ b/src/net_processing.cpp @@ -2860,7 +2860,9 @@ void PeerManagerImpl::ProcessMessage(CNode& pfrom, const std::string& msg_type, m_addrman.Add(vAddrOk, pfrom.addr, 2 * 60 * 60); if (vAddr.size() < 1000) peer->m_getaddr_sent = false; - if (pfrom.IsAddrFetchConn()) { + + // AddrFetch: Require multiple addresses to avoid disconnecting on self-announcements + if (pfrom.IsAddrFetchConn() && vAddr.size() > 1) { LogPrint(BCLog::NET, "addrfetch connection completed peer=%d; disconnecting\n", pfrom.GetId()); pfrom.fDisconnect = true; } @@ -4444,6 +4446,12 @@ bool PeerManagerImpl::SendMessages(CNode* pto) const auto current_time = GetTime<std::chrono::microseconds>(); + if (pto->IsAddrFetchConn() && current_time - std::chrono::seconds(pto->nTimeConnected) > 10 * AVG_ADDRESS_BROADCAST_INTERVAL) { + LogPrint(BCLog::NET, "addrfetch connection timeout; disconnecting peer=%d\n", pto->GetId()); + pto->fDisconnect = true; + return true; + } + MaybeSendPing(*pto, *peer, current_time); // MaybeSendPing may have marked peer for disconnection diff --git a/src/rpc/net.cpp b/src/rpc/net.cpp index 083ba31b71..dba0f971b2 100644 --- a/src/rpc/net.cpp +++ b/src/rpc/net.cpp @@ -339,7 +339,7 @@ static RPCHelpMan addconnection() "\nOpen an outbound connection to a specified node. This RPC is for testing only.\n", { {"address", RPCArg::Type::STR, RPCArg::Optional::NO, "The IP address and port to attempt connecting to."}, - {"connection_type", RPCArg::Type::STR, RPCArg::Optional::NO, "Type of connection to open, either \"outbound-full-relay\" or \"block-relay-only\"."}, + {"connection_type", RPCArg::Type::STR, RPCArg::Optional::NO, "Type of connection to open (\"outbound-full-relay\", \"block-relay-only\" or \"addr-fetch\")."}, }, RPCResult{ RPCResult::Type::OBJ, "", "", @@ -365,6 +365,8 @@ static RPCHelpMan addconnection() conn_type = ConnectionType::OUTBOUND_FULL_RELAY; } else if (conn_type_in == "block-relay-only") { conn_type = ConnectionType::BLOCK_RELAY; + } else if (conn_type_in == "addr-fetch") { + conn_type = ConnectionType::ADDR_FETCH; } else { throw JSONRPCError(RPC_INVALID_PARAMETER, self.ToString()); } |