From 608056dcd2dcf999a4541ca66bdb78caade4b9b1 Mon Sep 17 00:00:00 2001 From: orignal Date: Sun, 27 Oct 2024 11:55:10 -0400 Subject: [PATCH] don't handle RelayRequest and RelayIntro with same nonce twice --- libi2pd/SSU2.cpp | 4 +++- libi2pd/SSU2.h | 2 +- libi2pd/SSU2Session.cpp | 50 ++++++++++++++++++++++++----------------- 3 files changed, 33 insertions(+), 23 deletions(-) diff --git a/libi2pd/SSU2.cpp b/libi2pd/SSU2.cpp index 01a3bb6c..c8f2909b 100644 --- a/libi2pd/SSU2.cpp +++ b/libi2pd/SSU2.cpp @@ -477,7 +477,7 @@ namespace transport HandleReceivedPackets (std::move (receivedPackets)); } - void SSU2Server::AddSession (std::shared_ptr session) + bool SSU2Server::AddSession (std::shared_ptr session) { if (session) { @@ -485,8 +485,10 @@ namespace transport { if (session->GetState () != eSSU2SessionStatePeerTest) AddSessionByRouterHash (session); + return true; } } + return false; } void SSU2Server::RemoveSession (uint64_t connID) diff --git a/libi2pd/SSU2.h b/libi2pd/SSU2.h index 6f51f955..319a4780 100644 --- a/libi2pd/SSU2.h +++ b/libi2pd/SSU2.h @@ -85,7 +85,7 @@ namespace transport bool IsSyncClockFromPeers () const { return m_IsSyncClockFromPeers; }; void AdjustTimeOffset (int64_t offset, std::shared_ptr from); - void AddSession (std::shared_ptr session); + bool AddSession (std::shared_ptr session); void RemoveSession (uint64_t connID); void RequestRemoveSession (uint64_t connID); void AddSessionByRouterHash (std::shared_ptr session); diff --git a/libi2pd/SSU2Session.cpp b/libi2pd/SSU2Session.cpp index 8a1a44df..15cabac9 100644 --- a/libi2pd/SSU2Session.cpp +++ b/libi2pd/SSU2Session.cpp @@ -1931,25 +1931,28 @@ namespace transport return; } auto mts = i2p::util::GetMillisecondsSinceEpoch (); - session->m_RelaySessions.emplace (bufbe32toh (buf + 1), // nonce - std::make_pair (shared_from_this (), mts/1000) ); + uint32_t nonce = bufbe32toh (buf + 1); + if (session->m_RelaySessions.emplace (nonce, std::make_pair (shared_from_this (), mts/1000)).second) + { + // send relay intro to Charlie + auto r = i2p::data::netdb.FindRouter (GetRemoteIdentity ()->GetIdentHash ()); // Alice's RI + if (r && (r->IsUnreachable () || !i2p::data::netdb.PopulateRouterInfoBuffer (r))) r = nullptr; + if (!r) LogPrint (eLogWarning, "SSU2: RelayRequest Alice's router info not found"); - // send relay intro to Charlie - auto r = i2p::data::netdb.FindRouter (GetRemoteIdentity ()->GetIdentHash ()); // Alice's RI - if (r && (r->IsUnreachable () || !i2p::data::netdb.PopulateRouterInfoBuffer (r))) r = nullptr; - if (!r) LogPrint (eLogWarning, "SSU2: RelayRequest Alice's router info not found"); - - auto packet = m_Server.GetSentPacketsPool ().AcquireShared (); - packet->payloadSize = r ? CreateRouterInfoBlock (packet->payload, m_MaxPayloadSize - len - 32, r) : 0; - if (!packet->payloadSize && r) - session->SendFragmentedMessage (CreateDatabaseStoreMsg (r)); - packet->payloadSize += CreateRelayIntroBlock (packet->payload + packet->payloadSize, m_MaxPayloadSize - packet->payloadSize, buf + 1, len -1); - if (packet->payloadSize < m_MaxPayloadSize) - packet->payloadSize += CreatePaddingBlock (packet->payload + packet->payloadSize, m_MaxPayloadSize - packet->payloadSize); - uint32_t packetNum = session->SendData (packet->payload, packet->payloadSize); - packet->sendTime = mts; - // Charlie always responds with RelayResponse - session->m_SentPackets.emplace (packetNum, packet); + auto packet = m_Server.GetSentPacketsPool ().AcquireShared (); + packet->payloadSize = r ? CreateRouterInfoBlock (packet->payload, m_MaxPayloadSize - len - 32, r) : 0; + if (!packet->payloadSize && r) + session->SendFragmentedMessage (CreateDatabaseStoreMsg (r)); + packet->payloadSize += CreateRelayIntroBlock (packet->payload + packet->payloadSize, m_MaxPayloadSize - packet->payloadSize, buf + 1, len -1); + if (packet->payloadSize < m_MaxPayloadSize) + packet->payloadSize += CreatePaddingBlock (packet->payload + packet->payloadSize, m_MaxPayloadSize - packet->payloadSize); + uint32_t packetNum = session->SendData (packet->payload, packet->payloadSize); + packet->sendTime = mts; + // Charlie always responds with RelayResponse + session->m_SentPackets.emplace (packetNum, packet); + } + else + LogPrint (eLogInfo, "SSU2: Relay request nonce ", nonce, " already exists. Ignore"); } void SSU2Session::HandleRelayIntro (const uint8_t * buf, size_t len, int attempts) @@ -2035,8 +2038,13 @@ namespace transport { // send HolePunch auto holePunchSession = std::make_shared(m_Server, nonce, ep, addr); - m_Server.AddSession (holePunchSession); - holePunchSession->SendHolePunch (packet->payload, packet->payloadSize); // relay response block + if (m_Server.AddSession (holePunchSession)) + holePunchSession->SendHolePunch (packet->payload, packet->payloadSize); // relay response block + else + { + LogPrint (eLogInfo, "SSU2: Relay intro nonce ", nonce, " already exists. Ignore"); + return; + } } packet->payloadSize += CreatePaddingBlock (packet->payload + packet->payloadSize, m_MaxPayloadSize - packet->payloadSize); uint32_t packetNum = SendData (packet->payload, packet->payloadSize); @@ -3043,7 +3051,7 @@ namespace transport { if (ts > it->second.second + SSU2_RELAY_NONCE_EXPIRATION_TIMEOUT) { - LogPrint (eLogWarning, "SSU2: Relay nonce ", it->first, " was not responded in ", SSU2_RELAY_NONCE_EXPIRATION_TIMEOUT, " seconds, deleted"); + LogPrint (eLogInfo, "SSU2: Relay nonce ", it->first, " was not responded in ", SSU2_RELAY_NONCE_EXPIRATION_TIMEOUT, " seconds, deleted"); it = m_RelaySessions.erase (it); } else