Skip to content

Commit f79a4a8

Browse files
committed
Merge #19998: net: Add CNode::ConnectedThroughNetwork member function
3984b78 test: Add tests for CNode::ConnectedThroughNetwork (Hennadii Stepanov) 49fba9c net: Add CNode::ConnectedThroughNetwork member function (Hennadii Stepanov) d4dde24 net: Add CNode::m_inbound_onion data member (Hennadii Stepanov) Pull request description: This PR: - adds `CNode::ConnectedThroughNetwork` member function - is based on #19991, and only last two commits belong to it - is required for bitcoin-core#86 and #20002 ACKs for top commit: jonatack: re-ACK 3984b78 per `git diff 3989fcf 3984b78` laanwj: Code review ACK 3984b78 Tree-SHA512: 23a9c8bca8dca75113b5505fe443b294f2d42d03c98c7e34919da12d8396beb8d0ada3a58ae16e3da04b7044395f72cf9c216625afc078256cd6c897ac42bf3d
2 parents af22322 + 3984b78 commit f79a4a8

File tree

6 files changed

+83
-10
lines changed

6 files changed

+83
-10
lines changed

src/net.cpp

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
static_assert(MINIUPNPC_API_VERSION >= 10, "miniUPnPc API version >= 10 assumed");
4242
#endif
4343

44+
#include <algorithm>
4445
#include <cstdint>
4546
#include <unordered_map>
4647

@@ -538,6 +539,11 @@ void CNode::SetAddrLocal(const CService& addrLocalIn) {
538539
}
539540
}
540541

542+
Network CNode::ConnectedThroughNetwork() const
543+
{
544+
return IsInboundConn() && m_inbound_onion ? NET_ONION : addr.GetNetClass();
545+
}
546+
541547
#undef X
542548
#define X(name) stats.name = name
543549
void CNode::copyStats(CNodeStats &stats, const std::vector<bool> &m_asmap)
@@ -1118,7 +1124,9 @@ void CConnman::AcceptConnection(const ListenSocket& hListenSocket) {
11181124
if (NetPermissions::HasFlag(permissionFlags, PF_BLOOMFILTER)) {
11191125
nodeServices = static_cast<ServiceFlags>(nodeServices | NODE_BLOOM);
11201126
}
1121-
CNode* pnode = new CNode(id, nodeServices, GetBestHeight(), hSocket, addr, CalculateKeyedNetGroup(addr), nonce, addr_bind, "", ConnectionType::INBOUND);
1127+
1128+
const bool inbound_onion = std::find(m_onion_binds.begin(), m_onion_binds.end(), addr_bind) != m_onion_binds.end();
1129+
CNode* pnode = new CNode(id, nodeServices, GetBestHeight(), hSocket, addr, CalculateKeyedNetGroup(addr), nonce, addr_bind, "", ConnectionType::INBOUND, inbound_onion);
11221130
pnode->AddRef();
11231131
pnode->m_permissionFlags = permissionFlags;
11241132
// If this flag is present, the user probably expect that RPC and QT report it as whitelisted (backward compatibility)
@@ -2859,7 +2867,7 @@ int CConnman::GetBestHeight() const
28592867

28602868
unsigned int CConnman::GetReceiveFloodSize() const { return nReceiveFloodSize; }
28612869

2862-
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, ConnectionType conn_type_in)
2870+
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, ConnectionType conn_type_in, bool inbound_onion)
28632871
: nTimeConnected(GetSystemTimeInSeconds()),
28642872
addr(addrIn),
28652873
addrBind(addrBindIn),
@@ -2871,7 +2879,8 @@ CNode::CNode(NodeId idIn, ServiceFlags nLocalServicesIn, int nMyStartingHeightIn
28712879
nLocalHostNonce(nLocalHostNonceIn),
28722880
m_conn_type(conn_type_in),
28732881
nLocalServices(nLocalServicesIn),
2874-
nMyStartingHeight(nMyStartingHeightIn)
2882+
nMyStartingHeight(nMyStartingHeightIn),
2883+
m_inbound_onion(inbound_onion)
28752884
{
28762885
hSocket = hSocketIn;
28772886
addrName = addrNameIn == "" ? addr.ToStringIPPort() : addrNameIn;

src/net.h

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -253,6 +253,7 @@ class CConnman
253253
LOCK(cs_vAddedNodes);
254254
vAddedNodes = connOptions.m_added_nodes;
255255
}
256+
m_onion_binds = connOptions.onion_binds;
256257
}
257258

258259
CConnman(uint64_t seed0, uint64_t seed1, bool network_active = true);
@@ -586,6 +587,12 @@ class CConnman
586587

587588
std::atomic<int64_t> m_next_send_inv_to_incoming{0};
588589

590+
/**
591+
* A vector of -bind=<address>:<port>=onion arguments each of which is
592+
* an address and port that are designated for incoming Tor connections.
593+
*/
594+
std::vector<CService> m_onion_binds;
595+
589596
friend struct CConnmanTest;
590597
friend struct ConnmanTestMsg;
591598
};
@@ -944,6 +951,18 @@ class CNode
944951
assert(false);
945952
}
946953

954+
/**
955+
* Get network the peer connected through.
956+
*
957+
* Returns Network::NET_ONION for *inbound* onion connections,
958+
* and CNetAddr::GetNetClass() otherwise. The latter cannot be used directly
959+
* because it doesn't detect the former, and it's not the responsibility of
960+
* the CNetAddr class to know the actual network a peer is connected through.
961+
*
962+
* @return network the peer connected through.
963+
*/
964+
Network ConnectedThroughNetwork() const;
965+
947966
protected:
948967
mapMsgCmdSize mapSendBytesPerMsgCmd;
949968
mapMsgCmdSize mapRecvBytesPerMsgCmd GUARDED_BY(cs_vRecv);
@@ -1025,7 +1044,7 @@ class CNode
10251044

10261045
std::set<uint256> orphan_work_set;
10271046

1028-
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, ConnectionType conn_type_in);
1047+
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, ConnectionType conn_type_in, bool inbound_onion = false);
10291048
~CNode();
10301049
CNode(const CNode&) = delete;
10311050
CNode& operator=(const CNode&) = delete;
@@ -1063,6 +1082,10 @@ class CNode
10631082
// Our address, as reported by the peer
10641083
CService addrLocal GUARDED_BY(cs_addrLocal);
10651084
mutable RecursiveMutex cs_addrLocal;
1085+
1086+
//! Whether this peer connected via our Tor onion service.
1087+
const bool m_inbound_onion{false};
1088+
10661089
public:
10671090

10681091
NodeId GetId() const {

src/netaddress.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -649,7 +649,7 @@ uint32_t CNetAddr::GetLinkedIPv4() const
649649
assert(false);
650650
}
651651

652-
uint32_t CNetAddr::GetNetClass() const
652+
Network CNetAddr::GetNetClass() const
653653
{
654654
// Make sure that if we return NET_IPV6, then IsIPv6() is true. The callers expect that.
655655

src/netaddress.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -188,7 +188,7 @@ class CNetAddr
188188
std::string ToStringIP() const;
189189
uint64_t GetHash() const;
190190
bool GetInAddr(struct in_addr* pipv4Addr) const;
191-
uint32_t GetNetClass() const;
191+
Network GetNetClass() const;
192192

193193
//! For IPv4, mapped IPv4, SIIT translated IPv4, Teredo, 6to4 tunneled addresses, return the relevant IPv4 address as a uint32.
194194
uint32_t GetLinkedIPv4() const;

src/test/fuzz/net.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,8 @@ void test_one_input(const std::vector<uint8_t>& buffer)
4646
fuzzed_data_provider.ConsumeIntegral<uint64_t>(),
4747
*address_bind,
4848
fuzzed_data_provider.ConsumeRandomLengthString(32),
49-
fuzzed_data_provider.PickValueInArray({ConnectionType::INBOUND, ConnectionType::OUTBOUND_FULL_RELAY, ConnectionType::MANUAL, ConnectionType::FEELER, ConnectionType::BLOCK_RELAY, ConnectionType::ADDR_FETCH})};
49+
fuzzed_data_provider.PickValueInArray({ConnectionType::INBOUND, ConnectionType::OUTBOUND_FULL_RELAY, ConnectionType::MANUAL, ConnectionType::FEELER, ConnectionType::BLOCK_RELAY, ConnectionType::ADDR_FETCH}),
50+
fuzzed_data_provider.ConsumeBool()};
5051
while (fuzzed_data_provider.ConsumeBool()) {
5152
switch (fuzzed_data_provider.ConsumeIntegralInRange<int>(0, 11)) {
5253
case 0: {
@@ -148,4 +149,5 @@ void test_one_input(const std::vector<uint8_t>& buffer)
148149
fuzzed_data_provider.PickValueInArray<NetPermissionFlags>({NetPermissionFlags::PF_NONE, NetPermissionFlags::PF_BLOOMFILTER, NetPermissionFlags::PF_RELAY, NetPermissionFlags::PF_FORCERELAY, NetPermissionFlags::PF_NOBAN, NetPermissionFlags::PF_MEMPOOL, NetPermissionFlags::PF_ISIMPLICIT, NetPermissionFlags::PF_ALL}) :
149150
static_cast<NetPermissionFlags>(fuzzed_data_provider.ConsumeIntegral<uint32_t>());
150151
(void)node.HasPermission(net_permission_flags);
152+
(void)node.ConnectedThroughNetwork();
151153
}

src/test/net_tests.cpp

Lines changed: 42 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -185,21 +185,60 @@ BOOST_AUTO_TEST_CASE(cnode_simple_test)
185185
CAddress addr = CAddress(CService(ipv4Addr, 7777), NODE_NETWORK);
186186
std::string pszDest;
187187

188-
std::unique_ptr<CNode> pnode1 = MakeUnique<CNode>(id++, NODE_NETWORK, height, hSocket, addr, 0, 0, CAddress(), pszDest, ConnectionType::OUTBOUND_FULL_RELAY);
188+
std::unique_ptr<CNode> pnode1 = MakeUnique<CNode>(
189+
id++, NODE_NETWORK, height, hSocket, addr,
190+
/* nKeyedNetGroupIn = */ 0,
191+
/* nLocalHostNonceIn = */ 0,
192+
CAddress(), pszDest, ConnectionType::OUTBOUND_FULL_RELAY);
189193
BOOST_CHECK(pnode1->IsFullOutboundConn() == true);
190194
BOOST_CHECK(pnode1->IsManualConn() == false);
191195
BOOST_CHECK(pnode1->IsBlockOnlyConn() == false);
192196
BOOST_CHECK(pnode1->IsFeelerConn() == false);
193197
BOOST_CHECK(pnode1->IsAddrFetchConn() == false);
194198
BOOST_CHECK(pnode1->IsInboundConn() == false);
195-
196-
std::unique_ptr<CNode> pnode2 = MakeUnique<CNode>(id++, NODE_NETWORK, height, hSocket, addr, 1, 1, CAddress(), pszDest, ConnectionType::INBOUND);
199+
BOOST_CHECK_EQUAL(pnode1->ConnectedThroughNetwork(), Network::NET_IPV4);
200+
201+
std::unique_ptr<CNode> pnode2 = MakeUnique<CNode>(
202+
id++, NODE_NETWORK, height, hSocket, addr,
203+
/* nKeyedNetGroupIn = */ 1,
204+
/* nLocalHostNonceIn = */ 1,
205+
CAddress(), pszDest, ConnectionType::INBOUND,
206+
/* inbound_onion = */ false);
197207
BOOST_CHECK(pnode2->IsFullOutboundConn() == false);
198208
BOOST_CHECK(pnode2->IsManualConn() == false);
199209
BOOST_CHECK(pnode2->IsBlockOnlyConn() == false);
200210
BOOST_CHECK(pnode2->IsFeelerConn() == false);
201211
BOOST_CHECK(pnode2->IsAddrFetchConn() == false);
202212
BOOST_CHECK(pnode2->IsInboundConn() == true);
213+
BOOST_CHECK_EQUAL(pnode2->ConnectedThroughNetwork(), Network::NET_IPV4);
214+
215+
std::unique_ptr<CNode> pnode3 = MakeUnique<CNode>(
216+
id++, NODE_NETWORK, height, hSocket, addr,
217+
/* nKeyedNetGroupIn = */ 0,
218+
/* nLocalHostNonceIn = */ 0,
219+
CAddress(), pszDest, ConnectionType::OUTBOUND_FULL_RELAY,
220+
/* inbound_onion = */ true);
221+
BOOST_CHECK(pnode3->IsFullOutboundConn() == true);
222+
BOOST_CHECK(pnode3->IsManualConn() == false);
223+
BOOST_CHECK(pnode3->IsBlockOnlyConn() == false);
224+
BOOST_CHECK(pnode3->IsFeelerConn() == false);
225+
BOOST_CHECK(pnode3->IsAddrFetchConn() == false);
226+
BOOST_CHECK(pnode3->IsInboundConn() == false);
227+
BOOST_CHECK_EQUAL(pnode3->ConnectedThroughNetwork(), Network::NET_IPV4);
228+
229+
std::unique_ptr<CNode> pnode4 = MakeUnique<CNode>(
230+
id++, NODE_NETWORK, height, hSocket, addr,
231+
/* nKeyedNetGroupIn = */ 1,
232+
/* nLocalHostNonceIn = */ 1,
233+
CAddress(), pszDest, ConnectionType::INBOUND,
234+
/* inbound_onion = */ true);
235+
BOOST_CHECK(pnode4->IsFullOutboundConn() == false);
236+
BOOST_CHECK(pnode4->IsManualConn() == false);
237+
BOOST_CHECK(pnode4->IsBlockOnlyConn() == false);
238+
BOOST_CHECK(pnode4->IsFeelerConn() == false);
239+
BOOST_CHECK(pnode4->IsAddrFetchConn() == false);
240+
BOOST_CHECK(pnode4->IsInboundConn() == true);
241+
BOOST_CHECK_EQUAL(pnode4->ConnectedThroughNetwork(), Network::NET_ONION);
203242
}
204243

205244
BOOST_AUTO_TEST_CASE(cnetaddr_basic)

0 commit comments

Comments
 (0)