From dc30cd1112fa6c298c4e5cae196427008dbe8d72 Mon Sep 17 00:00:00 2001 From: orignal Date: Sat, 16 Jul 2022 16:08:55 -0400 Subject: [PATCH] handle SessionConfirmed fragments in reversed order --- libi2pd/SSU2Session.cpp | 31 ++++++++++++++++++++++++++----- libi2pd/SSU2Session.h | 1 + 2 files changed, 27 insertions(+), 5 deletions(-) diff --git a/libi2pd/SSU2Session.cpp b/libi2pd/SSU2Session.cpp index 12da45f7..cd18b281 100644 --- a/libi2pd/SSU2Session.cpp +++ b/libi2pd/SSU2Session.cpp @@ -409,7 +409,7 @@ namespace transport } default: { - LogPrint (eLogWarning, "SSU2: Unexpected message type ", (int)header.h.type, " from ", m_RemoteEndpoint); + LogPrint (eLogWarning, "SSU2: Unexpected message type ", (int)header.h.type, " from ", m_RemoteEndpoint, " of ", len, " bytes"); return false; } } @@ -727,8 +727,9 @@ namespace transport header.ll[1] ^= CreateHeaderMask (kh2, buf + (len - 12)); if (header.h.type != eSSU2SessionConfirmed) { - LogPrint (eLogWarning, "SSU2: Unexpected message type ", (int)header.h.type, " instead ", (int)eSSU2SessionConfirmed); - return false; + LogPrint (eLogInfo, "SSU2: Unexpected message type ", (int)header.h.type, " instead ", (int)eSSU2SessionConfirmed); + // TODO: queue up + return true; } // check if fragmented if ((header.h.flags[0] & 0x0F) > 1) @@ -743,13 +744,33 @@ namespace transport m_SessionConfirmedFragment->header = header; memcpy (m_SessionConfirmedFragment->payload, buf + 16, len - 16); m_SessionConfirmedFragment->payloadSize = len - 16; + return true; // wait for second fragment + } + else if (m_SessionConfirmedFragment->isSecondFragment) + { + // we have second fragment + m_SessionConfirmedFragment->header = header; + memmove (m_SessionConfirmedFragment->payload + (len - 16), m_SessionConfirmedFragment->payload, m_SessionConfirmedFragment->payloadSize); + memcpy (m_SessionConfirmedFragment->payload, buf + 16, len - 16); + m_SessionConfirmedFragment->payloadSize += (len - 16); + buf = m_SessionConfirmedFragment->payload - 16; + len = m_SessionConfirmedFragment->payloadSize + 16; } - return true; // wait for second fragment + else + return true; } else { // second fragment - if (!m_SessionConfirmedFragment) return false; // out of sequence + if (!m_SessionConfirmedFragment) + { + // out of sequence, save it + m_SessionConfirmedFragment.reset (new HandshakePacket); + memcpy (m_SessionConfirmedFragment->payload, buf + 16, len - 16); + m_SessionConfirmedFragment->payloadSize = len - 16; + m_SessionConfirmedFragment->isSecondFragment = true; + return true; + } header = m_SessionConfirmedFragment->header; memcpy (m_SessionConfirmedFragment->payload + m_SessionConfirmedFragment->payloadSize, buf + 16, len - 16); m_SessionConfirmedFragment->payloadSize += (len - 16); diff --git a/libi2pd/SSU2Session.h b/libi2pd/SSU2Session.h index e3886a7d..e7fcabac 100644 --- a/libi2pd/SSU2Session.h +++ b/libi2pd/SSU2Session.h @@ -199,6 +199,7 @@ namespace transport uint8_t payload[SSU2_MAX_PACKET_SIZE*2]; size_t payloadSize = 0; uint32_t nextResendTime = 0; // in seconds + bool isSecondFragment = false; // for SessionConfirmed }; typedef std::function OnEstablished;