From 64e4b3871a99989cd5f731e50fa0904698251148 Mon Sep 17 00:00:00 2001 From: orignal Date: Fri, 27 Sep 2024 13:32:20 -0400 Subject: [PATCH] update introducer's iTag is session to introducer was replaced to new one --- libi2pd/RouterContext.cpp | 6 ++++++ libi2pd/RouterContext.h | 1 + libi2pd/RouterInfo.cpp | 18 ++++++++++++++++++ libi2pd/RouterInfo.h | 1 + libi2pd/SSU2.cpp | 33 +++++++++++++++++++++------------ libi2pd/SSU2.h | 2 +- 6 files changed, 48 insertions(+), 13 deletions(-) diff --git a/libi2pd/RouterContext.cpp b/libi2pd/RouterContext.cpp index f9548139..1efb25db 100644 --- a/libi2pd/RouterContext.cpp +++ b/libi2pd/RouterContext.cpp @@ -557,6 +557,12 @@ namespace i2p UpdateRouterInfo (); } + void RouterContext::UpdateSSU2Introducer (const i2p::data::IdentHash& h, bool v4, uint32_t iTag, uint32_t iExp) + { + if (m_RouterInfo.UpdateSSU2Introducer (h, v4, iTag, iExp)) + UpdateRouterInfo (); + } + void RouterContext::ClearSSU2Introducers (bool v4) { auto addr = m_RouterInfo.GetSSU2Address (v4); diff --git a/libi2pd/RouterContext.h b/libi2pd/RouterContext.h index 03f1d10d..c620f8b1 100644 --- a/libi2pd/RouterContext.h +++ b/libi2pd/RouterContext.h @@ -154,6 +154,7 @@ namespace garlic void PublishSSU2Address (int port, bool publish, bool v4, bool v6); bool AddSSU2Introducer (const i2p::data::RouterInfo::Introducer& introducer, bool v4); void RemoveSSU2Introducer (const i2p::data::IdentHash& h, bool v4); + void UpdateSSU2Introducer (const i2p::data::IdentHash& h, bool v4, uint32_t iTag, uint32_t iExp); void ClearSSU2Introducers (bool v4); bool IsUnreachable () const; void SetUnreachable (bool v4, bool v6); diff --git a/libi2pd/RouterInfo.cpp b/libi2pd/RouterInfo.cpp index ce1ae72c..2da40ae8 100644 --- a/libi2pd/RouterInfo.cpp +++ b/libi2pd/RouterInfo.cpp @@ -1554,5 +1554,23 @@ namespace data } return false; } + + bool LocalRouterInfo::UpdateSSU2Introducer (const IdentHash& h, bool v4, uint32_t iTag, uint32_t iExp) + { + auto addresses = GetAddresses (); + if (!addresses) return false; + auto addr = (*addresses)[v4 ? eSSU2V4Idx : eSSU2V6Idx]; + if (addr) + { + for (auto& it: addr->ssu->introducers) + if (h == it.iH) + { + it.iTag = iTag; + it.iExp = iExp; + return true; + } + } + return false; + } } } diff --git a/libi2pd/RouterInfo.h b/libi2pd/RouterInfo.h index 68d6b0f0..72521797 100644 --- a/libi2pd/RouterInfo.h +++ b/libi2pd/RouterInfo.h @@ -380,6 +380,7 @@ namespace data bool AddSSU2Introducer (const Introducer& introducer, bool v4); bool RemoveSSU2Introducer (const IdentHash& h, bool v4); + bool UpdateSSU2Introducer (const IdentHash& h, bool v4, uint32_t iTag, uint32_t iExp); private: diff --git a/libi2pd/SSU2.cpp b/libi2pd/SSU2.cpp index 6378d7b8..d661c33b 100644 --- a/libi2pd/SSU2.cpp +++ b/libi2pd/SSU2.cpp @@ -1212,14 +1212,14 @@ namespace transport void SSU2Server::UpdateIntroducers (bool v4) { uint32_t ts = i2p::util::GetSecondsSinceEpoch (); - std::list newList, impliedList; + std::list > newList, impliedList; auto& introducers = v4 ? m_Introducers : m_IntroducersV6; std::unordered_set excluded; - for (const auto& it : introducers) + for (const auto& [ident, tag] : introducers) { - std::shared_ptr session = FindSession (it); + std::shared_ptr session = FindSession (ident); if (session) - excluded.insert (it); + excluded.insert (ident); if (session) { if (session->IsEstablished () && session->GetRelayTag () && session->IsOutgoing () && // still session with introducer? @@ -1227,19 +1227,27 @@ namespace transport { session->SendKeepAlive (); if (ts < session->GetCreationTime () + SSU2_TO_INTRODUCER_SESSION_DURATION) - newList.push_back (it); + { + newList.push_back ({ident, session->GetRelayTag ()}); + if (tag != session->GetRelayTag ()) + { + LogPrint (eLogDebug, "SSU2: Introducer session to ", session->GetIdentHashBase64() , " was replaced. iTag ", tag, "->", session->GetRelayTag ()); + i2p::context.UpdateSSU2Introducer (ident, v4, session->GetRelayTag (), + session->GetCreationTime () + SSU2_TO_INTRODUCER_SESSION_EXPIRATION); + } + } else { - impliedList.push_back (it); // keep in introducers list, but not publish + impliedList.push_back ({ident, session->GetRelayTag ()}); // keep in introducers list, but not publish session = nullptr; - } + } } else session = nullptr; } if (!session) - i2p::context.RemoveSSU2Introducer (it, v4); + i2p::context.RemoveSSU2Introducer (ident, v4); } if (newList.size () < SSU2_MAX_NUM_INTRODUCERS) { @@ -1249,13 +1257,14 @@ namespace transport // bump creation time for previous introducers if no new sessions found LogPrint (eLogDebug, "SSU2: No new introducers found. Trying to reuse existing"); impliedList.clear (); - for (auto& it : introducers) + for (const auto& [ident, tag] : introducers) { - auto session = FindSession (it); + auto session = FindSession (ident); if (session && session->IsEstablished () && session->GetRelayTag () && session->IsOutgoing ()) { session->SetCreationTime (session->GetCreationTime () + SSU2_TO_INTRODUCER_SESSION_DURATION); - if (std::find (newList.begin (), newList.end (), it) == newList.end ()) + if (std::find_if (newList.begin (), newList.end (), + [&ident](const auto& s){ return ident == s.first; }) == newList.end ()) sessions.push_back (session); } } @@ -1276,7 +1285,7 @@ namespace transport { LogPrint (eLogDebug, "SSU2: Introducer added ", it->GetRelayTag (), " at ", i2p::data::GetIdentHashAbbreviation (it->GetRemoteIdentity ()->GetIdentHash ())); - newList.push_back (it->GetRemoteIdentity ()->GetIdentHash ()); + newList.push_back ({ it->GetRemoteIdentity ()->GetIdentHash (), tag }); if (newList.size () >= SSU2_MAX_NUM_INTRODUCERS) break; } } diff --git a/libi2pd/SSU2.h b/libi2pd/SSU2.h index bae33aa2..36b946c5 100644 --- a/libi2pd/SSU2.h +++ b/libi2pd/SSU2.h @@ -170,7 +170,7 @@ namespace transport mutable std::mutex m_PendingOutgoingSessionsMutex; std::map > m_IncomingTokens, m_OutgoingTokens; // remote endpoint -> (token, expires in seconds) std::unordered_map > m_Relays; // we are introducer, relay tag -> session - std::list m_Introducers, m_IntroducersV6; // introducers we are connected to + std::list > m_Introducers, m_IntroducersV6; // introducers we are connected to i2p::util::MemoryPoolMt m_PacketsPool; i2p::util::MemoryPool m_SentPacketsPool; i2p::util::MemoryPool m_IncompleteMessagesPool;