From d3bc9eb11022002fc0c3a7ee56cd6d8f3795e9fb Mon Sep 17 00:00:00 2001 From: orignal Date: Mon, 27 Jun 2022 23:03:27 -0400 Subject: [PATCH] update token and conn id after HolePunch --- libi2pd/SSU2.cpp | 24 ++++++++++++++++++++++-- libi2pd/SSU2.h | 1 + libi2pd/SSU2Session.cpp | 20 ++++++++++++-------- 3 files changed, 35 insertions(+), 10 deletions(-) diff --git a/libi2pd/SSU2.cpp b/libi2pd/SSU2.cpp index 5b0a55dd..4210afc0 100644 --- a/libi2pd/SSU2.cpp +++ b/libi2pd/SSU2.cpp @@ -243,6 +243,17 @@ namespace transport } } + void SSU2Server::UpdateSessionConnID (uint64_t oldConnID) + { + auto it = m_Sessions.find (oldConnID); + if (it != m_Sessions.end ()) + { + auto session = it->second; + m_Sessions.erase (it); + m_Sessions.emplace (session->GetConnID (), session); + } + } + void SSU2Server::AddSessionByRouterHash (std::shared_ptr session) { if (session) @@ -369,8 +380,17 @@ namespace transport m_LastSession->ProcessSessionConfirmed (buf, len); break; case eSSU2SessionStateIntroduced: - m_LastSession->SetRemoteEndpoint (senderEndpoint); - m_LastSession->ProcessHolePunch (buf, len); + if (m_LastSession->GetRemoteEndpoint ().address ().is_unspecified ()) + m_LastSession->SetRemoteEndpoint (senderEndpoint); + if (m_LastSession->GetRemoteEndpoint () == senderEndpoint) + m_LastSession->ProcessHolePunch (buf, len); + else + { + LogPrint (eLogWarning, "SSU2: HolePunch endpoint ", senderEndpoint, + " doesn't match RelayResponse ", m_LastSession->GetRemoteEndpoint ()); + m_LastSession->Terminate (); + m_LastSession = nullptr; + } break; case eSSU2SessionStatePeerTest: m_LastSession->SetRemoteEndpoint (senderEndpoint); diff --git a/libi2pd/SSU2.h b/libi2pd/SSU2.h index 429cfdb7..2373ec17 100644 --- a/libi2pd/SSU2.h +++ b/libi2pd/SSU2.h @@ -53,6 +53,7 @@ namespace transport void AddSession (std::shared_ptr session); void RemoveSession (uint64_t connID); + void UpdateSessionConnID (uint64_t oldConnID); // session has new connID void AddSessionByRouterHash (std::shared_ptr session); bool AddPendingOutgoingSession (std::shared_ptr session); void RemovePendingOutgoingSession (const boost::asio::ip::udp::endpoint& ep); diff --git a/libi2pd/SSU2Session.cpp b/libi2pd/SSU2Session.cpp index 7ceb7188..e681e993 100644 --- a/libi2pd/SSU2Session.cpp +++ b/libi2pd/SSU2Session.cpp @@ -955,8 +955,16 @@ namespace transport // connect to Charlie if (m_State == eSSU2SessionStateIntroduced) { + // create new connID + uint64_t oldConnID = GetConnID (); + RAND_bytes ((uint8_t *)&m_DestConnID, 8); + RAND_bytes ((uint8_t *)&m_SourceConnID, 8); + m_Server.UpdateSessionConnID (oldConnID); + // new token + m_Server.UpdateOutgoingToken (m_RemoteEndpoint, headerX[1], i2p::util::GetSecondsSinceEpoch () + SSU2_TOKEN_EXPIRATION_TIMEOUT); + // connect m_State = eSSU2SessionStateUnknown; - Connect (); + SendSessionRequest (headerX[1]); } return true; @@ -1463,13 +1471,9 @@ namespace transport s.Insert (buf + 2, 10 + csz); // nonce, timestamp, ver, csz and Charlie's endpoint if (s.Verify (it->second.first->GetRemoteIdentity (), buf + 12 + csz)) { - // update Charlie's endpoint and connect - if (it->second.first->m_State == eSSU2SessionStateIntroduced && - ExtractEndpoint (buf + 12, csz, it->second.first->m_RemoteEndpoint)) - { - it->second.first->m_State = eSSU2SessionStateUnknown; - it->second.first->Connect (); - } + if (it->second.first->m_State == eSSU2SessionStateIntroduced) // HolePunch not received yet + // update Charlie's endpoint + ExtractEndpoint (buf + 12, csz, it->second.first->m_RemoteEndpoint); } else {