diff --git a/src/net.cpp b/src/net.cpp index 235317590..dda615c4a 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -190,6 +190,16 @@ bool GetLocal(CService& addr, const CNode& peer) LOCK(cs_mapLocalHost); for (map::iterator it = mapLocalHost.begin(); it != mapLocalHost.end(); it++) { + // For privacy reasons, don't advertise our privacy-network address + // to other networks and don't advertise our other-network address + // to privacy networks. + const Network our_net{(*it).first.GetNetwork()}; + const Network peers_net{peer.ConnectedThroughNetwork()}; + if (our_net != peers_net && + (our_net == NET_ONION || our_net == NET_I2P || + peers_net == NET_ONION || peers_net == NET_I2P)) { + continue; + } int nScore = (*it).second.nScore; int nReachability = (*it).first.GetReachabilityFrom(peer.addr); if (nReachability > nBestReachability || (nReachability == nBestReachability && nScore > nBestScore)) @@ -575,6 +585,11 @@ extern int32_t HUSH_NSPV; #define HUSH_NSPV_SUPERLITE (HUSH_NSPV > 0) #endif // !HUSH_NSPV_SUPERLITE +Network CNode::ConnectedThroughNetwork() const +{ + return m_inbound_onion ? NET_ONION : addr.GetNetClass(); +} + void CNode::PushVersion() { int nBestHeight = g_signals.GetHeight().get_value_or(0); @@ -1266,6 +1281,7 @@ void CreateNodeFromAcceptedSocket(SOCKET hSocket, return; } + // Don't accept connections from banned peers. if (CNode::IsBanned(addr) && !allowlisted) { LogPrintf("connection from %s dropped (banned)\n", addr.ToString()); @@ -1320,6 +1336,8 @@ void CreateNodeFromAcceptedSocket(SOCKET hSocket, return; } + const bool inbound_onion = std::find(m_onion_binds.begin(), m_onion_binds.end(), addr_bind) != m_onion_binds.end(); + CNode* pnode = new CNode(hSocket, addr, "", true, ssl); pnode->AddRef(); pnode->fAllowlisted = allowlisted; diff --git a/src/net.h b/src/net.h index 7df42b0db..4d3e60119 100644 --- a/src/net.h +++ b/src/net.h @@ -403,6 +403,8 @@ public: // const CAddress addrBind; // https://github.com/bitcoin/bitcoin/commit/a7e3c2814c8e49197889a4679461be42254e5c51 std::string addrName; CService addrLocal; + //! Whether this peer is an inbound onion, i.e. connected via our Tor onion service. + const bool m_inbound_onion; int nVersion; int lasthdrsreq,sendhdrsreq; // strSubVer is whatever byte array we read from the wire. However, this field is intended @@ -418,6 +420,17 @@ public: bool fNetworkNode; bool fSuccessfullyConnected; bool fDisconnect; + /** + * 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; // count blocks seen. int8_t nBlocksinARow; int8_t nBlocksinARow2;