diff --git a/libi2pd/SSU.cpp b/libi2pd/SSU.cpp index b1d5b77c..06e8d075 100644 --- a/libi2pd/SSU.cpp +++ b/libi2pd/SSU.cpp @@ -22,21 +22,8 @@ namespace i2p { namespace transport { - - SSUServer::SSUServer (const boost::asio::ip::address & addr, int port): - m_OnlyV6(true), m_IsRunning(false), m_Thread (nullptr), - m_ReceiversThread (nullptr), m_ReceiversThreadV6 (nullptr), m_Work (m_Service), - m_ReceiversWork (m_ReceiversService), m_ReceiversWorkV6 (m_ReceiversServiceV6), - m_EndpointV6 (addr, port), m_Socket (m_ReceiversService, m_Endpoint), - m_SocketV6 (m_ReceiversServiceV6), m_IntroducersUpdateTimer (m_Service), - m_PeerTestsCleanupTimer (m_Service), m_TerminationTimer (m_Service), - m_TerminationTimerV6 (m_Service) - { - OpenSocketV6 (); - } - SSUServer::SSUServer (int port): - m_OnlyV6(false), m_IsRunning(false), m_Thread (nullptr), + m_IsRunning(false), m_Thread (nullptr), m_ReceiversThread (nullptr), m_ReceiversThreadV6 (nullptr), m_Work (m_Service), m_ReceiversWork (m_ReceiversService), m_ReceiversWorkV6 (m_ReceiversServiceV6), m_Endpoint (boost::asio::ip::udp::v4 (), port), m_EndpointV6 (boost::asio::ip::udp::v6 (), port), @@ -44,9 +31,6 @@ namespace transport m_IntroducersUpdateTimer (m_Service), m_PeerTestsCleanupTimer (m_Service), m_TerminationTimer (m_Service), m_TerminationTimerV6 (m_Service) { - OpenSocket (); - if (context.SupportsV6 ()) - OpenSocketV6 (); } SSUServer::~SSUServer () @@ -91,18 +75,18 @@ namespace transport void SSUServer::Start () { m_IsRunning = true; - if (!m_OnlyV6) + m_Thread = new std::thread (std::bind (&SSUServer::Run, this)); + if (context.SupportsV4 ()) { - m_ReceiversThread = new std::thread (std::bind (&SSUServer::RunReceivers, this)); - m_Thread = new std::thread (std::bind (&SSUServer::Run, this)); + OpenSocket (); + m_ReceiversThread = new std::thread (std::bind (&SSUServer::RunReceivers, this)); m_ReceiversService.post (std::bind (&SSUServer::Receive, this)); ScheduleTermination (); } if (context.SupportsV6 ()) { + OpenSocketV6 (); m_ReceiversThreadV6 = new std::thread (std::bind (&SSUServer::RunReceiversV6, this)); - if (!m_Thread) - m_Thread = new std::thread (std::bind (&SSUServer::Run, this)); m_ReceiversServiceV6.post (std::bind (&SSUServer::ReceiveV6, this)); ScheduleTerminationV6 (); } @@ -205,6 +189,14 @@ namespace transport } } + void SSUServer::SetLocalAddress (const boost::asio::ip::address& localAddress) + { + if (localAddress.is_v6 ()) + m_EndpointV6.address (localAddress); + else if (localAddress.is_v4 ()) + m_Endpoint.address (localAddress); + } + void SSUServer::AddRelay (uint32_t tag, std::shared_ptr relay) { m_Relays[tag] = relay; diff --git a/libi2pd/SSU.h b/libi2pd/SSU.h index bce50a22..648d760c 100644 --- a/libi2pd/SSU.h +++ b/libi2pd/SSU.h @@ -48,7 +48,6 @@ namespace transport public: SSUServer (int port); - SSUServer (const boost::asio::ip::address & addr, int port); // ipv6 only constructor ~SSUServer (); void Start (); void Stop (); @@ -64,7 +63,8 @@ namespace transport void DeleteAllSessions (); boost::asio::io_service& GetService () { return m_Service; }; - const boost::asio::ip::udp::endpoint& GetEndpoint () const { return m_Endpoint; }; + void SetLocalAddress (const boost::asio::ip::address& localAddress); + void Send (const uint8_t * buf, size_t len, const boost::asio::ip::udp::endpoint& to); void AddRelay (uint32_t tag, std::shared_ptr relay); void RemoveRelay (uint32_t tag); @@ -118,7 +118,6 @@ namespace transport std::shared_ptr session; // for Bob to Alice }; - bool m_OnlyV6; volatile bool m_IsRunning; std::thread * m_Thread, * m_ReceiversThread, * m_ReceiversThreadV6; boost::asio::io_service m_Service, m_ReceiversService, m_ReceiversServiceV6; diff --git a/libi2pd/Transports.cpp b/libi2pd/Transports.cpp index c44672ec..705754f0 100644 --- a/libi2pd/Transports.cpp +++ b/libi2pd/Transports.cpp @@ -201,34 +201,22 @@ namespace transport m_NTCP2Server = new NTCP2Server (); } - // create acceptors - auto& addresses = context.GetRouterInfo ().GetAddresses (); - for (const auto& address : addresses) - { - if (!address) continue; - if (address->transportStyle == RouterInfo::eTransportSSU) + // create SSU server + int ssuPort = 0; + if (enableSSU) + { + auto& addresses = context.GetRouterInfo ().GetAddresses (); + for (const auto& address: addresses) { - if (m_SSUServer == nullptr && enableSSU) + if (!address) continue; + if (address->transportStyle == RouterInfo::eTransportSSU) { - if (address->host.is_v4()) - m_SSUServer = new SSUServer (address->port); - else - m_SSUServer = new SSUServer (address->host, address->port); - LogPrint (eLogInfo, "Transports: Start listening UDP port ", address->port); - try { - m_SSUServer->Start (); - } catch ( std::exception & ex ) { - LogPrint(eLogError, "Transports: Failed to bind to UDP port", address->port); - delete m_SSUServer; - m_SSUServer = nullptr; - continue; - } - DetectExternalIP (); + ssuPort = address->port; + m_SSUServer = new SSUServer (address->port); + break; } - else - LogPrint (eLogError, "Transports: SSU server already exists"); } - } + } // bind to interfaces bool ipv4; i2p::config::GetOption("ipv4", ipv4); @@ -239,8 +227,11 @@ namespace transport { boost::system::error_code ec; auto addr = boost::asio::ip::address::from_string (address, ec); - if (!ec && m_NTCP2Server) - m_NTCP2Server->SetLocalAddress (addr); + if (!ec) + { + if (m_NTCP2Server) m_NTCP2Server->SetLocalAddress (addr); + if (m_SSUServer) m_SSUServer->SetLocalAddress (addr); + } } } @@ -252,8 +243,11 @@ namespace transport { boost::system::error_code ec; auto addr = boost::asio::ip::address::from_string (address, ec); - if (!ec && m_NTCP2Server) - m_NTCP2Server->SetLocalAddress (addr); + if (!ec) + { + if (m_NTCP2Server) m_NTCP2Server->SetLocalAddress (addr); + if (m_SSUServer) m_SSUServer->SetLocalAddress (addr); + } } } @@ -272,6 +266,22 @@ namespace transport // start servers if (m_NTCP2Server) m_NTCP2Server->Start (); + if (m_SSUServer) + { + LogPrint (eLogInfo, "Transports: Start listening UDP port ", ssuPort); + try + { + m_SSUServer->Start (); + } + catch (std::exception& ex ) + { + LogPrint(eLogError, "Transports: Failed to bind to UDP port", ssuPort); + m_SSUServer->Stop (); + delete m_SSUServer; + m_SSUServer = nullptr; + } + if (m_SSUServer) DetectExternalIP (); + } m_PeerCleanupTimer->expires_from_now (boost::posix_time::seconds(5*SESSION_CREATION_TIMEOUT)); m_PeerCleanupTimer->async_wait (std::bind (&Transports::HandlePeerCleanupTimer, this, std::placeholders::_1));