diff --git a/libi2pd/Datagram.cpp b/libi2pd/Datagram.cpp index 732efca7..1903f7ae 100644 --- a/libi2pd/Datagram.cpp +++ b/libi2pd/Datagram.cpp @@ -126,6 +126,34 @@ namespace datagram LogPrint (eLogWarning, "DatagramDestination: no receiver for raw datagram"); } + void DatagramDestination::HandleDatagram3 (uint16_t fromPort, uint16_t toPort, const uint8_t * buf, size_t len, + i2p::garlic::ECIESX25519AEADRatchetSession * from) + { + if (from) + { + i2p::data::IdentHash ident(buf); + auto ls = m_Owner->FindLeaseSet (ident); + if (ls) + { + uint8_t staticKey[32]; + ls->Encrypt (nullptr, staticKey); + if (!memcmp (from->GetRemoteStaticKey (), staticKey, 32)) + { + auto session = ObtainSession (ident); + session->SetRemoteLeaseSet (ls); + session->Ack (); + // TODO: + } + else + LogPrint (eLogError, "Datagram: Remote LeaseSet static key mismatch for datagram3 from ", ident.ToBase32 ()); + } + else + LogPrint (eLogError, "Datagram: No remote LeaseSet for ", ident.ToBase32 ()); + } + else + LogPrint (eLogInfo, "Datagram: datagram3 received from non-ratchets session"); + } + void DatagramDestination::SetReceiver (const Receiver& receiver, uint16_t port) { std::lock_guard lock(m_ReceiversMutex); @@ -194,17 +222,31 @@ namespace datagram return r; } - void DatagramDestination::HandleDataMessagePayload (uint16_t fromPort, uint16_t toPort, const uint8_t * buf, size_t len, bool isRaw) + void DatagramDestination::HandleDataMessagePayload (uint16_t fromPort, uint16_t toPort, + const uint8_t * buf, size_t len, uint8_t protocolType, i2p::garlic::ECIESX25519AEADRatchetSession * from) { // unzip it uint8_t uncompressed[MAX_DATAGRAM_SIZE]; size_t uncompressedLen = m_Inflator.Inflate (buf, len, uncompressed, MAX_DATAGRAM_SIZE); if (uncompressedLen) { - if (isRaw) - HandleRawDatagram (fromPort, toPort, uncompressed, uncompressedLen); - else - HandleDatagram (fromPort, toPort, uncompressed, uncompressedLen); + switch (protocolType) + { + case i2p::client::PROTOCOL_TYPE_RAW: + HandleRawDatagram (fromPort, toPort, uncompressed, uncompressedLen); + break; + case i2p::client::PROTOCOL_TYPE_DATAGRAM3: + HandleDatagram3 (fromPort, toPort, uncompressed, uncompressedLen, from); + break; + case i2p::client::PROTOCOL_TYPE_DATAGRAM: + HandleDatagram (fromPort, toPort, uncompressed, uncompressedLen); + break; + case i2p::client::PROTOCOL_TYPE_DATAGRAM2: + // TODO: + break; + default: + LogPrint (eLogInfo, "Datagram: unknown protocol type ", protocolType); + }; } else LogPrint (eLogWarning, "Datagram: decompression failed"); diff --git a/libi2pd/Datagram.h b/libi2pd/Datagram.h index dd358434..d68bdd07 100644 --- a/libi2pd/Datagram.h +++ b/libi2pd/Datagram.h @@ -20,6 +20,7 @@ #include "LeaseSet.h" #include "I2NPProtocol.h" #include "Garlic.h" +#include "ECIESX25519AEADRatchetSession.h" namespace i2p { @@ -64,8 +65,9 @@ namespace datagram /** get the last time in milliseconds for when we used this datagram session */ uint64_t LastActivity() const { return m_LastUse; } - bool IsRatchets () const { return m_RoutingSession && m_RoutingSession->IsRatchets (); } - + bool IsRatchets () const { return m_RoutingSession && m_RoutingSession->IsRatchets (); } + void SetRemoteLeaseSet (std::shared_ptr ls) { m_RemoteLeaseSet = ls; } + struct Info { std::shared_ptr IBGW; @@ -124,8 +126,8 @@ namespace datagram void SendRawDatagram (std::shared_ptr session, const uint8_t * payload, size_t len, uint16_t fromPort, uint16_t toPort); void FlushSendQueue (std::shared_ptr session); - void HandleDataMessagePayload (uint16_t fromPort, uint16_t toPort, const uint8_t * buf, size_t len, bool isRaw = false); - + void HandleDataMessagePayload (uint16_t fromPort, uint16_t toPort, + const uint8_t * buf, size_t len, uint8_t protocolType, i2p::garlic::ECIESX25519AEADRatchetSession * from); void SetReceiver (const Receiver& receiver, uint16_t port); void ResetReceiver (uint16_t port); @@ -147,6 +149,8 @@ namespace datagram void HandleDatagram (uint16_t fromPort, uint16_t toPort, uint8_t *const& buf, size_t len); void HandleRawDatagram (uint16_t fromPort, uint16_t toPort, const uint8_t * buf, size_t len); + void HandleDatagram3 (uint16_t fromPort, uint16_t toPort, const uint8_t * buf, size_t len, + i2p::garlic::ECIESX25519AEADRatchetSession * from); Receiver FindReceiver(uint16_t port); RawReceiver FindRawReceiver(uint16_t port); diff --git a/libi2pd/Destination.cpp b/libi2pd/Destination.cpp index e1ccbc92..4ce825a6 100644 --- a/libi2pd/Destination.cpp +++ b/libi2pd/Destination.cpp @@ -1190,19 +1190,15 @@ namespace client } break; case PROTOCOL_TYPE_DATAGRAM: + case PROTOCOL_TYPE_RAW: + case PROTOCOL_TYPE_DATAGRAM2: + case PROTOCOL_TYPE_DATAGRAM3: // datagram protocol if (m_DatagramDestination) - m_DatagramDestination->HandleDataMessagePayload (fromPort, toPort, buf, length); + m_DatagramDestination->HandleDataMessagePayload (fromPort, toPort, buf, length, buf[9], from); else LogPrint (eLogError, "Destination: Missing datagram destination"); break; - case PROTOCOL_TYPE_RAW: - // raw datagram - if (m_DatagramDestination) - m_DatagramDestination->HandleDataMessagePayload (fromPort, toPort, buf, length, true); - else - LogPrint (eLogError, "Destination: Missing raw datagram destination"); - break; default: LogPrint (eLogError, "Destination: Data: Unexpected protocol ", buf[9]); } diff --git a/libi2pd/Destination.h b/libi2pd/Destination.h index f2bef491..717f35ce 100644 --- a/libi2pd/Destination.h +++ b/libi2pd/Destination.h @@ -37,6 +37,8 @@ namespace client const uint8_t PROTOCOL_TYPE_STREAMING = 6; const uint8_t PROTOCOL_TYPE_DATAGRAM = 17; const uint8_t PROTOCOL_TYPE_RAW = 18; + const uint8_t PROTOCOL_TYPE_DATAGRAM2 = 19; + const uint8_t PROTOCOL_TYPE_DATAGRAM3 = 20; const int PUBLISH_CONFIRMATION_TIMEOUT = 1800; // in milliseconds const int PUBLISH_VERIFICATION_TIMEOUT = 5; // in seconds after successful publish const int PUBLISH_VERIFICATION_TIMEOUT_VARIANCE = 3; // in seconds