diff --git a/libi2pd/Destination.cpp b/libi2pd/Destination.cpp index 71a5c329..ba74f61f 100644 --- a/libi2pd/Destination.cpp +++ b/libi2pd/Destination.cpp @@ -359,11 +359,11 @@ namespace client void LeaseSetDestination::HandleI2NPMessage (const uint8_t * buf, size_t len) { - uint8_t typeID = buf[I2NP_HEADER_TYPEID_OFFSET]; + I2NPMessageType typeID = (I2NPMessageType)(buf[I2NP_HEADER_TYPEID_OFFSET]); LeaseSetDestination::HandleCloveI2NPMessage (typeID, buf + I2NP_HEADER_SIZE, GetI2NPMessageLength(buf, len) - I2NP_HEADER_SIZE); } - bool LeaseSetDestination::HandleCloveI2NPMessage (uint8_t typeID, const uint8_t * payload, size_t len) + bool LeaseSetDestination::HandleCloveI2NPMessage (I2NPMessageType typeID, const uint8_t * payload, size_t len) { switch (typeID) { diff --git a/libi2pd/Destination.h b/libi2pd/Destination.h index 2b7f7bb8..f4483032 100644 --- a/libi2pd/Destination.h +++ b/libi2pd/Destination.h @@ -132,7 +132,7 @@ namespace client // implements GarlicDestination void HandleI2NPMessage (const uint8_t * buf, size_t len); - bool HandleCloveI2NPMessage (uint8_t typeID, const uint8_t * payload, size_t len); + bool HandleCloveI2NPMessage (I2NPMessageType typeID, const uint8_t * payload, size_t len); void SetLeaseSet (std::shared_ptr newLeaseSet); int GetLeaseSetType () const { return m_LeaseSetType; }; diff --git a/libi2pd/ECIESX25519AEADRatchetSession.cpp b/libi2pd/ECIESX25519AEADRatchetSession.cpp index a258e8f7..96efe5e6 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.cpp +++ b/libi2pd/ECIESX25519AEADRatchetSession.cpp @@ -5,7 +5,6 @@ #include "Elligator.h" #include "Tag.h" #include "I2PEndian.h" -#include "Garlic.h" #include "ECIESX25519AEADRatchetSession.h" namespace i2p @@ -36,7 +35,7 @@ namespace garlic } bool ECIESX25519AEADRatchetSession::NewIncomingSession (const i2p::data::LocalDestination& dest, - const uint8_t * buf, size_t len, CloveI2NPMsgHandler handleCloveI2NPMsg) + const uint8_t * buf, size_t len, CloveHandler handleClove) { // we are Bob // KDF1 @@ -87,12 +86,12 @@ namespace garlic } if (isStatic) MixHash (buf, len); // h = SHA256(h || ciphertext) - HandlePayload (payload.data (), len - 16, handleCloveI2NPMsg); + HandlePayload (payload.data (), len - 16, handleClove); return true; } - void ECIESX25519AEADRatchetSession::HandlePayload (const uint8_t * buf, size_t len, CloveI2NPMsgHandler& handleCloveI2NPMsg) + void ECIESX25519AEADRatchetSession::HandlePayload (const uint8_t * buf, size_t len, CloveHandler& handleClove) { size_t offset = 0; while (offset < len) @@ -110,7 +109,7 @@ namespace garlic switch (blk) { case eECIESx25519BlkGalicClove: - HandleClove (buf + offset, size, handleCloveI2NPMsg); + handleClove (buf + offset, size); break; case eECIESx25519BlkDateTime: LogPrint (eLogDebug, "Garlic: datetime"); @@ -119,7 +118,7 @@ namespace garlic LogPrint (eLogDebug, "Garlic: options"); break; case eECIESx25519BlkPadding: - LogPrint (eLogDebug, "NTCP2: padding"); + LogPrint (eLogDebug, "Garlic: padding"); break; default: LogPrint (eLogWarning, "Garlic: Unknown block type ", (int)blk); @@ -127,33 +126,6 @@ namespace garlic offset += size; } } - - void ECIESX25519AEADRatchetSession::HandleClove (const uint8_t * buf, size_t len, CloveI2NPMsgHandler& handleCloveI2NPMsg) - { - const uint8_t * buf1 = buf; - uint8_t flag = buf[0]; buf++; // flag - GarlicDeliveryType deliveryType = (GarlicDeliveryType)((flag >> 5) & 0x03); - switch (deliveryType) - { - case eGarlicDeliveryTypeDestination: - buf += 32; // TODO: check destination - // no break here - case eGarlicDeliveryTypeLocal: - { - uint8_t typeID = buf[0]; buf++; // typeid - buf += (4 + 4); // msgID + expiration - ptrdiff_t offset = buf - buf1; - if (offset <= (int)len) - handleCloveI2NPMsg (typeID, buf, len - offset); - else - LogPrint (eLogError, "Garlic: clove is too long"); - break; - } - // TODO: tunnel - default: - LogPrint (eLogWarning, "Garlic: unexpected delivery type ", (int)deliveryType); - } - } } } diff --git a/libi2pd/ECIESX25519AEADRatchetSession.h b/libi2pd/ECIESX25519AEADRatchetSession.h index dd28c669..aa482d54 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.h +++ b/libi2pd/ECIESX25519AEADRatchetSession.h @@ -24,20 +24,19 @@ namespace garlic { public: - typedef std::function CloveI2NPMsgHandler; + typedef std::function CloveHandler; ECIESX25519AEADRatchetSession (); ~ECIESX25519AEADRatchetSession (); bool NewIncomingSession (const i2p::data::LocalDestination& dest, const uint8_t * buf, size_t len, - CloveI2NPMsgHandler handleCloveI2NPMsg); + CloveHandler handleClove); private: void MixHash (const uint8_t * buf, size_t len); - void HandlePayload (const uint8_t * buf, size_t len, CloveI2NPMsgHandler& handleCloveI2NPMsg); - void HandleClove (const uint8_t * buf, size_t len, CloveI2NPMsgHandler& handleCloveI2NPMsg); + void HandlePayload (const uint8_t * buf, size_t len, CloveHandler& handleClove); private: diff --git a/libi2pd/Garlic.cpp b/libi2pd/Garlic.cpp index 5dfdfe79..aa715e0c 100644 --- a/libi2pd/Garlic.cpp +++ b/libi2pd/Garlic.cpp @@ -833,11 +833,64 @@ namespace garlic void GarlicDestination::HandleECIESx25519 (const uint8_t * buf, size_t len) { ECIESX25519AEADRatchetSession session; - session.NewIncomingSession (*this, buf, len, - [this](uint8_t typeID, const uint8_t * payload, size_t len) - { - HandleCloveI2NPMessage (typeID, payload,len); - }); - } + session.NewIncomingSession (*this, buf, len, std::bind (&GarlicDestination::HandleECIESx25519GarlicClove, + this, std::placeholders::_1, std::placeholders::_2)); + } + + void GarlicDestination::HandleECIESx25519GarlicClove (const uint8_t * buf, size_t len) + { + const uint8_t * buf1 = buf; + uint8_t flag = buf[0]; buf++; // flag + GarlicDeliveryType deliveryType = (GarlicDeliveryType)((flag >> 5) & 0x03); + switch (deliveryType) + { + case eGarlicDeliveryTypeDestination: + LogPrint (eLogDebug, "Garlic: type destination"); + buf += 32; // TODO: check destination + // no break here + case eGarlicDeliveryTypeLocal: + { + LogPrint (eLogDebug, "Garlic: type local"); + I2NPMessageType typeID = (I2NPMessageType)(buf[0]); buf++; // typeid + buf += (4 + 4); // msgID + expiration + ptrdiff_t offset = buf - buf1; + if (offset <= (int)len) + HandleCloveI2NPMessage (typeID, buf, len - offset); + else + LogPrint (eLogError, "Garlic: clove is too long"); + break; + } + case eGarlicDeliveryTypeTunnel: + { + LogPrint (eLogDebug, "Garlic: type tunnel"); + // gwHash and gwTunnel sequence is reverted + const uint8_t * gwHash = buf; + buf += 32; + ptrdiff_t offset = buf - buf1; + if (offset + 13 > (int)len) + { + LogPrint (eLogError, "Garlic: message is too short"); + break; + } + uint32_t gwTunnel = bufbe32toh (buf); buf += 4; + I2NPMessageType typeID = (I2NPMessageType)(buf[0]); buf++; // typeid + buf += (4 + 4); // msgID + expiration + offset += 13; + if (GetTunnelPool ()) + { + auto tunnel = GetTunnelPool ()->GetNextOutboundTunnel (); + if (tunnel) + tunnel->SendTunnelDataMsg (gwHash, gwTunnel, CreateI2NPMessage (typeID, buf, len - offset)); + else + LogPrint (eLogWarning, "Garlic: No outbound tunnels available for garlic clove"); + } + else + LogPrint (eLogError, "Garlic: Tunnel pool is not set for inbound tunnel"); + break; + } + default: + LogPrint (eLogWarning, "Garlic: unexpected delivery type ", (int)deliveryType); + } + } } } diff --git a/libi2pd/Garlic.h b/libi2pd/Garlic.h index 44ab2e82..30e6ff4b 100644 --- a/libi2pd/Garlic.h +++ b/libi2pd/Garlic.h @@ -194,7 +194,7 @@ namespace garlic protected: virtual void HandleI2NPMessage (const uint8_t * buf, size_t len) = 0; // called from clove only - virtual bool HandleCloveI2NPMessage (uint8_t typeID, const uint8_t * payload, size_t len) = 0; + virtual bool HandleCloveI2NPMessage (I2NPMessageType typeID, const uint8_t * payload, size_t len) = 0; void HandleGarlicMessage (std::shared_ptr msg); void HandleDeliveryStatusMessage (uint32_t msgID); @@ -209,6 +209,7 @@ namespace garlic // ECIES-X25519-AEAD-Ratchet void HandleECIESx25519 (const uint8_t * buf, size_t len); + void HandleECIESx25519GarlicClove (const uint8_t * buf, size_t len); private: diff --git a/libi2pd/RouterContext.h b/libi2pd/RouterContext.h index 1524270d..dfc05fe7 100644 --- a/libi2pd/RouterContext.h +++ b/libi2pd/RouterContext.h @@ -124,7 +124,7 @@ namespace i2p // implements GarlicDestination void HandleI2NPMessage (const uint8_t * buf, size_t len); - bool HandleCloveI2NPMessage (uint8_t typeID, const uint8_t * payload, size_t len) { return false; }; // not implemented + bool HandleCloveI2NPMessage (I2NPMessageType typeID, const uint8_t * payload, size_t len) { return false; }; // not implemented private: