From 15cd4feade93a217313a234deb0d40459280972d Mon Sep 17 00:00:00 2001 From: orignal Date: Sat, 28 Sep 2024 22:05:25 -0400 Subject: [PATCH] move Bob's peer tests from SSU2 session to server --- libi2pd/SSU2.cpp | 29 +++++++++++++++++++ libi2pd/SSU2.h | 4 +++ libi2pd/SSU2Session.cpp | 62 +++++++++++++++-------------------------- libi2pd/SSU2Session.h | 1 - 4 files changed, 56 insertions(+), 40 deletions(-) diff --git a/libi2pd/SSU2.cpp b/libi2pd/SSU2.cpp index 86cd335f..01680216 100644 --- a/libi2pd/SSU2.cpp +++ b/libi2pd/SSU2.cpp @@ -152,6 +152,7 @@ namespace transport m_SessionsByRouterHash.clear (); m_PendingOutgoingSessions.clear (); m_Relays.clear (); + m_PeerTests.clear (); m_Introducers.clear (); m_IntroducersV6.clear (); m_ConnectedRecently.clear (); @@ -621,6 +622,23 @@ namespace transport return nullptr; } + bool SSU2Server::AddPeerTest (uint32_t nonce, std::shared_ptr aliceSession, uint64_t ts) + { + return m_PeerTests.emplace (nonce, std::pair{ aliceSession, ts }).second; + } + + std::shared_ptr SSU2Server::GetPeerTest (uint32_t nonce) + { + auto it = m_PeerTests.find (nonce); + if (it != m_PeerTests.end ()) + { + auto s = it->second.first.lock (); + m_PeerTests.erase (it); + return s; + } + return nullptr; + } + bool SSU2Server::AddRequestedPeerTest (uint32_t nonce, std::shared_ptr session, uint64_t ts) { return m_RequestedPeerTests.emplace (nonce, std::pair{ session, ts }).second; @@ -1065,6 +1083,17 @@ namespace transport it++; } + for (auto it = m_PeerTests.begin (); it != m_PeerTests.end ();) + { + if (ts > it->second.second + SSU2_PEER_TEST_EXPIRATION_TIMEOUT || it->second.first.expired ()) + { + LogPrint (eLogInfo, "SSU2: Peer test nonce ", it->first, " was not responded in ", SSU2_PEER_TEST_EXPIRATION_TIMEOUT, " seconds or session invalid. Deleted"); + it = m_PeerTests.erase (it); + } + else + it++; + } + for (auto it = m_IncomingTokens.begin (); it != m_IncomingTokens.end (); ) { if (ts > it->second.second) diff --git a/libi2pd/SSU2.h b/libi2pd/SSU2.h index 97ef879f..06267ad4 100644 --- a/libi2pd/SSU2.h +++ b/libi2pd/SSU2.h @@ -111,6 +111,9 @@ namespace transport void RemoveRelay (uint32_t tag); std::shared_ptr FindRelaySession (uint32_t tag); + bool AddPeerTest (uint32_t nonce, std::shared_ptr aliceSession, uint64_t ts); + std::shared_ptr GetPeerTest (uint32_t nonce); + bool AddRequestedPeerTest (uint32_t nonce, std::shared_ptr session, uint64_t ts); std::shared_ptr GetRequestedPeerTest (uint32_t nonce); @@ -185,6 +188,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::unordered_map, uint64_t > > m_PeerTests; // nonce->(Alice, timestamp). We are Bob std::list > m_Introducers, m_IntroducersV6; // introducers we are connected to i2p::util::MemoryPoolMt m_PacketsPool; i2p::util::MemoryPoolMt m_PacketsArrayPool; diff --git a/libi2pd/SSU2Session.cpp b/libi2pd/SSU2Session.cpp index e9994b9f..027c6d9a 100644 --- a/libi2pd/SSU2Session.cpp +++ b/libi2pd/SSU2Session.cpp @@ -283,7 +283,6 @@ namespace transport m_SentPackets.clear (); m_IncompleteMessages.clear (); m_RelaySessions.clear (); - m_PeerTests.clear (); m_ReceivedI2NPMsgIDs.clear (); m_Server.RemoveSession (m_SourceConnID); transports.PeerDisconnected (shared_from_this ()); @@ -2145,7 +2144,7 @@ namespace transport GetRemoteIdentity ()->GetIdentHash ()); if (session) // session with Charlie { - session->m_PeerTests.emplace (nonce, std::make_pair (shared_from_this (), i2p::util::GetSecondsSinceEpoch ())); + m_Server.AddPeerTest (nonce, shared_from_this (), ts/1000); auto packet = m_Server.GetSentPacketsPool ().AcquireShared (); // Alice's RouterInfo auto r = i2p::data::netdb.FindRouter (GetRemoteIdentity ()->GetIdentHash ()); @@ -2251,34 +2250,29 @@ namespace transport } case 3: // Bob from Charlie { - auto it = m_PeerTests.find (nonce); - if (it != m_PeerTests.end ()) - { - auto aliceSession = it->second.first.lock (); - if (aliceSession && aliceSession->IsEstablished ()) - { - uint8_t payload[SSU2_MAX_PACKET_SIZE]; - // Charlie's RouterInfo - auto r = i2p::data::netdb.FindRouter (GetRemoteIdentity ()->GetIdentHash ()); - if (r && (r->IsUnreachable () || !i2p::data::netdb.PopulateRouterInfoBuffer (r))) r = nullptr; - size_t payloadSize = r ? CreateRouterInfoBlock (payload, m_MaxPayloadSize - len - 32, r) : 0; - if (!payloadSize && r) - aliceSession->SendFragmentedMessage (CreateDatabaseStoreMsg (r)); - if (payloadSize + len + 16 > m_MaxPayloadSize) - { - // doesn't fit one message, send RouterInfo in separate message - aliceSession->SendData (payload, payloadSize); - payloadSize = 0; - } - // PeerTest to Alice - payloadSize += CreatePeerTestBlock (payload + payloadSize, m_MaxPayloadSize, 4, - (SSU2PeerTestCode)buf[1], GetRemoteIdentity ()->GetIdentHash (), buf + offset, len - offset); - if (payloadSize < m_MaxPayloadSize) - payloadSize += CreatePaddingBlock (payload + payloadSize, m_MaxPayloadSize - payloadSize); + auto aliceSession = m_Server.GetPeerTest (nonce); + if (aliceSession && aliceSession->IsEstablished ()) + { + uint8_t payload[SSU2_MAX_PACKET_SIZE]; + // Charlie's RouterInfo + auto r = i2p::data::netdb.FindRouter (GetRemoteIdentity ()->GetIdentHash ()); + if (r && (r->IsUnreachable () || !i2p::data::netdb.PopulateRouterInfoBuffer (r))) r = nullptr; + size_t payloadSize = r ? CreateRouterInfoBlock (payload, m_MaxPayloadSize - len - 32, r) : 0; + if (!payloadSize && r) + aliceSession->SendFragmentedMessage (CreateDatabaseStoreMsg (r)); + if (payloadSize + len + 16 > m_MaxPayloadSize) + { + // doesn't fit one message, send RouterInfo in separate message aliceSession->SendData (payload, payloadSize); - } - m_PeerTests.erase (it); - } + payloadSize = 0; + } + // PeerTest to Alice + payloadSize += CreatePeerTestBlock (payload + payloadSize, m_MaxPayloadSize, 4, + (SSU2PeerTestCode)buf[1], GetRemoteIdentity ()->GetIdentHash (), buf + offset, len - offset); + if (payloadSize < m_MaxPayloadSize) + payloadSize += CreatePaddingBlock (payload + payloadSize, m_MaxPayloadSize - payloadSize); + aliceSession->SendData (payload, payloadSize); + } else LogPrint (eLogWarning, "SSU2: Unknown peer test 3 nonce ", nonce); break; @@ -3030,16 +3024,6 @@ namespace transport else ++it; } - for (auto it = m_PeerTests.begin (); it != m_PeerTests.end ();) - { - if (ts > it->second.second + SSU2_PEER_TEST_EXPIRATION_TIMEOUT || it->second.first.expired ()) - { - LogPrint (eLogWarning, "SSU2: Peer test nonce ", it->first, " was not responded in ", SSU2_PEER_TEST_EXPIRATION_TIMEOUT, " seconds or session invalid. Deleted"); - it = m_PeerTests.erase (it); - } - else - ++it; - } if (m_PathChallenge) RequestTermination (eSSU2TerminationReasonNormalClose); } diff --git a/libi2pd/SSU2Session.h b/libi2pd/SSU2Session.h index fdd7cc8e..caa16c01 100644 --- a/libi2pd/SSU2Session.h +++ b/libi2pd/SSU2Session.h @@ -373,7 +373,6 @@ namespace transport std::map > m_SentPackets; // packetNum -> packet std::unordered_map > m_IncompleteMessages; // msgID -> I2NP std::unordered_map, uint64_t > > m_RelaySessions; // nonce->(Alice, timestamp) for Bob or nonce->(Charlie, timestamp) for Alice - std::unordered_map, uint64_t > > m_PeerTests; // nonce->(Alice, timestamp). We are Bob std::list > m_SendQueue; i2p::I2NPMessagesHandler m_Handler; bool m_IsDataReceived;