From aca87b5fd1858c0455acab14836eddf60ff52930 Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 26 Nov 2014 13:20:35 -0500 Subject: [PATCH] remember last outgoing tunnel per stream rather than per client destination --- Datagram.cpp | 10 +++++++--- Destination.cpp | 22 +++------------------- Destination.h | 4 ---- Streaming.cpp | 24 +++++++++++++++--------- Streaming.h | 1 + 5 files changed, 26 insertions(+), 35 deletions(-) diff --git a/Datagram.cpp b/Datagram.cpp index 279a3033..d242891a 100644 --- a/Datagram.cpp +++ b/Datagram.cpp @@ -46,8 +46,9 @@ namespace datagram void DatagramDestination::SendMsg (I2NPMessage * msg, const i2p::data::LeaseSet& remote) { + auto outboundTunnel = m_Owner.GetTunnelPool ()->GetNextOutboundTunnel (); auto leases = remote.GetNonExpiredLeases (); - if (!leases.empty ()) + if (!leases.empty () && outboundTunnel) { std::vector msgs; uint32_t i = i2p::context.GetRandomNumberGenerator ().GenerateWord32 (0, leases.size () - 1); @@ -58,11 +59,14 @@ namespace datagram leases[i].tunnelGateway, leases[i].tunnelID, garlic }); - m_Owner.SendTunnelDataMsgs (msgs); + outboundTunnel->SendTunnelDataMsg (msgs); } else { - LogPrint (eLogWarning, "Failed to send datagram. All leases expired"); + if (outboundTunnel) + LogPrint (eLogWarning, "Failed to send datagram. All leases expired"); + else + LogPrint (eLogWarning, "Failed to send datagram. No outbound tunnels"); DeleteI2NPMessage (msg); } } diff --git a/Destination.cpp b/Destination.cpp index bfb0659e..8000a483 100644 --- a/Destination.cpp +++ b/Destination.cpp @@ -12,8 +12,7 @@ namespace client { ClientDestination::ClientDestination (bool isPublic, i2p::data::SigningKeyType sigType): m_IsRunning (false), m_Thread (nullptr), m_Service (nullptr), m_Work (nullptr), - m_CurrentOutboundTunnel (nullptr), m_LeaseSet (nullptr), m_IsPublic (isPublic), - m_DatagramDestination (nullptr) + m_LeaseSet (nullptr), m_IsPublic (isPublic), m_DatagramDestination (nullptr) { m_Keys = i2p::data::PrivateKeys::CreateRandomKeys (sigType); CryptoPP::DH dh (i2p::crypto::elgp, i2p::crypto::elgg); @@ -26,8 +25,7 @@ namespace client ClientDestination::ClientDestination (const std::string& fullPath, bool isPublic): m_IsRunning (false), m_Thread (nullptr), m_Service (nullptr), m_Work (nullptr), - m_CurrentOutboundTunnel (nullptr), m_LeaseSet (nullptr), m_IsPublic (isPublic), - m_DatagramDestination (nullptr) + m_LeaseSet (nullptr), m_IsPublic (isPublic), m_DatagramDestination (nullptr) { std::ifstream s(fullPath.c_str (), std::ifstream::binary); if (s.is_open ()) @@ -63,8 +61,7 @@ namespace client ClientDestination::ClientDestination (const i2p::data::PrivateKeys& keys, bool isPublic): m_IsRunning (false), m_Thread (nullptr), m_Service (nullptr), m_Work (nullptr), - m_Keys (keys), m_CurrentOutboundTunnel (nullptr), m_LeaseSet (nullptr), m_IsPublic (isPublic), - m_DatagramDestination (nullptr) + m_Keys (keys), m_LeaseSet (nullptr), m_IsPublic (isPublic), m_DatagramDestination (nullptr) { CryptoPP::DH dh (i2p::crypto::elgp, i2p::crypto::elgg); dh.GenerateKeyPair(i2p::context.GetRandomNumberGenerator (), m_EncryptionPrivateKey, m_EncryptionPublicKey); @@ -175,19 +172,6 @@ namespace client } } - void ClientDestination::SendTunnelDataMsgs (const std::vector& msgs) - { - m_CurrentOutboundTunnel = m_Pool->GetNextOutboundTunnel (m_CurrentOutboundTunnel); - if (m_CurrentOutboundTunnel) - m_CurrentOutboundTunnel->SendTunnelDataMsg (msgs); - else - { - LogPrint ("No outbound tunnels in the pool"); - for (auto it: msgs) - DeleteI2NPMessage (it.data); - } - } - void ClientDestination::ProcessGarlicMessage (I2NPMessage * msg) { m_Service->post (std::bind (&ClientDestination::HandleGarlicMessage, this, msg)); diff --git a/Destination.h b/Destination.h index cab024ac..ec70865e 100644 --- a/Destination.h +++ b/Destination.h @@ -35,10 +35,7 @@ namespace client boost::asio::io_service * GetService () { return m_Service; }; i2p::tunnel::TunnelPool * GetTunnelPool () { return m_Pool; }; bool IsReady () const { return m_LeaseSet && m_LeaseSet->HasNonExpiredLeases (); }; - - void ResetCurrentOutboundTunnel () { m_CurrentOutboundTunnel = nullptr; }; const i2p::data::LeaseSet * FindLeaseSet (const i2p::data::IdentHash& ident); - void SendTunnelDataMsgs (const std::vector& msgs); // streaming i2p::stream::StreamingDestination * GetStreamingDestination () const { return m_StreamingDestination; }; @@ -85,7 +82,6 @@ namespace client std::map m_RemoteLeaseSets; i2p::tunnel::TunnelPool * m_Pool; - i2p::tunnel::OutboundTunnel * m_CurrentOutboundTunnel; i2p::data::LeaseSet * m_LeaseSet; bool m_IsPublic; diff --git a/Streaming.cpp b/Streaming.cpp index 78a8f399..1aba822f 100644 --- a/Streaming.cpp +++ b/Streaming.cpp @@ -15,9 +15,9 @@ namespace stream const i2p::data::LeaseSet& remote, int port): m_Service (service), m_SendStreamID (0), m_SequenceNumber (0), m_LastReceivedSequenceNumber (-1), m_IsOpen (false), m_IsReset (false), m_IsAckSendScheduled (false), m_LocalDestination (local), - m_RemoteLeaseSet (&remote), m_RoutingSession (nullptr), m_ReceiveTimer (m_Service), - m_ResendTimer (m_Service), m_AckSendTimer (m_Service), m_NumSentBytes (0), - m_NumReceivedBytes (0), m_Port (port) + m_RemoteLeaseSet (&remote), m_RoutingSession (nullptr), m_CurrentOutboundTunnel (nullptr), + m_ReceiveTimer (m_Service), m_ResendTimer (m_Service), m_AckSendTimer (m_Service), + m_NumSentBytes (0), m_NumReceivedBytes (0), m_Port (port) { m_RecvStreamID = i2p::context.GetRandomNumberGenerator ().GenerateWord32 (); UpdateCurrentRemoteLease (); @@ -26,9 +26,9 @@ namespace stream Stream::Stream (boost::asio::io_service& service, StreamingDestination& local): m_Service (service), m_SendStreamID (0), m_SequenceNumber (0), m_LastReceivedSequenceNumber (-1), m_IsOpen (false), m_IsReset (false), m_IsAckSendScheduled (false), m_LocalDestination (local), - m_RemoteLeaseSet (nullptr), m_RoutingSession (nullptr), m_ReceiveTimer (m_Service), - m_ResendTimer (m_Service), m_AckSendTimer (m_Service), m_NumSentBytes (0), - m_NumReceivedBytes (0), m_Port (0) + m_RemoteLeaseSet (nullptr), m_RoutingSession (nullptr), m_CurrentOutboundTunnel (nullptr), + m_ReceiveTimer (m_Service), m_ResendTimer (m_Service), m_AckSendTimer (m_Service), + m_NumSentBytes (0), m_NumReceivedBytes (0), m_Port (0) { m_RecvStreamID = i2p::context.GetRandomNumberGenerator ().GenerateWord32 (); } @@ -116,7 +116,7 @@ namespace stream { // we have received duplicate. Most likely our outbound tunnel is dead LogPrint ("Duplicate message ", receivedSeqn, " received"); - m_LocalDestination.GetOwner ().ResetCurrentOutboundTunnel (); // pick another outbound tunnel + m_CurrentOutboundTunnel = nullptr; // pick another outbound tunnel UpdateCurrentRemoteLease (); // pick another lease SendQuickAck (); // resend ack for previous message again delete packet; // packet dropped @@ -432,6 +432,12 @@ namespace stream return; } } + m_CurrentOutboundTunnel = m_LocalDestination.GetOwner ().GetTunnelPool ()->GetNextOutboundTunnel (m_CurrentOutboundTunnel); + if (!m_CurrentOutboundTunnel) + { + LogPrint ("No outbound tunnels in the pool"); + return; + } auto ts = i2p::util::GetMillisecondsSinceEpoch (); if (ts >= m_CurrentRemoteLease.endDate) @@ -450,7 +456,7 @@ namespace stream }); m_NumSentBytes += it->GetLength (); } - m_LocalDestination.GetOwner ().SendTunnelDataMsgs (msgs); + m_CurrentOutboundTunnel->SendTunnelDataMsg (msgs); } else LogPrint ("All leases are expired"); @@ -484,7 +490,7 @@ namespace stream } if (packets.size () > 0) { - m_LocalDestination.GetOwner ().ResetCurrentOutboundTunnel (); // pick another outbound tunnel + m_CurrentOutboundTunnel = nullptr; // pick another outbound tunnel UpdateCurrentRemoteLease (); // pick another lease SendPackets (packets); } diff --git a/Streaming.h b/Streaming.h index ba9a40f7..8c43b7c5 100644 --- a/Streaming.h +++ b/Streaming.h @@ -141,6 +141,7 @@ namespace stream const i2p::data::LeaseSet * m_RemoteLeaseSet; i2p::garlic::GarlicRoutingSession * m_RoutingSession; i2p::data::Lease m_CurrentRemoteLease; + i2p::tunnel::OutboundTunnel * m_CurrentOutboundTunnel; std::queue m_ReceiveQueue; std::set m_SavedPackets; std::set m_SentPackets;