mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-03-05 14:06:27 -05:00
[net] Return CService from GetLocalAddrForPeer and GetLocalAddress
This commit is contained in:
parent
d9079fe18d
commit
5961f8eea1
4 changed files with 24 additions and 28 deletions
26
src/net.cpp
26
src/net.cpp
|
@ -206,15 +206,13 @@ static std::vector<CAddress> ConvertSeeds(const std::vector<uint8_t> &vSeedsIn)
|
|||
// Otherwise, return the unroutable 0.0.0.0 but filled in with
|
||||
// the normal parameters, since the IP may be changed to a useful
|
||||
// one by discovery.
|
||||
CAddress GetLocalAddress(const CNetAddr *paddrPeer, ServiceFlags nLocalServices)
|
||||
CService GetLocalAddress(const CNetAddr& addrPeer)
|
||||
{
|
||||
CAddress ret(CService(CNetAddr(),GetListenPort()), nLocalServices);
|
||||
CService ret{CNetAddr(), GetListenPort()};
|
||||
CService addr;
|
||||
if (GetLocal(addr, paddrPeer))
|
||||
{
|
||||
ret = CAddress(addr, nLocalServices);
|
||||
if (GetLocal(addr, &addrPeer)) {
|
||||
ret = CService{addr};
|
||||
}
|
||||
ret.nTime = GetAdjustedTime();
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -233,35 +231,35 @@ bool IsPeerAddrLocalGood(CNode *pnode)
|
|||
IsReachable(addrLocal.GetNetwork());
|
||||
}
|
||||
|
||||
std::optional<CAddress> GetLocalAddrForPeer(CNode *pnode)
|
||||
std::optional<CService> GetLocalAddrForPeer(CNode& node)
|
||||
{
|
||||
CAddress addrLocal = GetLocalAddress(&pnode->addr, pnode->GetLocalServices());
|
||||
CService addrLocal{GetLocalAddress(node.addr)};
|
||||
if (gArgs.GetBoolArg("-addrmantest", false)) {
|
||||
// use IPv4 loopback during addrmantest
|
||||
addrLocal = CAddress(CService(LookupNumeric("127.0.0.1", GetListenPort())), pnode->GetLocalServices());
|
||||
addrLocal = CService(LookupNumeric("127.0.0.1", GetListenPort()));
|
||||
}
|
||||
// If discovery is enabled, sometimes give our peer the address it
|
||||
// tells us that it sees us as in case it has a better idea of our
|
||||
// address than we do.
|
||||
FastRandomContext rng;
|
||||
if (IsPeerAddrLocalGood(pnode) && (!addrLocal.IsRoutable() ||
|
||||
if (IsPeerAddrLocalGood(&node) && (!addrLocal.IsRoutable() ||
|
||||
rng.randbits((GetnScore(addrLocal) > LOCAL_MANUAL) ? 3 : 1) == 0))
|
||||
{
|
||||
if (pnode->IsInboundConn()) {
|
||||
if (node.IsInboundConn()) {
|
||||
// For inbound connections, assume both the address and the port
|
||||
// as seen from the peer.
|
||||
addrLocal = CAddress{pnode->GetAddrLocal(), addrLocal.nServices, addrLocal.nTime};
|
||||
addrLocal = CService{node.GetAddrLocal()};
|
||||
} else {
|
||||
// For outbound connections, assume just the address as seen from
|
||||
// the peer and leave the port in `addrLocal` as returned by
|
||||
// `GetLocalAddress()` above. The peer has no way to observe our
|
||||
// listening port when we have initiated the connection.
|
||||
addrLocal.SetIP(pnode->GetAddrLocal());
|
||||
addrLocal.SetIP(node.GetAddrLocal());
|
||||
}
|
||||
}
|
||||
if (addrLocal.IsRoutable() || gArgs.GetBoolArg("-addrmantest", false))
|
||||
{
|
||||
LogPrint(BCLog::NET, "Advertising address %s to peer=%d\n", addrLocal.ToString(), pnode->GetId());
|
||||
LogPrint(BCLog::NET, "Advertising address %s to peer=%d\n", addrLocal.ToString(), node.GetId());
|
||||
return addrLocal;
|
||||
}
|
||||
// Address is unroutable. Don't advertise.
|
||||
|
|
|
@ -144,8 +144,8 @@ enum
|
|||
};
|
||||
|
||||
bool IsPeerAddrLocalGood(CNode *pnode);
|
||||
/** Returns a local address that we should advertise to this peer */
|
||||
std::optional<CAddress> GetLocalAddrForPeer(CNode *pnode);
|
||||
/** Returns a local address that we should advertise to this peer. */
|
||||
std::optional<CService> GetLocalAddrForPeer(CNode& node);
|
||||
|
||||
/**
|
||||
* Mark a network as reachable or unreachable (no automatic connects to it)
|
||||
|
@ -163,7 +163,7 @@ void RemoveLocal(const CService& addr);
|
|||
bool SeenLocal(const CService& addr);
|
||||
bool IsLocal(const CService& addr);
|
||||
bool GetLocal(CService &addr, const CNetAddr *paddrPeer = nullptr);
|
||||
CAddress GetLocalAddress(const CNetAddr *paddrPeer, ServiceFlags nLocalServices);
|
||||
CService GetLocalAddress(const CNetAddr& addrPeer);
|
||||
|
||||
|
||||
extern bool fDiscover;
|
||||
|
|
|
@ -2930,7 +2930,7 @@ void PeerManagerImpl::ProcessMessage(CNode& pfrom, const std::string& msg_type,
|
|||
// indicate to the peer that we will participate in addr relay.
|
||||
if (fListen && !m_chainman.ActiveChainstate().IsInitialBlockDownload())
|
||||
{
|
||||
CAddress addr = GetLocalAddress(&pfrom.addr, pfrom.GetLocalServices());
|
||||
CAddress addr{GetLocalAddress(pfrom.addr), peer->m_our_services, (uint32_t)GetAdjustedTime()};
|
||||
FastRandomContext insecure_rand;
|
||||
if (addr.IsRoutable())
|
||||
{
|
||||
|
@ -4685,9 +4685,10 @@ void PeerManagerImpl::MaybeSendAddr(CNode& node, Peer& peer, std::chrono::micros
|
|||
if (peer.m_next_local_addr_send != 0us) {
|
||||
peer.m_addr_known->reset();
|
||||
}
|
||||
if (std::optional<CAddress> local_addr = GetLocalAddrForPeer(&node)) {
|
||||
if (std::optional<CService> local_service = GetLocalAddrForPeer(node)) {
|
||||
CAddress local_addr{*local_service, peer.m_our_services, (uint32_t)GetAdjustedTime()};
|
||||
FastRandomContext insecure_rand;
|
||||
PushAddress(peer, *local_addr, insecure_rand);
|
||||
PushAddress(peer, local_addr, insecure_rand);
|
||||
}
|
||||
peer.m_next_local_addr_send = GetExponentialRand(current_time, AVG_LOCAL_ADDRESS_BROADCAST_INTERVAL);
|
||||
}
|
||||
|
|
|
@ -648,7 +648,7 @@ BOOST_AUTO_TEST_CASE(ipv4_peer_with_ipv6_addrMe_test)
|
|||
pnode->SetAddrLocal(addrLocal);
|
||||
|
||||
// before patch, this causes undefined behavior detectable with clang's -fsanitize=memory
|
||||
GetLocalAddrForPeer(&*pnode);
|
||||
GetLocalAddrForPeer(*pnode);
|
||||
|
||||
// suppress no-checks-run warning; if this test fails, it's by triggering a sanitizer
|
||||
BOOST_CHECK(1);
|
||||
|
@ -675,13 +675,10 @@ BOOST_AUTO_TEST_CASE(get_local_addr_for_peer_port)
|
|||
const uint16_t bind_port = 20001;
|
||||
m_node.args->ForceSetArg("-bind", strprintf("3.4.5.6:%u", bind_port));
|
||||
|
||||
const uint32_t current_time = static_cast<uint32_t>(GetAdjustedTime());
|
||||
SetMockTime(current_time);
|
||||
|
||||
// Our address:port as seen from the peer, completely different from the above.
|
||||
in_addr peer_us_addr;
|
||||
peer_us_addr.s_addr = htonl(0x02030405);
|
||||
const CAddress peer_us{CService{peer_us_addr, 20002}, NODE_NETWORK, current_time};
|
||||
const CService peer_us{peer_us_addr, 20002};
|
||||
|
||||
// Create a peer with a routable IPv4 address (outbound).
|
||||
in_addr peer_out_in_addr;
|
||||
|
@ -700,9 +697,9 @@ BOOST_AUTO_TEST_CASE(get_local_addr_for_peer_port)
|
|||
peer_out.SetAddrLocal(peer_us);
|
||||
|
||||
// Without the fix peer_us:8333 is chosen instead of the proper peer_us:bind_port.
|
||||
auto chosen_local_addr = GetLocalAddrForPeer(&peer_out);
|
||||
auto chosen_local_addr = GetLocalAddrForPeer(peer_out);
|
||||
BOOST_REQUIRE(chosen_local_addr);
|
||||
const CAddress expected{CService{peer_us_addr, bind_port}, NODE_NETWORK, current_time};
|
||||
const CService expected{peer_us_addr, bind_port};
|
||||
BOOST_CHECK(*chosen_local_addr == expected);
|
||||
|
||||
// Create a peer with a routable IPv4 address (inbound).
|
||||
|
@ -722,7 +719,7 @@ BOOST_AUTO_TEST_CASE(get_local_addr_for_peer_port)
|
|||
peer_in.SetAddrLocal(peer_us);
|
||||
|
||||
// Without the fix peer_us:8333 is chosen instead of the proper peer_us:peer_us.GetPort().
|
||||
chosen_local_addr = GetLocalAddrForPeer(&peer_in);
|
||||
chosen_local_addr = GetLocalAddrForPeer(peer_in);
|
||||
BOOST_REQUIRE(chosen_local_addr);
|
||||
BOOST_CHECK(*chosen_local_addr == peer_us);
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue