Browse Source

send errors for RelayIntro

pull/1769/head
orignal 2 years ago
parent
commit
22f9abc2f1
  1. 106
      libi2pd/SSU2Session.cpp
  2. 7
      libi2pd/SSU2Session.h

106
libi2pd/SSU2Session.cpp

@ -858,7 +858,8 @@ namespace transport
htobe32buf (payload + 3, i2p::util::GetSecondsSinceEpoch ()); htobe32buf (payload + 3, i2p::util::GetSecondsSinceEpoch ());
size_t payloadSize = 7; size_t payloadSize = 7;
payloadSize += CreateAddressBlock (payload + payloadSize, SSU2_MAX_PAYLOAD_SIZE - payloadSize, ep); payloadSize += CreateAddressBlock (payload + payloadSize, SSU2_MAX_PAYLOAD_SIZE - payloadSize, ep);
payloadSize += CreateRelayResponseBlock (payload + payloadSize, SSU2_MAX_PAYLOAD_SIZE - payloadSize, nonce); payloadSize += CreateRelayResponseBlock (payload + payloadSize, SSU2_MAX_PAYLOAD_SIZE - payloadSize,
eSSU2RelayResponseCodeAccept ,nonce, true);
payloadSize += CreatePaddingBlock (payload + payloadSize, SSU2_MAX_PAYLOAD_SIZE - payloadSize); payloadSize += CreatePaddingBlock (payload + payloadSize, SSU2_MAX_PAYLOAD_SIZE - payloadSize);
// encrypt // encrypt
uint8_t n[12]; uint8_t n[12];
@ -1300,7 +1301,7 @@ namespace transport
// send relay response back to Alice // send relay response back to Alice
uint8_t payload[SSU2_MAX_PAYLOAD_SIZE]; uint8_t payload[SSU2_MAX_PAYLOAD_SIZE];
size_t payloadSize = CreateRelayResponseBlock (payload, SSU2_MAX_PAYLOAD_SIZE, size_t payloadSize = CreateRelayResponseBlock (payload, SSU2_MAX_PAYLOAD_SIZE,
eSSU2RelayResponseCodeBobRelayTagNotFound, bufbe32toh (buf + 1)); eSSU2RelayResponseCodeBobRelayTagNotFound, bufbe32toh (buf + 1), false);
payloadSize += CreatePaddingBlock (payload + payloadSize, SSU2_MAX_PAYLOAD_SIZE - payloadSize); payloadSize += CreatePaddingBlock (payload + payloadSize, SSU2_MAX_PAYLOAD_SIZE - payloadSize);
SendData (payload, payloadSize); SendData (payload, payloadSize);
return; return;
@ -1324,43 +1325,50 @@ namespace transport
void SSU2Session::HandleRelayIntro (const uint8_t * buf, size_t len) void SSU2Session::HandleRelayIntro (const uint8_t * buf, size_t len)
{ {
// we are Charlie // we are Charlie
SSU2RelayResponseCode code = eSSU2RelayResponseCodeAccept;
auto r = i2p::data::netdb.FindRouter (buf + 1); // Alice auto r = i2p::data::netdb.FindRouter (buf + 1); // Alice
if (!r) if (r)
{ {
LogPrint (eLogError, "SSU2: RelayIntro unknown router to introduce"); SignedData s;
return; s.Insert ((const uint8_t *)"RelayRequestData", 16); // prologue
s.Insert (GetRemoteIdentity ()->GetIdentHash (), 32); // bhash
s.Insert (i2p::context.GetIdentHash (), 32); // chash
s.Insert (buf + 33, 14); // nonce, relay tag, timestamp, ver, asz
uint8_t asz = buf[46];
s.Insert (buf + 47, asz); // Alice Port, Alice IP
if (s.Verify (r->GetIdentity (), buf + 47 + asz))
{
// send HolePunch
boost::asio::ip::udp::endpoint ep;
if (ExtractEndpoint (buf + 47, asz, ep))
{
auto addr = ep.address ().is_v6 () ? r->GetSSU2V6Address () : r->GetSSU2V4Address ();
if (addr)
SendHolePunch (bufbe32toh (buf + 33), ep, addr->i);
else
{
LogPrint (eLogWarning, "SSU2: RelayInfo unknown address");
code = eSSU2RelayResponseCodeCharlieAliceIsUnknown;
}
}
}
else
{
LogPrint (eLogWarning, "SSU2: RelayIntro signature verification failed");
code = eSSU2RelayResponseCodeCharlieSignatureFailure;
}
} }
SignedData s; else
s.Insert ((const uint8_t *)"RelayRequestData", 16); // prologue
s.Insert (GetRemoteIdentity ()->GetIdentHash (), 32); // bhash
s.Insert (i2p::context.GetIdentHash (), 32); // chash
s.Insert (buf + 33, 14); // nonce, relay tag, timestamp, ver, asz
uint8_t asz = buf[46];
s.Insert (buf + 47, asz); // Alice Port, Alice IP
if (!s.Verify (r->GetIdentity (), buf + 47 + asz))
{ {
LogPrint (eLogWarning, "SSU2: RelayIntro signature verification failed"); LogPrint (eLogError, "SSU2: RelayIntro unknown router to introduce");
return; // TODO: send relay response code = eSSU2RelayResponseCodeCharlieAliceIsUnknown;
} }
// send relay response to Bob // send relay response to Bob
uint8_t payload[SSU2_MAX_PAYLOAD_SIZE]; uint8_t payload[SSU2_MAX_PAYLOAD_SIZE];
size_t payloadSize = CreateRelayResponseBlock (payload, SSU2_MAX_PAYLOAD_SIZE, bufbe32toh (buf + 33)); size_t payloadSize = CreateRelayResponseBlock (payload, SSU2_MAX_PAYLOAD_SIZE,
code, bufbe32toh (buf + 33), true);
payloadSize += CreatePaddingBlock (payload + payloadSize, SSU2_MAX_PAYLOAD_SIZE - payloadSize); payloadSize += CreatePaddingBlock (payload + payloadSize, SSU2_MAX_PAYLOAD_SIZE - payloadSize);
SendData (payload, payloadSize); SendData (payload, payloadSize);
// send HolePunch
boost::asio::ip::udp::endpoint ep;
if (ExtractEndpoint (buf + 47, asz, ep))
{
auto r = i2p::data::netdb.FindRouter (buf + 1); // Alice
if (r)
{
auto addr = ep.address ().is_v6 () ? r->GetSSU2V6Address () : r->GetSSU2V4Address ();
if (addr)
SendHolePunch (bufbe32toh (buf + 33), ep, addr->i);
}
}
} }
void SSU2Session::HandleRelayResponse (const uint8_t * buf, size_t len) void SSU2Session::HandleRelayResponse (const uint8_t * buf, size_t len)
@ -1827,21 +1835,26 @@ namespace transport
return payloadSize + 3; return payloadSize + 3;
} }
size_t SSU2Session::CreateRelayResponseBlock (uint8_t * buf, size_t len, uint32_t nonce) size_t SSU2Session::CreateRelayResponseBlock (uint8_t * buf, size_t len,
SSU2RelayResponseCode code, uint32_t nonce, bool endpoint)
{ {
buf[0] = eSSU2BlkRelayResponse; buf[0] = eSSU2BlkRelayResponse;
buf[3] = 0; // flag buf[3] = 0; // flag
buf[4] = 0; // code, accept buf[4] = code; // code
htobe32buf (buf + 5, nonce); // nonce htobe32buf (buf + 5, nonce); // nonce
htobe32buf (buf + 9, i2p::util::GetSecondsSinceEpoch ()); // timestamp htobe32buf (buf + 9, i2p::util::GetSecondsSinceEpoch ()); // timestamp
buf[13] = 2; // ver buf[13] = 2; // ver
size_t csz = CreateEndpoint (buf + 15, len - 15, boost::asio::ip::udp::endpoint (m_Address->host, m_Address->port)); size_t csz = 0;
if (!csz) return 0; if (endpoint)
{
csz = CreateEndpoint (buf + 15, len - 15, boost::asio::ip::udp::endpoint (m_Address->host, m_Address->port));
if (!csz) return 0;
}
buf[14] = csz; // csz buf[14] = csz; // csz
// signature // signature
SignedData s; SignedData s;
s.Insert ((const uint8_t *)"RelayAgreementOK", 16); // prologue s.Insert ((const uint8_t *)"RelayAgreementOK", 16); // prologue
s.Insert (GetRemoteIdentity ()->GetIdentHash (), 32); // bhash s.Insert (endpoint ? GetRemoteIdentity ()->GetIdentHash () : i2p::context.GetIdentity ()->GetIdentHash (), 32); // bhash
s.Insert (buf + 5, 10 + csz); // nonce, timestamp, ver, csz and Charlie's endpoint s.Insert (buf + 5, 10 + csz); // nonce, timestamp, ver, csz and Charlie's endpoint
s.Sign (i2p::context.GetPrivateKeys (), buf + 15 + csz); s.Sign (i2p::context.GetPrivateKeys (), buf + 15 + csz);
size_t payloadSize = 12 + csz + i2p::context.GetIdentity ()->GetSignatureLen (); size_t payloadSize = 12 + csz + i2p::context.GetIdentity ()->GetSignatureLen ();
@ -1849,27 +1862,6 @@ namespace transport
return payloadSize + 3; return payloadSize + 3;
} }
size_t SSU2Session::CreateRelayResponseBlock (uint8_t * buf, size_t len, SSU2RelayResponseCode code, uint32_t nonce)
{
// we are Bob
buf[0] = eSSU2BlkRelayResponse;
buf[3] = 0; // flag
buf[4] = (uint8_t)code; // code
htobe32buf (buf + 5, nonce); // nonce
htobe32buf (buf + 9, i2p::util::GetSecondsSinceEpoch ()); // timestamp
buf[13] = 2; // ver
buf[14] = 0; // csz
// signature
SignedData s;
s.Insert ((const uint8_t *)"RelayAgreementOK", 16); // prologue
s.Insert (i2p::context.GetIdentity ()->GetIdentHash (), 32); // bhash
s.Insert (buf + 5, 10); // nonce, timestamp, ver, csz
s.Sign (i2p::context.GetPrivateKeys (), buf + 15);
size_t payloadSize = 12 + i2p::context.GetIdentity ()->GetSignatureLen ();
htobe16buf (buf + 1, payloadSize); // size
return payloadSize + 3;
}
size_t SSU2Session::CreatePeerTestBlock (uint8_t * buf, size_t len, uint8_t msg, SSU2PeerTestCode code, size_t SSU2Session::CreatePeerTestBlock (uint8_t * buf, size_t len, uint8_t msg, SSU2PeerTestCode code,
const uint8_t * routerHash, const uint8_t * signedData, size_t signedDataLen) const uint8_t * routerHash, const uint8_t * signedData, size_t signedDataLen)
{ {

7
libi2pd/SSU2Session.h

@ -107,7 +107,9 @@ namespace transport
enum SSU2RelayResponseCode enum SSU2RelayResponseCode
{ {
eSSU2RelayResponseCodeAccept = 0, eSSU2RelayResponseCodeAccept = 0,
eSSU2RelayResponseCodeBobRelayTagNotFound = 5 eSSU2RelayResponseCodeBobRelayTagNotFound = 5,
eSSU2RelayResponseCodeCharlieSignatureFailure = 67,
eSSU2RelayResponseCodeCharlieAliceIsUnknown = 70
}; };
struct SSU2IncompleteMessage struct SSU2IncompleteMessage
@ -249,8 +251,7 @@ namespace transport
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, uint32_t nonce); // Charlie size_t CreateRelayResponseBlock (uint8_t * buf, size_t len, SSU2RelayResponseCode code, uint32_t nonce, bool endpoint); // add endpoint for Chralie and no endpoint for Bob
size_t CreateRelayResponseBlock (uint8_t * buf, size_t len, SSU2RelayResponseCode code, uint32_t nonce); // Bob reject
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, 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

Loading…
Cancel
Save