handle ssu2.version in config and pq in SSU2 address in RouterInfo

This commit is contained in:
orignal committed 2026-03-12 20:26:29 -04:00
1 parent 772b046258
commit eb5a808232
7 files changed
+58 -21

No files matched your search

+1
View File
@@ -339,6 +339,7 @@ namespace config {
("ssu2.proxy", value<std::string>()->default_value(""), "Socks5 proxy URL for SSU2 transport")
("ssu2.firewalled4", value<bool>()->default_value(false), "Set ipv4 network status to Firewalled even if OK (default: disabled)")
("ssu2.firewalled6", value<bool>()->default_value(false), "Set ipv6 network status to Firewalled even if OK (default: disabled)")
("ssu2.version", value<int>()->default_value(2), "Protocol version. 2 - standard, 3,4 - post quantum (default: 2")
;
options_description nettime("Time sync options");
+17 -14
View File
@@ -219,7 +219,6 @@ namespace data
offset++; // cost, ignore
address->date = bufbe64toh (buf + offset); offset += 8; // date
bool isHost = false, isStaticKey = false, isV2 = false, isIntroKey = false;
int pq = 0;
auto transportStyle = ExtractString (buf + offset, len - offset); offset += transportStyle.length () + 1;
if (!transportStyle.compare (0, 4, "NTCP")) // NTCP or NTCP2
address->transportStyle = eTransportNTCP2;
@@ -308,14 +307,8 @@ namespace data
}
else if (key == "v")
{
if (value.size () == 1 && value[0] >= '2' && value[0] <= '5') // only 2,3,4,5 allowed
{
if (pq >= 3 && pq <= 5)
address->v = pq;
else
address->v = value[0] - '0';
if (value == "2") // only 2 is allowed
isV2 = true;
}
else
{
LogPrint (eLogWarning, "RouterInfo: Unexpected value ", value, " for v");
@@ -324,9 +317,16 @@ namespace data
}
else if (key == "pq")
{
if (address->transportStyle == eTransportNTCP2 && // for NTCP2 only for now
value.size () == 1 && value[0] >= '3' && value[0] <= '5') // only 3,4,5 allowed
pq = value[0] - '0';
if (address->transportStyle == eTransportNTCP2)
{
if (value.size () == 1 && value[0] >= '3' && value[0] <= '5') // only 3,4,5 allowed
address->v = value[0] - '0';
}
else if (address->transportStyle == eTransportSSU2)
{
if (value.size () == 1 && value[0] >= '3' && value[0] <= '4') // only 3,4 allowed
address->v = value[0] - '0';
}
}
else if (key[0] == 'i')
{
@@ -1453,10 +1453,13 @@ namespace data
WriteString (std::to_string(address.port), properties);
properties << ';';
}
if (address.v >= 3 && address.v <= 5 && address.IsNTCP2 ()) // post quantum
if (address.v >= 3) // post quantum
{
WriteString ("pq", properties); properties << '=';
WriteString (std::to_string (address.v), properties); properties << ';';
if (address.v <= 4 || (address.v == 5 && address.IsNTCP2 ()))
{
WriteString ("pq", properties); properties << '=';
WriteString (std::to_string (address.v), properties); properties << ';';
}
}
if (address.IsNTCP2 () || address.IsSSU2 ())
{
+9 -1
View File
@@ -26,7 +26,7 @@ namespace transport
m_IntroducersUpdateTimer (GetService ()), m_IntroducersUpdateTimerV6 (GetService ()),
m_IsPublished (true), m_IsSyncClockFromPeers (true), m_PendingTimeOffset (0),
m_Rng(i2p::util::GetMonotonicMicroseconds ()%1000000LL), m_IsForcedFirewalled4 (false),
m_IsForcedFirewalled6 (false), m_IsThroughProxy (false)
m_IsForcedFirewalled6 (false), m_Version (2), m_IsThroughProxy (false)
{
}
@@ -784,6 +784,7 @@ namespace transport
{
auto session = std::make_shared<SSU2Session> (*this);
session->SetRemoteEndpoint (senderEndpoint);
session->SetVersion (m_Version);
session->ProcessFirstIncomingMessage (connID, buf, len);
}
else
@@ -1559,6 +1560,13 @@ namespace transport
m_ChaCha20 (msg, msgLen, key, nonce, out);
}
void SSU2Server::SetVersion (int version)
{
#if OPENSSL_PQ
m_Version = version;
#endif
}
void SSU2Server::SendThroughProxy (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)
{
+4
View File
@@ -139,6 +139,9 @@ namespace transport
i2p::util::MemoryPool<SSU2IncompleteMessage>& GetIncompleteMessagesPool () { return m_IncompleteMessagesPool; };
i2p::util::MemoryPool<SSU2IncompleteMessage::Fragment>& GetFragmentsPool () { return m_FragmentsPool; };
void SetVersion (int version);
int GetVersion () const { return m_Version; }
private:
boost::asio::ip::udp::socket& OpenSocket (const boost::asio::ip::udp::endpoint& localEndpoint);
@@ -215,6 +218,7 @@ namespace transport
i2p::crypto::AEADChaCha20Poly1305Decryptor m_Decryptor;
i2p::crypto::ChaCha20Context m_ChaCha20;
bool m_IsForcedFirewalled4, m_IsForcedFirewalled6;
int m_Version;
// proxy
bool m_IsThroughProxy;
+5 -1
View File
@@ -165,7 +165,7 @@ namespace transport
header.h.connID = GetDestConnID (); // dest id
RAND_bytes (header.buf + 8, 4); // random packet num
header.h.type = eSSU2PeerTest;
header.h.flags[0] = GetVersion (); // ver
header.h.flags[0] = 2; // ver, always 2 even for post-quantum
header.h.flags[1] = (uint8_t)i2p::context.GetNetID (); // netID
header.h.flags[2] = 0; // flag
memcpy (h, header.buf, 16);
@@ -263,6 +263,10 @@ namespace transport
SetState (eSSU2SessionStateHolePunch);
SetRemoteEndpoint (remoteEndpoint);
SetAddress (addr);
#if OPENSSL_PQ
if (server.GetVersion () > 2) // we support post quantum in config
SetVersion (addr->v);
#endif
SetTerminationTimeout (SSU2_RELAY_NONCE_EXPIRATION_TIMEOUT);
}
+19 -4
View File
@@ -710,6 +710,10 @@ namespace transport
bool SSU2Session::SendSessionRequest (uint64_t token)
{
// we are Alice
#if OPENSSL_PQ
if (m_Server.GetVersion () > 2) // we support post quantum in config
SetVersion (m_Address->v);
#endif
m_EphemeralKeys = i2p::transport::transports.GetNextX25519KeysPair ();
m_SentHandshakePacket.reset (new HandshakePacket);
auto ts = i2p::util::GetMillisecondsSinceEpoch ();
@@ -823,9 +827,16 @@ namespace transport
LogPrint (eLogWarning, "SSU2: SessionRequest message too short ", len);
return;
}
if (header.h.flags[0] <= m_Version) // ver
SetVersion (header.h.flags[0]);
#if OPENSSL_PQ
if (header.h.flags[0] >= 2 && header.h.flags[0] <= 4) // ver
{
if (m_Version > 2)
SetVersion (header.h.flags[0]);
}
else
#else
if (header.h.flags[0] != 2) // ver
#endif
{
LogPrint (eLogWarning, "SSU2: SessionRequest protocol version ", header.h.flags[0], " is not supported");
return;
@@ -1423,13 +1434,17 @@ namespace transport
void SSU2Session::SendTokenRequest ()
{
// we are Alice
#if OPENSSL_PQ
if (m_Server.GetVersion () > 2) // we support post quantum in config
SetVersion (m_Address->v);
#endif
Header header;
uint8_t h[32], payload[41];
// fill packet
header.h.connID = m_DestConnID; // dest id
RAND_bytes (header.buf + 8, 4); // random packet num
header.h.type = eSSU2TokenRequest;
header.h.flags[0] = 2; // ver
header.h.flags[0] = GetVersion (); // ver
header.h.flags[1] = (uint8_t)i2p::context.GetNetID (); // netID
header.h.flags[2] = 0; // flag
memcpy (h, header.buf, 16);
@@ -1497,7 +1512,7 @@ namespace transport
header.h.connID = m_DestConnID; // dest id
RAND_bytes (header.buf + 8, 4); // random packet num
header.h.type = eSSU2Retry;
header.h.flags[0] = 2; // ver
header.h.flags[0] = GetVersion (); // ver
header.h.flags[1] = (uint8_t)i2p::context.GetNetID (); // netID
header.h.flags[2] = 0; // flag
memcpy (h, header.buf, 16);
+3 -1
View File
@@ -197,9 +197,10 @@ namespace transport
m_IsRunning = true;
m_Thread = new std::thread (std::bind (&Transports::Run, this));
std::string ntcp2proxy; i2p::config::GetOption("ntcp2.proxy", ntcp2proxy);
int ntcp2version = 2;
int ntcp2version = 2, ssu2version = 2;
#if OPENSSL_PQ
i2p::config::GetOption("ntcp2.version", ntcp2version);
i2p::config::GetOption("ssu2.version", ssu2version);
#endif
i2p::http::URL proxyurl;
// create NTCP2. TODO: move to acceptor
@@ -237,6 +238,7 @@ namespace transport
if (enableSSU2)
{
m_SSU2Server = new SSU2Server ();
m_SSU2Server->SetVersion (ssu2version);
std::string ssu2proxy; i2p::config::GetOption("ssu2.proxy", ssu2proxy);
if (!ssu2proxy.empty())
{