From 616f0b2a21c3b96b900ae01e2c44f2639f35871e Mon Sep 17 00:00:00 2001 From: orignal Date: Fri, 19 Feb 2021 15:15:58 -0500 Subject: [PATCH] address parameter for server tunnels --- libi2pd_client/ClientContext.cpp | 3 ++- libi2pd_client/I2PTunnel.cpp | 27 ++++++++++++++++++++++++++- libi2pd_client/I2PTunnel.h | 6 +++++- 3 files changed, 33 insertions(+), 3 deletions(-) diff --git a/libi2pd_client/ClientContext.cpp b/libi2pd_client/ClientContext.cpp index cac472f9..eb35b403 100644 --- a/libi2pd_client/ClientContext.cpp +++ b/libi2pd_client/ClientContext.cpp @@ -750,12 +750,13 @@ namespace client else // regular server tunnel by default serverTunnel = std::make_shared (name, host, port, localDestination, inPort, gzip); + if (!address.empty ()) + serverTunnel->SetLocalAddress (address); if(!isUniqueLocal) { LogPrint(eLogInfo, "Clients: disabling loopback address mapping"); serverTunnel->SetUniqueLocal(isUniqueLocal); } - if (accessList.length () > 0) { std::set idents; diff --git a/libi2pd_client/I2PTunnel.cpp b/libi2pd_client/I2PTunnel.cpp index 61c42b24..4cf1031d 100644 --- a/libi2pd_client/I2PTunnel.cpp +++ b/libi2pd_client/I2PTunnel.cpp @@ -107,6 +107,18 @@ namespace client } } + void I2PTunnelConnection::Connect (const boost::asio::ip::address& localAddress) + { + if (m_Socket) + { + boost::system::error_code ec; + m_Socket->bind (boost::asio::ip::tcp::endpoint (localAddress, 0), ec); + if (ec) + LogPrint (eLogError, "I2PTunnel: can't bind to ", localAddress.to_string (), ": ", ec.message ()); + } + Connect (false); + } + void I2PTunnelConnection::Terminate () { if (Kill()) return; @@ -600,6 +612,16 @@ namespace client m_IsAccessList = true; } + void I2PServerTunnel::SetLocalAddress (const std::string& localAddress) + { + boost::system::error_code ec; + auto addr = boost::asio::ip::address::from_string(localAddress, ec); + if (!ec) + m_LocalAddress.reset (new boost::asio::ip::address (addr)); + else + LogPrint (eLogError, "I2PTunnel: can't set local address ", localAddress); + } + void I2PServerTunnel::Accept () { if (m_PortDestination) @@ -631,7 +653,10 @@ namespace client // new connection auto conn = CreateI2PConnection (stream); AddHandler (conn); - conn->Connect (m_IsUniqueLocal); + if (m_LocalAddress) + conn->Connect (*m_LocalAddress); + else + conn->Connect (m_IsUniqueLocal); } } diff --git a/libi2pd_client/I2PTunnel.h b/libi2pd_client/I2PTunnel.h index f7185dfd..3b52ea1a 100644 --- a/libi2pd_client/I2PTunnel.h +++ b/libi2pd_client/I2PTunnel.h @@ -48,7 +48,8 @@ namespace client ~I2PTunnelConnection (); void I2PConnect (const uint8_t * msg = nullptr, size_t len = 0); void Connect (bool isUniqueLocal = true); - + void Connect (const boost::asio::ip::address& localAddress); + protected: void Terminate (); @@ -314,6 +315,8 @@ namespace client void SetUniqueLocal (bool isUniqueLocal) { m_IsUniqueLocal = isUniqueLocal; } bool IsUniqueLocal () const { return m_IsUniqueLocal; } + void SetLocalAddress (const std::string& localAddress); + const std::string& GetAddress() const { return m_Address; } int GetPort () const { return m_Port; }; uint16_t GetLocalPort () const { return m_PortDestination->GetLocalPort (); }; @@ -339,6 +342,7 @@ namespace client std::shared_ptr m_PortDestination; std::set m_AccessList; bool m_IsAccessList; + std::unique_ptr m_LocalAddress; }; class I2PServerTunnelHTTP: public I2PServerTunnel