From 7745ea523ca517f0f19522a1783a33f51c2ff09b Mon Sep 17 00:00:00 2001 From: Vasil Dimov Date: Tue, 14 Jan 2025 17:24:22 +0100 Subject: [PATCH] net: separate the listening socket from the permissions They were coupled in `struct ListenSocket`, but the socket belongs to the lower level transport protocol, whereas the permissions are specific to the higher Bitcoin P2P protocol. --- src/net.cpp | 14 ++++++++++---- src/net.h | 16 +++++++++------- 2 files changed, 19 insertions(+), 11 deletions(-) diff --git a/src/net.cpp b/src/net.cpp index 735985a8414..3c4d99ddd9e 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -1755,7 +1755,10 @@ void CConnman::AcceptConnection(const ListenSocket& hListenSocket) { const CService addr_bind{MaybeFlipIPv6toCJDNS(GetBindAddress(*sock))}; NetPermissionFlags permission_flags = NetPermissionFlags::None; - hListenSocket.AddSocketPermissionFlags(permission_flags); + auto it{m_listen_permissions.find(addr_bind)}; + if (it != m_listen_permissions.end()) { + NetPermissions::AddFlag(permission_flags, it->second); + } CreateNodeFromAcceptedSocket(std::move(sock), permission_flags, addr_bind, addr); } @@ -3111,7 +3114,7 @@ void CConnman::ThreadI2PAcceptIncoming() } } -bool CConnman::BindListenPort(const CService& addrBind, bilingual_str& strError, NetPermissionFlags permissions) +bool CConnman::BindListenPort(const CService& addrBind, bilingual_str& strError) { int nOne = 1; @@ -3176,7 +3179,7 @@ bool CConnman::BindListenPort(const CService& addrBind, bilingual_str& strError, return false; } - vhListenSocket.emplace_back(std::move(sock), permissions); + vhListenSocket.emplace_back(std::move(sock)); return true; } @@ -3242,13 +3245,15 @@ bool CConnman::Bind(const CService& addr_, unsigned int flags, NetPermissionFlag const CService addr{MaybeFlipIPv6toCJDNS(addr_)}; bilingual_str strError; - if (!BindListenPort(addr, strError, permissions)) { + if (!BindListenPort(addr, strError)) { if ((flags & BF_REPORT_ERROR) && m_client_interface) { m_client_interface->ThreadSafeMessageBox(strError, "", CClientUIInterface::MSG_ERROR); } return false; } + m_listen_permissions.emplace(addr, permissions); + if (addr.IsRoutable() && fDiscover && !(flags & BF_DONT_ADVERTISE) && !NetPermissions::HasFlag(permissions, NetPermissionFlags::NoBan)) { AddLocal(addr, LOCAL_BIND); } @@ -3482,6 +3487,7 @@ void CConnman::StopNodes() DeleteNode(pnode); } m_nodes_disconnected.clear(); + m_listen_permissions.clear(); vhListenSocket.clear(); semOutbound.reset(); semAddnode.reset(); diff --git a/src/net.h b/src/net.h index e64d9a67f46..8ece1071278 100644 --- a/src/net.h +++ b/src/net.h @@ -1276,21 +1276,17 @@ private: struct ListenSocket { public: std::shared_ptr sock; - inline void AddSocketPermissionFlags(NetPermissionFlags& flags) const { NetPermissions::AddFlag(flags, m_permissions); } - ListenSocket(std::shared_ptr sock_, NetPermissionFlags permissions_) - : sock{sock_}, m_permissions{permissions_} + ListenSocket(std::shared_ptr sock_) + : sock{sock_} { } - - private: - NetPermissionFlags m_permissions; }; //! returns the time left in the current max outbound cycle //! in case of no limit, it will always return 0 std::chrono::seconds GetMaxOutboundTimeLeftInCycle_() const EXCLUSIVE_LOCKS_REQUIRED(m_total_bytes_sent_mutex); - bool BindListenPort(const CService& bindAddr, bilingual_str& strError, NetPermissionFlags permissions); + bool BindListenPort(const CService& bindAddr, bilingual_str& strError); bool Bind(const CService& addr, unsigned int flags, NetPermissionFlags permissions); bool InitBinds(const Options& options); @@ -1431,6 +1427,12 @@ private: unsigned int nReceiveFloodSize{0}; std::vector vhListenSocket; + + /** + * Permissions that incoming peers get based on our listening address they connected to. + */ + std::unordered_map m_listen_permissions; + std::atomic fNetworkActive{true}; bool fAddressesInitialized{false}; AddrMan& addrman;