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 // Advertise our address
if (fListen && !IsInitialBlockDownload()) if (fListen && !IsInitialBlockDownload())
{ {
CAddress addr = GetLocalAddress(&pfrom->addr); CService service { GetLocalAddress(*pfrom) };
CAddress addr(service);
if (addr.IsRoutable()) if (addr.IsRoutable())
{ {
LogPrintf("ProcessMessages: advertizing address %s\n", addr.ToString()); 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 // find 'best' local address for a particular peer
bool GetLocal(CService& addr, const CNetAddr *paddrPeer) bool GetLocal(CService& addr, const CNode& peer)
{ {
if (!fListen) if (!fListen)
return false; return false;
@ -190,8 +190,18 @@ bool GetLocal(CService& addr, const CNetAddr *paddrPeer)
LOCK(cs_mapLocalHost); LOCK(cs_mapLocalHost);
for (map<CNetAddr, LocalServiceInfo>::iterator it = mapLocalHost.begin(); it != mapLocalHost.end(); it++) 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 nScore = (*it).second.nScore;
int nReachability = (*it).first.GetReachabilityFrom(paddrPeer); int nReachability = (*it).first.GetReachabilityFrom(peer.addr);
if (nReachability > nBestReachability || (nReachability == nBestReachability && nScore > nBestScore)) if (nReachability > nBestReachability || (nReachability == nBestReachability && nScore > nBestScore))
{ {
addr = CService((*it).first, (*it).second.nPort); 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 // Otherwise, return the unroutable 0.0.0.0 but filled in with
// the normal parameters, since the IP may be changed to a useful // the normal parameters, since the IP may be changed to a useful
// one by discovery. // one by discovery.
CAddress GetLocalAddress(const CNetAddr *paddrPeer) CService GetLocalAddress(const CNode& peer)
{ {
CAddress ret(CService(CNetAddr(),GetListenPort()),0); CAddress ret(CService(CNetAddr(),GetListenPort()),0);
CService addr; CService addr;
if (GetLocal(addr, paddrPeer)) if (GetLocal(addr, peer)) {
{
ret = CAddress(addr); ret = CAddress(addr);
} }
ret.nServices = nLocalServices; ret.nServices = nLocalServices;
@ -261,7 +270,7 @@ void AdvertizeLocal(CNode *pnode)
{ {
if (fListen && pnode->fSuccessfullyConnected) if (fListen && pnode->fSuccessfullyConnected)
{ {
CAddress addrLocal = GetLocalAddress(&pnode->addr); CAddress addrLocal { GetLocalAddress(*pnode) };
// If discovery is enabled, sometimes give our peer the address it // 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 // tells us that it sees us as in case it has a better idea of our
// address than we do. // address than we do.
@ -576,6 +585,10 @@ extern int32_t HUSH_NSPV;
#define HUSH_NSPV_SUPERLITE (HUSH_NSPV > 0) #define HUSH_NSPV_SUPERLITE (HUSH_NSPV > 0)
#endif // !HUSH_NSPV_SUPERLITE #endif // !HUSH_NSPV_SUPERLITE
Network CNode::ConnectedThroughNetwork() const
{
return m_inbound_onion ? NET_ONION : addr.GetNetClass();
}
void CNode::PushVersion() void CNode::PushVersion()
{ {
@ -583,7 +596,9 @@ void CNode::PushVersion()
int64_t nTime = (fInbound ? GetTime() : GetTime()); int64_t nTime = (fInbound ? GetTime() : GetTime());
CAddress addrYou = (addr.IsRoutable() && !IsProxy(addr) ? addr : CAddress(CService(), addr.nServices)); 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)); GetRandBytes((unsigned char*)&nLocalHostNonce, sizeof(nLocalHostNonce));
if (fLogIPs) 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); 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; return;
} }
// Don't accept connections from banned peers.
if (CNode::IsBanned(addr) && !allowlisted) if (CNode::IsBanned(addr) && !allowlisted)
{ {
LogPrintf("connection from %s dropped (banned)\n", addr.ToString()); LogPrintf("connection from %s dropped (banned)\n", addr.ToString());
@ -1320,6 +1336,8 @@ void CreateNodeFromAcceptedSocket(SOCKET hSocket,
return; 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); CNode* pnode = new CNode(hSocket, addr, "", true, ssl);
pnode->AddRef(); pnode->AddRef();
pnode->fAllowlisted = allowlisted; pnode->fAllowlisted = allowlisted;

16
src/net.h

@ -228,8 +228,7 @@ void SetReachable(enum Network net, bool reachable);
bool IsReachable(enum Network net); bool IsReachable(enum Network net);
/** @returns true if the address is in a reachable network, false otherwise */ /** @returns true if the address is in a reachable network, false otherwise */
bool IsReachable(const CNetAddr& addr); bool IsReachable(const CNetAddr& addr);
CAddress GetLocalAddress(const CNetAddr *paddrPeer = NULL); CService GetLocalAddress(const CNode& peer);
extern bool fDiscover; extern bool fDiscover;
extern bool fListen; extern bool fListen;
@ -404,6 +403,8 @@ public:
// const CAddress addrBind; // https://github.com/bitcoin/bitcoin/commit/a7e3c2814c8e49197889a4679461be42254e5c51 // const CAddress addrBind; // https://github.com/bitcoin/bitcoin/commit/a7e3c2814c8e49197889a4679461be42254e5c51
std::string addrName; std::string addrName;
CService addrLocal; 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 nVersion;
int lasthdrsreq,sendhdrsreq; int lasthdrsreq,sendhdrsreq;
// strSubVer is whatever byte array we read from the wire. However, this field is intended // strSubVer is whatever byte array we read from the wire. However, this field is intended
@ -419,6 +420,17 @@ public:
bool fNetworkNode; bool fNetworkNode;
bool fSuccessfullyConnected; bool fSuccessfullyConnected;
bool fDisconnect; 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. // count blocks seen.
int8_t nBlocksinARow; int8_t nBlocksinARow;
int8_t nBlocksinARow2; 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, // private extensions to enum Network, only returned by GetExtNetwork,
// and only used in GetReachabilityFrom // and only used in GetReachabilityFrom
static const int NET_UNKNOWN = NET_MAX + 0; // Teredo is IPv6-over-UDP
static const int NET_TEREDO = NET_MAX + 1; static const int NET_TEREDO = NET_MAX;
int static GetExtNetwork(const CNetAddr *addr) int static GetExtNetwork(const CNetAddr& addr)
{ {
if (addr == NULL) if (addr.IsRFC4380())
return NET_UNKNOWN;
if (addr->IsRFC4380())
return NET_TEREDO; return NET_TEREDO;
return addr->GetNetwork(); return addr.GetNetwork();
} }
/** Calculates a metric for how reachable (*this) is from a given partner */ /** 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 { enum Reachability {
REACH_UNREACHABLE, REACH_UNREACHABLE,
@ -865,7 +863,7 @@ int CNetAddr::GetReachabilityFrom(const CNetAddr *paddrPartner) const
if (!IsRoutable() || IsInternal()) if (!IsRoutable() || IsInternal())
return REACH_UNREACHABLE; return REACH_UNREACHABLE;
int ourNet = GetExtNetwork(this); int ourNet = GetExtNetwork(*this);
int theirNet = GetExtNetwork(paddrPartner); int theirNet = GetExtNetwork(paddrPartner);
bool fTunnel = IsRFC3964() || IsRFC6052() || IsRFC6145(); bool fTunnel = IsRFC3964() || IsRFC6052() || IsRFC6145();
@ -886,7 +884,7 @@ int CNetAddr::GetReachabilityFrom(const CNetAddr *paddrPartner) const
switch(ourNet) { switch(ourNet) {
default: return REACH_DEFAULT; default: return REACH_DEFAULT;
case NET_IPV4: return REACH_IPV4; // Tor users can connect to IPv4 as well 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: case NET_TEREDO:
switch(ourNet) { switch(ourNet) {
@ -895,7 +893,6 @@ int CNetAddr::GetReachabilityFrom(const CNetAddr *paddrPartner) const
case NET_IPV6: return REACH_IPV6_WEAK; case NET_IPV6: return REACH_IPV6_WEAK;
case NET_IPV4: return REACH_IPV4; case NET_IPV4: return REACH_IPV4;
} }
case NET_UNKNOWN:
case NET_UNROUTABLE: case NET_UNROUTABLE:
default: default:
switch(ourNet) { switch(ourNet) {
@ -903,7 +900,7 @@ int CNetAddr::GetReachabilityFrom(const CNetAddr *paddrPartner) const
case NET_TEREDO: return REACH_TEREDO; case NET_TEREDO: return REACH_TEREDO;
case NET_IPV6: return REACH_IPV6_WEAK; case NET_IPV6: return REACH_IPV6_WEAK;
case NET_IPV4: return REACH_IPV4; 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> GetGroup(const std::vector<bool> &asmap) const;
std::vector<unsigned char> GetAddrBytes() 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); CNetAddr(const struct in6_addr& pipv6Addr, const uint32_t scope = 0);
bool GetIn6Addr(struct in6_addr* pipv6Addr) const; bool GetIn6Addr(struct in6_addr* pipv6Addr) const;

Loading…
Cancel
Save