Browse Source

handle PeerTest msg 4 if msg 5 was received before

pull/1769/head
orignal 2 years ago
parent
commit
58186f0283
  1. 29
      libi2pd/SSU2Session.cpp
  2. 7
      libi2pd/SSU2Session.h

29
libi2pd/SSU2Session.cpp

@ -1413,8 +1413,13 @@ namespace transport
void SSU2Session::HandlePeerTest (const uint8_t * buf, size_t len) void SSU2Session::HandlePeerTest (const uint8_t * buf, size_t len)
{ {
uint32_t nonce = bufbe32toh ((buf[0] == 2 || buf[0] == 4) ? buf + 36 : buf + 4); // hash is presented for msg 2 and 4 only if (len < 3) return;
switch (buf[0]) // msg uint8_t msg = buf[0];
size_t offset = 3; // points to signed data
if (msg == 2 || msg == 4) offset += 32; // hash is presented for msg 2 and 4 only
if (len < offset + 5) return;
uint32_t nonce = bufbe32toh (buf + offset + 1);
switch (msg) // msg
{ {
case 1: // Bob from Alice case 1: // Bob from Alice
{ {
@ -1437,7 +1442,7 @@ namespace transport
} }
// PeerTest to Charlie // PeerTest to Charlie
payloadSize += CreatePeerTestBlock (payload + payloadSize, SSU2_MAX_PAYLOAD_SIZE - payloadSize, 2, payloadSize += CreatePeerTestBlock (payload + payloadSize, SSU2_MAX_PAYLOAD_SIZE - payloadSize, 2,
eSSU2PeerTestCodeAccept, GetRemoteIdentity ()->GetIdentHash (), buf + 3, len - 3); eSSU2PeerTestCodeAccept, GetRemoteIdentity ()->GetIdentHash (), buf + offset, len - offset);
payloadSize += CreatePaddingBlock (payload + payloadSize, SSU2_MAX_PAYLOAD_SIZE - payloadSize); payloadSize += CreatePaddingBlock (payload + payloadSize, SSU2_MAX_PAYLOAD_SIZE - payloadSize);
session->SendData (payload, payloadSize); session->SendData (payload, payloadSize);
} }
@ -1446,7 +1451,7 @@ namespace transport
// Charlie not found, send error back to Alice // Charlie not found, send error back to Alice
uint8_t payload[SSU2_MAX_PAYLOAD_SIZE], zeroHash[32] = {0}; uint8_t payload[SSU2_MAX_PAYLOAD_SIZE], zeroHash[32] = {0};
size_t payloadSize = CreatePeerTestBlock (payload, SSU2_MAX_PAYLOAD_SIZE, 4, size_t payloadSize = CreatePeerTestBlock (payload, SSU2_MAX_PAYLOAD_SIZE, 4,
eSSU2PeerTestCodeBobNoCharlieAvailable, zeroHash, buf + 3, len - 3); eSSU2PeerTestCodeBobNoCharlieAvailable, zeroHash, buf + offset, len - offset);
payloadSize += CreatePaddingBlock (payload + payloadSize, SSU2_MAX_PAYLOAD_SIZE - payloadSize); payloadSize += CreatePaddingBlock (payload + payloadSize, SSU2_MAX_PAYLOAD_SIZE - payloadSize);
SendData (payload, payloadSize); SendData (payload, payloadSize);
} }
@ -1536,7 +1541,7 @@ namespace transport
} }
// PeerTest to Alice // PeerTest to Alice
payloadSize += CreatePeerTestBlock (payload + payloadSize, SSU2_MAX_PAYLOAD_SIZE, 4, payloadSize += CreatePeerTestBlock (payload + payloadSize, SSU2_MAX_PAYLOAD_SIZE, 4,
(SSU2PeerTestCode)buf[1], GetRemoteIdentity ()->GetIdentHash (), buf + 3, len - 3); (SSU2PeerTestCode)buf[1], GetRemoteIdentity ()->GetIdentHash (), buf + offset, len - offset);
if (payloadSize < SSU2_MAX_PAYLOAD_SIZE) if (payloadSize < SSU2_MAX_PAYLOAD_SIZE)
payloadSize += CreatePaddingBlock (payload + payloadSize, SSU2_MAX_PAYLOAD_SIZE - payloadSize); payloadSize += CreatePaddingBlock (payload + payloadSize, SSU2_MAX_PAYLOAD_SIZE - payloadSize);
it->second.first->SendData (payload, payloadSize); it->second.first->SendData (payload, payloadSize);
@ -1558,6 +1563,12 @@ namespace transport
auto addr = r->GetSSU2Address (m_Address->IsV4 ()); auto addr = r->GetSSU2Address (m_Address->IsV4 ());
if (addr) if (addr)
it->second.first->m_Address = addr; it->second.first->m_Address = addr;
if (it->second.first->m_State == eSSU2SessionStatePeerTestReceived)
{
// msg 5 already received. send msg 6
it->second.first->m_State = eSSU2SessionStatePeerTest;
it->second.first->SendPeerTest (6, buf + offset, len - offset, addr->i);
}
} }
m_PeerTests.erase (it); m_PeerTests.erase (it);
} }
@ -1569,17 +1580,17 @@ namespace transport
if (htobe64 (((uint64_t)nonce << 32) | nonce) == m_SourceConnID) if (htobe64 (((uint64_t)nonce << 32) | nonce) == m_SourceConnID)
{ {
if (m_Address) if (m_Address)
SendPeerTest (6, buf + 3, len - 3, m_Address->i); SendPeerTest (6, buf + offset, len - offset, m_Address->i);
else else
// TODO: we should wait for msg 4 // we received msg 5 before msg 4
LogPrint (eLogWarning, "SSU2: Unknown address for peer test 5"); m_State = eSSU2SessionStatePeerTestReceived;
} }
else else
LogPrint (eLogWarning, "SSU2: Peer test 5 nonce mismatch ", nonce, " connID=", m_SourceConnID); LogPrint (eLogWarning, "SSU2: Peer test 5 nonce mismatch ", nonce, " connID=", m_SourceConnID);
break; break;
case 6: // Charlie from Alice case 6: // Charlie from Alice
if (m_Address) if (m_Address)
SendPeerTest (7, buf + 3, len - 3, m_Address->i); SendPeerTest (7, buf + offset, len - offset, m_Address->i);
else else
LogPrint (eLogWarning, "SSU2: Unknown address for peer test 6"); LogPrint (eLogWarning, "SSU2: Unknown address for peer test 6");
m_Server.RemoveSession (~(((uint64_t)htobe32 (nonce) << 32) | htobe32 (nonce))); m_Server.RemoveSession (~(((uint64_t)htobe32 (nonce) << 32) | htobe32 (nonce)));

7
libi2pd/SSU2Session.h

@ -79,11 +79,12 @@ namespace transport
enum SSU2SessionState enum SSU2SessionState
{ {
eSSU2SessionStateUnknown, eSSU2SessionStateUnknown,
eSSU2SessionStateIntroduced,
eSSU2SessionStatePeerTest,
eSSU2SessionStateEstablished, eSSU2SessionStateEstablished,
eSSU2SessionStateTerminated, eSSU2SessionStateTerminated,
eSSU2SessionStateFailed eSSU2SessionStateFailed,
eSSU2SessionStateIntroduced,
eSSU2SessionStatePeerTest,
eSSU2SessionStatePeerTestReceived // 5 before 4
}; };
enum SSU2PeerTestCode enum SSU2PeerTestCode

Loading…
Cancel
Save