Browse Source

recognize SSU2 addresses

pull/1742/head
orignal 3 years ago
parent
commit
68d015763e
  1. 29
      libi2pd/RouterInfo.cpp
  2. 4
      libi2pd/RouterInfo.h
  3. 37
      libi2pd/SSU2.cpp
  4. 12
      libi2pd/SSU2.h
  5. 11
      libi2pd/Transports.cpp
  6. 4
      libi2pd/Transports.h

29
libi2pd/RouterInfo.cpp

@ -221,9 +221,9 @@ namespace data
ReadString (transportStyle, 6, s); ReadString (transportStyle, 6, s);
if (!strncmp (transportStyle, "NTCP", 4)) // NTCP or NTCP2 if (!strncmp (transportStyle, "NTCP", 4)) // NTCP or NTCP2
address->transportStyle = eTransportNTCP; address->transportStyle = eTransportNTCP;
else if (!strcmp (transportStyle, "SSU")) else if (!strncmp (transportStyle, "SSU", 3)) // SSU or SSU2
{ {
address->transportStyle = eTransportSSU; address->transportStyle = (transportStyle[3] == '2') ? eTransportSSU2 : eTransportSSU;
address->ssu.reset (new SSUExt ()); address->ssu.reset (new SSUExt ());
address->ssu->mtu = 0; address->ssu->mtu = 0;
} }
@ -266,12 +266,12 @@ namespace data
} }
else if (!strcmp (key, "caps")) else if (!strcmp (key, "caps"))
address->caps = ExtractAddressCaps (value); address->caps = ExtractAddressCaps (value);
else if (!strcmp (key, "s")) // ntcp2 static key else if (!strcmp (key, "s")) // ntcp2 or ssu2 static key
{ {
Base64ToByteStream (value, strlen (value), address->s, 32); Base64ToByteStream (value, strlen (value), address->s, 32);
isStaticKey = true; isStaticKey = true;
} }
else if (!strcmp (key, "i")) // ntcp2 iv else if (!strcmp (key, "i")) // ntcp2 iv or ssu2 intro
{ {
Base64ToByteStream (value, strlen (value), address->i, 16); Base64ToByteStream (value, strlen (value), address->i, 16);
address->published = true; // presence if "i" means "published" address->published = true; // presence if "i" means "published"
@ -378,6 +378,10 @@ namespace data
} }
} }
} }
else if (address->transportStyle == eTransportSSU2)
{
// TODO:
}
if (supportedTransports) if (supportedTransports)
{ {
if (!(m_SupportedTransports & supportedTransports)) // avoid duplicates if (!(m_SupportedTransports & supportedTransports)) // avoid duplicates
@ -1104,6 +1108,19 @@ namespace data
WriteString (caps, properties); WriteString (caps, properties);
properties << ';'; properties << ';';
} }
else if (address.transportStyle == eTransportSSU2)
{
WriteString ("SSU2", s);
// caps
WriteString ("caps", properties);
properties << '=';
std::string caps;
if (address.IsV4 ()) caps += CAPS_FLAG_V4;
if (address.IsV6 ()) caps += CAPS_FLAG_V6;
if (caps.empty ()) caps += CAPS_FLAG_V4;
WriteString (caps, properties);
properties << ';';
}
else else
WriteString ("", s); WriteString ("", s);
@ -1203,9 +1220,9 @@ namespace data
WriteString (boost::lexical_cast<std::string>(address.port), properties); WriteString (boost::lexical_cast<std::string>(address.port), properties);
properties << ';'; properties << ';';
} }
if (address.IsNTCP2 ()) if (address.IsNTCP2 () || address.IsSSU2 ())
{ {
// publish s and v for NTCP2 // publish s and v for NTCP2 or SSU2
WriteString ("s", properties); properties << '='; WriteString ("s", properties); properties << '=';
WriteString (address.s.ToBase64 (), properties); properties << ';'; WriteString (address.s.ToBase64 (), properties); properties << ';';
WriteString ("v", properties); properties << '='; WriteString ("v", properties); properties << '=';

4
libi2pd/RouterInfo.h

@ -92,7 +92,8 @@ namespace data
{ {
eTransportUnknown = 0, eTransportUnknown = 0,
eTransportNTCP, eTransportNTCP,
eTransportSSU eTransportSSU,
eTransportSSU2
}; };
typedef Tag<32> IntroKey; // should be castable to MacKey and AESKey typedef Tag<32> IntroKey; // should be castable to MacKey and AESKey
@ -141,6 +142,7 @@ namespace data
} }
bool IsNTCP2 () const { return transportStyle == eTransportNTCP; }; bool IsNTCP2 () const { return transportStyle == eTransportNTCP; };
bool IsSSU2 () const { return transportStyle == eTransportSSU2; };
bool IsPublishedNTCP2 () const { return IsNTCP2 () && published; }; bool IsPublishedNTCP2 () const { return IsNTCP2 () && published; };
bool IsReachableSSU () const { return (bool)ssu && (published || !ssu->introducers.empty ()); }; bool IsReachableSSU () const { return (bool)ssu && (published || !ssu->introducers.empty ()); };
bool UsesIntroducer () const { return (bool)ssu && !ssu->introducers.empty (); }; bool UsesIntroducer () const { return (bool)ssu && !ssu->introducers.empty (); };

37
libi2pd/SSU2.cpp

@ -196,25 +196,48 @@ namespace transport
return true; return true;
} }
SSU2Server::SSU2Server (int port): SSU2Server::SSU2Server ():
m_Socket (m_Service), m_Endpoint (boost::asio::ip::udp::v6 (), port) RunnableServiceWithWork ("SSU2"), m_Socket (GetService ())
{ {
} }
void SSU2Server::OpenSocket () void SSU2Server::Start ()
{
if (!IsRunning ())
{
StartIOService ();
auto& addresses = i2p::context.GetRouterInfo ().GetAddresses ();
for (const auto& address: addresses)
{
if (!address) continue;
if (address->transportStyle == i2p::data::RouterInfo::eTransportSSU2 && address->port)
{
OpenSocket (address->port);
break;
}
}
}
}
void SSU2Server::Stop ()
{
StopIOService ();
}
void SSU2Server::OpenSocket (int port)
{ {
try try
{ {
m_Socket.open (boost::asio::ip::udp::v6()); m_Socket.open (boost::asio::ip::udp::v6());
m_Socket.set_option (boost::asio::socket_base::receive_buffer_size (SSU2_SOCKET_RECEIVE_BUFFER_SIZE)); m_Socket.set_option (boost::asio::socket_base::receive_buffer_size (SSU2_SOCKET_RECEIVE_BUFFER_SIZE));
m_Socket.set_option (boost::asio::socket_base::send_buffer_size (SSU2_SOCKET_SEND_BUFFER_SIZE)); m_Socket.set_option (boost::asio::socket_base::send_buffer_size (SSU2_SOCKET_SEND_BUFFER_SIZE));
m_Socket.bind (m_Endpoint); m_Socket.bind (boost::asio::ip::udp::endpoint (boost::asio::ip::udp::v6(), port));
LogPrint (eLogInfo, "SSU2: Start listening port ", m_Endpoint.port()); LogPrint (eLogInfo, "SSU2: Start listening port ", port);
} }
catch (std::exception& ex ) catch (std::exception& ex )
{ {
LogPrint (eLogError, "SSU2: Failed to bind to port ", m_Endpoint.port(), ": ", ex.what()); LogPrint (eLogError, "SSU2: Failed to bind to port ", port, ": ", ex.what());
ThrowFatal ("Unable to start SSU2 transport at port ", m_Endpoint.port(), ": ", ex.what ()); ThrowFatal ("Unable to start SSU2 transport at port ", port, ": ", ex.what ());
} }
} }

12
libi2pd/SSU2.h

@ -76,13 +76,17 @@ namespace transport
uint64_t m_DestConnID, m_SourceConnID; uint64_t m_DestConnID, m_SourceConnID;
}; };
class SSU2Server class SSU2Server: private i2p::util::RunnableServiceWithWork
{ {
public: public:
SSU2Server (int port); SSU2Server ();
~SSU2Server () {}; ~SSU2Server () {};
void Start ();
void Stop ();
boost::asio::io_service& GetService () { return GetIOService (); };
void AddSession (uint64_t connID, std::shared_ptr<SSU2Session> session); void AddSession (uint64_t connID, std::shared_ptr<SSU2Session> session);
void AddPendingOutgoingSession (const boost::asio::ip::udp::endpoint& ep, std::shared_ptr<SSU2Session> session); void AddPendingOutgoingSession (const boost::asio::ip::udp::endpoint& ep, std::shared_ptr<SSU2Session> session);
@ -91,14 +95,12 @@ namespace transport
private: private:
void OpenSocket (); void OpenSocket (int port);
void ProcessNextPacket (uint8_t * buf, size_t len, const boost::asio::ip::udp::endpoint& senderEndpoint); void ProcessNextPacket (uint8_t * buf, size_t len, const boost::asio::ip::udp::endpoint& senderEndpoint);
private: private:
boost::asio::io_service m_Service;
boost::asio::ip::udp::socket m_Socket; boost::asio::ip::udp::socket m_Socket;
boost::asio::ip::udp::endpoint m_Endpoint;
std::unordered_map<uint64_t, std::shared_ptr<SSU2Session> > m_Sessions; std::unordered_map<uint64_t, std::shared_ptr<SSU2Session> > m_Sessions;
std::map<boost::asio::ip::udp::endpoint, std::shared_ptr<SSU2Session> > m_PendingOutgoingSessions; std::map<boost::asio::ip::udp::endpoint, std::shared_ptr<SSU2Session> > m_PendingOutgoingSessions;
}; };

11
libi2pd/Transports.cpp

@ -136,7 +136,7 @@ namespace transport
Transports::Transports (): Transports::Transports ():
m_IsOnline (true), m_IsRunning (false), m_IsNAT (true), m_CheckReserved(true), m_Thread (nullptr), m_IsOnline (true), m_IsRunning (false), m_IsNAT (true), m_CheckReserved(true), m_Thread (nullptr),
m_Service (nullptr), m_Work (nullptr), m_PeerCleanupTimer (nullptr), m_PeerTestTimer (nullptr), m_Service (nullptr), m_Work (nullptr), m_PeerCleanupTimer (nullptr), m_PeerTestTimer (nullptr),
m_SSUServer (nullptr), m_NTCP2Server (nullptr), m_SSUServer (nullptr), m_SSU2Server (nullptr), m_NTCP2Server (nullptr),
m_X25519KeysPairSupplier (15), // 15 pre-generated keys m_X25519KeysPairSupplier (15), // 15 pre-generated keys
m_TotalSentBytes(0), m_TotalReceivedBytes(0), m_TotalTransitTransmittedBytes (0), m_TotalSentBytes(0), m_TotalReceivedBytes(0), m_TotalTransitTransmittedBytes (0),
m_InBandwidth (0), m_OutBandwidth (0), m_TransitBandwidth(0), m_InBandwidth (0), m_OutBandwidth (0), m_TransitBandwidth(0),
@ -304,7 +304,14 @@ namespace transport
delete m_SSUServer; delete m_SSUServer;
m_SSUServer = nullptr; m_SSUServer = nullptr;
} }
if (m_SSU2Server)
{
m_SSU2Server->Stop ();
delete m_SSU2Server;
m_SSU2Server = nullptr;
}
if (m_NTCP2Server) if (m_NTCP2Server)
{ {
m_NTCP2Server->Stop (); m_NTCP2Server->Stop ();

4
libi2pd/Transports.h

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2013-2020, The PurpleI2P Project * Copyright (c) 2013-2022, The PurpleI2P Project
* *
* This file is part of Purple i2pd project and licensed under BSD3 * This file is part of Purple i2pd project and licensed under BSD3
* *
@ -22,6 +22,7 @@
#include <boost/asio.hpp> #include <boost/asio.hpp>
#include "TransportSession.h" #include "TransportSession.h"
#include "SSU.h" #include "SSU.h"
#include "SSU2.h"
#include "NTCP2.h" #include "NTCP2.h"
#include "RouterInfo.h" #include "RouterInfo.h"
#include "I2NPProtocol.h" #include "I2NPProtocol.h"
@ -159,6 +160,7 @@ namespace transport
boost::asio::deadline_timer * m_PeerCleanupTimer, * m_PeerTestTimer; boost::asio::deadline_timer * m_PeerCleanupTimer, * m_PeerTestTimer;
SSUServer * m_SSUServer; SSUServer * m_SSUServer;
SSU2Server * m_SSU2Server;
NTCP2Server * m_NTCP2Server; NTCP2Server * m_NTCP2Server;
mutable std::mutex m_PeersMutex; mutable std::mutex m_PeersMutex;
std::unordered_map<i2p::data::IdentHash, Peer> m_Peers; std::unordered_map<i2p::data::IdentHash, Peer> m_Peers;

Loading…
Cancel
Save