moved SendPeerTest for msgs 5,6,7 to SSU2PeerTestSession

This commit is contained in:
orignal 2024-09-24 14:37:27 -04:00
parent 5cd0248494
commit 74f0330730
2 changed files with 63 additions and 51 deletions

View File

@ -1425,42 +1425,6 @@ namespace transport
return true; return true;
} }
void SSU2Session::SendPeerTest (uint8_t msg, const uint8_t * signedData, size_t signedDataLen, const uint8_t * introKey)
{
Header header;
uint8_t h[32], payload[SSU2_MAX_PACKET_SIZE];
// fill packet
header.h.connID = m_DestConnID; // dest id
RAND_bytes (header.buf + 8, 4); // random packet num
header.h.type = eSSU2PeerTest;
header.h.flags[0] = 2; // ver
header.h.flags[1] = (uint8_t)i2p::context.GetNetID (); // netID
header.h.flags[2] = 0; // flag
memcpy (h, header.buf, 16);
memcpy (h + 16, &m_SourceConnID, 8); // source id
// payload
payload[0] = eSSU2BlkDateTime;
htobe16buf (payload + 1, 4);
htobe32buf (payload + 3, (i2p::util::GetMillisecondsSinceEpoch () + 500)/1000);
size_t payloadSize = 7;
if (msg == 6 || msg == 7)
payloadSize += CreateAddressBlock (payload + payloadSize, m_MaxPayloadSize - payloadSize, m_RemoteEndpoint);
payloadSize += CreatePeerTestBlock (payload + payloadSize, m_MaxPayloadSize - payloadSize,
msg, eSSU2PeerTestCodeAccept, nullptr, signedData, signedDataLen);
payloadSize += CreatePaddingBlock (payload + payloadSize, m_MaxPayloadSize - payloadSize);
// encrypt
uint8_t n[12];
CreateNonce (be32toh (header.h.packetNum), n);
i2p::crypto::AEADChaCha20Poly1305 (payload, payloadSize, h, 32, introKey, n, payload, payloadSize + 16, true);
payloadSize += 16;
header.ll[0] ^= CreateHeaderMask (introKey, payload + (payloadSize - 24));
header.ll[1] ^= CreateHeaderMask (introKey, payload + (payloadSize - 12));
memset (n, 0, 12);
i2p::crypto::ChaCha20 (h + 16, 16, introKey, n, h + 16);
// send
m_Server.Send (header.buf, 16, h + 16, 16, payload, payloadSize, m_RemoteEndpoint);
}
bool SSU2Session::ProcessPeerTest (uint8_t * buf, size_t len) bool SSU2Session::ProcessPeerTest (uint8_t * buf, size_t len)
{ {
LogPrint (eLogWarning, "SSU2: Unexpected peer test message for this session type"); LogPrint (eLogWarning, "SSU2: Unexpected peer test message for this session type");
@ -2256,10 +2220,9 @@ 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)); 0, htobe64 (((uint64_t)nonce << 32) | nonce));
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);
session->SendPeerTest (5, newSignedData.data (), newSignedData.size (), addr->i); session->SendPeerTest (5, newSignedData.data (), newSignedData.size (), addr);
} }
else else
code = eSSU2PeerTestCodeCharlieAliceIsAlreadyConnected; code = eSSU2PeerTestCodeCharlieAliceIsAlreadyConnected;
@ -2340,7 +2303,6 @@ namespace transport
auto addr = r->GetSSU2Address (m_Address->IsV4 ()); auto addr = r->GetSSU2Address (m_Address->IsV4 ());
if (addr) if (addr)
{ {
session->m_Address = addr;
if (session->GetMsgNumReceived () >= 5) if (session->GetMsgNumReceived () >= 5)
{ {
// msg 5 already received // msg 5 already received
@ -2349,7 +2311,7 @@ namespace transport
if (!session->IsConnectedRecently ()) if (!session->IsConnectedRecently ())
SetRouterStatus (eRouterStatusOK); SetRouterStatus (eRouterStatusOK);
// send msg 6 // send msg 6
session->SendPeerTest (6, buf + offset, len - offset, addr->i); session->SendPeerTest (6, buf + offset, len - offset, addr);
} }
else else
LogPrint (eLogWarning, "SSU2: PeerTest 4 received, but msg ", session->GetMsgNumReceived (), " already received"); LogPrint (eLogWarning, "SSU2: PeerTest 4 received, but msg ", session->GetMsgNumReceived (), " already received");
@ -3158,14 +3120,13 @@ namespace transport
if (htobe64 (((uint64_t)nonce << 32) | nonce) == GetSourceConnID ()) if (htobe64 (((uint64_t)nonce << 32) | nonce) == GetSourceConnID ())
{ {
m_IsConnectedRecently = GetServer ().IsConnectedRecently (GetRemoteEndpoint ()); m_IsConnectedRecently = GetServer ().IsConnectedRecently (GetRemoteEndpoint ());
auto addr = GetAddress (); if (GetAddress ())
if (addr)
{ {
if (!m_IsConnectedRecently) if (!m_IsConnectedRecently)
SetRouterStatus (eRouterStatusOK); SetRouterStatus (eRouterStatusOK);
else if (m_IsStatusChanged && GetRouterStatus () == eRouterStatusFirewalled) else if (m_IsStatusChanged && GetRouterStatus () == eRouterStatusFirewalled)
SetRouterStatus (eRouterStatusUnknown); SetRouterStatus (eRouterStatusUnknown);
SendPeerTest (6, buf + offset, len - offset, addr->i); SendPeerTest (6, buf + offset, len - offset);
} }
} }
else else
@ -3174,9 +3135,8 @@ namespace transport
} }
case 6: // Charlie from Alice case 6: // Charlie from Alice
{ {
auto addr = GetAddress (); if (GetAddress ())
if (addr) SendPeerTest (7, buf + offset, len - offset);
SendPeerTest (7, buf + offset, len - offset, addr->i);
else else
LogPrint (eLogWarning, "SSU2: Unknown address for peer test 6"); LogPrint (eLogWarning, "SSU2: Unknown address for peer test 6");
GetServer ().RemoveSession (~htobe64 (((uint64_t)nonce << 32) | nonce)); GetServer ().RemoveSession (~htobe64 (((uint64_t)nonce << 32) | nonce));
@ -3195,6 +3155,52 @@ namespace transport
return; return;
} }
m_MsgNumReceived = msg; m_MsgNumReceived = msg;
}
void SSU2PeerTestSession::SendPeerTest (uint8_t msg, const uint8_t * signedData, size_t signedDataLen)
{
auto addr = GetAddress ();
if (!addr) return;
Header header;
uint8_t h[32], payload[SSU2_MAX_PACKET_SIZE];
// fill packet
header.h.connID = GetDestConnID (); // dest id
RAND_bytes (header.buf + 8, 4); // random packet num
header.h.type = eSSU2PeerTest;
header.h.flags[0] = 2; // ver
header.h.flags[1] = (uint8_t)i2p::context.GetNetID (); // netID
header.h.flags[2] = 0; // flag
memcpy (h, header.buf, 16);
htobuf64 (h + 16, GetSourceConnID ()); // source id
// payload
payload[0] = eSSU2BlkDateTime;
htobe16buf (payload + 1, 4);
htobe32buf (payload + 3, (i2p::util::GetMillisecondsSinceEpoch () + 500)/1000);
size_t payloadSize = 7;
if (msg == 6 || msg == 7)
payloadSize += CreateAddressBlock (payload + payloadSize, GetMaxPayloadSize () - payloadSize, GetRemoteEndpoint ());
payloadSize += CreatePeerTestBlock (payload + payloadSize, GetMaxPayloadSize () - payloadSize,
msg, eSSU2PeerTestCodeAccept, nullptr, signedData, signedDataLen);
payloadSize += CreatePaddingBlock (payload + payloadSize, GetMaxPayloadSize () - payloadSize);
// encrypt
uint8_t n[12];
CreateNonce (be32toh (header.h.packetNum), n);
i2p::crypto::AEADChaCha20Poly1305 (payload, payloadSize, h, 32, addr->i, n, payload, payloadSize + 16, true);
payloadSize += 16;
header.ll[0] ^= CreateHeaderMask (addr->i, payload + (payloadSize - 24));
header.ll[1] ^= CreateHeaderMask (addr->i, payload + (payloadSize - 12));
memset (n, 0, 12);
i2p::crypto::ChaCha20 (h + 16, 16, addr->i, n, h + 16);
// send
GetServer ().Send (header.buf, 16, h + 16, 16, payload, payloadSize, GetRemoteEndpoint ());
}
void SSU2PeerTestSession::SendPeerTest (uint8_t msg, const uint8_t * signedData, size_t signedDataLen,
std::shared_ptr<const i2p::data::RouterInfo::Address> addr)
{
if (!addr) return;
SetAddress (addr);
SendPeerTest (msg, signedData, signedDataLen);
} }
} }
} }

View File

@ -281,14 +281,19 @@ namespace transport
SSU2Server& GetServer () { return m_Server; } SSU2Server& GetServer () { return m_Server; }
RouterStatus GetRouterStatus () const; RouterStatus GetRouterStatus () const;
void SetRouterStatus (RouterStatus status) const; void SetRouterStatus (RouterStatus status) const;
size_t GetMaxPayloadSize () const { return m_MaxPayloadSize; }
uint64_t GetSourceConnID () const { return m_SourceConnID; } uint64_t GetSourceConnID () const { return m_SourceConnID; }
void SetSourceConnID (uint64_t sourceConnID) { m_SourceConnID = sourceConnID; } void SetSourceConnID (uint64_t sourceConnID) { m_SourceConnID = sourceConnID; }
uint64_t GetDestConnID () const { return m_DestConnID; } uint64_t GetDestConnID () const { return m_DestConnID; }
void SetDestConnID (uint64_t destConnID) { m_DestConnID = destConnID; } void SetDestConnID (uint64_t destConnID) { m_DestConnID = destConnID; }
void SetAddress (std::shared_ptr<const i2p::data::RouterInfo::Address> addr) { m_Address = addr; }
void HandlePayload (const uint8_t * buf, size_t len); void HandlePayload (const uint8_t * buf, size_t len);
void SendPeerTest (uint8_t msg, const uint8_t * signedData, size_t signedDataLen, const uint8_t * introKey); // PeerTest message
size_t CreateAddressBlock (uint8_t * buf, size_t len, const boost::asio::ip::udp::endpoint& ep);
size_t CreatePaddingBlock (uint8_t * buf, size_t len, size_t minSize = 0);
size_t CreatePeerTestBlock (uint8_t * buf, size_t len, uint8_t msg, SSU2PeerTestCode code, const uint8_t * routerHash, const uint8_t * signedData, size_t signedDataLen);
private: private:
@ -339,17 +344,14 @@ namespace transport
virtual void HandlePeerTest (const uint8_t * buf, size_t len); virtual void HandlePeerTest (const uint8_t * buf, size_t len);
void HandleI2NPMsg (std::shared_ptr<I2NPMessage>&& msg); void HandleI2NPMsg (std::shared_ptr<I2NPMessage>&& msg);
size_t CreateAddressBlock (uint8_t * buf, size_t len, const boost::asio::ip::udp::endpoint& ep);
size_t CreateRouterInfoBlock (uint8_t * buf, size_t len, std::shared_ptr<const i2p::data::RouterInfo> r); size_t CreateRouterInfoBlock (uint8_t * buf, size_t len, std::shared_ptr<const i2p::data::RouterInfo> r);
size_t CreateRouterInfoBlock (uint8_t * buf, size_t len, std::shared_ptr<const i2p::data::RouterInfo::Buffer> riBuffer); size_t CreateRouterInfoBlock (uint8_t * buf, size_t len, std::shared_ptr<const i2p::data::RouterInfo::Buffer> riBuffer);
size_t CreateAckBlock (uint8_t * buf, size_t len); size_t CreateAckBlock (uint8_t * buf, size_t len);
size_t CreatePaddingBlock (uint8_t * buf, size_t len, size_t minSize = 0);
size_t CreateI2NPBlock (uint8_t * buf, size_t len, std::shared_ptr<I2NPMessage>&& msg); size_t CreateI2NPBlock (uint8_t * buf, size_t len, std::shared_ptr<I2NPMessage>&& msg);
size_t CreateFirstFragmentBlock (uint8_t * buf, size_t len, std::shared_ptr<I2NPMessage> msg); size_t CreateFirstFragmentBlock (uint8_t * buf, size_t len, std::shared_ptr<I2NPMessage> msg);
size_t CreateFollowOnFragmentBlock (uint8_t * buf, size_t len, std::shared_ptr<I2NPMessage> msg, uint8_t& fragmentNum, uint32_t msgID); size_t CreateFollowOnFragmentBlock (uint8_t * buf, size_t len, std::shared_ptr<I2NPMessage> msg, uint8_t& fragmentNum, uint32_t msgID);
size_t CreateRelayIntroBlock (uint8_t * buf, size_t len, const uint8_t * introData, size_t introDataLen); size_t CreateRelayIntroBlock (uint8_t * buf, size_t len, const uint8_t * introData, size_t introDataLen);
size_t CreateRelayResponseBlock (uint8_t * buf, size_t len, SSU2RelayResponseCode code, uint32_t nonce, uint64_t token, bool v4); size_t CreateRelayResponseBlock (uint8_t * buf, size_t len, SSU2RelayResponseCode code, uint32_t nonce, uint64_t token, bool v4);
size_t CreatePeerTestBlock (uint8_t * buf, size_t len, uint8_t msg, SSU2PeerTestCode code, const uint8_t * routerHash, const uint8_t * signedData, size_t signedDataLen);
size_t CreatePeerTestBlock (uint8_t * buf, size_t len, uint32_t nonce); // Alice size_t CreatePeerTestBlock (uint8_t * buf, size_t len, uint32_t nonce); // Alice
size_t CreateTerminationBlock (uint8_t * buf, size_t len); size_t CreateTerminationBlock (uint8_t * buf, size_t len);
@ -398,12 +400,16 @@ namespace transport
uint8_t GetMsgNumReceived () const { return m_MsgNumReceived; } uint8_t GetMsgNumReceived () const { return m_MsgNumReceived; }
bool IsConnectedRecently () const { return m_IsConnectedRecently; } bool IsConnectedRecently () const { return m_IsConnectedRecently; }
void SetStatusChanged () { m_IsStatusChanged = true; } void SetStatusChanged () { m_IsStatusChanged = true; }
void SendPeerTest (uint8_t msg, const uint8_t * signedData, size_t signedDataLen,
std::shared_ptr<const i2p::data::RouterInfo::Address> addr);
bool ProcessPeerTest (uint8_t * buf, size_t len) override; bool ProcessPeerTest (uint8_t * buf, size_t len) override;
private: private:
void SendPeerTest (uint8_t msg, const uint8_t * signedData, size_t signedDataLen); // PeerTest message
void HandlePeerTest (const uint8_t * buf, size_t len) override; void HandlePeerTest (const uint8_t * buf, size_t len) override;
private: private:
uint8_t m_MsgNumReceived; uint8_t m_MsgNumReceived;