From 61d36ea8c390e79d494b044610a33cc0dbcb95c8 Mon Sep 17 00:00:00 2001 From: orignal Date: Thu, 23 Oct 2014 16:56:50 -0400 Subject: [PATCH] send datagram --- Datagram.cpp | 62 ++++++++++++++++++++++++++++++++++++++++++++++++++++ Datagram.h | 12 +++++++++- 2 files changed, 73 insertions(+), 1 deletion(-) diff --git a/Datagram.cpp b/Datagram.cpp index 5c3cd259..e05b5463 100644 --- a/Datagram.cpp +++ b/Datagram.cpp @@ -1,11 +1,56 @@ +#include +#include +#include #include #include "Log.h" +#include "TunnelBase.h" +#include "RouterContext.h" +#include "Destination.h" #include "Datagram.h" namespace i2p { namespace datagram { + DatagramDestination::DatagramDestination (i2p::client::ClientDestination& owner): + m_Owner (owner) + { + auto identityLen = m_Owner.GetIdentity ().ToBuffer (m_OutgoingBuffer, MAX_DATAGRAM_SIZE); + m_Signature = m_OutgoingBuffer + identityLen; + auto signatureLen = m_Owner.GetIdentity ().GetSignatureLen (); + m_Payload = m_Signature + signatureLen; + m_HeaderLen = identityLen + signatureLen; + } + + void DatagramDestination::SendDatagramTo (const uint8_t * payload, size_t len, const i2p::data::LeaseSet& remote) + { + auto leases = remote.GetNonExpiredLeases (); + if (!leases.empty ()) + { + memcpy (m_Payload, payload, len); + if (m_Owner.GetIdentity ().GetSigningKeyType () == i2p::data::SIGNING_KEY_TYPE_DSA_SHA1) + { + uint8_t hash[32]; + CryptoPP::SHA256().CalculateDigest (hash, m_Payload, len); + m_Owner.Sign (hash, 32, m_Signature); + } + else + m_Owner.Sign (m_Payload, len, m_Signature); + + std::vector msgs; + uint32_t i = i2p::context.GetRandomNumberGenerator ().GenerateWord32 (0, leases.size () - 1); + auto msg = m_Owner.WrapMessage (remote, CreateDataMessage (m_OutgoingBuffer, len + m_HeaderLen)); + msgs.push_back (i2p::tunnel::TunnelMessageBlock + { + i2p::tunnel::eDeliveryTypeTunnel, + leases[i].tunnelGateway, leases[i].tunnelID, + msg + }); + } + else + LogPrint ("Failed to send datagram. All leases expired"); + } + void DatagramDestination::HandleDataMessagePayload (const uint8_t * buf, size_t len) { // unzip it @@ -24,6 +69,23 @@ namespace datagram } + I2NPMessage * DatagramDestination::CreateDataMessage (const uint8_t * payload, size_t len) + { + I2NPMessage * msg = NewI2NPMessage (); + CryptoPP::Gzip compressor; // default level + compressor.Put (payload, len); + compressor.MessageEnd(); + int size = compressor.MaxRetrievable (); + uint8_t * buf = msg->GetPayload (); + *(uint32_t *)buf = htobe32 (size); // length + buf += 4; + compressor.Get (buf, size); + memset (buf + 4, 0, 4); // source and destination are zeroes + buf[9] = i2p::client::PROTOCOL_TYPE_DATAGRAM; // datagram protocol + msg->len += size + 4; + FillI2NPMessageHeader (msg, eI2NPData); + return msg; + } } } diff --git a/Datagram.h b/Datagram.h index d5c21f6b..5d8f6f5b 100644 --- a/Datagram.h +++ b/Datagram.h @@ -2,6 +2,8 @@ #define DATAGRAM_H__ #include +#include "LeaseSet.h" +#include "I2NPProtocol.h" namespace i2p { @@ -16,14 +18,22 @@ namespace datagram { public: - DatagramDestination (i2p::client::ClientDestination& owner): m_Owner (owner) {}; + DatagramDestination (i2p::client::ClientDestination& owner); ~DatagramDestination () {}; + void SendDatagramTo (const uint8_t * payload, size_t len, const i2p::data::LeaseSet& remote); void HandleDataMessagePayload (const uint8_t * buf, size_t len); + private: + + I2NPMessage * CreateDataMessage (const uint8_t * payload, size_t len); + private: i2p::client::ClientDestination& m_Owner; + uint8_t m_OutgoingBuffer[MAX_DATAGRAM_SIZE]; + uint8_t * m_Signature, * m_Payload; + size_t m_HeaderLen; }; } }