Browse Source

Send peer test msg 6 with delay if msg 4 was received before msg 5

pull/2108/head
orignal 1 month ago
parent
commit
0213f058d1
  1. 30
      libi2pd/SSU2OutOfSession.cpp
  2. 7
      libi2pd/SSU2OutOfSession.h
  3. 4
      libi2pd/SSU2Session.cpp

30
libi2pd/SSU2OutOfSession.cpp

@ -83,6 +83,7 @@ namespace transport
{ {
if (htobe64 (((uint64_t)nonce << 32) | nonce) == GetSourceConnID ()) if (htobe64 (((uint64_t)nonce << 32) | nonce) == GetSourceConnID ())
{ {
m_PeerTestResendTimer.cancel (); // calcel delayed msg 6 if any
m_IsConnectedRecently = GetServer ().IsConnectedRecently (GetRemoteEndpoint ()); m_IsConnectedRecently = GetServer ().IsConnectedRecently (GetRemoteEndpoint ());
if (GetAddress ()) if (GetAddress ())
{ {
@ -111,9 +112,6 @@ namespace transport
case 7: // Alice from Charlie 2 case 7: // Alice from Charlie 2
{ {
m_PeerTestResendTimer.cancel (); // no more msg 6 resends m_PeerTestResendTimer.cancel (); // no more msg 6 resends
auto addr = GetAddress ();
if (addr && addr->IsV6 ())
i2p::context.SetStatusV6 (eRouterStatusOK); // set status OK for ipv6 even if from SSU2
GetServer ().AddConnectedRecently (GetRemoteEndpoint (), i2p::util::GetSecondsSinceEpoch ()); GetServer ().AddConnectedRecently (GetRemoteEndpoint (), i2p::util::GetSecondsSinceEpoch ());
GetServer ().RequestRemoveSession (GetConnID ()); GetServer ().RequestRemoveSession (GetConnID ());
break; break;
@ -163,7 +161,7 @@ namespace transport
GetServer ().Send (header.buf, 16, h + 16, 16, payload, payloadSize, GetRemoteEndpoint ()); GetServer ().Send (header.buf, 16, h + 16, 16, payload, payloadSize, GetRemoteEndpoint ());
} }
void SSU2PeerTestSession::SendPeerTest (uint8_t msg, const uint8_t * signedData, size_t signedDataLen) void SSU2PeerTestSession::SendPeerTest (uint8_t msg, const uint8_t * signedData, size_t signedDataLen, bool delayed)
{ {
#if __cplusplus >= 202002L // C++20 #if __cplusplus >= 202002L // C++20
m_SignedData.assign (signedData, signedData + signedDataLen); m_SignedData.assign (signedData, signedData + signedDataLen);
@ -171,18 +169,19 @@ namespace transport
m_SignedData.resize (signedDataLen); m_SignedData.resize (signedDataLen);
memcpy (m_SignedData.data (), signedData, signedDataLen); memcpy (m_SignedData.data (), signedData, signedDataLen);
#endif #endif
if (!delayed)
SendPeerTest (msg); SendPeerTest (msg);
// schedule resend for msgs 5 or 6 // schedule resend for msgs 5 or 6
if (msg == 5 || msg == 6) if (msg == 5 || msg == 6)
ScheduleResend (); ScheduleResend (msg);
} }
void SSU2PeerTestSession::SendPeerTest (uint8_t msg, const uint8_t * signedData, size_t signedDataLen, void SSU2PeerTestSession::SendPeerTest (uint8_t msg, const uint8_t * signedData, size_t signedDataLen,
std::shared_ptr<const i2p::data::RouterInfo::Address> addr) std::shared_ptr<const i2p::data::RouterInfo::Address> addr, bool delayed)
{ {
if (!addr) return; if (!addr) return;
SetAddress (addr); SetAddress (addr);
SendPeerTest (msg, signedData, signedDataLen); SendPeerTest (msg, signedData, signedDataLen, delayed);
} }
void SSU2PeerTestSession::Connect () void SSU2PeerTestSession::Connect ()
@ -196,32 +195,29 @@ namespace transport
return false; return false;
} }
void SSU2PeerTestSession::ScheduleResend () void SSU2PeerTestSession::ScheduleResend (uint8_t msg)
{ {
if (m_NumResends < SSU2_PEER_TEST_MAX_NUM_RESENDS) if (m_NumResends < SSU2_PEER_TEST_MAX_NUM_RESENDS)
{ {
m_PeerTestResendTimer.expires_from_now (boost::posix_time::milliseconds( m_PeerTestResendTimer.expires_from_now (boost::posix_time::milliseconds(
SSU2_PEER_TEST_RESEND_INTERVAL + GetServer ().GetRng ()() % SSU2_PEER_TEST_RESEND_INTERVAL_VARIANCE)); SSU2_PEER_TEST_RESEND_INTERVAL + GetServer ().GetRng ()() % SSU2_PEER_TEST_RESEND_INTERVAL_VARIANCE));
std::weak_ptr<SSU2PeerTestSession> s(std::static_pointer_cast<SSU2PeerTestSession>(shared_from_this ())); std::weak_ptr<SSU2PeerTestSession> s(std::static_pointer_cast<SSU2PeerTestSession>(shared_from_this ()));
m_PeerTestResendTimer.async_wait ([s](const boost::system::error_code& ecode) m_PeerTestResendTimer.async_wait ([s, msg](const boost::system::error_code& ecode)
{ {
if (ecode != boost::asio::error::operation_aborted) if (ecode != boost::asio::error::operation_aborted)
{ {
auto s1 = s.lock (); auto s1 = s.lock ();
if (s1) if (s1)
{ {
int msg = 0; if (msg > s1->m_MsgNumReceived)
if (s1->m_MsgNumReceived < 6)
msg = (s1->m_MsgNumReceived == 5) ? 6 : 5;
if (msg) // 5 or 6
{ {
s1->SendPeerTest (msg); s1->SendPeerTest (msg);
s1->ScheduleResend (); s1->m_NumResends++;
s1->ScheduleResend (msg);
} }
} }
} }
}); });
m_NumResends++;
} }
} }
@ -229,7 +225,7 @@ namespace transport
const boost::asio::ip::udp::endpoint& remoteEndpoint, const boost::asio::ip::udp::endpoint& remoteEndpoint,
std::shared_ptr<const i2p::data::RouterInfo::Address> addr): std::shared_ptr<const i2p::data::RouterInfo::Address> addr):
SSU2Session (server), // we create full incoming session SSU2Session (server), // we create full incoming session
m_Nonce (nonce), m_NumResends (0), m_HolePunchResendTimer (server.GetService ()) m_NumResends (0), m_HolePunchResendTimer (server.GetService ())
{ {
// we are Charlie // we are Charlie
uint64_t destConnID = htobe64 (((uint64_t)nonce << 32) | nonce); // dest id uint64_t destConnID = htobe64 (((uint64_t)nonce << 32) | nonce); // dest id
@ -313,11 +309,11 @@ namespace transport
if (s1 && s1->GetState () == eSSU2SessionStateHolePunch) if (s1 && s1->GetState () == eSSU2SessionStateHolePunch)
{ {
s1->SendHolePunch (); s1->SendHolePunch ();
s1->m_NumResends++;
s1->ScheduleResend (); s1->ScheduleResend ();
} }
} }
}); });
m_NumResends++;
} }
} }

7
libi2pd/SSU2OutOfSession.h

@ -31,18 +31,18 @@ namespace transport
void SetStatusChanged () { m_IsStatusChanged = true; } void SetStatusChanged () { m_IsStatusChanged = true; }
void SendPeerTest (uint8_t msg, const uint8_t * signedData, size_t signedDataLen, void SendPeerTest (uint8_t msg, const uint8_t * signedData, size_t signedDataLen,
std::shared_ptr<const i2p::data::RouterInfo::Address> addr); std::shared_ptr<const i2p::data::RouterInfo::Address> addr, bool delayed = false);
bool ProcessPeerTest (uint8_t * buf, size_t len) override; bool ProcessPeerTest (uint8_t * buf, size_t len) override;
void Connect () override; // outgoing void Connect () override; // outgoing
bool ProcessFirstIncomingMessage (uint64_t connID, uint8_t * buf, size_t len) override; // incoming bool ProcessFirstIncomingMessage (uint64_t connID, uint8_t * buf, size_t len) override; // incoming
private: private:
void SendPeerTest (uint8_t msg, const uint8_t * signedData, size_t signedDataLen); // PeerTest message void SendPeerTest (uint8_t msg, const uint8_t * signedData, size_t signedDataLen, bool delayed = false); // PeerTest message
void SendPeerTest (uint8_t msg); // send or resend m_SignedData void SendPeerTest (uint8_t msg); // send or resend m_SignedData
void HandlePeerTest (const uint8_t * buf, size_t len) override; void HandlePeerTest (const uint8_t * buf, size_t len) override;
void ScheduleResend (); void ScheduleResend (uint8_t msg);
private: private:
@ -74,7 +74,6 @@ namespace transport
private: private:
uint32_t m_Nonce;
int m_NumResends; int m_NumResends;
std::vector<uint8_t> m_RelayResponseBlock; std::vector<uint8_t> m_RelayResponseBlock;
boost::asio::deadline_timer m_HolePunchResendTimer; boost::asio::deadline_timer m_HolePunchResendTimer;

4
libi2pd/SSU2Session.cpp

@ -2312,7 +2312,7 @@ namespace transport
{ {
if (!session->IsConnectedRecently ()) if (!session->IsConnectedRecently ())
SetRouterStatus (eRouterStatusOK); SetRouterStatus (eRouterStatusOK);
// send msg 6 // send msg 6 immeditely
session->SendPeerTest (6, buf + offset, len - offset, addr); session->SendPeerTest (6, buf + offset, len - offset, addr);
} }
else else
@ -2323,6 +2323,8 @@ namespace transport
session->m_Address = addr; session->m_Address = addr;
if (GetTestingState ()) if (GetTestingState ())
{ {
// schedule msg 6 with delay
session->SendPeerTest (6, buf + offset, len - offset, addr, true);
SetTestingState (false); SetTestingState (false);
if (GetRouterStatus () != eRouterStatusFirewalled && addr->IsPeerTesting ()) if (GetRouterStatus () != eRouterStatusFirewalled && addr->IsPeerTesting ())
{ {

Loading…
Cancel
Save