From 247c7dfcb21e5ef6e631189178610daec3cd5481 Mon Sep 17 00:00:00 2001 From: Kittywhiskers Van Gogh <63189531+kittywhiskers@users.noreply.github.com> Date: Sun, 16 Apr 2023 04:56:24 +0000 Subject: [PATCH] partial bitcoin#19998: Add CNode::ConnectedThroughNetwork member function excludes - 3984b78cd7f49e409377f2175a56e8e4bd71d1d8 --- src/net.cpp | 15 ++++++++++++--- src/net.h | 24 +++++++++++++++++++++++- src/netaddress.cpp | 2 +- src/netaddress.h | 2 +- src/test/fuzz/net.cpp | 2 ++ 5 files changed, 39 insertions(+), 6 deletions(-) diff --git a/src/net.cpp b/src/net.cpp index 165d15858a..82791f3b38 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -54,6 +54,7 @@ #include #endif +#include #include #include @@ -585,6 +586,11 @@ std::string CNode::GetLogString() const return fLogIPs ? addr.ToString() : strprintf("%d", id); } +Network CNode::ConnectedThroughNetwork() const +{ + return fInbound && m_inbound_onion ? NET_ONION : addr.GetNetClass(); +} + #undef X #define X(name) stats.name = name void CNode::copyStats(CNodeStats &stats, const std::vector &m_asmap) @@ -1204,7 +1210,9 @@ void CConnman::AcceptConnection(const ListenSocket& hListenSocket) { if (NetPermissions::HasFlag(permissionFlags, PF_BLOOMFILTER)) { nodeServices = static_cast(nodeServices | NODE_BLOOM); } - CNode* pnode = new CNode(id, nodeServices, GetBestHeight(), hSocket, addr, CalculateKeyedNetGroup(addr), nonce, addr_bind, "", true); + + const bool inbound_onion = std::find(m_onion_binds.begin(), m_onion_binds.end(), addr_bind) != m_onion_binds.end(); + CNode* pnode = new CNode(id, nodeServices, GetBestHeight(), hSocket, addr, CalculateKeyedNetGroup(addr), nonce, addr_bind, "", true, inbound_onion); 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) @@ -3756,7 +3764,7 @@ 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, bool fInboundIn, bool block_relay_only, bool inbound_onion) : nTimeConnected(GetSystemTimeInSeconds()), addr(addrIn), addrBind(addrBindIn), @@ -3767,7 +3775,8 @@ CNode::CNode(NodeId idIn, ServiceFlags nLocalServicesIn, int nMyStartingHeightIn id(idIn), nLocalHostNonce(nLocalHostNonceIn), nLocalServices(nLocalServicesIn), - nMyStartingHeight(nMyStartingHeightIn) + nMyStartingHeight(nMyStartingHeightIn), + m_inbound_onion(inbound_onion) { hSocket = hSocketIn; addrName = addrNameIn == "" ? addr.ToStringIPPort() : addrNameIn; diff --git a/src/net.h b/src/net.h index e4c323f4ac..cc77ead8ae 100644 --- a/src/net.h +++ b/src/net.h @@ -212,6 +212,7 @@ public: vAddedNodes = connOptions.m_added_nodes; } socketEventsMode = connOptions.socketEventsMode; + m_onion_binds = connOptions.onion_binds; } CConnman(uint64_t seed0, uint64_t seed1, CAddrMan& addrman); @@ -680,6 +681,12 @@ private: std::atomic m_next_send_inv_to_incoming{0}; + /** + * A vector of -bind=
:=onion arguments each of which is + * an address and port that are designated for incoming Tor connections. + */ + std::vector m_onion_binds; + friend struct CConnmanTest; friend struct ConnmanTestMsg; }; @@ -1015,6 +1022,18 @@ public: std::atomic_bool fHasRecvData{false}; std::atomic_bool fCanSendData{false}; + /** + * Get network the peer connected through. + * + * Returns Network::NET_ONION for *inbound* onion connections, + * and CNetAddr::GetNetClass() otherwise. The latter cannot be used directly + * because it doesn't detect the former, and it's not the responsibility of + * the CNetAddr class to know the actual network a peer is connected through. + * + * @return network the peer connected through. + */ + Network ConnectedThroughNetwork() const; + protected: mapMsgCmdSize mapSendBytesPerMsgCmd; mapMsgCmdSize mapRecvBytesPerMsgCmd GUARDED_BY(cs_vRecv); @@ -1117,7 +1136,7 @@ public: std::set 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 = "", bool fInboundIn = false, bool block_relay_only = false, bool inbound_onion = false); ~CNode(); CNode(const CNode&) = delete; CNode& operator=(const CNode&) = delete; @@ -1155,6 +1174,9 @@ private: CService addrLocal GUARDED_BY(cs_addrLocal); mutable CCriticalSection cs_addrLocal; + //! Whether this peer connected via our Tor onion service. + const bool m_inbound_onion{false}; + // Challenge sent in VERSION to be answered with MNAUTH (only happens between MNs) mutable CCriticalSection cs_mnauth; uint256 sentMNAuthChallenge GUARDED_BY(cs_mnauth); diff --git a/src/netaddress.cpp b/src/netaddress.cpp index ce3a3745d6..78e7fa871b 100644 --- a/src/netaddress.cpp +++ b/src/netaddress.cpp @@ -668,7 +668,7 @@ uint32_t CNetAddr::GetLinkedIPv4() const assert(false); } -uint32_t CNetAddr::GetNetClass() const +Network CNetAddr::GetNetClass() const { // Make sure that if we return NET_IPV6, then IsIPv6() is true. The callers expect that. diff --git a/src/netaddress.h b/src/netaddress.h index c771f760e3..708a91c074 100644 --- a/src/netaddress.h +++ b/src/netaddress.h @@ -200,7 +200,7 @@ class CNetAddr std::string ToStringIP(bool fUseGetnameinfo = true) const; uint64_t GetHash() const; bool GetInAddr(struct in_addr* pipv4Addr) const; - uint32_t GetNetClass() const; + Network GetNetClass() const; //! For IPv4, mapped IPv4, SIIT translated IPv4, Teredo, 6to4 tunneled addresses, return the relevant IPv4 address as a uint32. uint32_t GetLinkedIPv4() const; diff --git a/src/test/fuzz/net.cpp b/src/test/fuzz/net.cpp index 8f44042dd9..970cc6ee81 100644 --- a/src/test/fuzz/net.cpp +++ b/src/test/fuzz/net.cpp @@ -47,6 +47,7 @@ FUZZ_TARGET_INIT(net, initialize_net) *address_bind, fuzzed_data_provider.ConsumeRandomLengthString(32), fuzzed_data_provider.ConsumeBool(), + fuzzed_data_provider.ConsumeBool(), fuzzed_data_provider.ConsumeBool() }; while (fuzzed_data_provider.ConsumeBool()) { @@ -148,4 +149,5 @@ FUZZ_TARGET_INIT(net, initialize_net) fuzzed_data_provider.PickValueInArray({NetPermissionFlags::PF_NONE, NetPermissionFlags::PF_BLOOMFILTER, NetPermissionFlags::PF_RELAY, NetPermissionFlags::PF_FORCERELAY, NetPermissionFlags::PF_NOBAN, NetPermissionFlags::PF_MEMPOOL, NetPermissionFlags::PF_ISIMPLICIT, NetPermissionFlags::PF_ALL}) : static_cast(fuzzed_data_provider.ConsumeIntegral()); (void)node.HasPermission(net_permission_flags); + (void)node.ConnectedThroughNetwork(); }