From 9b6c229b7138bf5bc1a0bf9c25f721bf1333d311 Mon Sep 17 00:00:00 2001 From: orignal Date: Fri, 8 Jul 2016 14:17:41 -0400 Subject: [PATCH] remember tunnels selection for following messages --- Garlic.cpp | 15 ++++++++++++--- Garlic.h | 1 + I2CP.cpp | 44 ++++++++++++++++++++++++++++++++++++-------- 3 files changed, 49 insertions(+), 11 deletions(-) diff --git a/Garlic.cpp b/Garlic.cpp index dc29cc5b..d48e9d94 100644 --- a/Garlic.cpp +++ b/Garlic.cpp @@ -125,6 +125,14 @@ namespace garlic else it++; } + CleanupUnconfirmedTags (); + return !m_SessionTags.empty () || !m_UnconfirmedTagsMsgs.empty (); + } + + bool GarlicRoutingSession::CleanupUnconfirmedTags () + { + bool ret = false; + uint32_t ts = i2p::util::GetSecondsSinceEpoch (); // delete expired unconfirmed tags for (auto it = m_UnconfirmedTagsMsgs.begin (); it != m_UnconfirmedTagsMsgs.end ();) { @@ -133,12 +141,13 @@ namespace garlic if (m_Owner) m_Owner->RemoveDeliveryStatusSession ((*it)->msgID); it = m_UnconfirmedTagsMsgs.erase (it); + ret = true; } else it++; } - return !m_SessionTags.empty () || !m_UnconfirmedTagsMsgs.empty (); - } + return ret; + } std::shared_ptr GarlicRoutingSession::WrapSingleMessage (std::shared_ptr msg) { @@ -625,7 +634,7 @@ namespace garlic it++; } } - + void GarlicDestination::RemoveDeliveryStatusSession (uint32_t msgID) { m_DeliveryStatusSessions.erase (msgID); diff --git a/Garlic.h b/Garlic.h index 21acf561..6a92b94a 100644 --- a/Garlic.h +++ b/Garlic.h @@ -98,6 +98,7 @@ namespace garlic std::shared_ptr WrapSingleMessage (std::shared_ptr msg); void MessageConfirmed (uint32_t msgID); bool CleanupExpiredTags (); // returns true if something left + bool CleanupUnconfirmedTags (); // returns true if something has been deleted void SetLeaseSetUpdated () { diff --git a/I2CP.cpp b/I2CP.cpp index 061f220c..0867d719 100644 --- a/I2CP.cpp +++ b/I2CP.cpp @@ -87,23 +87,51 @@ namespace client } bool I2CPDestination::SendMsg (std::shared_ptr msg, std::shared_ptr remote) - { - auto outboundTunnel = GetTunnelPool ()->GetNextOutboundTunnel (); - auto leases = remote->GetNonExpiredLeases (); - if (!leases.empty () && outboundTunnel) + { + auto remoteSession = GetRoutingSession (remote, true); + if (!remoteSession) + { + LogPrint (eLogError, "I2CP: Failed to create remote session"); + return false; + } + auto path = remoteSession->GetSharedRoutingPath (); + std::shared_ptr outboundTunnel; + std::shared_ptr remoteLease; + if (path) + { + if (!remoteSession->CleanupUnconfirmedTags ()) // no stuck tags + { + outboundTunnel = path->outboundTunnel; + remoteLease = path->remoteLease; + } + else + remoteSession->SetSharedRoutingPath (nullptr); + } + else + { + auto outboundTunnel = GetTunnelPool ()->GetNextOutboundTunnel (); + auto leases = remote->GetNonExpiredLeases (); + if (!leases.empty ()) + remoteLease = leases[rand () % leases.size ()]; + if (remoteLease && outboundTunnel) + remoteSession->SetSharedRoutingPath (std::make_shared ( + i2p::garlic::GarlicRoutingPath{outboundTunnel, remoteLease, 10000, 0, 0})); // 10 secs RTT + else + remoteSession->SetSharedRoutingPath (nullptr); + } + if (remoteLease && outboundTunnel) { std::vector msgs; - uint32_t i = rand () % leases.size (); - auto garlic = WrapMessage (remote, msg, true); + auto garlic = remoteSession->WrapSingleMessage (msg); msgs.push_back (i2p::tunnel::TunnelMessageBlock { i2p::tunnel::eDeliveryTypeTunnel, - leases[i]->tunnelGateway, leases[i]->tunnelID, + remoteLease->tunnelGateway, remoteLease->tunnelID, garlic }); outboundTunnel->SendTunnelDataMsg (msgs); return true; - } + } else { if (outboundTunnel)