diff --git a/libi2pd/I2NPProtocol.cpp b/libi2pd/I2NPProtocol.cpp index 5ae89c23..369107b4 100644 --- a/libi2pd/I2NPProtocol.cpp +++ b/libi2pd/I2NPProtocol.cpp @@ -36,6 +36,11 @@ namespace i2p return std::make_shared >(); } + std::shared_ptr NewI2NPMediumMessage () + { + return std::make_shared >(); + } + std::shared_ptr NewI2NPTunnelMessage (bool endpoint) { return i2p::tunnel::tunnels.NewI2NPTunnelMessage (endpoint); @@ -43,7 +48,10 @@ namespace i2p std::shared_ptr NewI2NPMessage (size_t len) { - return (len < I2NP_MAX_SHORT_MESSAGE_SIZE - I2NP_HEADER_SIZE - 2) ? NewI2NPShortMessage () : NewI2NPMessage (); + len += I2NP_HEADER_SIZE + 2; + if (len <= I2NP_MAX_SHORT_MESSAGE_SIZE) return NewI2NPShortMessage (); + if (len <= I2NP_MAX_MEDIUM_MESSAGE_SIZE) return NewI2NPMediumMessage (); + return NewI2NPMessage (); } void I2NPMessage::FillI2NPMessageHeader (I2NPMessageType msgType, uint32_t replyMsgID, bool checksum) diff --git a/libi2pd/I2NPProtocol.h b/libi2pd/I2NPProtocol.h index 80757501..c0685190 100644 --- a/libi2pd/I2NPProtocol.h +++ b/libi2pd/I2NPProtocol.h @@ -140,6 +140,7 @@ namespace tunnel const size_t I2NP_MAX_MESSAGE_SIZE = 62708; const size_t I2NP_MAX_SHORT_MESSAGE_SIZE = 4096; + const size_t I2NP_MAX_MEDIUM_MESSAGE_SIZE = 16384; const unsigned int I2NP_MESSAGE_EXPIRATION_TIMEOUT = 8000; // in milliseconds (as initial RTT) const unsigned int I2NP_MESSAGE_CLOCK_SKEW = 60*1000; // 1 minute in milliseconds @@ -262,6 +263,7 @@ namespace tunnel std::shared_ptr NewI2NPMessage (); std::shared_ptr NewI2NPShortMessage (); + std::shared_ptr NewI2NPMediumMessage (); std::shared_ptr NewI2NPTunnelMessage (bool endpoint); std::shared_ptr NewI2NPMessage (size_t len); diff --git a/libi2pd/SSU2Session.cpp b/libi2pd/SSU2Session.cpp index 9a2fea9a..4d3a9866 100644 --- a/libi2pd/SSU2Session.cpp +++ b/libi2pd/SSU2Session.cpp @@ -23,7 +23,7 @@ namespace transport if (msg->len + fragmentSize > msg->maxLen) { LogPrint (eLogInfo, "SSU2: I2NP message size ", msg->maxLen, " is not enough"); - auto newMsg = NewI2NPMessage (); + auto newMsg = NewI2NPMessage (msg->len + fragmentSize); *newMsg = *msg; msg = newMsg; } diff --git a/libi2pd/TunnelEndpoint.cpp b/libi2pd/TunnelEndpoint.cpp index 9c294374..7d3b3cbe 100644 --- a/libi2pd/TunnelEndpoint.cpp +++ b/libi2pd/TunnelEndpoint.cpp @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2020, The PurpleI2P Project +* Copyright (c) 2013-2023, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -208,7 +208,7 @@ namespace tunnel if (msg.data->len + size > msg.data->maxLen) { // LogPrint (eLogWarning, "TunnelMessage: I2NP message size ", msg.data->maxLen, " is not enough"); - auto newMsg = NewI2NPMessage (); + auto newMsg = NewI2NPMessage (msg.data->len + size); *newMsg = *(msg.data); msg.data = newMsg; } @@ -297,11 +297,11 @@ namespace tunnel if (msg.data->len + size > msg.data->maxLen) { LogPrint (eLogWarning, "TunnelMessage: Tunnel endpoint I2NP message size ", msg.data->maxLen, " is not enough"); - auto newMsg = NewI2NPMessage (); + auto newMsg = NewI2NPMessage (msg.data->len + size); *newMsg = *(msg.data); msg.data = newMsg; } - if (msg.data->Concat (it->second->data.data (), size) < size) // concatenate out-of-sync fragment + if (msg.data->Concat (it->second->data.data (), size) < size) // concatenate out-of-sync fragment LogPrint (eLogError, "TunnelMessage: Tunnel endpoint I2NP buffer overflow ", msg.data->maxLen); if (it->second->isLastFragment) // message complete