separate and move own peer test to SSU2Server

This commit is contained in:
orignal 2024-09-23 14:16:24 -04:00
parent 9968afc038
commit 2dfc9003a7
4 changed files with 58 additions and 25 deletions

View File

@ -154,6 +154,8 @@ namespace transport
m_Relays.clear (); m_Relays.clear ();
m_Introducers.clear (); m_Introducers.clear ();
m_IntroducersV6.clear (); m_IntroducersV6.clear ();
m_ConnectedRecently.clear ();
m_RequestedPeerTests.clear ();
} }
void SSU2Server::SetLocalAddress (const boost::asio::ip::address& localAddress) void SSU2Server::SetLocalAddress (const boost::asio::ip::address& localAddress)
@ -572,6 +574,23 @@ namespace transport
return nullptr; return nullptr;
} }
bool SSU2Server::AddRequestedPeerTest (uint32_t nonce, std::shared_ptr<SSU2PeerTestSession> session, uint64_t ts)
{
return m_RequestedPeerTests.emplace (nonce, std::pair{ session, ts }).second;
}
std::shared_ptr<SSU2PeerTestSession> SSU2Server::GetRequestedPeerTest (uint32_t nonce)
{
auto it = m_RequestedPeerTests.find (nonce);
if (it != m_RequestedPeerTests.end ())
{
auto s = it->second.first.lock ();
m_RequestedPeerTests.erase (it);
return s;
}
return nullptr;
}
void SSU2Server::ProcessNextPacket (uint8_t * buf, size_t len, const boost::asio::ip::udp::endpoint& senderEndpoint) void SSU2Server::ProcessNextPacket (uint8_t * buf, size_t len, const boost::asio::ip::udp::endpoint& senderEndpoint)
{ {
if (len < 24) return; if (len < 24) return;
@ -1032,6 +1051,14 @@ namespace transport
it++; it++;
} }
for (auto it = m_RequestedPeerTests.begin (); it != m_RequestedPeerTests.end ();)
{
if (ts > it->second.second + SSU2_PEER_TEST_EXPIRATION_TIMEOUT)
it = m_RequestedPeerTests.erase (it);
else
it++;
}
m_PacketsPool.CleanUpMt (); m_PacketsPool.CleanUpMt ();
m_SentPacketsPool.CleanUp (); m_SentPacketsPool.CleanUp ();
m_IncompleteMessagesPool.CleanUp (); m_IncompleteMessagesPool.CleanUp ();

View File

@ -94,6 +94,9 @@ namespace transport
void RemoveRelay (uint32_t tag); void RemoveRelay (uint32_t tag);
std::shared_ptr<SSU2Session> FindRelaySession (uint32_t tag); std::shared_ptr<SSU2Session> FindRelaySession (uint32_t tag);
bool AddRequestedPeerTest (uint32_t nonce, std::shared_ptr<SSU2PeerTestSession> session, uint64_t ts);
std::shared_ptr<SSU2PeerTestSession> GetRequestedPeerTest (uint32_t nonce);
void Send (const uint8_t * header, size_t headerLen, const uint8_t * payload, size_t payloadLen, void Send (const uint8_t * header, size_t headerLen, const uint8_t * payload, size_t payloadLen,
const boost::asio::ip::udp::endpoint& to); const boost::asio::ip::udp::endpoint& to);
void Send (const uint8_t * header, size_t headerLen, const uint8_t * headerX, size_t headerXLen, void Send (const uint8_t * header, size_t headerLen, const uint8_t * headerX, size_t headerXLen,
@ -178,6 +181,7 @@ namespace transport
std::shared_ptr<const i2p::data::IdentityEx> m_PendingTimeOffsetFrom; std::shared_ptr<const i2p::data::IdentityEx> m_PendingTimeOffsetFrom;
std::mt19937 m_Rng; std::mt19937 m_Rng;
std::map<boost::asio::ip::udp::endpoint, uint64_t> m_ConnectedRecently; // endpoint -> last activity time in seconds std::map<boost::asio::ip::udp::endpoint, uint64_t> m_ConnectedRecently; // endpoint -> last activity time in seconds
std::unordered_map<uint32_t, std::pair <std::weak_ptr<SSU2PeerTestSession>, uint64_t > > m_RequestedPeerTests; // nonce->(Alice, timestamp)
// proxy // proxy
bool m_IsThroughProxy; bool m_IsThroughProxy;

View File

@ -237,8 +237,8 @@ namespace transport
auto ts = i2p::util::GetMillisecondsSinceEpoch (); auto ts = i2p::util::GetMillisecondsSinceEpoch ();
// session for message 5 // session for message 5
auto session = std::make_shared<SSU2PeerTestSession> (m_Server, auto session = std::make_shared<SSU2PeerTestSession> (m_Server,
htobe64 (((uint64_t)nonce << 32) | nonce), 0, shared_from_this ()); htobe64 (((uint64_t)nonce << 32) | nonce), 0);
m_PeerTests.emplace (nonce, std::make_pair (session, ts/1000)); m_Server.AddRequestedPeerTest (nonce, session, ts/1000);
m_Server.AddSession (session); m_Server.AddSession (session);
// peer test block // peer test block
auto packet = m_Server.GetSentPacketsPool ().AcquireShared (); auto packet = m_Server.GetSentPacketsPool ().AcquireShared ();
@ -2255,7 +2255,7 @@ namespace transport
{ {
// send msg 5 to Alice // send msg 5 to Alice
auto session = std::make_shared<SSU2PeerTestSession> (m_Server, auto session = std::make_shared<SSU2PeerTestSession> (m_Server,
0, htobe64 (((uint64_t)nonce << 32) | nonce), shared_from_this ()); 0, htobe64 (((uint64_t)nonce << 32) | nonce));
session->m_Address = addr; session->m_Address = addr;
session->m_RemoteEndpoint = ep; // might be different session->m_RemoteEndpoint = ep; // might be different
m_Server.AddSession (session); m_Server.AddSession (session);
@ -2318,15 +2318,15 @@ namespace transport
} }
case 4: // Alice from Bob case 4: // Alice from Bob
{ {
auto it = m_PeerTests.find (nonce); auto session = m_Server.GetRequestedPeerTest (nonce);
if (it != m_PeerTests.end ()) if (session)
{ {
if (buf[1] == eSSU2PeerTestCodeAccept) if (buf[1] == eSSU2PeerTestCodeAccept)
{ {
if (GetRouterStatus () == eRouterStatusUnknown) if (GetRouterStatus () == eRouterStatusUnknown)
SetTestingState (true); SetTestingState (true);
auto r = i2p::data::netdb.FindRouter (buf + 3); // find Charlie auto r = i2p::data::netdb.FindRouter (buf + 3); // find Charlie
if (r && it->second.first) if (r)
{ {
uint8_t asz = buf[offset + 9]; uint8_t asz = buf[offset + 9];
SignedData s; SignedData s;
@ -2336,19 +2336,19 @@ namespace transport
s.Insert (buf + offset, asz + 10); // ver, nonce, ts, asz, Alice's endpoint s.Insert (buf + offset, asz + 10); // ver, nonce, ts, asz, Alice's endpoint
if (s.Verify (r->GetIdentity (), buf + offset + asz + 10)) if (s.Verify (r->GetIdentity (), buf + offset + asz + 10))
{ {
it->second.first->SetRemoteIdentity (r->GetIdentity ()); session->SetRemoteIdentity (r->GetIdentity ());
auto addr = r->GetSSU2Address (m_Address->IsV4 ()); auto addr = r->GetSSU2Address (m_Address->IsV4 ());
if (addr) if (addr)
{ {
it->second.first->m_Address = addr; session->m_Address = addr;
auto& state = it->second.first->m_State; auto& state = session->m_State;
if (state == eSSU2SessionStatePeerTestReceived || state == eSSU2SessionStateVoidPeerTestReceived) if (state == eSSU2SessionStatePeerTestReceived || state == eSSU2SessionStateVoidPeerTestReceived)
{ {
// msg 5 already received. send msg 6 // msg 5 already received. send msg 6
if (state == eSSU2SessionStatePeerTestReceived) if (state == eSSU2SessionStatePeerTestReceived)
SetRouterStatus (eRouterStatusOK); SetRouterStatus (eRouterStatusOK);
state = eSSU2SessionStatePeerTest; state = eSSU2SessionStatePeerTest;
it->second.first->SendPeerTest (6, buf + offset, len - offset, addr->i); session->SendPeerTest (6, buf + offset, len - offset, addr->i);
} }
else else
{ {
@ -2371,20 +2371,19 @@ namespace transport
else else
{ {
LogPrint (eLogWarning, "SSU2: Peer test 4 address not found"); LogPrint (eLogWarning, "SSU2: Peer test 4 address not found");
it->second.first->Done (); session->Done ();
} }
} }
else else
{ {
LogPrint (eLogWarning, "SSU2: Peer test 4 signature verification failed"); LogPrint (eLogWarning, "SSU2: Peer test 4 signature verification failed");
it->second.first->Done (); session->Done ();
} }
} }
else else
{ {
LogPrint (eLogWarning, "SSU2: Peer test 4 router not found"); LogPrint (eLogWarning, "SSU2: Peer test 4 router not found");
if (it->second.first) session->Done ();
it->second.first->Done ();
} }
} }
else else
@ -2393,9 +2392,8 @@ namespace transport
i2p::data::GetIdentHashAbbreviation (buf[1] < 64 ? GetRemoteIdentity ()->GetIdentHash () : i2p::data::IdentHash (buf + 3))); i2p::data::GetIdentHashAbbreviation (buf[1] < 64 ? GetRemoteIdentity ()->GetIdentHash () : i2p::data::IdentHash (buf + 3)));
if (GetTestingState ()) if (GetTestingState ())
SetRouterStatus (eRouterStatusUnknown); SetRouterStatus (eRouterStatusUnknown);
it->second.first->Done (); session->Done ();
} }
m_PeerTests.erase (it);
} }
else else
LogPrint (eLogWarning, "SSU2: Unknown peer test 4 nonce ", nonce); LogPrint (eLogWarning, "SSU2: Unknown peer test 4 nonce ", nonce);
@ -3089,10 +3087,8 @@ namespace transport
Resend (i2p::util::GetMillisecondsSinceEpoch ()); // than right time to resend Resend (i2p::util::GetMillisecondsSinceEpoch ()); // than right time to resend
} }
SSU2PeerTestSession::SSU2PeerTestSession (SSU2Server& server, uint64_t sourceConnID, SSU2PeerTestSession::SSU2PeerTestSession (SSU2Server& server, uint64_t sourceConnID, uint64_t destConnID):
uint64_t destConnID, std::shared_ptr<SSU2Session> mainSession): SSU2Session (server, nullptr, nullptr, false), m_MsgNumReceived (0)
SSU2Session (server, nullptr, nullptr, false),
m_MainSession (mainSession)
{ {
if (!sourceConnID) sourceConnID = ~destConnID; if (!sourceConnID) sourceConnID = ~destConnID;
if (!destConnID) destConnID = ~sourceConnID; if (!destConnID) destConnID = ~sourceConnID;
@ -3143,6 +3139,10 @@ namespace transport
// msgs 5-7 // msgs 5-7
if (len < 8) return; if (len < 8) return;
uint8_t msg = buf[0]; uint8_t msg = buf[0];
if (msg < m_MsgNumReceived)
{
LogPrint (eLogInfo, "SSU2: PeerTest msg num ", msg, " received after ", m_MsgNumReceived, ". Ignored");
}
size_t offset = 3; // points to signed data after msg + code + flag size_t offset = 3; // points to signed data after msg + code + flag
uint32_t nonce = bufbe32toh (buf + offset + 1); // 1 - ver uint32_t nonce = bufbe32toh (buf + offset + 1); // 1 - ver
switch (msg) // msg switch (msg) // msg
@ -3187,7 +3187,9 @@ namespace transport
} }
default: default:
LogPrint (eLogWarning, "SSU2: PeerTest unexpected msg num ", msg); LogPrint (eLogWarning, "SSU2: PeerTest unexpected msg num ", msg);
return;
} }
m_MsgNumReceived = msg;
} }
} }
} }

View File

@ -395,9 +395,9 @@ namespace transport
{ {
public: public:
SSU2PeerTestSession (SSU2Server& server, uint64_t sourceConnID, uint64_t destConnID, SSU2PeerTestSession (SSU2Server& server, uint64_t sourceConnID, uint64_t destConnID);
std::shared_ptr<SSU2Session> mainSession);
uint8_t GetMsgNumReceived () const { return m_MsgNumReceived; }
bool ProcessPeerTest (uint8_t * buf, size_t len) override; bool ProcessPeerTest (uint8_t * buf, size_t len) override;
private: private:
@ -406,7 +406,7 @@ namespace transport
private: private:
std::weak_ptr<SSU2Session> m_MainSession; uint8_t m_MsgNumReceived;
}; };
inline uint64_t CreateHeaderMask (const uint8_t * kh, const uint8_t * nonce) inline uint64_t CreateHeaderMask (const uint8_t * kh, const uint8_t * nonce)