Browse Source

bind SSU socket to specified address

pull/1638/head
orignal 4 years ago
parent
commit
bef9a54f4a
  1. 36
      libi2pd/SSU.cpp
  2. 5
      libi2pd/SSU.h
  3. 66
      libi2pd/Transports.cpp

36
libi2pd/SSU.cpp

@ -22,21 +22,8 @@ namespace i2p
{ {
namespace transport 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): 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_ReceiversThread (nullptr), m_ReceiversThreadV6 (nullptr), m_Work (m_Service),
m_ReceiversWork (m_ReceiversService), m_ReceiversWorkV6 (m_ReceiversServiceV6), m_ReceiversWork (m_ReceiversService), m_ReceiversWorkV6 (m_ReceiversServiceV6),
m_Endpoint (boost::asio::ip::udp::v4 (), port), m_EndpointV6 (boost::asio::ip::udp::v6 (), port), 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_IntroducersUpdateTimer (m_Service), m_PeerTestsCleanupTimer (m_Service),
m_TerminationTimer (m_Service), m_TerminationTimerV6 (m_Service) m_TerminationTimer (m_Service), m_TerminationTimerV6 (m_Service)
{ {
OpenSocket ();
if (context.SupportsV6 ())
OpenSocketV6 ();
} }
SSUServer::~SSUServer () SSUServer::~SSUServer ()
@ -91,18 +75,18 @@ namespace transport
void SSUServer::Start () void SSUServer::Start ()
{ {
m_IsRunning = true; 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)); OpenSocket ();
m_Thread = new std::thread (std::bind (&SSUServer::Run, this)); m_ReceiversThread = new std::thread (std::bind (&SSUServer::RunReceivers, this));
m_ReceiversService.post (std::bind (&SSUServer::Receive, this)); m_ReceiversService.post (std::bind (&SSUServer::Receive, this));
ScheduleTermination (); ScheduleTermination ();
} }
if (context.SupportsV6 ()) if (context.SupportsV6 ())
{ {
OpenSocketV6 ();
m_ReceiversThreadV6 = new std::thread (std::bind (&SSUServer::RunReceiversV6, this)); 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)); m_ReceiversServiceV6.post (std::bind (&SSUServer::ReceiveV6, this));
ScheduleTerminationV6 (); 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<SSUSession> relay) void SSUServer::AddRelay (uint32_t tag, std::shared_ptr<SSUSession> relay)
{ {
m_Relays[tag] = relay; m_Relays[tag] = relay;

5
libi2pd/SSU.h

@ -48,7 +48,6 @@ namespace transport
public: public:
SSUServer (int port); SSUServer (int port);
SSUServer (const boost::asio::ip::address & addr, int port); // ipv6 only constructor
~SSUServer (); ~SSUServer ();
void Start (); void Start ();
void Stop (); void Stop ();
@ -64,7 +63,8 @@ namespace transport
void DeleteAllSessions (); void DeleteAllSessions ();
boost::asio::io_service& GetService () { return m_Service; }; 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 Send (const uint8_t * buf, size_t len, const boost::asio::ip::udp::endpoint& to);
void AddRelay (uint32_t tag, std::shared_ptr<SSUSession> relay); void AddRelay (uint32_t tag, std::shared_ptr<SSUSession> relay);
void RemoveRelay (uint32_t tag); void RemoveRelay (uint32_t tag);
@ -118,7 +118,6 @@ namespace transport
std::shared_ptr<SSUSession> session; // for Bob to Alice std::shared_ptr<SSUSession> session; // for Bob to Alice
}; };
bool m_OnlyV6;
volatile bool m_IsRunning; volatile bool m_IsRunning;
std::thread * m_Thread, * m_ReceiversThread, * m_ReceiversThreadV6; std::thread * m_Thread, * m_ReceiversThread, * m_ReceiversThreadV6;
boost::asio::io_service m_Service, m_ReceiversService, m_ReceiversServiceV6; boost::asio::io_service m_Service, m_ReceiversService, m_ReceiversServiceV6;

66
libi2pd/Transports.cpp

@ -201,34 +201,22 @@ namespace transport
m_NTCP2Server = new NTCP2Server (); m_NTCP2Server = new NTCP2Server ();
} }
// create acceptors // create SSU server
auto& addresses = context.GetRouterInfo ().GetAddresses (); int ssuPort = 0;
for (const auto& address : addresses) if (enableSSU)
{ {
if (!address) continue; auto& addresses = context.GetRouterInfo ().GetAddresses ();
if (address->transportStyle == RouterInfo::eTransportSSU) for (const auto& address: addresses)
{ {
if (m_SSUServer == nullptr && enableSSU) if (!address) continue;
if (address->transportStyle == RouterInfo::eTransportSSU)
{ {
if (address->host.is_v4()) ssuPort = address->port;
m_SSUServer = new SSUServer (address->port); m_SSUServer = new SSUServer (address->port);
else break;
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 ();
} }
else
LogPrint (eLogError, "Transports: SSU server already exists");
} }
} }
// bind to interfaces // bind to interfaces
bool ipv4; i2p::config::GetOption("ipv4", ipv4); bool ipv4; i2p::config::GetOption("ipv4", ipv4);
@ -239,8 +227,11 @@ namespace transport
{ {
boost::system::error_code ec; boost::system::error_code ec;
auto addr = boost::asio::ip::address::from_string (address, ec); auto addr = boost::asio::ip::address::from_string (address, ec);
if (!ec && m_NTCP2Server) if (!ec)
m_NTCP2Server->SetLocalAddress (addr); {
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; boost::system::error_code ec;
auto addr = boost::asio::ip::address::from_string (address, ec); auto addr = boost::asio::ip::address::from_string (address, ec);
if (!ec && m_NTCP2Server) if (!ec)
m_NTCP2Server->SetLocalAddress (addr); {
if (m_NTCP2Server) m_NTCP2Server->SetLocalAddress (addr);
if (m_SSUServer) m_SSUServer->SetLocalAddress (addr);
}
} }
} }
@ -272,6 +266,22 @@ namespace transport
// start servers // start servers
if (m_NTCP2Server) m_NTCP2Server->Start (); 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->expires_from_now (boost::posix_time::seconds(5*SESSION_CREATION_TIMEOUT));
m_PeerCleanupTimer->async_wait (std::bind (&Transports::HandlePeerCleanupTimer, this, std::placeholders::_1)); m_PeerCleanupTimer->async_wait (std::bind (&Transports::HandlePeerCleanupTimer, this, std::placeholders::_1));

Loading…
Cancel
Save