From f2434d66fc2aae0555741fe8db5357c553f38470 Mon Sep 17 00:00:00 2001 From: orignal Date: Mon, 27 Oct 2014 15:08:50 -0400 Subject: [PATCH] incoming ipv6 connections --- HTTPServer.cpp | 5 ++++- NTCPSession.cpp | 2 ++ README.md | 1 + RouterContext.cpp | 30 ++++++++++++++++++++++++++++++ RouterContext.h | 4 +++- Transports.cpp | 33 ++++++++++++++++++++++++++++++++- Transports.h | 3 ++- 7 files changed, 74 insertions(+), 4 deletions(-) diff --git a/HTTPServer.cpp b/HTTPServer.cpp index 35ef512c..57656334 100644 --- a/HTTPServer.cpp +++ b/HTTPServer.cpp @@ -644,7 +644,10 @@ namespace util switch (address.transportStyle) { case i2p::data::RouterInfo::eTransportNTCP: - s << "NTCP  "; + if (address.host.is_v6 ()) + s << "NTCP6  "; + else + s << "NTCP  "; break; case i2p::data::RouterInfo::eTransportSSU: s << "SSU     "; diff --git a/NTCPSession.cpp b/NTCPSession.cpp index 8f6faa4b..c75755b3 100644 --- a/NTCPSession.cpp +++ b/NTCPSession.cpp @@ -623,6 +623,8 @@ namespace transport else { LogPrint ("Connected"); + if (GetSocket ().local_endpoint ().protocol () == boost::asio::ip::tcp::v6()) // ipv6 + context.UpdateV6Address (GetSocket ().local_endpoint ().address ().to_string ()); ClientLogin (); } } diff --git a/README.md b/README.md index b9da1f3e..395500c3 100644 --- a/README.md +++ b/README.md @@ -51,6 +51,7 @@ Options * --daemon= - Enable or disable daemon mode. 1 for yes, 0 for no. * --service= - 1 if uses system folders (/var/run/i2pd.pid, /var/log/i2pd.log, /var/lib/i2pd). * --unreachable= - 1 if router is declared as unreachable and works through introducers. +* --v6= - 1 if supports communication through ipv6, off by default * --httpproxyport= - The port to listen on (HTTP Proxy) * --socksproxyport= - The port to listen on (SOCKS Proxy) * --ircport= - The local port of IRC tunnel to listen on. 6668 by default diff --git a/RouterContext.cpp b/RouterContext.cpp index 8832e81e..65905196 100644 --- a/RouterContext.cpp +++ b/RouterContext.cpp @@ -138,6 +138,36 @@ namespace i2p else m_RouterInfo.DisableV6 (); } + + void RouterContext::UpdateV6Address (const std::string& host) + { + bool updated = false, found = false; + int port = 0; + auto newAddress = boost::asio::ip::address::from_string (host); + auto& addresses = m_RouterInfo.GetAddresses (); + for (auto& addr : addresses) + { + if (addr.host.is_v6 ()) + { + if (addr.host != newAddress) + { + addr.host = newAddress; + updated = true; + } + found = true; + } + else + port = addr.port; + } + if (!found) + { + // create new address + m_RouterInfo.AddNTCPAddress (host.c_str (), port); + updated = true; + } + if (updated) + UpdateRouterInfo (); + } bool RouterContext::Load () { diff --git a/RouterContext.h b/RouterContext.h index 35f11e2d..e2e5b24e 100644 --- a/RouterContext.h +++ b/RouterContext.h @@ -2,6 +2,7 @@ #define ROUTER_CONTEXT_H__ #include +#include #include #include #include "Identity.h" @@ -34,7 +35,8 @@ namespace i2p void SetAcceptsTunnels (bool acceptsTunnels) { m_AcceptsTunnels = acceptsTunnels; }; bool SupportsV6 () const { return m_RouterInfo.IsV6 (); }; void SetSupportsV6 (bool supportsV6); - + void UpdateV6Address (const std::string& host); // called from NTCP session + // implements LocalDestination const i2p::data::PrivateKeys& GetPrivateKeys () const { return m_Keys; }; const uint8_t * GetEncryptionPrivateKey () const { return m_Keys.GetPrivateKey (); }; diff --git a/Transports.cpp b/Transports.cpp index cfe368e7..c0c7bfca 100644 --- a/Transports.cpp +++ b/Transports.cpp @@ -96,7 +96,7 @@ namespace transport Transports transports; Transports::Transports (): - m_Thread (nullptr), m_Work (m_Service), m_NTCPAcceptor (nullptr), + m_Thread (nullptr), m_Work (m_Service), m_NTCPAcceptor (nullptr), m_NTCPV6Acceptor (nullptr), m_SSUServer (nullptr), m_DHKeysPairSupplier (5) // 5 pre-generated keys { } @@ -124,6 +124,17 @@ namespace transport auto conn = new NTCPServerConnection (m_Service); m_NTCPAcceptor->async_accept(conn->GetSocket (), boost::bind (&Transports::HandleAccept, this, conn, boost::asio::placeholders::error)); + + if (context.SupportsV6 ()) + { + m_NTCPV6Acceptor = new boost::asio::ip::tcp::acceptor (m_Service, + boost::asio::ip::tcp::endpoint(boost::asio::ip::tcp::v6(), address.port)); + + LogPrint ("Start listening V6 TCP port ", address.port); + auto conn = new NTCPServerConnection (m_Service); + m_NTCPV6Acceptor->async_accept(conn->GetSocket (), boost::bind (&Transports::HandleAcceptV6, + this, conn, boost::asio::placeholders::error)); + } } else if (address.transportStyle == RouterInfo::eTransportSSU) { @@ -154,6 +165,8 @@ namespace transport m_NTCPSessions.clear (); delete m_NTCPAcceptor; m_NTCPAcceptor = nullptr; + delete m_NTCPV6Acceptor; + m_NTCPV6Acceptor = nullptr; m_DHKeysPairSupplier.Stop (); m_IsRunning = false; @@ -211,6 +224,24 @@ namespace transport } } + void Transports::HandleAcceptV6 (NTCPServerConnection * conn, const boost::system::error_code& error) + { + if (!error) + { + LogPrint ("Connected from ", conn->GetSocket ().remote_endpoint().address ().to_string ()); + conn->ServerLogin (); + } + else + delete conn; + + if (error != boost::asio::error::operation_aborted) + { + conn = new NTCPServerConnection (m_Service); + m_NTCPV6Acceptor->async_accept(conn->GetSocket (), boost::bind (&Transports::HandleAcceptV6, this, + conn, boost::asio::placeholders::error)); + } + } + NTCPSession * Transports::GetNextNTCPSession () { for (auto session: m_NTCPSessions) diff --git a/Transports.h b/Transports.h index c795c2b4..d306de77 100644 --- a/Transports.h +++ b/Transports.h @@ -76,6 +76,7 @@ namespace transport void Run (); void HandleAccept (NTCPServerConnection * conn, const boost::system::error_code& error); + void HandleAcceptV6 (NTCPServerConnection * conn, const boost::system::error_code& error); void HandleResendTimer (const boost::system::error_code& ecode, boost::asio::deadline_timer * timer, const i2p::data::IdentHash& ident, i2p::I2NPMessage * msg); void PostMessage (const i2p::data::IdentHash& ident, i2p::I2NPMessage * msg); @@ -89,7 +90,7 @@ namespace transport std::thread * m_Thread; boost::asio::io_service m_Service; boost::asio::io_service::work m_Work; - boost::asio::ip::tcp::acceptor * m_NTCPAcceptor; + boost::asio::ip::tcp::acceptor * m_NTCPAcceptor, * m_NTCPV6Acceptor; std::map m_NTCPSessions; SSUServer * m_SSUServer;