diff options
Diffstat (limited to 'src/net.cpp')
-rw-r--r-- | src/net.cpp | 110 |
1 files changed, 51 insertions, 59 deletions
diff --git a/src/net.cpp b/src/net.cpp index fe1a0dfded..1b6f04dead 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -16,6 +16,7 @@ #include <crypto/sha256.h> #include <i2p.h> #include <net_permissions.h> +#include <netaddress.h> #include <netbase.h> #include <node/ui_interface.h> #include <protocol.h> @@ -23,6 +24,7 @@ #include <scheduler.h> #include <util/sock.h> #include <util/strencodings.h> +#include <util/thread.h> #include <util/translation.h> #ifdef WIN32 @@ -681,19 +683,19 @@ int V1TransportDeserializer::readHeader(Span<const uint8_t> msg_bytes) hdrbuf >> hdr; } catch (const std::exception&) { - LogPrint(BCLog::NET, "HEADER ERROR - UNABLE TO DESERIALIZE, peer=%d\n", m_node_id); + LogPrint(BCLog::NET, "Header error: Unable to deserialize, peer=%d\n", m_node_id); return -1; } // Check start string, network magic if (memcmp(hdr.pchMessageStart, m_chain_params.MessageStart(), CMessageHeader::MESSAGE_START_SIZE) != 0) { - LogPrint(BCLog::NET, "HEADER ERROR - MESSAGESTART (%s, %u bytes), received %s, peer=%d\n", hdr.GetCommand(), hdr.nMessageSize, HexStr(hdr.pchMessageStart), m_node_id); + LogPrint(BCLog::NET, "Header error: Wrong MessageStart %s received, peer=%d\n", HexStr(hdr.pchMessageStart), m_node_id); return -1; } // reject messages larger than MAX_SIZE or MAX_PROTOCOL_MESSAGE_LENGTH if (hdr.nMessageSize > MAX_SIZE || hdr.nMessageSize > MAX_PROTOCOL_MESSAGE_LENGTH) { - LogPrint(BCLog::NET, "HEADER ERROR - SIZE (%s, %u bytes), peer=%d\n", hdr.GetCommand(), hdr.nMessageSize, m_node_id); + LogPrint(BCLog::NET, "Header error: Size too large (%s, %u bytes), peer=%d\n", SanitizeString(hdr.GetCommand()), hdr.nMessageSize, m_node_id); return -1; } @@ -746,7 +748,7 @@ std::optional<CNetMessage> V1TransportDeserializer::GetMessage(const std::chrono // Check checksum and header command string if (memcmp(hash.begin(), hdr.pchChecksum, CMessageHeader::CHECKSUM_SIZE) != 0) { - LogPrint(BCLog::NET, "CHECKSUM ERROR (%s, %u bytes), expected %s was %s, peer=%d\n", + LogPrint(BCLog::NET, "Header error: Wrong checksum (%s, %u bytes), expected %s was %s, peer=%d\n", SanitizeString(msg->m_command), msg->m_message_size, HexStr(Span<uint8_t>(hash.begin(), hash.begin() + CMessageHeader::CHECKSUM_SIZE)), HexStr(hdr.pchChecksum), @@ -754,8 +756,8 @@ std::optional<CNetMessage> V1TransportDeserializer::GetMessage(const std::chrono out_err_raw_size = msg->m_raw_message_size; msg = std::nullopt; } else if (!hdr.IsCommandValid()) { - LogPrint(BCLog::NET, "HEADER ERROR - COMMAND (%s, %u bytes), peer=%d\n", - hdr.GetCommand(), msg->m_message_size, m_node_id); + LogPrint(BCLog::NET, "Header error: Invalid message type (%s, %u bytes), peer=%d\n", + SanitizeString(hdr.GetCommand()), msg->m_message_size, m_node_id); out_err_raw_size = msg->m_raw_message_size; msg.reset(); } @@ -1004,7 +1006,7 @@ bool CConnman::AttemptToEvictConnection() LOCK(cs_vNodes); for (const CNode* node : vNodes) { - if (node->HasPermission(PF_NOBAN)) + if (node->HasPermission(NetPermissionFlags::NoBan)) continue; if (!node->IsInboundConn()) continue; @@ -1061,7 +1063,7 @@ void CConnman::AcceptConnection(const ListenSocket& hListenSocket) { const CAddress addr_bind = GetBindAddress(hSocket); - NetPermissionFlags permissionFlags = NetPermissionFlags::PF_NONE; + NetPermissionFlags permissionFlags = NetPermissionFlags::None; hListenSocket.AddSocketPermissionFlags(permissionFlags); CreateNodeFromAcceptedSocket(hSocket, permissionFlags, addr_bind, addr); @@ -1076,12 +1078,12 @@ void CConnman::CreateNodeFromAcceptedSocket(SOCKET hSocket, int nMaxInbound = nMaxConnections - m_max_outbound; AddWhitelistPermissionFlags(permissionFlags, addr); - if (NetPermissions::HasFlag(permissionFlags, NetPermissionFlags::PF_ISIMPLICIT)) { - NetPermissions::ClearFlag(permissionFlags, PF_ISIMPLICIT); - if (gArgs.GetBoolArg("-whitelistforcerelay", DEFAULT_WHITELISTFORCERELAY)) NetPermissions::AddFlag(permissionFlags, PF_FORCERELAY); - if (gArgs.GetBoolArg("-whitelistrelay", DEFAULT_WHITELISTRELAY)) NetPermissions::AddFlag(permissionFlags, PF_RELAY); - NetPermissions::AddFlag(permissionFlags, PF_MEMPOOL); - NetPermissions::AddFlag(permissionFlags, PF_NOBAN); + if (NetPermissions::HasFlag(permissionFlags, NetPermissionFlags::Implicit)) { + NetPermissions::ClearFlag(permissionFlags, NetPermissionFlags::Implicit); + if (gArgs.GetBoolArg("-whitelistforcerelay", DEFAULT_WHITELISTFORCERELAY)) NetPermissions::AddFlag(permissionFlags, NetPermissionFlags::ForceRelay); + if (gArgs.GetBoolArg("-whitelistrelay", DEFAULT_WHITELISTRELAY)) NetPermissions::AddFlag(permissionFlags, NetPermissionFlags::Relay); + NetPermissions::AddFlag(permissionFlags, NetPermissionFlags::Mempool); + NetPermissions::AddFlag(permissionFlags, NetPermissionFlags::NoBan); } { @@ -1110,7 +1112,7 @@ void CConnman::CreateNodeFromAcceptedSocket(SOCKET hSocket, // Don't accept connections from banned peers. bool banned = m_banman && m_banman->IsBanned(addr); - if (!NetPermissions::HasFlag(permissionFlags, NetPermissionFlags::PF_NOBAN) && banned) + if (!NetPermissions::HasFlag(permissionFlags, NetPermissionFlags::NoBan) && banned) { LogPrint(BCLog::NET, "connection from %s dropped (banned)\n", addr.ToString()); CloseSocket(hSocket); @@ -1119,7 +1121,7 @@ void CConnman::CreateNodeFromAcceptedSocket(SOCKET hSocket, // Only accept connections from discouraged peers if our inbound slots aren't (almost) full. bool discouraged = m_banman && m_banman->IsDiscouraged(addr); - if (!NetPermissions::HasFlag(permissionFlags, NetPermissionFlags::PF_NOBAN) && nInbound + 1 >= nMaxInbound && discouraged) + if (!NetPermissions::HasFlag(permissionFlags, NetPermissionFlags::NoBan) && nInbound + 1 >= nMaxInbound && discouraged) { LogPrint(BCLog::NET, "connection from %s dropped (discouraged)\n", addr.ToString()); CloseSocket(hSocket); @@ -1140,7 +1142,7 @@ void CConnman::CreateNodeFromAcceptedSocket(SOCKET hSocket, uint64_t nonce = GetDeterministicRandomizer(RANDOMIZER_ID_LOCALHOSTNONCE).Write(id).Finalize(); ServiceFlags nodeServices = nLocalServices; - if (NetPermissions::HasFlag(permissionFlags, PF_BLOOMFILTER)) { + if (NetPermissions::HasFlag(permissionFlags, NetPermissionFlags::BloomFilter)) { nodeServices = static_cast<ServiceFlags>(nodeServices | NODE_BLOOM); } @@ -1224,19 +1226,10 @@ void CConnman::DisconnectNodes() std::list<CNode*> vNodesDisconnectedCopy = vNodesDisconnected; for (CNode* pnode : vNodesDisconnectedCopy) { - // wait until threads are done using it + // Destroy the object only after other threads have stopped using it. if (pnode->GetRefCount() <= 0) { - bool fDelete = false; - { - TRY_LOCK(pnode->cs_vSend, lockSend); - if (lockSend) { - fDelete = true; - } - } - if (fDelete) { - vNodesDisconnected.remove(pnode); - DeleteNode(pnode); - } + vNodesDisconnected.remove(pnode); + DeleteNode(pnode); } } } @@ -1645,7 +1638,7 @@ void CConnman::ThreadDNSAddressSeed() { LOCK(cs_vNodes); for (const CNode* pnode : vNodes) { - if (pnode->fSuccessfullyConnected && pnode->IsOutboundOrBlockRelayConn()) ++nRelevant; + if (pnode->fSuccessfullyConnected && pnode->IsFullOutboundConn()) ++nRelevant; } } if (nRelevant >= 2) { @@ -2253,7 +2246,7 @@ void CConnman::ThreadI2PAcceptIncoming() } if (!advertising_listen_addr) { - AddLocal(conn.me, LOCAL_BIND); + AddLocal(conn.me, LOCAL_MANUAL); advertising_listen_addr = true; } @@ -2261,7 +2254,7 @@ void CConnman::ThreadI2PAcceptIncoming() continue; } - CreateNodeFromAcceptedSocket(conn.sock->Release(), NetPermissionFlags::PF_NONE, + CreateNodeFromAcceptedSocket(conn.sock->Release(), NetPermissionFlags::None, CAddress{conn.me, NODE_NONE}, CAddress{conn.peer, NODE_NONE}); } } @@ -2408,8 +2401,9 @@ NodeId CConnman::GetNewNodeId() bool CConnman::Bind(const CService &addr, unsigned int flags, NetPermissionFlags permissions) { - if (!(flags & BF_EXPLICIT) && !IsReachable(addr)) + if (!(flags & BF_EXPLICIT) && !IsReachable(addr)) { return false; + } bilingual_str strError; if (!BindListenPort(addr, strError, permissions)) { if ((flags & BF_REPORT_ERROR) && clientInterface) { @@ -2418,7 +2412,7 @@ bool CConnman::Bind(const CService &addr, unsigned int flags, NetPermissionFlags return false; } - if (addr.IsRoutable() && fDiscover && !(flags & BF_DONT_ADVERTISE) && !(permissions & PF_NOBAN)) { + if (addr.IsRoutable() && fDiscover && !(flags & BF_DONT_ADVERTISE) && !NetPermissions::HasFlag(permissions, NetPermissionFlags::NoBan)) { AddLocal(addr, LOCAL_BIND); } @@ -2432,7 +2426,7 @@ bool CConnman::InitBinds( { bool fBound = false; for (const auto& addrBind : binds) { - fBound |= Bind(addrBind, (BF_EXPLICIT | BF_REPORT_ERROR), NetPermissionFlags::PF_NONE); + fBound |= Bind(addrBind, (BF_EXPLICIT | BF_REPORT_ERROR), NetPermissionFlags::None); } for (const auto& addrBind : whiteBinds) { fBound |= Bind(addrBind.m_service, (BF_EXPLICIT | BF_REPORT_ERROR), addrBind.m_flags); @@ -2441,12 +2435,12 @@ bool CConnman::InitBinds( struct in_addr inaddr_any; inaddr_any.s_addr = htonl(INADDR_ANY); struct in6_addr inaddr6_any = IN6ADDR_ANY_INIT; - fBound |= Bind(CService(inaddr6_any, GetListenPort()), BF_NONE, NetPermissionFlags::PF_NONE); - fBound |= Bind(CService(inaddr_any, GetListenPort()), !fBound ? BF_REPORT_ERROR : BF_NONE, NetPermissionFlags::PF_NONE); + fBound |= Bind(CService(inaddr6_any, GetListenPort()), BF_NONE, NetPermissionFlags::None); + fBound |= Bind(CService(inaddr_any, GetListenPort()), !fBound ? BF_REPORT_ERROR : BF_NONE, NetPermissionFlags::None); } for (const auto& addr_bind : onion_binds) { - fBound |= Bind(addr_bind, BF_EXPLICIT | BF_DONT_ADVERTISE, NetPermissionFlags::PF_NONE); + fBound |= Bind(addr_bind, BF_EXPLICIT | BF_DONT_ADVERTISE, NetPermissionFlags::None); } return fBound; @@ -2467,7 +2461,7 @@ bool CConnman::Start(CScheduler& scheduler, const Options& connOptions) proxyType i2p_sam; if (GetProxy(NET_I2P, i2p_sam)) { - m_i2p_sam_session = std::make_unique<i2p::sam::Session>(GetDataDir() / "i2p_private_key", + m_i2p_sam_session = std::make_unique<i2p::sam::Session>(gArgs.GetDataDirNet() / "i2p_private_key", i2p_sam.proxy, &interruptNet); } @@ -2476,7 +2470,7 @@ bool CConnman::Start(CScheduler& scheduler, const Options& connOptions) } if (clientInterface) { - clientInterface->InitMessage(_("Loading P2P addresses...").translated); + clientInterface->InitMessage(_("Loading P2P addresses…").translated); } // Load addresses from peers.dat int64_t nStart = GetTimeMillis(); @@ -2493,14 +2487,14 @@ bool CConnman::Start(CScheduler& scheduler, const Options& connOptions) if (m_use_addrman_outgoing) { // Load addresses from anchors.dat - m_anchors = ReadAnchors(GetDataDir() / ANCHORS_DATABASE_FILENAME); + m_anchors = ReadAnchors(gArgs.GetDataDirNet() / ANCHORS_DATABASE_FILENAME); if (m_anchors.size() > MAX_BLOCK_RELAY_ONLY_ANCHORS) { m_anchors.resize(MAX_BLOCK_RELAY_ONLY_ANCHORS); } LogPrintf("%i block-relay-only anchors will be tried for connections.\n", m_anchors.size()); } - uiInterface.InitMessage(_("Starting network threads...").translated); + uiInterface.InitMessage(_("Starting network threads…").translated); fAddressesInitialized = true; @@ -2527,15 +2521,15 @@ bool CConnman::Start(CScheduler& scheduler, const Options& connOptions) } // Send and receive from sockets, accept connections - threadSocketHandler = std::thread(&TraceThread<std::function<void()> >, "net", std::function<void()>(std::bind(&CConnman::ThreadSocketHandler, this))); + threadSocketHandler = std::thread(&util::TraceThread, "net", [this] { ThreadSocketHandler(); }); if (!gArgs.GetBoolArg("-dnsseed", DEFAULT_DNSSEED)) LogPrintf("DNS seeding disabled\n"); else - threadDNSAddressSeed = std::thread(&TraceThread<std::function<void()> >, "dnsseed", std::function<void()>(std::bind(&CConnman::ThreadDNSAddressSeed, this))); + threadDNSAddressSeed = std::thread(&util::TraceThread, "dnsseed", [this] { ThreadDNSAddressSeed(); }); // Initiate manual connections - threadOpenAddedConnections = std::thread(&TraceThread<std::function<void()> >, "addcon", std::function<void()>(std::bind(&CConnman::ThreadOpenAddedConnections, this))); + threadOpenAddedConnections = std::thread(&util::TraceThread, "addcon", [this] { ThreadOpenAddedConnections(); }); if (connOptions.m_use_addrman_outgoing && !connOptions.m_specified_outgoing.empty()) { if (clientInterface) { @@ -2545,16 +2539,18 @@ bool CConnman::Start(CScheduler& scheduler, const Options& connOptions) } return false; } - if (connOptions.m_use_addrman_outgoing || !connOptions.m_specified_outgoing.empty()) - threadOpenConnections = std::thread(&TraceThread<std::function<void()> >, "opencon", std::function<void()>(std::bind(&CConnman::ThreadOpenConnections, this, connOptions.m_specified_outgoing))); + if (connOptions.m_use_addrman_outgoing || !connOptions.m_specified_outgoing.empty()) { + threadOpenConnections = std::thread( + &util::TraceThread, "opencon", + [this, connect = connOptions.m_specified_outgoing] { ThreadOpenConnections(connect); }); + } // Process messages - threadMessageHandler = std::thread(&TraceThread<std::function<void()> >, "msghand", std::function<void()>(std::bind(&CConnman::ThreadMessageHandler, this))); + threadMessageHandler = std::thread(&util::TraceThread, "msghand", [this] { ThreadMessageHandler(); }); if (connOptions.m_i2p_accept_incoming && m_i2p_sam_session.get() != nullptr) { threadI2PAcceptIncoming = - std::thread(&TraceThread<std::function<void()>>, "i2paccept", - std::function<void()>(std::bind(&CConnman::ThreadI2PAcceptIncoming, this))); + std::thread(&util::TraceThread, "i2paccept", [this] { ThreadI2PAcceptIncoming(); }); } // Dump network addresses @@ -2631,7 +2627,7 @@ void CConnman::StopNodes() if (anchors_to_dump.size() > MAX_BLOCK_RELAY_ONLY_ANCHORS) { anchors_to_dump.resize(MAX_BLOCK_RELAY_ONLY_ANCHORS); } - DumpAnchors(GetDataDir() / ANCHORS_DATABASE_FILENAME, anchors_to_dump); + DumpAnchors(gArgs.GetDataDirNet() / ANCHORS_DATABASE_FILENAME, anchors_to_dump); } } @@ -2674,9 +2670,9 @@ CConnman::~CConnman() Stop(); } -std::vector<CAddress> CConnman::GetAddresses(size_t max_addresses, size_t max_pct) const +std::vector<CAddress> CConnman::GetAddresses(size_t max_addresses, size_t max_pct, std::optional<Network> network) const { - std::vector<CAddress> addresses = addrman.GetAddr(max_addresses, max_pct); + std::vector<CAddress> addresses = addrman.GetAddr(max_addresses, max_pct, network); if (m_banman) { addresses.erase(std::remove_if(addresses.begin(), addresses.end(), [this](const CAddress& addr){return m_banman->IsDiscouraged(addr) || m_banman->IsBanned(addr);}), @@ -2696,7 +2692,7 @@ std::vector<CAddress> CConnman::GetAddresses(CNode& requestor, size_t max_addres auto r = m_addr_response_caches.emplace(cache_id, CachedAddrResponse{}); CachedAddrResponse& cache_entry = r.first->second; if (cache_entry.m_cache_entry_expiration < current_time) { // If emplace() added new one it has expiration 0. - cache_entry.m_addrs_response_cache = GetAddresses(max_addresses, max_pct); + cache_entry.m_addrs_response_cache = GetAddresses(max_addresses, max_pct, /* network */ std::nullopt); // Choosing a proper cache lifetime is a trade-off between the privacy leak minimization // and the usefulness of ADDR responses to honest users. // @@ -2933,10 +2929,6 @@ CNode::CNode(NodeId idIn, ServiceFlags nLocalServicesIn, SOCKET hSocketIn, const m_tx_relay = std::make_unique<TxRelay>(); } - if (RelayAddrsWithConn()) { - m_addr_known = std::make_unique<CRollingBloomFilter>(5000, 0.001); - } - for (const std::string &msg : getAllNetMessageTypes()) mapRecvBytesPerMsgCmd[msg] = 0; mapRecvBytesPerMsgCmd[NET_MESSAGE_COMMAND_OTHER] = 0; @@ -3047,7 +3039,7 @@ void CaptureMessage(const CAddress& addr, const std::string& msg_type, const Spa std::string clean_addr = addr.ToString(); std::replace(clean_addr.begin(), clean_addr.end(), ':', '_'); - fs::path base_path = GetDataDir() / "message_capture" / clean_addr; + fs::path base_path = gArgs.GetDataDirNet() / "message_capture" / clean_addr; fs::create_directories(base_path); fs::path path = base_path / (is_incoming ? "msgs_recv.dat" : "msgs_sent.dat"); |