mirror of
https://github.com/PurpleI2P/i2pd.git
synced 2025-01-22 12:24:19 +00:00
handle RelayResponse
This commit is contained in:
parent
eb6437050f
commit
40340cf9c2
@ -823,6 +823,8 @@ namespace transport
|
|||||||
HandleRelayRequest (buf + offset, size);
|
HandleRelayRequest (buf + offset, size);
|
||||||
break;
|
break;
|
||||||
case eSSU2BlkRelayResponse:
|
case eSSU2BlkRelayResponse:
|
||||||
|
LogPrint (eLogDebug, "SSU2: RelayResponse");
|
||||||
|
HandleRelayResponse (buf + offset, size);
|
||||||
break;
|
break;
|
||||||
case eSSU2BlkRelayIntro:
|
case eSSU2BlkRelayIntro:
|
||||||
break;
|
break;
|
||||||
@ -1023,19 +1025,9 @@ namespace transport
|
|||||||
LogPrint (eLogWarning, "SSU2: Session with relay tag ", relayTag, " not found");
|
LogPrint (eLogWarning, "SSU2: Session with relay tag ", relayTag, " not found");
|
||||||
return; // TODO: send relay response
|
return; // TODO: send relay response
|
||||||
}
|
}
|
||||||
SignedData s;
|
session->m_RelaySessions.emplace (bufbe32toh (buf + 1), // nonce
|
||||||
s.Insert ((const uint8_t *)"RelayRequestData", 16); // prologue
|
std::make_pair (shared_from_this (), i2p::util::GetSecondsSinceEpoch ()) );
|
||||||
s.Insert (i2p::context.GetIdentHash (), 32); // bhash
|
|
||||||
s.Insert (session->GetRemoteIdentity ()->GetIdentHash (), 32); // chash
|
|
||||||
s.Insert (buf + 1, 14); // nonce, relay tag, timestamp, ver, asz
|
|
||||||
uint8_t asz = buf[14];
|
|
||||||
s.Insert (buf + 15, asz); // Alice Port, Alice IP
|
|
||||||
if (!s.Verify (GetRemoteIdentity (), buf + 15 + asz))
|
|
||||||
{
|
|
||||||
LogPrint (eLogWarning, "SSU2: RelayRequest signature verification failed");
|
|
||||||
return; // TODO: send relay response
|
|
||||||
}
|
|
||||||
|
|
||||||
// send relay intro to Charlie
|
// send relay intro to Charlie
|
||||||
uint8_t payload[SSU2_MTU];
|
uint8_t payload[SSU2_MTU];
|
||||||
size_t payloadSize = CreateRelayIntroBlock (payload, SSU2_MTU, buf + 1, len -1);
|
size_t payloadSize = CreateRelayIntroBlock (payload, SSU2_MTU, buf + 1, len -1);
|
||||||
@ -1067,7 +1059,7 @@ namespace transport
|
|||||||
|
|
||||||
// send relay response to Bob
|
// send relay response to Bob
|
||||||
uint8_t payload[SSU2_MTU];
|
uint8_t payload[SSU2_MTU];
|
||||||
size_t payloadSize = CreateRelayResponseBlock (payload, SSU2_MTU, bufbe32toh (buf + 33), bufbe32toh (buf + 37));
|
size_t payloadSize = CreateRelayResponseBlock (payload, SSU2_MTU, bufbe32toh (buf + 33));
|
||||||
payloadSize += CreatePaddingBlock (payload + payloadSize, SSU2_MTU - payloadSize);
|
payloadSize += CreatePaddingBlock (payload + payloadSize, SSU2_MTU - payloadSize);
|
||||||
SendData (payload, payloadSize);
|
SendData (payload, payloadSize);
|
||||||
|
|
||||||
@ -1076,6 +1068,24 @@ namespace transport
|
|||||||
if (ExtractEndpoint (buf + 47, asz, ep))
|
if (ExtractEndpoint (buf + 47, asz, ep))
|
||||||
m_Server.SendHolePunch (ep);
|
m_Server.SendHolePunch (ep);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SSU2Session::HandleRelayResponse (const uint8_t * buf, size_t len)
|
||||||
|
{
|
||||||
|
auto it = m_RelaySessions.find (bufbe32toh (buf + 2)); // nonce
|
||||||
|
if (it != m_RelaySessions.end ())
|
||||||
|
{
|
||||||
|
if (it->second.first && it->second.first->IsEstablished ())
|
||||||
|
// we are Bob, message from Charlie
|
||||||
|
it->second.first->SendData (buf, len); // forward to Alice as is
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// we are Alice, message from Bob
|
||||||
|
}
|
||||||
|
m_RelaySessions.erase (it);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
LogPrint (eLogWarning, "SSU2: RelayResponse unknown nonce ", bufbe32toh (buf + 2));
|
||||||
|
}
|
||||||
|
|
||||||
bool SSU2Session::ExtractEndpoint (const uint8_t * buf, size_t size, boost::asio::ip::udp::endpoint& ep)
|
bool SSU2Session::ExtractEndpoint (const uint8_t * buf, size_t size, boost::asio::ip::udp::endpoint& ep)
|
||||||
{
|
{
|
||||||
@ -1261,25 +1271,24 @@ namespace transport
|
|||||||
return payloadSize + 3;
|
return payloadSize + 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t SSU2Session::CreateRelayResponseBlock (uint8_t * buf, size_t len, uint32_t nonce, uint32_t relayTag)
|
size_t SSU2Session::CreateRelayResponseBlock (uint8_t * buf, size_t len, uint32_t nonce)
|
||||||
{
|
{
|
||||||
buf[0] = eSSU2BlkRelayResponse;
|
buf[0] = eSSU2BlkRelayResponse;
|
||||||
buf[3] = 0; // flag
|
buf[3] = 0; // flag
|
||||||
buf[4] = 0; // code, accept
|
buf[4] = 0; // code, accept
|
||||||
htobe32buf (buf + 5, nonce); // nonce
|
htobe32buf (buf + 5, nonce); // nonce
|
||||||
htobe32buf (buf + 9, relayTag); // relayTag
|
htobe32buf (buf + 9, i2p::util::GetSecondsSinceEpoch ()); // timestamp
|
||||||
htobe32buf (buf + 13, i2p::util::GetSecondsSinceEpoch ()); // timestamp
|
buf[13] = 2; // ver
|
||||||
buf[17] = 2; // ver
|
size_t csz = CreateEndpoint (buf + 15, len - 15, boost::asio::ip::udp::endpoint (m_Address->host, m_Address->port));
|
||||||
size_t csz = CreateEndpoint (buf + 19, len - 19, boost::asio::ip::udp::endpoint (m_Address->host, m_Address->port));
|
|
||||||
if (!csz) return 0;
|
if (!csz) return 0;
|
||||||
buf[18] = 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 (GetRemoteIdentity ()->GetIdentHash (), 32); // bhash
|
||||||
s.Insert (buf + 9, 10 + csz); // relay tag, 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 + 19 + csz);
|
s.Sign (i2p::context.GetPrivateKeys (), buf + 15 + csz);
|
||||||
size_t payloadSize = 16 + csz + i2p::context.GetIdentity ()->GetSignatureLen ();
|
size_t payloadSize = 12 + csz + i2p::context.GetIdentity ()->GetSignatureLen ();
|
||||||
htobe16buf (buf + 1, payloadSize); // size
|
htobe16buf (buf + 1, payloadSize); // size
|
||||||
return payloadSize + 3;
|
return payloadSize + 3;
|
||||||
}
|
}
|
||||||
@ -1368,6 +1377,16 @@ namespace transport
|
|||||||
m_ReceivePacketNum = *m_OutOfSequencePackets.rbegin ();
|
m_ReceivePacketNum = *m_OutOfSequencePackets.rbegin ();
|
||||||
m_OutOfSequencePackets.clear ();
|
m_OutOfSequencePackets.clear ();
|
||||||
}
|
}
|
||||||
|
for (auto it = m_RelaySessions.begin (); it != m_RelaySessions.end ();)
|
||||||
|
{
|
||||||
|
if (ts > it->second.second + SSU2_RELAY_NONCE_EXPIRATION_TIMEOUT)
|
||||||
|
{
|
||||||
|
LogPrint (eLogWarning, "SSU2: noce ", it->first, " was not responded in ", SSU2_RELAY_NONCE_EXPIRATION_TIMEOUT, " seconds, deleted");
|
||||||
|
it = m_RelaySessions.erase (it);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
++it;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SSU2Session::FlushData ()
|
void SSU2Session::FlushData ()
|
||||||
|
@ -25,7 +25,8 @@ namespace transport
|
|||||||
const int SSU2_CONNECT_TIMEOUT = 5; // 5 seconds
|
const int SSU2_CONNECT_TIMEOUT = 5; // 5 seconds
|
||||||
const int SSU2_TERMINATION_TIMEOUT = 330; // 5.5 minutes
|
const int SSU2_TERMINATION_TIMEOUT = 330; // 5.5 minutes
|
||||||
const int SSU2_TERMINATION_CHECK_TIMEOUT = 30; // 30 seconds
|
const int SSU2_TERMINATION_CHECK_TIMEOUT = 30; // 30 seconds
|
||||||
const int SSU2_TOKEN_EXPIRATION_TIMEOUT = 9; // in second
|
const int SSU2_TOKEN_EXPIRATION_TIMEOUT = 9; // in seconds
|
||||||
|
const int SSU2_RELAY_NONCE_EXPIRATION_TIMEOUT = 10; // in seconds
|
||||||
const size_t SSU2_SOCKET_RECEIVE_BUFFER_SIZE = 0x1FFFF; // 128K
|
const size_t SSU2_SOCKET_RECEIVE_BUFFER_SIZE = 0x1FFFF; // 128K
|
||||||
const size_t SSU2_SOCKET_SEND_BUFFER_SIZE = 0x1FFFF; // 128K
|
const size_t SSU2_SOCKET_SEND_BUFFER_SIZE = 0x1FFFF; // 128K
|
||||||
const size_t SSU2_MTU = 1488;
|
const size_t SSU2_MTU = 1488;
|
||||||
@ -74,6 +75,7 @@ namespace transport
|
|||||||
enum SSU2SessionState
|
enum SSU2SessionState
|
||||||
{
|
{
|
||||||
eSSU2SessionStateUnknown,
|
eSSU2SessionStateUnknown,
|
||||||
|
eSSU2SessionStateIntroduced,
|
||||||
eSSU2SessionStateEstablished,
|
eSSU2SessionStateEstablished,
|
||||||
eSSU2SessionStateTerminated,
|
eSSU2SessionStateTerminated,
|
||||||
eSSU2SessionStateFailed
|
eSSU2SessionStateFailed
|
||||||
@ -188,6 +190,7 @@ namespace transport
|
|||||||
bool ConcatOutOfSequenceFragments (std::shared_ptr<SSU2IncompleteMessage> m); // true if message complete
|
bool ConcatOutOfSequenceFragments (std::shared_ptr<SSU2IncompleteMessage> m); // true if message complete
|
||||||
void HandleRelayRequest (const uint8_t * buf, size_t len);
|
void HandleRelayRequest (const uint8_t * buf, size_t len);
|
||||||
void HandleRelayIntro (const uint8_t * buf, size_t len);
|
void HandleRelayIntro (const uint8_t * buf, size_t len);
|
||||||
|
void HandleRelayResponse (const uint8_t * buf, size_t len);
|
||||||
|
|
||||||
size_t CreateAddressBlock (const boost::asio::ip::udp::endpoint& ep, uint8_t * buf, size_t len);
|
size_t CreateAddressBlock (const boost::asio::ip::udp::endpoint& ep, uint8_t * buf, size_t len);
|
||||||
size_t CreateAckBlock (uint8_t * buf, size_t len);
|
size_t CreateAckBlock (uint8_t * buf, size_t len);
|
||||||
@ -196,7 +199,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, uint32_t relayTag); // Charlie
|
size_t CreateRelayResponseBlock (uint8_t * buf, size_t len, uint32_t nonce); // Charlie
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
@ -213,6 +216,7 @@ namespace transport
|
|||||||
std::set<uint32_t> m_OutOfSequencePackets; // packet nums > receive packet num
|
std::set<uint32_t> m_OutOfSequencePackets; // packet nums > receive packet num
|
||||||
std::map<uint32_t, std::shared_ptr<SentPacket> > m_SentPackets; // packetNum -> packet
|
std::map<uint32_t, std::shared_ptr<SentPacket> > m_SentPackets; // packetNum -> packet
|
||||||
std::map<uint32_t, std::shared_ptr<SSU2IncompleteMessage> > m_IncompleteMessages; // I2NP
|
std::map<uint32_t, std::shared_ptr<SSU2IncompleteMessage> > m_IncompleteMessages; // I2NP
|
||||||
|
std::map<uint32_t, std::pair <std::shared_ptr<SSU2Session>, uint64_t > > m_RelaySessions; // nonce->(Alice, timestamp) for Bob or nonce->(Charlie, timestamp) for Alice
|
||||||
std::list<std::shared_ptr<I2NPMessage> > m_SendQueue;
|
std::list<std::shared_ptr<I2NPMessage> > m_SendQueue;
|
||||||
i2p::I2NPMessagesHandler m_Handler;
|
i2p::I2NPMessagesHandler m_Handler;
|
||||||
bool m_IsDataReceived;
|
bool m_IsDataReceived;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user