bind NTCP2 connections to specified address

This commit is contained in:
orignal 2021-02-26 19:31:38 -05:00
parent 2cdf84cdab
commit a4e8bf9857
4 changed files with 79 additions and 2 deletions

View File

@ -50,7 +50,9 @@ namespace config {
("nat", bool_switch()->default_value(true), "Should we assume we are behind NAT? (default: enabled)")
("port", value<uint16_t>()->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<std::string>()->default_value(""), "Local address to bind ipv4 transport sockets to")
("ipv6", bool_switch()->default_value(false), "Enable communication through ipv6 (default: disabled)")
("address6", value<std::string>()->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<int>()->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<bool>()->default_value(true), "Enable NTCP2 (default: enabled)")
("ntcp2.published", value<bool>()->default_value(true), "Publish NTCP2 (default: enabled)")
("ntcp2.port", value<uint16_t>()->default_value(0), "Port to listen for incoming NTCP2 connections (default: auto)")
("ntcp2.addressv6", value<std::string>()->default_value("::"), "Address to bind NTCP2 on")
("ntcp2.addressv6", value<std::string>()->default_value("::"), "Address to publish NTCP2 with")
("ntcp2.proxy", value<std::string>()->default_value(""), "Proxy URL for NTCP2 transport")
;

View File

@ -1291,6 +1291,24 @@ namespace transport
conn->Terminate ();
}
});
// bind to local address
std::shared_ptr<boost::asio::ip::tcp::endpoint> 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>(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;
}
}
}

View File

@ -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<NTCP2Session> 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<boost::asio::ip::tcp::endpoint> m_ProxyEndpoint;
std::shared_ptr<boost::asio::ip::tcp::endpoint> m_Address4, m_Address6, m_YggdrasilAddress;
public:
// for HTTP/I2PControl

View File

@ -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)