diff --git a/libi2pd/SSU2.cpp b/libi2pd/SSU2.cpp index 1c142db1..c1eb09f3 100644 --- a/libi2pd/SSU2.cpp +++ b/libi2pd/SSU2.cpp @@ -374,7 +374,11 @@ namespace transport m_LastSession->ProcessData (buf, len); break; case eSSU2SessionStateSessionCreatedSent: - m_LastSession->ProcessSessionConfirmed (buf, len); + if (!m_LastSession->ProcessSessionConfirmed (buf, len)) + { + m_LastSession->Terminate (); + m_LastSession = nullptr; + } break; case eSSU2SessionStateIntroduced: if (m_LastSession->GetRemoteEndpoint ().address ().is_unspecified ()) diff --git a/libi2pd/SSU2Session.cpp b/libi2pd/SSU2Session.cpp index 367663da..d081e957 100644 --- a/libi2pd/SSU2Session.cpp +++ b/libi2pd/SSU2Session.cpp @@ -325,7 +325,6 @@ namespace transport LogPrint (eLogDebug, "SSU2: Resending ", (int)m_State); m_Server.Send (m_SentHandshakePacket->header.buf, 16, m_SentHandshakePacket->headerX, 48, m_SentHandshakePacket->payload, m_SentHandshakePacket->payloadSize, m_RemoteEndpoint); - m_SentHandshakePacket->numResends++; m_SentHandshakePacket->nextResendTime = ts + SSU2_HANDSHAKE_RESEND_INTERVAL; return; } @@ -678,22 +677,24 @@ namespace transport if (!(header.h.flags[0] & 0xF0)) { // first fragment - m_SessionConfirmedFragment1.reset (new HandshakePacket); - m_SessionConfirmedFragment1->header = header; - memcpy (m_SessionConfirmedFragment1->payload, buf + 16, len - 16); - m_SessionConfirmedFragment1->payloadSize = len - 16; + if (!m_SessionConfirmedFragment1) + { + m_SessionConfirmedFragment1.reset (new HandshakePacket); + m_SessionConfirmedFragment1->header = header; + memcpy (m_SessionConfirmedFragment1->payload, buf + 16, len - 16); + m_SessionConfirmedFragment1->payloadSize = len - 16; + } return true; // wait for second fragment } else { // second fragment if (!m_SessionConfirmedFragment1) return false; // out of sequence - uint8_t fullMsg[2*SSU2_MTU]; header = m_SessionConfirmedFragment1->header; - memcpy (fullMsg + 16, m_SessionConfirmedFragment1->payload, m_SessionConfirmedFragment1->payloadSize); - memcpy (fullMsg + 16 + m_SessionConfirmedFragment1->payloadSize, buf + 16, len - 16); - buf = fullMsg; - len += m_SessionConfirmedFragment1->payloadSize; + memcpy (m_SessionConfirmedFragment1->payload + m_SessionConfirmedFragment1->payloadSize, buf + 16, len - 16); + m_SessionConfirmedFragment1->payloadSize += (len - 16); + buf = m_SessionConfirmedFragment1->payload - 16; + len = m_SessionConfirmedFragment1->payloadSize + 16; } } // KDF for Session Confirmed part 1 @@ -724,6 +725,7 @@ namespace transport return false; } m_NoiseState->MixHash (payload, len - 64); // h = SHA256(h || ciphertext); + if (m_SessionConfirmedFragment1) m_SessionConfirmedFragment1.reset (nullptr); // payload // handle RouterInfo block that must be first if (decryptedPayload[0] != eSSU2BlkRouterInfo) diff --git a/libi2pd/SSU2Session.h b/libi2pd/SSU2Session.h index f5964b8f..e9adfe8e 100644 --- a/libi2pd/SSU2Session.h +++ b/libi2pd/SSU2Session.h @@ -190,10 +190,13 @@ namespace transport int numResends = 0; }; - struct HandshakePacket: public SentPacket + struct HandshakePacket { Header header; uint8_t headerX[48]; // part1 for SessionConfirmed + uint8_t payload[SSU2_MAX_PACKET_SIZE*2]; + size_t payloadSize = 0; + uint32_t nextResendTime = 0; // in seconds }; typedef std::function OnEstablished;