Browse Source

limit number of incoming ECIES sessions. Don't try to create ECIES session for incoming stream

pull/2125/head
orignal 4 days ago
parent
commit
3c4926f377
  1. 25
      libi2pd/Garlic.cpp
  2. 5
      libi2pd/Garlic.h
  3. 22
      libi2pd/Streaming.cpp

25
libi2pd/Garlic.cpp

@ -426,7 +426,8 @@ namespace garlic
} }
GarlicDestination::GarlicDestination (): m_NumTags (32), // 32 tags by default GarlicDestination::GarlicDestination (): m_NumTags (32), // 32 tags by default
m_PayloadBuffer (nullptr), m_NumRatchetInboundTags (0) // 0 means standard m_PayloadBuffer (nullptr), m_LastIncomingSessionTimestamp (0),
m_NumRatchetInboundTags (0) // 0 means standard
{ {
} }
@ -539,9 +540,17 @@ namespace garlic
else if (SupportsEncryptionType (i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD)) else if (SupportsEncryptionType (i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD))
{ {
// otherwise ECIESx25519 // otherwise ECIESx25519
auto session = std::make_shared<ECIESX25519AEADRatchetSession> (this, false); // incoming auto ts = i2p::util::GetMillisecondsSinceEpoch ();
if (!session->HandleNextMessage (buf, length, nullptr, 0)) if (ts > m_LastIncomingSessionTimestamp + INCOMING_SESSIONS_MINIMAL_INTERVAL)
LogPrint (eLogError, "Garlic: Can't handle ECIES-X25519-AEAD-Ratchet message"); {
auto session = std::make_shared<ECIESX25519AEADRatchetSession> (this, false); // incoming
if (session->HandleNextMessage (buf, length, nullptr, 0))
m_LastIncomingSessionTimestamp = ts;
else
LogPrint (eLogError, "Garlic: Can't handle ECIES-X25519-AEAD-Ratchet message");
}
else
LogPrint (eLogWarning, "Garlic: Incoming sessions come too ofter");
} }
else else
LogPrint (eLogError, "Garlic: Failed to decrypt message"); LogPrint (eLogError, "Garlic: Failed to decrypt message");
@ -737,7 +746,8 @@ namespace garlic
} }
std::shared_ptr<GarlicRoutingSession> GarlicDestination::GetRoutingSession ( std::shared_ptr<GarlicRoutingSession> GarlicDestination::GetRoutingSession (
std::shared_ptr<const i2p::data::RoutingDestination> destination, bool attachLeaseSet) std::shared_ptr<const i2p::data::RoutingDestination> destination, bool attachLeaseSet,
bool requestNewIfNotFound)
{ {
if (destination->GetEncryptionType () == i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD && if (destination->GetEncryptionType () == i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD &&
SupportsEncryptionType (i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD)) SupportsEncryptionType (i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD))
@ -752,15 +762,16 @@ namespace garlic
if (session->IsInactive (i2p::util::GetSecondsSinceEpoch ())) if (session->IsInactive (i2p::util::GetSecondsSinceEpoch ()))
{ {
LogPrint (eLogDebug, "Garlic: Session restarted"); LogPrint (eLogDebug, "Garlic: Session restarted");
requestNewIfNotFound = true; // it's not a new session
session = nullptr; session = nullptr;
} }
} }
if (!session) if (!session && requestNewIfNotFound)
{ {
session = std::make_shared<ECIESX25519AEADRatchetSession> (this, true); session = std::make_shared<ECIESX25519AEADRatchetSession> (this, true);
session->SetRemoteStaticKey (staticKey); session->SetRemoteStaticKey (staticKey);
} }
if (destination->IsDestination ()) if (session && destination->IsDestination ())
session->SetDestination (destination->GetIdentHash ()); // NS or NSR session->SetDestination (destination->GetIdentHash ()); // NS or NSR
return session; return session;
} }

5
libi2pd/Garlic.h

@ -52,6 +52,7 @@ namespace garlic
const int OUTGOING_TAGS_CONFIRMATION_TIMEOUT = 10; // 10 seconds const int OUTGOING_TAGS_CONFIRMATION_TIMEOUT = 10; // 10 seconds
const int LEASESET_CONFIRMATION_TIMEOUT = 4000; // in milliseconds const int LEASESET_CONFIRMATION_TIMEOUT = 4000; // in milliseconds
const int ROUTING_PATH_EXPIRATION_TIMEOUT = 120; // in seconds const int ROUTING_PATH_EXPIRATION_TIMEOUT = 120; // in seconds
const int INCOMING_SESSIONS_MINIMAL_INTERVAL = 200; // in milliseconds
struct SessionTag: public i2p::data::Tag<32> struct SessionTag: public i2p::data::Tag<32>
{ {
@ -234,7 +235,8 @@ namespace garlic
int GetNumTags () const { return m_NumTags; }; int GetNumTags () const { return m_NumTags; };
void SetNumRatchetInboundTags (int numTags) { m_NumRatchetInboundTags = numTags; }; void SetNumRatchetInboundTags (int numTags) { m_NumRatchetInboundTags = numTags; };
int GetNumRatchetInboundTags () const { return m_NumRatchetInboundTags; }; int GetNumRatchetInboundTags () const { return m_NumRatchetInboundTags; };
std::shared_ptr<GarlicRoutingSession> GetRoutingSession (std::shared_ptr<const i2p::data::RoutingDestination> destination, bool attachLeaseSet); std::shared_ptr<GarlicRoutingSession> GetRoutingSession (std::shared_ptr<const i2p::data::RoutingDestination> destination,
bool attachLeaseSet, bool requestNewIfNotFound = true);
void CleanupExpiredTags (); void CleanupExpiredTags ();
void RemoveDeliveryStatusSession (uint32_t msgID); void RemoveDeliveryStatusSession (uint32_t msgID);
std::shared_ptr<I2NPMessage> WrapMessageForRouter (std::shared_ptr<const i2p::data::RouterInfo> router, std::shared_ptr<I2NPMessage> WrapMessageForRouter (std::shared_ptr<const i2p::data::RouterInfo> router,
@ -284,6 +286,7 @@ namespace garlic
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 uint8_t * m_PayloadBuffer; // for ECIESX25519AEADRatchet
uint64_t m_LastIncomingSessionTimestamp; // in millseconds
// 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;

22
libi2pd/Streaming.cpp

@ -757,8 +757,8 @@ namespace stream
if (!m_RemoteLeaseSet) m_RemoteLeaseSet = m_LocalDestination.GetOwner ()->FindLeaseSet (m_RemoteIdentity->GetIdentHash ());; if (!m_RemoteLeaseSet) m_RemoteLeaseSet = m_LocalDestination.GetOwner ()->FindLeaseSet (m_RemoteIdentity->GetIdentHash ());;
if (m_RemoteLeaseSet) if (m_RemoteLeaseSet)
{ {
m_RoutingSession = m_LocalDestination.GetOwner ()->GetRoutingSession (m_RemoteLeaseSet, true); m_RoutingSession = m_LocalDestination.GetOwner ()->GetRoutingSession (m_RemoteLeaseSet, true, !m_IsIncoming);
m_MTU = m_RoutingSession->IsRatchets () ? STREAMING_MTU_RATCHETS : STREAMING_MTU; m_MTU = (m_RoutingSession && m_RoutingSession->IsRatchets ()) ? STREAMING_MTU_RATCHETS : STREAMING_MTU;
} }
uint16_t flags = PACKET_FLAG_SYNCHRONIZE | PACKET_FLAG_FROM_INCLUDED | uint16_t flags = PACKET_FLAG_SYNCHRONIZE | PACKET_FLAG_FROM_INCLUDED |
PACKET_FLAG_SIGNATURE_INCLUDED | PACKET_FLAG_MAX_PACKET_SIZE_INCLUDED; PACKET_FLAG_SIGNATURE_INCLUDED | PACKET_FLAG_MAX_PACKET_SIZE_INCLUDED;
@ -1115,7 +1115,15 @@ namespace stream
} }
} }
if (!m_RoutingSession || m_RoutingSession->IsTerminated () || !m_RoutingSession->IsReadyToSend ()) // expired and detached or new session sent if (!m_RoutingSession || m_RoutingSession->IsTerminated () || !m_RoutingSession->IsReadyToSend ()) // expired and detached or new session sent
m_RoutingSession = m_LocalDestination.GetOwner ()->GetRoutingSession (m_RemoteLeaseSet, true); {
m_RoutingSession = m_LocalDestination.GetOwner ()->GetRoutingSession (m_RemoteLeaseSet, true, !m_IsIncoming);
if (!m_RoutingSession)
{
LogPrint (eLogError, "Streaming: Can't obtain routing session, sSID=", m_SendStreamID);
Terminate ();
return;
}
}
if (!m_CurrentOutboundTunnel && m_RoutingSession) // first message to send if (!m_CurrentOutboundTunnel && m_RoutingSession) // first message to send
{ {
// try to get shared path first // try to get shared path first
@ -1416,7 +1424,13 @@ namespace stream
SendPackets (packets); SendPackets (packets);
m_LastSendTime = ts; m_LastSendTime = ts;
m_IsSendTime = false; m_IsSendTime = false;
if (m_IsNAcked || m_IsResendNeeded) ScheduleSend (); if (m_IsNAcked || m_IsResendNeeded)
{
if (m_SequenceNumber > 1) // doesn't resend agressively very first packet
ScheduleSend ();
else
ScheduleResend ();
}
} }
else else
SendBuffer (); SendBuffer ();

Loading…
Cancel
Save