Compare commits

...

2 Commits

  1. 3
      src/main.cpp
  2. 32
      src/net.cpp
  3. 16
      src/net.h
  4. 21
      src/netaddress.cpp
  5. 2
      src/netaddress.h

3
src/main.cpp

@ -6950,7 +6950,8 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
// Advertise our address
if (fListen && !IsInitialBlockDownload())
{
CAddress addr = GetLocalAddress(&pfrom->addr);
CService service { GetLocalAddress(*pfrom) };
CAddress addr(service);
if (addr.IsRoutable())
{
LogPrintf("ProcessMessages: advertizing address %s\n", addr.ToString());

32
src/net.cpp

@ -179,7 +179,7 @@ unsigned short GetListenPort()
}
// find 'best' local address for a particular peer
bool GetLocal(CService& addr, const CNetAddr *paddrPeer)
bool GetLocal(CService& addr, const CNode& peer)
{
if (!fListen)
return false;
@ -190,8 +190,18 @@ bool GetLocal(CService& addr, const CNetAddr *paddrPeer)
LOCK(cs_mapLocalHost);
for (map<CNetAddr, LocalServiceInfo>::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(paddrPeer);
int nReachability = (*it).first.GetReachabilityFrom(peer.addr);
if (nReachability > nBestReachability || (nReachability == nBestReachability && nScore > nBestScore))
{
addr = CService((*it).first, (*it).second.nPort);
@ -228,12 +238,11 @@ 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)
CService GetLocalAddress(const CNode& peer)
{
CAddress ret(CService(CNetAddr(),GetListenPort()),0);
CService addr;
if (GetLocal(addr, paddrPeer))
{
if (GetLocal(addr, peer)) {
ret = CAddress(addr);
}
ret.nServices = nLocalServices;
@ -261,7 +270,7 @@ void AdvertizeLocal(CNode *pnode)
{
if (fListen && pnode->fSuccessfullyConnected)
{
CAddress addrLocal = GetLocalAddress(&pnode->addr);
CAddress addrLocal { GetLocalAddress(*pnode) };
// 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.
@ -576,6 +585,10 @@ 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()
{
@ -583,7 +596,9 @@ void CNode::PushVersion()
int64_t nTime = (fInbound ? GetTime() : GetTime());
CAddress addrYou = (addr.IsRoutable() && !IsProxy(addr) ? addr : CAddress(CService(), addr.nServices));
CAddress addrMe = GetLocalAddress(&addr);
CNode *addr = this;
CService service = GetLocalAddress(*addr);
CAddress addrMe(service);
GetRandBytes((unsigned char*)&nLocalHostNonce, sizeof(nLocalHostNonce));
if (fLogIPs)
LogPrint("net", "send version message: version %d, blocks=%d, us=%s, them=%s, peer=%d\n", PROTOCOL_VERSION, nBestHeight, addrMe.ToString(), addrYou.ToString(), id);
@ -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;

16
src/net.h

@ -228,8 +228,7 @@ void SetReachable(enum Network net, bool reachable);
bool IsReachable(enum Network net);
/** @returns true if the address is in a reachable network, false otherwise */
bool IsReachable(const CNetAddr& addr);
CAddress GetLocalAddress(const CNetAddr *paddrPeer = NULL);
CService GetLocalAddress(const CNode& peer);
extern bool fDiscover;
extern bool fListen;
@ -404,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
@ -419,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;

21
src/netaddress.cpp

@ -838,19 +838,17 @@ uint64_t CNetAddr::GetHash() const
// private extensions to enum Network, only returned by GetExtNetwork,
// and only used in GetReachabilityFrom
static const int NET_UNKNOWN = NET_MAX + 0;
static const int NET_TEREDO = NET_MAX + 1;
int static GetExtNetwork(const CNetAddr *addr)
// Teredo is IPv6-over-UDP
static const int NET_TEREDO = NET_MAX;
int static GetExtNetwork(const CNetAddr& addr)
{
if (addr == NULL)
return NET_UNKNOWN;
if (addr->IsRFC4380())
if (addr.IsRFC4380())
return NET_TEREDO;
return addr->GetNetwork();
return addr.GetNetwork();
}
/** Calculates a metric for how reachable (*this) is from a given partner */
int CNetAddr::GetReachabilityFrom(const CNetAddr *paddrPartner) const
int CNetAddr::GetReachabilityFrom(const CNetAddr& paddrPartner) const
{
enum Reachability {
REACH_UNREACHABLE,
@ -865,7 +863,7 @@ int CNetAddr::GetReachabilityFrom(const CNetAddr *paddrPartner) const
if (!IsRoutable() || IsInternal())
return REACH_UNREACHABLE;
int ourNet = GetExtNetwork(this);
int ourNet = GetExtNetwork(*this);
int theirNet = GetExtNetwork(paddrPartner);
bool fTunnel = IsRFC3964() || IsRFC6052() || IsRFC6145();
@ -886,7 +884,7 @@ int CNetAddr::GetReachabilityFrom(const CNetAddr *paddrPartner) const
switch(ourNet) {
default: return REACH_DEFAULT;
case NET_IPV4: return REACH_IPV4; // Tor users can connect to IPv4 as well
case NET_ONION: return REACH_PRIVATE;
case NET_ONION: return REACH_PRIVATE;
}
case NET_TEREDO:
switch(ourNet) {
@ -895,7 +893,6 @@ int CNetAddr::GetReachabilityFrom(const CNetAddr *paddrPartner) const
case NET_IPV6: return REACH_IPV6_WEAK;
case NET_IPV4: return REACH_IPV4;
}
case NET_UNKNOWN:
case NET_UNROUTABLE:
default:
switch(ourNet) {
@ -903,7 +900,7 @@ int CNetAddr::GetReachabilityFrom(const CNetAddr *paddrPartner) const
case NET_TEREDO: return REACH_TEREDO;
case NET_IPV6: return REACH_IPV6_WEAK;
case NET_IPV4: return REACH_IPV4;
case NET_ONION: return REACH_PRIVATE; // either from Tor, or don't care about our address
case NET_ONION: return REACH_PRIVATE; // either from Tor, or don't care about our address
}
}
}

2
src/netaddress.h

@ -204,7 +204,7 @@ class CNetAddr
std::vector<unsigned char> GetGroup(const std::vector<bool> &asmap) const;
std::vector<unsigned char> GetAddrBytes() const;
int GetReachabilityFrom(const CNetAddr *paddrPartner = nullptr) const;
int GetReachabilityFrom(const CNetAddr& paddrPartner) const;
CNetAddr(const struct in6_addr& pipv6Addr, const uint32_t scope = 0);
bool GetIn6Addr(struct in6_addr* pipv6Addr) const;

Loading…
Cancel
Save