From a4e8bf985798b43fae5aa87e4fff8f2a21b9810d Mon Sep 17 00:00:00 2001 From: orignal Date: Fri, 26 Feb 2021 19:31:38 -0500 Subject: [PATCH] bind NTCP2 connections to specified address --- libi2pd/Config.cpp | 4 +++- libi2pd/NTCP2.cpp | 32 ++++++++++++++++++++++++++++++++ libi2pd/NTCP2.h | 5 ++++- libi2pd/Transports.cpp | 40 ++++++++++++++++++++++++++++++++++++++++ 4 files changed, 79 insertions(+), 2 deletions(-) diff --git a/libi2pd/Config.cpp b/libi2pd/Config.cpp index 9da0bbe0..cc79c87c 100644 --- a/libi2pd/Config.cpp +++ b/libi2pd/Config.cpp @@ -50,7 +50,9 @@ namespace config { ("nat", bool_switch()->default_value(true), "Should we assume we are behind NAT? (default: enabled)") ("port", value()->default_value(0), "Port to listen for incoming connections (default: auto)") ("ipv4", bool_switch()->default_value(true), "Enable communication through ipv4 (default: enabled)") + ("address4", value()->default_value(""), "Local address to bind ipv4 transport sockets to") ("ipv6", bool_switch()->default_value(false), "Enable communication through ipv6 (default: disabled)") + ("address6", value()->default_value(""), "Local address to bind ipv6 transport sockets to") ("reservedrange", bool_switch()->default_value(true), "Check remote RI for being in blacklist of reserved IP ranges (default: enabled)") ("netid", value()->default_value(I2PD_NET_ID), "Specify NetID. Main I2P is 2") ("daemon", bool_switch()->default_value(false), "Router will go to background after start (default: disabled)") @@ -247,7 +249,7 @@ namespace config { ("ntcp2.enabled", value()->default_value(true), "Enable NTCP2 (default: enabled)") ("ntcp2.published", value()->default_value(true), "Publish NTCP2 (default: enabled)") ("ntcp2.port", value()->default_value(0), "Port to listen for incoming NTCP2 connections (default: auto)") - ("ntcp2.addressv6", value()->default_value("::"), "Address to bind NTCP2 on") + ("ntcp2.addressv6", value()->default_value("::"), "Address to publish NTCP2 with") ("ntcp2.proxy", value()->default_value(""), "Proxy URL for NTCP2 transport") ; diff --git a/libi2pd/NTCP2.cpp b/libi2pd/NTCP2.cpp index 61e766ea..078c5045 100644 --- a/libi2pd/NTCP2.cpp +++ b/libi2pd/NTCP2.cpp @@ -1291,6 +1291,24 @@ namespace transport conn->Terminate (); } }); + // bind to local address + std::shared_ptr localAddress; + if (conn->GetRemoteEndpoint ().address ().is_v6 ()) + { + if (i2p::util::net::IsYggdrasilAddress (conn->GetRemoteEndpoint ().address ())) + localAddress = m_YggdrasilAddress; + else + localAddress = m_Address6; + } + else + localAddress = m_Address4; + if (localAddress) + { + boost::system::error_code ec; + conn->GetSocket ().bind (*localAddress, ec); + if (ec) + LogPrint (eLogError, "NTCP2: can't bind to ", localAddress->address ().to_string (), ": ", ec.message ()); + } conn->GetSocket ().async_connect (conn->GetRemoteEndpoint (), std::bind (&NTCP2Server::HandleConnect, this, std::placeholders::_1, conn, timer)); } else @@ -1631,5 +1649,19 @@ namespace transport conn->Terminate(); }); } + + void NTCP2Server::SetLocalAddress (const boost::asio::ip::address& localAddress) + { + auto addr = std::make_shared(boost::asio::ip::tcp::endpoint(localAddress, 0)); + if (localAddress.is_v6 ()) + { + if (i2p::util::net::IsYggdrasilAddress (localAddress)) + m_YggdrasilAddress = addr; + else + m_Address6 = addr; + } + else + m_Address4 = addr; + } } } diff --git a/libi2pd/NTCP2.h b/libi2pd/NTCP2.h index c3909225..23b619e8 100644 --- a/libi2pd/NTCP2.h +++ b/libi2pd/NTCP2.h @@ -248,6 +248,8 @@ namespace transport bool UsingProxy() const { return m_ProxyType != eNoProxy; }; void UseProxy(ProxyType proxy, const std::string & address, uint16_t port); + void SetLocalAddress (const boost::asio::ip::address& localAddress); + private: void HandleAccept (std::shared_ptr conn, const boost::system::error_code& error); @@ -273,7 +275,8 @@ namespace transport uint16_t m_ProxyPort; boost::asio::ip::tcp::resolver m_Resolver; std::unique_ptr m_ProxyEndpoint; - + std::shared_ptr m_Address4, m_Address6, m_YggdrasilAddress; + public: // for HTTP/I2PControl diff --git a/libi2pd/Transports.cpp b/libi2pd/Transports.cpp index 5848fd16..09b0991a 100644 --- a/libi2pd/Transports.cpp +++ b/libi2pd/Transports.cpp @@ -205,6 +205,46 @@ namespace transport } } + // bind to interfaces + bool ipv4; i2p::config::GetOption("ipv4", ipv4); + if (ipv4) + { + std::string address; i2p::config::GetOption("address4", address); + if (!address.empty ()) + { + boost::system::error_code ec; + auto addr = boost::asio::ip::address::from_string (address, ec); + if (!ec && m_NTCP2Server) + m_NTCP2Server->SetLocalAddress (addr); + } + } + + bool ipv6; i2p::config::GetOption("ipv6", ipv6); + if (ipv6) + { + std::string address; i2p::config::GetOption("address6", address); + if (!address.empty ()) + { + boost::system::error_code ec; + auto addr = boost::asio::ip::address::from_string (address, ec); + if (!ec && m_NTCP2Server) + m_NTCP2Server->SetLocalAddress (addr); + } + } + + bool ygg; i2p::config::GetOption("meshnets.yggdrasil", ygg); + if (ygg) + { + std::string address; i2p::config::GetOption("meshnets.yggdrasil", address); + if (!address.empty ()) + { + boost::system::error_code ec; + auto addr = boost::asio::ip::address::from_string (address, ec); + if (!ec && m_NTCP2Server && i2p::util::net::IsYggdrasilAddress (addr)) + m_NTCP2Server->SetLocalAddress (addr); + } + } + // create acceptors auto& addresses = context.GetRouterInfo ().GetAddresses (); for (const auto& address : addresses)