From c05f411ba077db64e691e512ab721a05ffe07564 Mon Sep 17 00:00:00 2001 From: "Francisco Blas (klondike) Izquierdo Riera" Date: Sat, 3 Jan 2015 02:07:55 +0100 Subject: [PATCH 1/3] Fix a memory leak in ClientConnection --- I2PTunnel.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/I2PTunnel.cpp b/I2PTunnel.cpp index d083ba6a..5a5b88f7 100644 --- a/I2PTunnel.cpp +++ b/I2PTunnel.cpp @@ -188,7 +188,9 @@ namespace client m_Acceptor.close(); m_Timer.cancel (); ClearConnections (); + auto *originalIdentHash = m_DestinationIdentHash; m_DestinationIdentHash = nullptr; + delete originalIdentHash; } void I2PClientTunnel::Accept () From 6489230e681e000d3242343d4ec994294321b6a6 Mon Sep 17 00:00:00 2001 From: "Francisco Blas (klondike) Izquierdo Riera" Date: Sat, 3 Jan 2015 02:17:01 +0100 Subject: [PATCH 2/3] Simplify and merge the identHash caching codepath on I2PClientTunnel --- I2PTunnel.cpp | 45 ++++++++++++++++++++++++--------------------- I2PTunnel.h | 1 + 2 files changed, 25 insertions(+), 21 deletions(-) diff --git a/I2PTunnel.cpp b/I2PTunnel.cpp index 5a5b88f7..3a2c846c 100644 --- a/I2PTunnel.cpp +++ b/I2PTunnel.cpp @@ -174,11 +174,7 @@ namespace client void I2PClientTunnel::Start () { - i2p::data::IdentHash identHash; - if (i2p::client::context.GetAddressBook ().GetIdentHash (m_Destination, identHash)) - m_DestinationIdentHash = new i2p::data::IdentHash (identHash); - if (!m_DestinationIdentHash) - LogPrint ("I2PTunnel unknown destination ", m_Destination); + GetIdentHash(); m_Acceptor.listen (); Accept (); } @@ -193,6 +189,21 @@ namespace client delete originalIdentHash; } + /* HACK: maybe we should create a caching IdentHash provider in AddressBook */ + const i2p::data::IdentHash * I2PClientTunnel::GetIdentHash () + { + if (!m_DestinationIdentHash) + { + i2p::data::IdentHash identHash; + if (i2p::client::context.GetAddressBook ().GetIdentHash (m_Destination, identHash)) + m_DestinationIdentHash = new i2p::data::IdentHash (identHash); + else + LogPrint ("Remote destination ", m_Destination, " not found"); + } + return m_DestinationIdentHash; + } + + void I2PClientTunnel::Accept () { auto newSocket = new boost::asio::ip::tcp::socket (GetService ()); @@ -204,31 +215,22 @@ namespace client { if (!ecode) { - if (!m_DestinationIdentHash) - { - i2p::data::IdentHash identHash; - if (i2p::client::context.GetAddressBook ().GetIdentHash (m_Destination, identHash)) - m_DestinationIdentHash = new i2p::data::IdentHash (identHash); - } - if (m_DestinationIdentHash) + const i2p::data::IdentHash *identHash = GetIdentHash(); + if (identHash) { // try to get a LeaseSet - m_RemoteLeaseSet = GetLocalDestination ()->FindLeaseSet (*m_DestinationIdentHash); + m_RemoteLeaseSet = GetLocalDestination ()->FindLeaseSet (*identHash); if (m_RemoteLeaseSet && m_RemoteLeaseSet->HasNonExpiredLeases ()) CreateConnection (socket); else { - GetLocalDestination ()->RequestDestination (*m_DestinationIdentHash, + GetLocalDestination ()->RequestDestination (*identHash, std::bind (&I2PClientTunnel::HandleLeaseSetRequestComplete, this, std::placeholders::_1, socket)); } - } + } else - { - LogPrint ("Remote destination ", m_Destination, " not found"); delete socket; - } - Accept (); } else @@ -239,9 +241,10 @@ namespace client { if (success) { - if (m_DestinationIdentHash) + const i2p::data::IdentHash *identHash = GetIdentHash(); + if (identHash) { - m_RemoteLeaseSet = GetLocalDestination ()->FindLeaseSet (*m_DestinationIdentHash); + m_RemoteLeaseSet = GetLocalDestination ()->FindLeaseSet (*identHash); CreateConnection (socket); return; } diff --git a/I2PTunnel.h b/I2PTunnel.h index 070641fd..d1ccbf38 100644 --- a/I2PTunnel.h +++ b/I2PTunnel.h @@ -88,6 +88,7 @@ namespace client private: + const i2p::data::IdentHash * GetIdentHash (); void Accept (); void HandleAccept (const boost::system::error_code& ecode, boost::asio::ip::tcp::socket * socket); void HandleLeaseSetRequestComplete (bool success, boost::asio::ip::tcp::socket * socket); From 1ae55e587272ba02ee52b60a193c616fbf3caf33 Mon Sep 17 00:00:00 2001 From: "Francisco Blas (klondike) Izquierdo Riera" Date: Sat, 3 Jan 2015 02:43:59 +0100 Subject: [PATCH 3/3] Use the new asynchronous API on I2PClientTunnel and clean up after ourselves --- I2PTunnel.cpp | 57 +++++++++++++++++++++------------------------------ I2PTunnel.h | 5 +++-- 2 files changed, 26 insertions(+), 36 deletions(-) diff --git a/I2PTunnel.cpp b/I2PTunnel.cpp index 3a2c846c..e0200da1 100644 --- a/I2PTunnel.cpp +++ b/I2PTunnel.cpp @@ -16,6 +16,13 @@ namespace client m_Stream = m_Owner->GetLocalDestination ()->CreateStream (*leaseSet); } + I2PTunnelConnection::I2PTunnelConnection (I2PTunnel * owner, + boost::asio::ip::tcp::socket * socket, std::shared_ptr stream): + m_Socket (socket), m_Stream (stream), m_Owner (owner), + m_RemoteEndpoint (socket->remote_endpoint ()), m_IsQuiet (true) + { + } + I2PTunnelConnection::I2PTunnelConnection (I2PTunnel * owner, std::shared_ptr stream, boost::asio::ip::tcp::socket * socket, const boost::asio::ip::tcp::endpoint& target, bool quiet): m_Socket (socket), m_Stream (stream), m_Owner (owner), m_RemoteEndpoint (target), m_IsQuiet (quiet) @@ -198,7 +205,7 @@ namespace client if (i2p::client::context.GetAddressBook ().GetIdentHash (m_Destination, identHash)) m_DestinationIdentHash = new i2p::data::IdentHash (identHash); else - LogPrint ("Remote destination ", m_Destination, " not found"); + LogPrint (eLogWarning,"Remote destination ", m_Destination, " not found"); } return m_DestinationIdentHash; } @@ -217,55 +224,37 @@ namespace client { const i2p::data::IdentHash *identHash = GetIdentHash(); if (identHash) - { - // try to get a LeaseSet - m_RemoteLeaseSet = GetLocalDestination ()->FindLeaseSet (*identHash); - if (m_RemoteLeaseSet && m_RemoteLeaseSet->HasNonExpiredLeases ()) - CreateConnection (socket); - else - { - GetLocalDestination ()->RequestDestination (*identHash, - std::bind (&I2PClientTunnel::HandleLeaseSetRequestComplete, - this, std::placeholders::_1, socket)); - } - } + GetLocalDestination ()->CreateStream ( + std::bind (&I2PClientTunnel::HandleStreamRequestComplete, + this, std::placeholders::_1, socket), *identHash); else + { + LogPrint (eLogError,"Closing socket"); delete socket; + } Accept (); } else - delete socket; - } - - void I2PClientTunnel::HandleLeaseSetRequestComplete (bool success, boost::asio::ip::tcp::socket * socket) - { - if (success) { - const i2p::data::IdentHash *identHash = GetIdentHash(); - if (identHash) - { - m_RemoteLeaseSet = GetLocalDestination ()->FindLeaseSet (*identHash); - CreateConnection (socket); - return; - } + LogPrint (eLogError,"Closing socket on accept because: ", ecode.message ()); + delete socket; } - delete socket; } - void I2PClientTunnel::CreateConnection (boost::asio::ip::tcp::socket * socket) + void I2PClientTunnel::HandleStreamRequestComplete (std::shared_ptr stream, boost::asio::ip::tcp::socket * socket) { - if (m_RemoteLeaseSet) // leaseSet found - { - LogPrint ("New I2PTunnel connection"); - auto connection = std::make_shared(this, socket, m_RemoteLeaseSet); + if (stream) + { + LogPrint (eLogInfo,"New I2PTunnel connection"); + auto connection = std::make_shared(this, socket, stream); AddConnection (connection); connection->I2PConnect (); } else { - LogPrint ("LeaseSet for I2PTunnel destination not found"); + LogPrint (eLogError,"Issue when creating the stream, check the previous warnings for more info."); delete socket; - } + } } I2PServerTunnel::I2PServerTunnel (const std::string& address, int port, ClientDestination * localDestination): diff --git a/I2PTunnel.h b/I2PTunnel.h index d1ccbf38..a6748ced 100644 --- a/I2PTunnel.h +++ b/I2PTunnel.h @@ -26,6 +26,8 @@ namespace client I2PTunnelConnection (I2PTunnel * owner, boost::asio::ip::tcp::socket * socket, const i2p::data::LeaseSet * leaseSet); // to I2P + I2PTunnelConnection (I2PTunnel * owner, boost::asio::ip::tcp::socket * socket, + std::shared_ptr stream); // to I2P using simplified API :) I2PTunnelConnection (I2PTunnel * owner, std::shared_ptr stream, boost::asio::ip::tcp::socket * socket, const boost::asio::ip::tcp::endpoint& target, bool quiet = true); // from I2P ~I2PTunnelConnection (); @@ -91,8 +93,7 @@ namespace client const i2p::data::IdentHash * GetIdentHash (); void Accept (); void HandleAccept (const boost::system::error_code& ecode, boost::asio::ip::tcp::socket * socket); - void HandleLeaseSetRequestComplete (bool success, boost::asio::ip::tcp::socket * socket); - void CreateConnection (boost::asio::ip::tcp::socket * socket); + void HandleStreamRequestComplete (std::shared_ptr stream, boost::asio::ip::tcp::socket * socket); private: