mirror of
https://github.com/PurpleI2P/i2pd.git
synced 2025-01-22 08:14:15 +00:00
don't allocate payload buffer for every single ECIESx25519 message
This commit is contained in:
parent
a37cf058cd
commit
6ecfe0789f
@ -795,8 +795,9 @@ namespace garlic
|
|||||||
|
|
||||||
std::shared_ptr<I2NPMessage> ECIESX25519AEADRatchetSession::WrapSingleMessage (std::shared_ptr<const I2NPMessage> msg)
|
std::shared_ptr<I2NPMessage> ECIESX25519AEADRatchetSession::WrapSingleMessage (std::shared_ptr<const I2NPMessage> msg)
|
||||||
{
|
{
|
||||||
auto payload = CreatePayload (msg, m_State != eSessionStateEstablished);
|
uint8_t * payload = GetOwner ()->GetPayloadBuffer ();
|
||||||
size_t len = payload.size ();
|
if (!payload) return nullptr;
|
||||||
|
size_t len = CreatePayload (msg, m_State != eSessionStateEstablished, payload);
|
||||||
if (!len) return nullptr;
|
if (!len) return nullptr;
|
||||||
auto m = NewI2NPMessage (len + 100); // 96 + 4
|
auto m = NewI2NPMessage (len + 100); // 96 + 4
|
||||||
m->Align (12); // in order to get buf aligned to 16 (12 + 4)
|
m->Align (12); // in order to get buf aligned to 16 (12 + 4)
|
||||||
@ -805,27 +806,27 @@ namespace garlic
|
|||||||
switch (m_State)
|
switch (m_State)
|
||||||
{
|
{
|
||||||
case eSessionStateEstablished:
|
case eSessionStateEstablished:
|
||||||
if (!NewExistingSessionMessage (payload.data (), payload.size (), buf, m->maxLen))
|
if (!NewExistingSessionMessage (payload, len, buf, m->maxLen))
|
||||||
return nullptr;
|
return nullptr;
|
||||||
len += 24;
|
len += 24;
|
||||||
break;
|
break;
|
||||||
case eSessionStateNew:
|
case eSessionStateNew:
|
||||||
if (!NewOutgoingSessionMessage (payload.data (), payload.size (), buf, m->maxLen))
|
if (!NewOutgoingSessionMessage (payload, len, buf, m->maxLen))
|
||||||
return nullptr;
|
return nullptr;
|
||||||
len += 96;
|
len += 96;
|
||||||
break;
|
break;
|
||||||
case eSessionStateNewSessionReceived:
|
case eSessionStateNewSessionReceived:
|
||||||
if (!NewSessionReplyMessage (payload.data (), payload.size (), buf, m->maxLen))
|
if (!NewSessionReplyMessage (payload, len, buf, m->maxLen))
|
||||||
return nullptr;
|
return nullptr;
|
||||||
len += 72;
|
len += 72;
|
||||||
break;
|
break;
|
||||||
case eSessionStateNewSessionReplySent:
|
case eSessionStateNewSessionReplySent:
|
||||||
if (!NextNewSessionReplyMessage (payload.data (), payload.size (), buf, m->maxLen))
|
if (!NextNewSessionReplyMessage (payload, len, buf, m->maxLen))
|
||||||
return nullptr;
|
return nullptr;
|
||||||
len += 72;
|
len += 72;
|
||||||
break;
|
break;
|
||||||
case eSessionStateOneTime:
|
case eSessionStateOneTime:
|
||||||
if (!NewOutgoingSessionMessage (payload.data (), payload.size (), buf, m->maxLen, false))
|
if (!NewOutgoingSessionMessage (payload, len, buf, m->maxLen, false))
|
||||||
return nullptr;
|
return nullptr;
|
||||||
len += 96;
|
len += 96;
|
||||||
break;
|
break;
|
||||||
@ -845,7 +846,7 @@ namespace garlic
|
|||||||
return WrapSingleMessage (msg);
|
return WrapSingleMessage (msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<uint8_t> ECIESX25519AEADRatchetSession::CreatePayload (std::shared_ptr<const I2NPMessage> msg, bool first)
|
size_t ECIESX25519AEADRatchetSession::CreatePayload (std::shared_ptr<const I2NPMessage> msg, bool first, uint8_t * payload)
|
||||||
{
|
{
|
||||||
uint64_t ts = i2p::util::GetMillisecondsSinceEpoch ();
|
uint64_t ts = i2p::util::GetMillisecondsSinceEpoch ();
|
||||||
size_t payloadLen = 0;
|
size_t payloadLen = 0;
|
||||||
@ -907,89 +908,93 @@ namespace garlic
|
|||||||
payloadLen += paddingSize + 3;
|
payloadLen += paddingSize + 3;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
std::vector<uint8_t> v(payloadLen);
|
|
||||||
if (payloadLen)
|
if (payloadLen)
|
||||||
{
|
{
|
||||||
|
if (payloadLen > I2NP_MAX_MESSAGE_SIZE)
|
||||||
|
{
|
||||||
|
LogPrint (eLogError, "Garlic: payload length ", payloadLen, " is too long");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
m_LastSentTimestamp = ts;
|
m_LastSentTimestamp = ts;
|
||||||
size_t offset = 0;
|
size_t offset = 0;
|
||||||
// DateTime
|
// DateTime
|
||||||
if (first)
|
if (first)
|
||||||
{
|
{
|
||||||
v[offset] = eECIESx25519BlkDateTime; offset++;
|
payload[offset] = eECIESx25519BlkDateTime; offset++;
|
||||||
htobe16buf (v.data () + offset, 4); offset += 2;
|
htobe16buf (payload + offset, 4); offset += 2;
|
||||||
htobe32buf (v.data () + offset, ts/1000); offset += 4; // in seconds
|
htobe32buf (payload + offset, ts/1000); offset += 4; // in seconds
|
||||||
}
|
}
|
||||||
// LeaseSet
|
// LeaseSet
|
||||||
if (leaseSet)
|
if (leaseSet)
|
||||||
{
|
{
|
||||||
offset += CreateLeaseSetClove (leaseSet, ts, v.data () + offset, payloadLen - offset);
|
offset += CreateLeaseSetClove (leaseSet, ts, payload + offset, payloadLen - offset);
|
||||||
if (!first)
|
if (!first)
|
||||||
{
|
{
|
||||||
// ack request
|
// ack request
|
||||||
v[offset] = eECIESx25519BlkAckRequest; offset++;
|
payload[offset] = eECIESx25519BlkAckRequest; offset++;
|
||||||
htobe16buf (v.data () + offset, 1); offset += 2;
|
htobe16buf (payload + offset, 1); offset += 2;
|
||||||
v[offset] = 0; offset++; // flags
|
payload[offset] = 0; offset++; // flags
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// msg
|
// msg
|
||||||
if (msg)
|
if (msg)
|
||||||
offset += CreateGarlicClove (msg, v.data () + offset, payloadLen - offset);
|
offset += CreateGarlicClove (msg, payload + offset, payloadLen - offset);
|
||||||
// ack
|
// ack
|
||||||
if (m_AckRequests.size () > 0)
|
if (m_AckRequests.size () > 0)
|
||||||
{
|
{
|
||||||
v[offset] = eECIESx25519BlkAck; offset++;
|
payload[offset] = eECIESx25519BlkAck; offset++;
|
||||||
htobe16buf (v.data () + offset, m_AckRequests.size () * 4); offset += 2;
|
htobe16buf (payload + offset, m_AckRequests.size () * 4); offset += 2;
|
||||||
for (auto& it: m_AckRequests)
|
for (auto& it: m_AckRequests)
|
||||||
{
|
{
|
||||||
htobe16buf (v.data () + offset, it.first); offset += 2;
|
htobe16buf (payload + offset, it.first); offset += 2;
|
||||||
htobe16buf (v.data () + offset, it.second); offset += 2;
|
htobe16buf (payload + offset, it.second); offset += 2;
|
||||||
}
|
}
|
||||||
m_AckRequests.clear ();
|
m_AckRequests.clear ();
|
||||||
}
|
}
|
||||||
// next keys
|
// next keys
|
||||||
if (m_SendReverseKey)
|
if (m_SendReverseKey)
|
||||||
{
|
{
|
||||||
v[offset] = eECIESx25519BlkNextKey; offset++;
|
payload[offset] = eECIESx25519BlkNextKey; offset++;
|
||||||
htobe16buf (v.data () + offset, m_NextReceiveRatchet->newKey ? 35 : 3); offset += 2;
|
htobe16buf (payload + offset, m_NextReceiveRatchet->newKey ? 35 : 3); offset += 2;
|
||||||
v[offset] = ECIESX25519_NEXT_KEY_REVERSE_KEY_FLAG;
|
payload[offset] = ECIESX25519_NEXT_KEY_REVERSE_KEY_FLAG;
|
||||||
int keyID = m_NextReceiveRatchet->keyID - 1;
|
int keyID = m_NextReceiveRatchet->keyID - 1;
|
||||||
if (m_NextReceiveRatchet->newKey)
|
if (m_NextReceiveRatchet->newKey)
|
||||||
{
|
{
|
||||||
v[offset] |= ECIESX25519_NEXT_KEY_KEY_PRESENT_FLAG;
|
payload[offset] |= ECIESX25519_NEXT_KEY_KEY_PRESENT_FLAG;
|
||||||
keyID++;
|
keyID++;
|
||||||
}
|
}
|
||||||
offset++; // flag
|
offset++; // flag
|
||||||
htobe16buf (v.data () + offset, keyID); offset += 2; // keyid
|
htobe16buf (payload + offset, keyID); offset += 2; // keyid
|
||||||
if (m_NextReceiveRatchet->newKey)
|
if (m_NextReceiveRatchet->newKey)
|
||||||
{
|
{
|
||||||
memcpy (v.data () + offset, m_NextReceiveRatchet->key->GetPublicKey (), 32);
|
memcpy (payload + offset, m_NextReceiveRatchet->key->GetPublicKey (), 32);
|
||||||
offset += 32; // public key
|
offset += 32; // public key
|
||||||
}
|
}
|
||||||
m_SendReverseKey = false;
|
m_SendReverseKey = false;
|
||||||
}
|
}
|
||||||
if (m_SendForwardKey)
|
if (m_SendForwardKey)
|
||||||
{
|
{
|
||||||
v[offset] = eECIESx25519BlkNextKey; offset++;
|
payload[offset] = eECIESx25519BlkNextKey; offset++;
|
||||||
htobe16buf (v.data () + offset, m_NextSendRatchet->newKey ? 35 : 3); offset += 2;
|
htobe16buf (payload + offset, m_NextSendRatchet->newKey ? 35 : 3); offset += 2;
|
||||||
v[offset] = m_NextSendRatchet->newKey ? ECIESX25519_NEXT_KEY_KEY_PRESENT_FLAG : ECIESX25519_NEXT_KEY_REQUEST_REVERSE_KEY_FLAG;
|
payload[offset] = m_NextSendRatchet->newKey ? ECIESX25519_NEXT_KEY_KEY_PRESENT_FLAG : ECIESX25519_NEXT_KEY_REQUEST_REVERSE_KEY_FLAG;
|
||||||
if (!m_NextSendRatchet->keyID) v[offset] |= ECIESX25519_NEXT_KEY_REQUEST_REVERSE_KEY_FLAG; // for first key only
|
if (!m_NextSendRatchet->keyID) payload[offset] |= ECIESX25519_NEXT_KEY_REQUEST_REVERSE_KEY_FLAG; // for first key only
|
||||||
offset++; // flag
|
offset++; // flag
|
||||||
htobe16buf (v.data () + offset, m_NextSendRatchet->keyID); offset += 2; // keyid
|
htobe16buf (payload + offset, m_NextSendRatchet->keyID); offset += 2; // keyid
|
||||||
if (m_NextSendRatchet->newKey)
|
if (m_NextSendRatchet->newKey)
|
||||||
{
|
{
|
||||||
memcpy (v.data () + offset, m_NextSendRatchet->key->GetPublicKey (), 32);
|
memcpy (payload + offset, m_NextSendRatchet->key->GetPublicKey (), 32);
|
||||||
offset += 32; // public key
|
offset += 32; // public key
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// padding
|
// padding
|
||||||
if (paddingSize)
|
if (paddingSize)
|
||||||
{
|
{
|
||||||
v[offset] = eECIESx25519BlkPadding; offset++;
|
payload[offset] = eECIESx25519BlkPadding; offset++;
|
||||||
htobe16buf (v.data () + offset, paddingSize); offset += 2;
|
htobe16buf (payload + offset, paddingSize); offset += 2;
|
||||||
memset (v.data () + offset, 0, paddingSize); offset += paddingSize;
|
memset (payload + offset, 0, paddingSize); offset += paddingSize;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return v;
|
return payloadLen;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t ECIESX25519AEADRatchetSession::CreateGarlicClove (std::shared_ptr<const I2NPMessage> msg, uint8_t * buf, size_t len)
|
size_t ECIESX25519AEADRatchetSession::CreateGarlicClove (std::shared_ptr<const I2NPMessage> msg, uint8_t * buf, size_t len)
|
||||||
|
@ -208,7 +208,7 @@ namespace garlic
|
|||||||
bool NextNewSessionReplyMessage (const uint8_t * payload, size_t len, uint8_t * out, size_t outLen);
|
bool NextNewSessionReplyMessage (const uint8_t * payload, size_t len, uint8_t * out, size_t outLen);
|
||||||
bool NewExistingSessionMessage (const uint8_t * payload, size_t len, uint8_t * out, size_t outLen);
|
bool NewExistingSessionMessage (const uint8_t * payload, size_t len, uint8_t * out, size_t outLen);
|
||||||
|
|
||||||
std::vector<uint8_t> CreatePayload (std::shared_ptr<const I2NPMessage> msg, bool first);
|
size_t CreatePayload (std::shared_ptr<const I2NPMessage> msg, bool first, uint8_t * payload);
|
||||||
size_t CreateGarlicClove (std::shared_ptr<const I2NPMessage> msg, uint8_t * buf, size_t len);
|
size_t CreateGarlicClove (std::shared_ptr<const I2NPMessage> msg, uint8_t * buf, size_t len);
|
||||||
size_t CreateLeaseSetClove (std::shared_ptr<const i2p::data::LocalLeaseSet> ls, uint64_t ts, uint8_t * buf, size_t len);
|
size_t CreateLeaseSetClove (std::shared_ptr<const i2p::data::LocalLeaseSet> ls, uint64_t ts, uint8_t * buf, size_t len);
|
||||||
|
|
||||||
|
@ -433,7 +433,7 @@ namespace garlic
|
|||||||
}
|
}
|
||||||
|
|
||||||
GarlicDestination::GarlicDestination (): m_NumTags (32), // 32 tags by default
|
GarlicDestination::GarlicDestination (): m_NumTags (32), // 32 tags by default
|
||||||
m_NumRatchetInboundTags (0) // 0 means standard
|
m_PayloadBuffer (nullptr), m_NumRatchetInboundTags (0) // 0 means standard
|
||||||
{
|
{
|
||||||
m_Ctx = BN_CTX_new ();
|
m_Ctx = BN_CTX_new ();
|
||||||
}
|
}
|
||||||
@ -441,6 +441,8 @@ namespace garlic
|
|||||||
GarlicDestination::~GarlicDestination ()
|
GarlicDestination::~GarlicDestination ()
|
||||||
{
|
{
|
||||||
BN_CTX_free (m_Ctx);
|
BN_CTX_free (m_Ctx);
|
||||||
|
if (m_PayloadBuffer)
|
||||||
|
delete[] m_PayloadBuffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GarlicDestination::CleanUp ()
|
void GarlicDestination::CleanUp ()
|
||||||
@ -1121,5 +1123,12 @@ namespace garlic
|
|||||||
m_ECIESx25519Sessions.erase (it);
|
m_ECIESx25519Sessions.erase (it);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint8_t * GarlicDestination::GetPayloadBuffer ()
|
||||||
|
{
|
||||||
|
if (!m_PayloadBuffer)
|
||||||
|
m_PayloadBuffer = new uint8_t[I2NP_MAX_MESSAGE_SIZE];
|
||||||
|
return m_PayloadBuffer;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -250,7 +250,8 @@ namespace garlic
|
|||||||
void AddECIESx25519Session (const uint8_t * staticKey, ECIESX25519AEADRatchetSessionPtr session);
|
void AddECIESx25519Session (const uint8_t * staticKey, ECIESX25519AEADRatchetSessionPtr session);
|
||||||
void RemoveECIESx25519Session (const uint8_t * staticKey);
|
void RemoveECIESx25519Session (const uint8_t * staticKey);
|
||||||
void HandleECIESx25519GarlicClove (const uint8_t * buf, size_t len);
|
void HandleECIESx25519GarlicClove (const uint8_t * buf, size_t len);
|
||||||
|
uint8_t * GetPayloadBuffer ();
|
||||||
|
|
||||||
virtual void ProcessGarlicMessage (std::shared_ptr<I2NPMessage> msg);
|
virtual void ProcessGarlicMessage (std::shared_ptr<I2NPMessage> msg);
|
||||||
virtual void ProcessDeliveryStatusMessage (std::shared_ptr<I2NPMessage> msg);
|
virtual void ProcessDeliveryStatusMessage (std::shared_ptr<I2NPMessage> msg);
|
||||||
virtual void SetLeaseSetUpdated ();
|
virtual void SetLeaseSetUpdated ();
|
||||||
@ -284,6 +285,7 @@ namespace garlic
|
|||||||
std::mutex m_SessionsMutex;
|
std::mutex m_SessionsMutex;
|
||||||
std::unordered_map<i2p::data::IdentHash, ElGamalAESSessionPtr> m_Sessions;
|
std::unordered_map<i2p::data::IdentHash, ElGamalAESSessionPtr> m_Sessions;
|
||||||
std::unordered_map<i2p::data::Tag<32>, ECIESX25519AEADRatchetSessionPtr> m_ECIESx25519Sessions; // static key -> session
|
std::unordered_map<i2p::data::Tag<32>, ECIESX25519AEADRatchetSessionPtr> m_ECIESx25519Sessions; // static key -> session
|
||||||
|
uint8_t * m_PayloadBuffer; // for ECIESX25519AEADRatchet
|
||||||
// incoming
|
// incoming
|
||||||
int m_NumRatchetInboundTags;
|
int m_NumRatchetInboundTags;
|
||||||
std::unordered_map<SessionTag, std::shared_ptr<AESDecryption>, std::hash<i2p::data::Tag<32> > > m_Tags;
|
std::unordered_map<SessionTag, std::shared_ptr<AESDecryption>, std::hash<i2p::data::Tag<32> > > m_Tags;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user