Browse Source

SSU2 through a socks5 proxy

pull/1797/head
orignal 2 years ago
parent
commit
2a703e0844
  1. 1
      libi2pd/Config.cpp
  2. 50
      libi2pd/SSU2.cpp
  3. 1
      libi2pd/SSU2.h
  4. 18
      libi2pd/Transports.cpp

1
libi2pd/Config.cpp

@ -277,6 +277,7 @@ namespace config {
("ssu2.enabled", value<bool>()->default_value(true), "Enable SSU2 (default: enabled)") ("ssu2.enabled", value<bool>()->default_value(true), "Enable SSU2 (default: enabled)")
("ssu2.published", value<bool>()->default_value(true), "Publish SSU2 (default: enabled)") ("ssu2.published", value<bool>()->default_value(true), "Publish SSU2 (default: enabled)")
("ssu2.port", value<uint16_t>()->default_value(0), "Port to listen for incoming SSU2 packets (default: auto)") ("ssu2.port", value<uint16_t>()->default_value(0), "Port to listen for incoming SSU2 packets (default: auto)")
("ssu2.proxy", value<std::string>()->default_value(""), "Socks5 proxy URL for SSU2 transport")
; ;
options_description nettime("Time sync options"); options_description nettime("Time sync options");

50
libi2pd/SSU2.cpp

@ -42,6 +42,11 @@ namespace transport
if (!address) continue; if (!address) continue;
if (address->transportStyle == i2p::data::RouterInfo::eTransportSSU2) if (address->transportStyle == i2p::data::RouterInfo::eTransportSSU2)
{ {
if (m_IsThroughProxy)
{
found = true;
break; // we don't need port for proxy
}
auto port = address->port; auto port = address->port;
if (!port) if (!port)
{ {
@ -84,7 +89,11 @@ namespace transport
} }
} }
if (found) if (found)
{
m_ReceiveService.Start (); m_ReceiveService.Start ();
if (m_IsThroughProxy)
ConnectToProxy ();
}
ScheduleTermination (); ScheduleTermination ();
ScheduleResend (false); ScheduleResend (false);
} }
@ -257,7 +266,10 @@ namespace transport
{ {
if (packet) if (packet)
{ {
ProcessNextPacket (packet->buf, packet->len, packet->from); if (m_IsThroughProxy)
ProcessNextPacketFromProxy (packet->buf, packet->len);
else
ProcessNextPacket (packet->buf, packet->len, packet->from);
m_PacketsPool.ReleaseMt (packet); m_PacketsPool.ReleaseMt (packet);
if (m_LastSession && m_LastSession->GetState () != eSSU2SessionStateTerminated) if (m_LastSession && m_LastSession->GetState () != eSSU2SessionStateTerminated)
m_LastSession->FlushData (); m_LastSession->FlushData ();
@ -266,8 +278,12 @@ namespace transport
void SSU2Server::HandleReceivedPackets (std::vector<Packet *> packets) void SSU2Server::HandleReceivedPackets (std::vector<Packet *> packets)
{ {
for (auto& packet: packets) if (m_IsThroughProxy)
ProcessNextPacket (packet->buf, packet->len, packet->from); for (auto& packet: packets)
ProcessNextPacketFromProxy (packet->buf, packet->len);
else
for (auto& packet: packets)
ProcessNextPacket (packet->buf, packet->len, packet->from);
m_PacketsPool.ReleaseMt (packets); m_PacketsPool.ReleaseMt (packets);
if (m_LastSession && m_LastSession->GetState () != eSSU2SessionStateTerminated) if (m_LastSession && m_LastSession->GetState () != eSSU2SessionStateTerminated)
m_LastSession->FlushData (); m_LastSession->FlushData ();
@ -479,6 +495,11 @@ namespace transport
void SSU2Server::Send (const uint8_t * header, size_t headerLen, const uint8_t * payload, size_t payloadLen, void SSU2Server::Send (const uint8_t * header, size_t headerLen, const uint8_t * payload, size_t payloadLen,
const boost::asio::ip::udp::endpoint& to) const boost::asio::ip::udp::endpoint& to)
{ {
if (m_IsThroughProxy)
{
SendThroughProxy (header, headerLen, nullptr, 0, payload, payloadLen, to);
return;
}
std::vector<boost::asio::const_buffer> bufs std::vector<boost::asio::const_buffer> bufs
{ {
boost::asio::buffer (header, headerLen), boost::asio::buffer (header, headerLen),
@ -498,6 +519,11 @@ namespace transport
void SSU2Server::Send (const uint8_t * header, size_t headerLen, const uint8_t * headerX, size_t headerXLen, void SSU2Server::Send (const uint8_t * header, size_t headerLen, const uint8_t * headerX, size_t headerXLen,
const uint8_t * payload, size_t payloadLen, const boost::asio::ip::udp::endpoint& to) const uint8_t * payload, size_t payloadLen, const boost::asio::ip::udp::endpoint& to)
{ {
if (m_IsThroughProxy)
{
SendThroughProxy (header, headerLen, headerX, headerXLen, payload, payloadLen, to);
return;
}
std::vector<boost::asio::const_buffer> bufs std::vector<boost::asio::const_buffer> bufs
{ {
boost::asio::buffer (header, headerLen), boost::asio::buffer (header, headerLen),
@ -1250,5 +1276,23 @@ namespace transport
ReadUDPAssociateSocket (); ReadUDPAssociateSocket ();
}); });
} }
bool SSU2Server::SetProxy (const std::string& address, uint16_t port)
{
boost::system::error_code ecode;
auto addr = boost::asio::ip::address::from_string (address, ecode);
if (!ecode && !addr.is_unspecified () && port)
{
m_IsThroughProxy = true;
m_ProxyEndpoint.reset (new boost::asio::ip::tcp::endpoint (addr, port));
}
else
{
if (ecode)
LogPrint (eLogError, "SSU2: Invalid proxy address ", address, " ", ecode.message());
return false;
}
return true;
}
} }
} }

1
libi2pd/SSU2.h

@ -57,6 +57,7 @@ namespace transport
void Stop (); void Stop ();
boost::asio::io_service& GetService () { return GetIOService (); }; boost::asio::io_service& GetService () { return GetIOService (); };
void SetLocalAddress (const boost::asio::ip::address& localAddress); void SetLocalAddress (const boost::asio::ip::address& localAddress);
bool SetProxy (const std::string& address, uint16_t port);
bool IsSupported (const boost::asio::ip::address& addr) const; bool IsSupported (const boost::asio::ip::address& addr) const;
uint16_t GetPort (bool v4) const; uint16_t GetPort (bool v4) const;
bool IsSyncClockFromPeers () const { return m_IsSyncClockFromPeers; }; bool IsSyncClockFromPeers () const { return m_IsSyncClockFromPeers; };

18
libi2pd/Transports.cpp

@ -218,7 +218,23 @@ namespace transport
} }
} }
// create SSU2 server // create SSU2 server
if (enableSSU2) m_SSU2Server = new SSU2Server (); if (enableSSU2)
{
m_SSU2Server = new SSU2Server ();
std::string ssu2proxy; i2p::config::GetOption("ssu2.proxy", ssu2proxy);
if (!ssu2proxy.empty())
{
if (proxyurl.parse (ssu2proxy) && proxyurl.schema == "socks")
{
if (m_SSU2Server->SetProxy (proxyurl.host, proxyurl.port))
i2p::context.SetStatus (eRouterStatusProxy);
else
LogPrint(eLogError, "Transports: Can't set SSU2 proxy ", ssu2proxy);
}
else
LogPrint(eLogError, "Transports: Invalid SSU2 proxy URL ", ssu2proxy);
}
}
// bind to interfaces // bind to interfaces
bool ipv4; i2p::config::GetOption("ipv4", ipv4); bool ipv4; i2p::config::GetOption("ipv4", ipv4);

Loading…
Cancel
Save