From ffee29272f3eec8acc6247813a6a0ee2a9a68f13 Mon Sep 17 00:00:00 2001 From: orignal Date: Sun, 14 Apr 2024 20:09:06 -0400 Subject: [PATCH] avoid two firewalled routers in the row --- libi2pd/NetDb.cpp | 4 ++-- libi2pd/RouterInfo.cpp | 28 +++++++++++++++------------- libi2pd/RouterInfo.h | 3 ++- 3 files changed, 19 insertions(+), 16 deletions(-) diff --git a/libi2pd/NetDb.cpp b/libi2pd/NetDb.cpp index 5922c740..a8fb297f 100644 --- a/libi2pd/NetDb.cpp +++ b/libi2pd/NetDb.cpp @@ -1239,7 +1239,7 @@ namespace data { return !router->IsHidden () && router != compatibleWith && (reverse ? (compatibleWith->IsReachableFrom (*router) && router->GetCompatibleTransports (true)): - router->IsReachableFrom (*compatibleWith)) && + router->IsReachableFrom (*compatibleWith)) && !router->IsNAT2NATOnly (*compatibleWith) && router->IsECIES () && !router->IsHighCongestion (false) && (!endpoint || (router->IsV4 () && (!reverse || router->IsPublished (true)))); // endpoint must be ipv4 and published if inbound(reverse) }); @@ -1273,7 +1273,7 @@ namespace data { return !router->IsHidden () && router != compatibleWith && (reverse ? (compatibleWith->IsReachableFrom (*router) && router->GetCompatibleTransports (true)) : - router->IsReachableFrom (*compatibleWith)) && + router->IsReachableFrom (*compatibleWith)) && !router->IsNAT2NATOnly (*compatibleWith) && (router->GetCaps () & RouterInfo::eHighBandwidth) && router->GetVersion () >= NETDB_MIN_HIGHBANDWIDTH_VERSION && router->IsECIES () && !router->IsHighCongestion (true) && diff --git a/libi2pd/RouterInfo.cpp b/libi2pd/RouterInfo.cpp index a9c43b2e..ae1ad967 100644 --- a/libi2pd/RouterInfo.cpp +++ b/libi2pd/RouterInfo.cpp @@ -43,7 +43,7 @@ namespace data RouterInfo::RouterInfo (const std::string& fullPath): m_FamilyID (0), m_IsUpdated (false), m_IsUnreachable (false), - m_SupportedTransports (0),m_ReachableTransports (0), + m_SupportedTransports (0),m_ReachableTransports (0), m_PublishedTransports (0), m_Caps (0), m_Version (0), m_Congestion (eLowCongestion) { m_Addresses = boost::make_shared(); // create empty list @@ -53,7 +53,7 @@ namespace data RouterInfo::RouterInfo (std::shared_ptr&& buf, size_t len): m_FamilyID (0), m_IsUpdated (true), m_IsUnreachable (false), - m_SupportedTransports (0), m_ReachableTransports (0), + m_SupportedTransports (0), m_ReachableTransports (0), m_PublishedTransports (0), m_Caps (0), m_Version (0), m_Congestion (eLowCongestion) { if (len <= MAX_RI_BUFFER_SIZE) @@ -96,6 +96,7 @@ namespace data m_IsUnreachable = false; m_SupportedTransports = 0; m_ReachableTransports = 0; + m_PublishedTransports = 0; m_Caps = 0; // don't clean up m_Addresses, it will be replaced in ReadFromStream ClearProperties (); @@ -375,7 +376,7 @@ namespace data supportedTransports |= (i2p::util::net::IsYggdrasilAddress (address->host) ? eNTCP2V6Mesh : eNTCP2V6); else supportedTransports |= eNTCP2V4; - m_ReachableTransports |= supportedTransports; + m_PublishedTransports |= supportedTransports; } else { @@ -396,11 +397,11 @@ namespace data if (address->IsV6 ()) supportedTransports |= eSSU2V6; if (isHost && address->port) { - if (address->host.is_v4 ()) m_ReachableTransports |= eSSU2V4; - if (address->host.is_v6 ()) m_ReachableTransports |= eSSU2V6; + if (address->host.is_v4 ()) m_PublishedTransports |= eSSU2V4; + if (address->host.is_v6 ()) m_PublishedTransports |= eSSU2V6; address->published = true; } - if (address->ssu && !address->ssu->introducers.empty ()) + else if (address->ssu && !address->ssu->introducers.empty ()) { // exclude invalid introducers uint32_t ts = i2p::util::GetSecondsSinceEpoch (); @@ -420,6 +421,7 @@ namespace data m_SupportedTransports |= supportedTransports; } } + m_ReachableTransports |= m_PublishedTransports; // update addresses #if (BOOST_VERSION >= 105300) boost::atomic_store (&m_Addresses, addresses); @@ -996,13 +998,13 @@ namespace data bool RouterInfo::IsPublished (bool v4) const { if (m_Caps & (eUnreachable | eHidden)) return false; // if router sets U or H we assume that all addresses are not published - auto addr = GetAddresses (); - if (v4) - return ((*addr)[eNTCP2V4Idx] && ((*addr)[eNTCP2V4Idx])->published) || - ((*addr)[eSSU2V4Idx] && ((*addr)[eSSU2V4Idx])->published); - else - return ((*addr)[eNTCP2V6Idx] && ((*addr)[eNTCP2V6Idx])->published) || - ((*addr)[eSSU2V6Idx] && ((*addr)[eSSU2V6Idx])->published); + return m_PublishedTransports & (eNTCP2V4 | eSSU2V4); + } + + bool RouterInfo::IsNAT2NATOnly (const RouterInfo& other) const + { + return !(m_PublishedTransports & other.m_SupportedTransports) && + !(other.m_PublishedTransports & m_SupportedTransports); } bool RouterInfo::IsSSU2PeerTesting (bool v4) const diff --git a/libi2pd/RouterInfo.h b/libi2pd/RouterInfo.h index 9e074b9a..ffbef597 100644 --- a/libi2pd/RouterInfo.h +++ b/libi2pd/RouterInfo.h @@ -253,6 +253,7 @@ namespace data bool IsExtraBandwidth () const { return m_Caps & RouterInfo::eExtraBandwidth; }; bool IsEligibleFloodfill () const; bool IsPublished (bool v4) const; + bool IsNAT2NATOnly (const RouterInfo& other) const; // only NAT-to-NAT connection is possible bool IsSSU2PeerTesting (bool v4) const; bool IsSSU2Introducer (bool v4) const; bool IsHighCongestion (bool highBandwidth) const; @@ -327,7 +328,7 @@ namespace data uint64_t m_Timestamp; // in milliseconds boost::shared_ptr m_Addresses; // TODO: use std::shared_ptr and std::atomic_store for gcc >= 4.9 bool m_IsUpdated, m_IsUnreachable; - CompatibleTransports m_SupportedTransports, m_ReachableTransports; + CompatibleTransports m_SupportedTransports, m_ReachableTransports, m_PublishedTransports; uint8_t m_Caps; int m_Version; Congestion m_Congestion;