From 1a8a32a773deffa80ccd03102cfa687eb1622a9e Mon Sep 17 00:00:00 2001 From: orignal Date: Fri, 5 Nov 2021 14:51:24 -0400 Subject: [PATCH] select next tunnel with compatible transports --- libi2pd/Destination.cpp | 24 ++++++++++++------------ libi2pd/RouterInfo.h | 3 ++- libi2pd/Tunnel.cpp | 2 +- libi2pd/Tunnel.h | 1 + libi2pd/TunnelConfig.h | 4 ++-- libi2pd/TunnelPool.cpp | 15 +++++++++------ libi2pd/TunnelPool.h | 9 ++++++--- 7 files changed, 33 insertions(+), 25 deletions(-) diff --git a/libi2pd/Destination.cpp b/libi2pd/Destination.cpp index 54137664..f523243a 100644 --- a/libi2pd/Destination.cpp +++ b/libi2pd/Destination.cpp @@ -555,26 +555,26 @@ namespace client shared_from_this (), std::placeholders::_1)); return; } - auto outbound = m_Pool->GetNextOutboundTunnel (); + auto floodfill = i2p::data::netdb.GetClosestFloodfill (leaseSet->GetIdentHash (), m_ExcludedFloodfills); + if (!floodfill) + { + LogPrint (eLogError, "Destination: Can't publish LeaseSet, no more floodfills found"); + m_ExcludedFloodfills.clear (); + return; + } + m_ExcludedFloodfills.insert (floodfill->GetIdentHash ()); + auto outbound = m_Pool->GetNextOutboundTunnel (nullptr, floodfill->GetCompatibleTransports (false)); if (!outbound) { LogPrint (eLogError, "Destination: Can't publish LeaseSet. No outbound tunnels"); return; } - auto inbound = m_Pool->GetNextInboundTunnel (); + auto inbound = m_Pool->GetNextInboundTunnel (nullptr, floodfill->GetCompatibleTransports (true)); if (!inbound) { LogPrint (eLogError, "Destination: Can't publish LeaseSet. No inbound tunnels"); return; } - auto floodfill = i2p::data::netdb.GetClosestFloodfill (leaseSet->GetIdentHash (), m_ExcludedFloodfills); - if (!floodfill) - { - LogPrint (eLogError, "Destination: Can't publish LeaseSet, no more floodfills found"); - m_ExcludedFloodfills.clear (); - return; - } - m_ExcludedFloodfills.insert (floodfill->GetIdentHash ()); LogPrint (eLogDebug, "Destination: Publish LeaseSet of ", GetIdentHash ().ToBase32 ()); RAND_bytes ((uint8_t *)&m_PublishReplyToken, 4); auto msg = WrapMessageForRouter (floodfill, i2p::CreateDatabaseStoreMsg (leaseSet, m_PublishReplyToken, inbound)); @@ -751,10 +751,10 @@ namespace client std::shared_ptr nextFloodfill, std::shared_ptr request) { if (!request->replyTunnel || !request->replyTunnel->IsEstablished ()) - request->replyTunnel = m_Pool->GetNextInboundTunnel (); + request->replyTunnel = m_Pool->GetNextInboundTunnel (nullptr, nextFloodfill->GetCompatibleTransports (true)); if (!request->replyTunnel) LogPrint (eLogError, "Destination: Can't send LeaseSet request, no inbound tunnels found"); if (!request->outboundTunnel || !request->outboundTunnel->IsEstablished ()) - request->outboundTunnel = m_Pool->GetNextOutboundTunnel (); + request->outboundTunnel = m_Pool->GetNextOutboundTunnel (nullptr, nextFloodfill->GetCompatibleTransports (false)); if (!request->outboundTunnel) LogPrint (eLogError, "Destination: Can't send LeaseSet request, no outbound tunnels found"); if (request->replyTunnel && request->outboundTunnel) diff --git a/libi2pd/RouterInfo.h b/libi2pd/RouterInfo.h index b2b883dc..de1fe235 100644 --- a/libi2pd/RouterInfo.h +++ b/libi2pd/RouterInfo.h @@ -64,7 +64,8 @@ namespace data eNTCP2V6 = 0x02, eSSUV4 = 0x04, eSSUV6 = 0x08, - eNTCP2V6Mesh = 0x10 + eNTCP2V6Mesh = 0x10, + eAllTransports = 0xFF }; typedef uint8_t CompatibleTransports; diff --git a/libi2pd/Tunnel.cpp b/libi2pd/Tunnel.cpp index a315ff49..ad048bb8 100644 --- a/libi2pd/Tunnel.cpp +++ b/libi2pd/Tunnel.cpp @@ -32,7 +32,7 @@ namespace tunnel Tunnel::Tunnel (std::shared_ptr config): TunnelBase (config->GetTunnelID (), config->GetNextTunnelID (), config->GetNextIdentHash ()), m_Config (config), m_IsShortBuildMessage (false), m_Pool (nullptr), - m_State (eTunnelStatePending), m_FarEndTransports (0), + m_State (eTunnelStatePending), m_FarEndTransports (i2p::data::RouterInfo::eAllTransports), m_IsRecreated (false), m_Latency (0) { } diff --git a/libi2pd/Tunnel.h b/libi2pd/Tunnel.h index 56166e0b..3ab366c8 100644 --- a/libi2pd/Tunnel.h +++ b/libi2pd/Tunnel.h @@ -76,6 +76,7 @@ namespace tunnel std::vector > GetPeers () const; std::vector > GetInvertedPeers () const; bool IsShortBuildMessage () const { return m_IsShortBuildMessage; }; + i2p::data::RouterInfo::CompatibleTransports GetFarEndTransports () const { return m_FarEndTransports; }; TunnelState GetState () const { return m_State; }; void SetState (TunnelState state); bool IsEstablished () const { return m_State == eTunnelStateEstablished; }; diff --git a/libi2pd/TunnelConfig.h b/libi2pd/TunnelConfig.h index ae924ba6..c514a404 100644 --- a/libi2pd/TunnelConfig.h +++ b/libi2pd/TunnelConfig.h @@ -82,7 +82,7 @@ namespace tunnel public: TunnelConfig (const std::vector >& peers, - bool isShort, i2p::data::RouterInfo::CompatibleTransports farEndTransports = 0): // inbound + bool isShort, i2p::data::RouterInfo::CompatibleTransports farEndTransports = i2p::data::RouterInfo::eAllTransports): // inbound m_IsShort (isShort), m_FarEndTransports (farEndTransports) { CreatePeers (peers); @@ -91,7 +91,7 @@ namespace tunnel TunnelConfig (const std::vector >& peers, uint32_t replyTunnelID, const i2p::data::IdentHash& replyIdent, bool isShort, - i2p::data::RouterInfo::CompatibleTransports farEndTransports = 0): // outbound + i2p::data::RouterInfo::CompatibleTransports farEndTransports = i2p::data::RouterInfo::eAllTransports): // outbound m_IsShort (isShort), m_FarEndTransports (farEndTransports) { CreatePeers (peers); diff --git a/libi2pd/TunnelPool.cpp b/libi2pd/TunnelPool.cpp index 5ed330c8..c9897b29 100644 --- a/libi2pd/TunnelPool.cpp +++ b/libi2pd/TunnelPool.cpp @@ -190,20 +190,23 @@ namespace tunnel return v; } - std::shared_ptr TunnelPool::GetNextOutboundTunnel (std::shared_ptr excluded) const + std::shared_ptr TunnelPool::GetNextOutboundTunnel (std::shared_ptr excluded, + i2p::data::RouterInfo::CompatibleTransports compatible) const { std::unique_lock l(m_OutboundTunnelsMutex); - return GetNextTunnel (m_OutboundTunnels, excluded); + return GetNextTunnel (m_OutboundTunnels, excluded, compatible); } - std::shared_ptr TunnelPool::GetNextInboundTunnel (std::shared_ptr excluded) const + std::shared_ptr TunnelPool::GetNextInboundTunnel (std::shared_ptr excluded, + i2p::data::RouterInfo::CompatibleTransports compatible) const { std::unique_lock l(m_InboundTunnelsMutex); - return GetNextTunnel (m_InboundTunnels, excluded); + return GetNextTunnel (m_InboundTunnels, excluded, compatible); } template - typename TTunnels::value_type TunnelPool::GetNextTunnel (TTunnels& tunnels, typename TTunnels::value_type excluded) const + typename TTunnels::value_type TunnelPool::GetNextTunnel (TTunnels& tunnels, + typename TTunnels::value_type excluded, i2p::data::RouterInfo::CompatibleTransports compatible) const { if (tunnels.empty ()) return nullptr; uint32_t ind = rand () % (tunnels.size ()/2 + 1), i = 0; @@ -211,7 +214,7 @@ namespace tunnel typename TTunnels::value_type tunnel = nullptr; for (const auto& it: tunnels) { - if (it->IsEstablished () && it != excluded) + if (it->IsEstablished () && it != excluded && (compatible & it->GetFarEndTransports ())) { if (it->IsSlow () || (HasLatencyRequirement() && it->LatencyIsKnown() && !it->LatencyFitsRange(m_MinLatency, m_MaxLatency))) diff --git a/libi2pd/TunnelPool.h b/libi2pd/TunnelPool.h index 875a9955..2f4018ce 100644 --- a/libi2pd/TunnelPool.h +++ b/libi2pd/TunnelPool.h @@ -76,8 +76,10 @@ namespace tunnel void RecreateInboundTunnel (std::shared_ptr tunnel); void RecreateOutboundTunnel (std::shared_ptr tunnel); std::vector > GetInboundTunnels (int num) const; - std::shared_ptr GetNextOutboundTunnel (std::shared_ptr excluded = nullptr) const; - std::shared_ptr GetNextInboundTunnel (std::shared_ptr excluded = nullptr) const; + std::shared_ptr GetNextOutboundTunnel (std::shared_ptr excluded = nullptr, + i2p::data::RouterInfo::CompatibleTransports compatible = i2p::data::RouterInfo::eAllTransports) const; + std::shared_ptr GetNextInboundTunnel (std::shared_ptr excluded = nullptr, + i2p::data::RouterInfo::CompatibleTransports compatible = i2p::data::RouterInfo::eAllTransports) const; std::shared_ptr GetNewOutboundTunnel (std::shared_ptr old) const; void TestTunnels (); void ManageTunnels (uint64_t ts); @@ -120,7 +122,8 @@ namespace tunnel void CreateOutboundTunnel (); void CreatePairedInboundTunnel (std::shared_ptr outboundTunnel); template - typename TTunnels::value_type GetNextTunnel (TTunnels& tunnels, typename TTunnels::value_type excluded) const; + typename TTunnels::value_type GetNextTunnel (TTunnels& tunnels, + typename TTunnels::value_type excluded, i2p::data::RouterInfo::CompatibleTransports compatible) const; bool SelectPeers (Path& path, bool isInbound); bool SelectExplicitPeers (Path& path, bool isInbound);