From 8403c17c59f8d6f56843739e5e9e82622611c9a5 Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 29 Oct 2014 15:02:48 -0400 Subject: [PATCH] incoming SSU V6 sessions --- SSU.cpp | 58 +++++++++++++++++++++++++++++++++++++++----------- SSU.h | 13 ++++++----- Transports.cpp | 4 ++-- 3 files changed, 55 insertions(+), 20 deletions(-) diff --git a/SSU.cpp b/SSU.cpp index 72f7ba1b..404021e2 100644 --- a/SSU.cpp +++ b/SSU.cpp @@ -1010,11 +1010,19 @@ namespace transport SSUServer::SSUServer (int port): m_Thread (nullptr), m_Work (m_Service), - m_Endpoint (boost::asio::ip::udp::v4 (), port), m_Socket (m_Service, m_Endpoint), - m_IntroducersUpdateTimer (m_Service) + m_Endpoint (boost::asio::ip::udp::v4 (), port), m_EndpointV6 (boost::asio::ip::udp::v6 (), port), + m_Socket (m_Service, m_Endpoint), m_SocketV6 (m_Service), m_IntroducersUpdateTimer (m_Service) { m_Socket.set_option (boost::asio::socket_base::receive_buffer_size (65535)); m_Socket.set_option (boost::asio::socket_base::send_buffer_size (65535)); + if (context.SupportsV6 ()) + { + m_SocketV6.open (boost::asio::ip::udp::v6()); + m_SocketV6.set_option (boost::asio::ip::v6_only (true)); + m_SocketV6.set_option (boost::asio::socket_base::receive_buffer_size (65535)); + m_SocketV6.set_option (boost::asio::socket_base::send_buffer_size (65535)); + m_SocketV6.bind (m_EndpointV6); + } } SSUServer::~SSUServer () @@ -1028,6 +1036,8 @@ namespace transport m_IsRunning = true; m_Thread = new std::thread (std::bind (&SSUServer::Run, this)); m_Service.post (boost::bind (&SSUServer::Receive, this)); + if (context.SupportsV6 ()) + m_Service.post (boost::bind (&SSUServer::ReceiveV6, this)); if (i2p::context.IsUnreachable ()) ScheduleIntroducersUpdateTimer (); } @@ -1085,27 +1095,49 @@ namespace transport boost::bind (&SSUServer::HandleReceivedFrom, this, boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred)); } + void SSUServer::ReceiveV6 () + { + m_SocketV6.async_receive_from (boost::asio::buffer (m_ReceiveBufferV6, SSU_MTU_V6), m_SenderEndpointV6, + boost::bind (&SSUServer::HandleReceivedFromV6, this, boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred)); + } + void SSUServer::HandleReceivedFrom (const boost::system::error_code& ecode, std::size_t bytes_transferred) { if (!ecode) { - SSUSession * session = nullptr; - auto it = m_Sessions.find (m_SenderEndpoint); - if (it != m_Sessions.end ()) - session = it->second; - if (!session) - { - session = new SSUSession (*this, m_SenderEndpoint); - m_Sessions[m_SenderEndpoint] = session; - LogPrint ("New SSU session from ", m_SenderEndpoint.address ().to_string (), ":", m_SenderEndpoint.port (), " created"); - } - session->ProcessNextMessage (m_ReceiveBuffer, bytes_transferred, m_SenderEndpoint); + HandleReceivedBuffer (m_SenderEndpoint, m_ReceiveBuffer, bytes_transferred); Receive (); } else LogPrint ("SSU receive error: ", ecode.message ()); } + void SSUServer::HandleReceivedFromV6 (const boost::system::error_code& ecode, std::size_t bytes_transferred) + { + if (!ecode) + { + HandleReceivedBuffer (m_SenderEndpointV6, m_ReceiveBufferV6, bytes_transferred); + ReceiveV6 (); + } + else + LogPrint ("SSU V6 receive error: ", ecode.message ()); + } + + void SSUServer::HandleReceivedBuffer (boost::asio::ip::udp::endpoint& from, uint8_t * buf, std::size_t bytes_transferred) + { + SSUSession * session = nullptr; + auto it = m_Sessions.find (from); + if (it != m_Sessions.end ()) + session = it->second; + if (!session) + { + session = new SSUSession (*this, from); + m_Sessions[m_SenderEndpoint] = session; + LogPrint ("New SSU session from ", from.address ().to_string (), ":", from.port (), " created"); + } + session->ProcessNextMessage (buf, bytes_transferred, from); + } + SSUSession * SSUServer::FindSession (const i2p::data::RouterInfo * router) { if (!router) return nullptr; diff --git a/SSU.h b/SSU.h index c93a18a2..db6844dc 100644 --- a/SSU.h +++ b/SSU.h @@ -169,7 +169,10 @@ namespace transport void Run (); void Receive (); - void HandleReceivedFrom (const boost::system::error_code& ecode, std::size_t bytes_transferred); + void ReceiveV6 (); + void HandleReceivedFrom (const boost::system::error_code& ecode, std::size_t bytes_transferred); + void HandleReceivedFromV6 (const boost::system::error_code& ecode, std::size_t bytes_transferred); + void HandleReceivedBuffer (boost::asio::ip::udp::endpoint& from, uint8_t * buf, std::size_t bytes_transferred); template SSUSession * GetRandomSession (Filter filter); @@ -184,12 +187,12 @@ namespace transport std::thread * m_Thread; boost::asio::io_service m_Service; boost::asio::io_service::work m_Work; - boost::asio::ip::udp::endpoint m_Endpoint; - boost::asio::ip::udp::socket m_Socket; - boost::asio::ip::udp::endpoint m_SenderEndpoint; + boost::asio::ip::udp::endpoint m_Endpoint, m_EndpointV6; + boost::asio::ip::udp::socket m_Socket, m_SocketV6; + boost::asio::ip::udp::endpoint m_SenderEndpoint, m_SenderEndpointV6; boost::asio::deadline_timer m_IntroducersUpdateTimer; std::list m_Introducers; // introducers we are connected to - uint8_t m_ReceiveBuffer[2*SSU_MTU_V4]; + uint8_t m_ReceiveBuffer[2*SSU_MTU_V4], m_ReceiveBufferV6[2*SSU_MTU_V6]; std::map m_Sessions; std::map m_Relays; // we are introducer diff --git a/Transports.cpp b/Transports.cpp index 012b0e4c..8981125a 100644 --- a/Transports.cpp +++ b/Transports.cpp @@ -139,7 +139,7 @@ namespace transport this, conn, boost::asio::placeholders::error)); } } - else if (address.transportStyle == RouterInfo::eTransportSSU) + else if (address.transportStyle == RouterInfo::eTransportSSU && address.host.is_v4 ()) { if (!m_SSUServer) { @@ -356,7 +356,7 @@ namespace transport void Transports::DetectExternalIP () { - for (int i = 0; i < 5; i ++) + for (int i = 0; i < 5; i++) { auto router = i2p::data::netdb.GetRandomRouter (); if (router && router->IsSSU () && m_SSUServer)