mirror of
https://github.com/PurpleI2P/i2pd.git
synced 2025-01-22 21:37:17 +01:00
wait for Ack for SessionConfirmed or resend
This commit is contained in:
parent
ae77d4ad22
commit
dd1dd3b7cf
|
@ -359,6 +359,7 @@ namespace transport
|
||||||
switch (m_LastSession->GetState ())
|
switch (m_LastSession->GetState ())
|
||||||
{
|
{
|
||||||
case eSSU2SessionStateEstablished:
|
case eSSU2SessionStateEstablished:
|
||||||
|
case eSSU2SessionStateSessionConfirmedSent:
|
||||||
m_LastSession->ProcessData (buf, len);
|
m_LastSession->ProcessData (buf, len);
|
||||||
break;
|
break;
|
||||||
case eSSU2SessionStateSessionCreatedSent:
|
case eSSU2SessionStateSessionCreatedSent:
|
||||||
|
|
|
@ -306,8 +306,7 @@ namespace transport
|
||||||
// resend handshake packet
|
// resend handshake packet
|
||||||
if (m_SentHandshakePacket && ts >= m_SentHandshakePacket->nextResendTime)
|
if (m_SentHandshakePacket && ts >= m_SentHandshakePacket->nextResendTime)
|
||||||
{
|
{
|
||||||
// TODO: implement SessionConfirmed
|
LogPrint (eLogDebug, "SSU2: Resending ", (int)m_State);
|
||||||
LogPrint (eLogDebug, "SSU2: Resending ", (m_State == eSSU2SessionStateSessionRequestSent) ? "SessionRequest" : "SessionCreated");
|
|
||||||
m_Server.Send (m_SentHandshakePacket->header.buf, 16, m_SentHandshakePacket->headerX, 48,
|
m_Server.Send (m_SentHandshakePacket->header.buf, 16, m_SentHandshakePacket->headerX, 48,
|
||||||
m_SentHandshakePacket->payload, m_SentHandshakePacket->payloadSize, m_RemoteEndpoint);
|
m_SentHandshakePacket->payload, m_SentHandshakePacket->payloadSize, m_RemoteEndpoint);
|
||||||
m_SentHandshakePacket->numResends++;
|
m_SentHandshakePacket->numResends++;
|
||||||
|
@ -575,7 +574,6 @@ namespace transport
|
||||||
m_Server.AddSession (shared_from_this ());
|
m_Server.AddSession (shared_from_this ());
|
||||||
SendSessionConfirmed (headerX + 16);
|
SendSessionConfirmed (headerX + 16);
|
||||||
KDFDataPhase (m_KeyDataSend, m_KeyDataReceive);
|
KDFDataPhase (m_KeyDataSend, m_KeyDataReceive);
|
||||||
Established ();
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -583,10 +581,14 @@ namespace transport
|
||||||
void SSU2Session::SendSessionConfirmed (const uint8_t * Y)
|
void SSU2Session::SendSessionConfirmed (const uint8_t * Y)
|
||||||
{
|
{
|
||||||
// we are Alice
|
// we are Alice
|
||||||
|
m_SentHandshakePacket.reset (new HandshakePacket);
|
||||||
|
auto ts = i2p::util::GetSecondsSinceEpoch ();
|
||||||
|
m_SentHandshakePacket->nextResendTime = ts + SSU2_HANDSHAKE_RESEND_INTERVAL;
|
||||||
|
|
||||||
uint8_t kh2[32];
|
uint8_t kh2[32];
|
||||||
i2p::crypto::HKDF (m_NoiseState->m_CK, nullptr, 0, "SessionConfirmed", kh2, 32); // k_header_2 = HKDF(chainKey, ZEROLEN, "SessionConfirmed", 32)
|
i2p::crypto::HKDF (m_NoiseState->m_CK, nullptr, 0, "SessionConfirmed", kh2, 32); // k_header_2 = HKDF(chainKey, ZEROLEN, "SessionConfirmed", 32)
|
||||||
// fill packet
|
// fill packet
|
||||||
Header header;
|
Header& header = m_SentHandshakePacket->header;
|
||||||
header.h.connID = m_DestConnID; // dest id
|
header.h.connID = m_DestConnID; // dest id
|
||||||
header.h.packetNum = 0;
|
header.h.packetNum = 0;
|
||||||
header.h.type = eSSU2SessionConfirmed;
|
header.h.type = eSSU2SessionConfirmed;
|
||||||
|
@ -594,7 +596,7 @@ namespace transport
|
||||||
header.h.flags[0] = 1; // frag, total fragments always 1
|
header.h.flags[0] = 1; // frag, total fragments always 1
|
||||||
// payload
|
// payload
|
||||||
const size_t maxPayloadSize = SSU2_MAX_PAYLOAD_SIZE - 48; // part 2
|
const size_t maxPayloadSize = SSU2_MAX_PAYLOAD_SIZE - 48; // part 2
|
||||||
uint8_t payload[maxPayloadSize + 16];
|
uint8_t * payload = m_SentHandshakePacket->payload;
|
||||||
size_t payloadSize = CreateRouterInfoBlock (payload, maxPayloadSize, i2p::context.GetSharedRouterInfo ());
|
size_t payloadSize = CreateRouterInfoBlock (payload, maxPayloadSize, i2p::context.GetSharedRouterInfo ());
|
||||||
// TODO: check is RouterInfo doesn't fit and split by two fragments
|
// TODO: check is RouterInfo doesn't fit and split by two fragments
|
||||||
if (payloadSize < maxPayloadSize)
|
if (payloadSize < maxPayloadSize)
|
||||||
|
@ -602,7 +604,7 @@ namespace transport
|
||||||
// KDF for Session Confirmed part 1
|
// KDF for Session Confirmed part 1
|
||||||
m_NoiseState->MixHash (header.buf, 16); // h = SHA256(h || header)
|
m_NoiseState->MixHash (header.buf, 16); // h = SHA256(h || header)
|
||||||
// Encrypt part 1
|
// Encrypt part 1
|
||||||
uint8_t part1[48];
|
uint8_t * part1 = m_SentHandshakePacket->headerX;
|
||||||
uint8_t nonce[12];
|
uint8_t nonce[12];
|
||||||
CreateNonce (1, nonce);
|
CreateNonce (1, nonce);
|
||||||
i2p::crypto::AEADChaCha20Poly1305 (i2p::context.GetSSU2StaticPublicKey (), 32, m_NoiseState->m_H, 32, m_NoiseState->m_CK + 32, nonce, part1, 48, true);
|
i2p::crypto::AEADChaCha20Poly1305 (i2p::context.GetSSU2StaticPublicKey (), 32, m_NoiseState->m_H, 32, m_NoiseState->m_CK + 32, nonce, part1, 48, true);
|
||||||
|
@ -619,6 +621,8 @@ namespace transport
|
||||||
// Encrypt header
|
// Encrypt header
|
||||||
header.ll[0] ^= CreateHeaderMask (m_Address->i, payload + (payloadSize - 24));
|
header.ll[0] ^= CreateHeaderMask (m_Address->i, payload + (payloadSize - 24));
|
||||||
header.ll[1] ^= CreateHeaderMask (kh2, payload + (payloadSize - 12));
|
header.ll[1] ^= CreateHeaderMask (kh2, payload + (payloadSize - 12));
|
||||||
|
m_State = eSSU2SessionStateSessionConfirmedSent;
|
||||||
|
m_SentHandshakePacket->payloadSize = payloadSize;
|
||||||
// send
|
// send
|
||||||
m_Server.Send (header.buf, 16, part1, 48, payload, payloadSize, m_RemoteEndpoint);
|
m_Server.Send (header.buf, 16, part1, 48, payload, payloadSize, m_RemoteEndpoint);
|
||||||
m_SendPacketNum++;
|
m_SendPacketNum++;
|
||||||
|
@ -1199,6 +1203,11 @@ namespace transport
|
||||||
|
|
||||||
void SSU2Session::HandleAck (const uint8_t * buf, size_t len)
|
void SSU2Session::HandleAck (const uint8_t * buf, size_t len)
|
||||||
{
|
{
|
||||||
|
if (m_State == eSSU2SessionStateSessionConfirmedSent)
|
||||||
|
{
|
||||||
|
Established ();
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (m_SentPackets.empty ()) return;
|
if (m_SentPackets.empty ()) return;
|
||||||
if (len < 5) return;
|
if (len < 5) return;
|
||||||
// acnt
|
// acnt
|
||||||
|
|
|
@ -83,6 +83,7 @@ namespace transport
|
||||||
eSSU2SessionStateTokenReceived,
|
eSSU2SessionStateTokenReceived,
|
||||||
eSSU2SessionStateSessionRequestSent,
|
eSSU2SessionStateSessionRequestSent,
|
||||||
eSSU2SessionStateSessionCreatedSent,
|
eSSU2SessionStateSessionCreatedSent,
|
||||||
|
eSSU2SessionStateSessionConfirmedSent,
|
||||||
eSSU2SessionStateEstablished,
|
eSSU2SessionStateEstablished,
|
||||||
eSSU2SessionStateTerminated,
|
eSSU2SessionStateTerminated,
|
||||||
eSSU2SessionStateFailed,
|
eSSU2SessionStateFailed,
|
||||||
|
@ -163,7 +164,7 @@ namespace transport
|
||||||
struct HandshakePacket: public SentPacket
|
struct HandshakePacket: public SentPacket
|
||||||
{
|
{
|
||||||
Header header;
|
Header header;
|
||||||
uint8_t headerX[48]; // not used in SessionConfirmed
|
uint8_t headerX[48]; // part1 for SessionConfirmed
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef std::function<void ()> OnEstablished;
|
typedef std::function<void ()> OnEstablished;
|
||||||
|
|
Loading…
Reference in a new issue