mirror of
https://github.com/PurpleI2P/i2pd.git
synced 2025-01-22 21:37:17 +01:00
don't copy datagram payload
This commit is contained in:
parent
0b1cfb2102
commit
329439d0ae
|
@ -24,34 +24,32 @@ namespace datagram
|
||||||
void DatagramDestination::SendDatagramTo(const uint8_t * payload, size_t len, const i2p::data::IdentHash & identity, uint16_t fromPort, uint16_t toPort)
|
void DatagramDestination::SendDatagramTo(const uint8_t * payload, size_t len, const i2p::data::IdentHash & identity, uint16_t fromPort, uint16_t toPort)
|
||||||
{
|
{
|
||||||
auto owner = m_Owner;
|
auto owner = m_Owner;
|
||||||
std::vector<uint8_t> v(MAX_DATAGRAM_SIZE);
|
auto localIdentity = m_Owner->GetIdentity ();
|
||||||
uint8_t * buf = v.data();
|
auto identityLen = localIdentity->GetFullLen ();
|
||||||
auto localIdentity = m_Owner->GetIdentity ();
|
|
||||||
auto identityLen = localIdentity->ToBuffer (buf, MAX_DATAGRAM_SIZE);
|
|
||||||
uint8_t * signature = buf + identityLen;
|
|
||||||
auto signatureLen = localIdentity->GetSignatureLen ();
|
auto signatureLen = localIdentity->GetSignatureLen ();
|
||||||
uint8_t * buf1 = signature + signatureLen;
|
|
||||||
size_t headerLen = identityLen + signatureLen;
|
size_t headerLen = identityLen + signatureLen;
|
||||||
|
|
||||||
memcpy (buf1, payload, len);
|
std::vector<uint8_t> header(headerLen);
|
||||||
|
localIdentity->ToBuffer (header.data (), identityLen);
|
||||||
|
uint8_t * signature = header.data () + identityLen;
|
||||||
if (localIdentity->GetSigningKeyType () == i2p::data::SIGNING_KEY_TYPE_DSA_SHA1)
|
if (localIdentity->GetSigningKeyType () == i2p::data::SIGNING_KEY_TYPE_DSA_SHA1)
|
||||||
{
|
{
|
||||||
uint8_t hash[32];
|
uint8_t hash[32];
|
||||||
SHA256(buf1, len, hash);
|
SHA256(payload, len, hash);
|
||||||
owner->Sign (hash, 32, signature);
|
owner->Sign (hash, 32, signature);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
owner->Sign (buf1, len, signature);
|
owner->Sign (payload, len, signature);
|
||||||
|
|
||||||
auto msg = CreateDataMessage (buf, len + headerLen, fromPort, toPort);
|
|
||||||
auto session = ObtainSession(identity);
|
auto session = ObtainSession(identity);
|
||||||
|
auto msg = CreateDataMessage ({{header.data (), headerLen}, {payload, len}}, fromPort, toPort, false, !session->IsRatchets ()); // datagram
|
||||||
session->SendMsg(msg);
|
session->SendMsg(msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DatagramDestination::SendRawDatagramTo(const uint8_t * payload, size_t len, const i2p::data::IdentHash & identity, uint16_t fromPort, uint16_t toPort)
|
void DatagramDestination::SendRawDatagramTo(const uint8_t * payload, size_t len, const i2p::data::IdentHash & identity, uint16_t fromPort, uint16_t toPort)
|
||||||
{
|
{
|
||||||
auto msg = CreateDataMessage (payload, len, fromPort, toPort, true); // raw
|
|
||||||
auto session = ObtainSession(identity);
|
auto session = ObtainSession(identity);
|
||||||
|
auto msg = CreateDataMessage ({{payload, len}}, fromPort, toPort, true, !session->IsRatchets ()); // raw
|
||||||
session->SendMsg(msg);
|
session->SendMsg(msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -122,12 +120,14 @@ namespace datagram
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
std::shared_ptr<I2NPMessage> DatagramDestination::CreateDataMessage (const uint8_t * payload, size_t len, uint16_t fromPort, uint16_t toPort, bool isRaw)
|
std::shared_ptr<I2NPMessage> DatagramDestination::CreateDataMessage (
|
||||||
|
const std::vector<std::pair<const uint8_t *, size_t> >& payloads,
|
||||||
|
uint16_t fromPort, uint16_t toPort, bool isRaw, bool checksum)
|
||||||
{
|
{
|
||||||
auto msg = NewI2NPMessage ();
|
auto msg = NewI2NPMessage ();
|
||||||
uint8_t * buf = msg->GetPayload ();
|
uint8_t * buf = msg->GetPayload ();
|
||||||
buf += 4; // reserve for length
|
buf += 4; // reserve for length
|
||||||
size_t size = m_Deflator.Deflate (payload, len, buf, msg->maxLen - msg->len);
|
size_t size = m_Deflator.Deflate (payloads, buf, msg->maxLen - msg->len);
|
||||||
if (size)
|
if (size)
|
||||||
{
|
{
|
||||||
htobe32buf (msg->GetPayload (), size); // length
|
htobe32buf (msg->GetPayload (), size); // length
|
||||||
|
@ -135,7 +135,7 @@ namespace datagram
|
||||||
htobe16buf (buf + 6, toPort); // destination port
|
htobe16buf (buf + 6, toPort); // destination port
|
||||||
buf[9] = isRaw ? i2p::client::PROTOCOL_TYPE_RAW : i2p::client::PROTOCOL_TYPE_DATAGRAM; // raw or datagram protocol
|
buf[9] = isRaw ? i2p::client::PROTOCOL_TYPE_RAW : i2p::client::PROTOCOL_TYPE_DATAGRAM; // raw or datagram protocol
|
||||||
msg->len += size + 4;
|
msg->len += size + 4;
|
||||||
msg->FillI2NPMessageHeader (eI2NPData);
|
msg->FillI2NPMessageHeader (eI2NPData, 0, checksum);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
msg = nullptr;
|
msg = nullptr;
|
||||||
|
@ -247,7 +247,7 @@ namespace datagram
|
||||||
auto path = GetSharedRoutingPath();
|
auto path = GetSharedRoutingPath();
|
||||||
if(path)
|
if(path)
|
||||||
path->updateTime = i2p::util::GetSecondsSinceEpoch ();
|
path->updateTime = i2p::util::GetSecondsSinceEpoch ();
|
||||||
if (m_RoutingSession && m_RoutingSession->IsRatchets ())
|
if (IsRatchets ())
|
||||||
SendMsg (nullptr); // send empty message in case if we have some data to send
|
SendMsg (nullptr); // send empty message in case if we have some data to send
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -51,6 +51,8 @@ namespace datagram
|
||||||
/** get the last time in milliseconds for when we used this datagram session */
|
/** get the last time in milliseconds for when we used this datagram session */
|
||||||
uint64_t LastActivity() const { return m_LastUse; }
|
uint64_t LastActivity() const { return m_LastUse; }
|
||||||
|
|
||||||
|
bool IsRatchets () const { return m_RoutingSession && m_RoutingSession->IsRatchets (); }
|
||||||
|
|
||||||
struct Info
|
struct Info
|
||||||
{
|
{
|
||||||
std::shared_ptr<const i2p::data::IdentHash> IBGW;
|
std::shared_ptr<const i2p::data::IdentHash> IBGW;
|
||||||
|
@ -130,7 +132,8 @@ namespace datagram
|
||||||
|
|
||||||
std::shared_ptr<DatagramSession> ObtainSession(const i2p::data::IdentHash & ident);
|
std::shared_ptr<DatagramSession> ObtainSession(const i2p::data::IdentHash & ident);
|
||||||
|
|
||||||
std::shared_ptr<I2NPMessage> CreateDataMessage (const uint8_t * payload, size_t len, uint16_t fromPort, uint16_t toPort, bool isRaw = false);
|
std::shared_ptr<I2NPMessage> CreateDataMessage (const std::vector<std::pair<const uint8_t *, size_t> >& payloads,
|
||||||
|
uint16_t fromPort, uint16_t toPort, bool isRaw = false, bool checksum = true);
|
||||||
|
|
||||||
void HandleDatagram (uint16_t fromPort, uint16_t toPort, uint8_t *const& buf, size_t len);
|
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 HandleRawDatagram (uint16_t fromPort, uint16_t toPort, const uint8_t * buf, size_t len);
|
||||||
|
|
|
@ -116,6 +116,36 @@ namespace data
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
size_t GzipDeflator::Deflate (const std::vector<std::pair<const uint8_t *, size_t> >& bufs, uint8_t * out, size_t outLen)
|
||||||
|
{
|
||||||
|
if (m_IsDirty) deflateReset (&m_Deflator);
|
||||||
|
m_IsDirty = true;
|
||||||
|
size_t offset = 0;
|
||||||
|
int err;
|
||||||
|
for (const auto& it: bufs)
|
||||||
|
{
|
||||||
|
m_Deflator.next_in = const_cast<uint8_t *>(it.first);
|
||||||
|
m_Deflator.avail_in = it.second;
|
||||||
|
m_Deflator.next_out = out + offset;
|
||||||
|
m_Deflator.avail_out = outLen - offset;
|
||||||
|
auto flush = (it == bufs.back ()) ? Z_FINISH : Z_NO_FLUSH;
|
||||||
|
err = deflate (&m_Deflator, flush);
|
||||||
|
if (err)
|
||||||
|
{
|
||||||
|
if (flush && err == Z_STREAM_END)
|
||||||
|
{
|
||||||
|
out[9] = 0xff; // OS is always unknown
|
||||||
|
return outLen - m_Deflator.avail_out;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
offset = outLen - m_Deflator.avail_out;
|
||||||
|
}
|
||||||
|
// else
|
||||||
|
LogPrint (eLogError, "Gzip: Deflate error ", err);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
size_t GzipNoCompression (const uint8_t * in, uint16_t inLen, uint8_t * out, size_t outLen)
|
size_t GzipNoCompression (const uint8_t * in, uint16_t inLen, uint8_t * out, size_t outLen)
|
||||||
{
|
{
|
||||||
static const uint8_t gzipHeader[11] = { 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0xff, 0x01 };
|
static const uint8_t gzipHeader[11] = { 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0xff, 0x01 };
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
#define GZIP_H__
|
#define GZIP_H__
|
||||||
|
|
||||||
#include <zlib.h>
|
#include <zlib.h>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
namespace i2p
|
namespace i2p
|
||||||
{
|
{
|
||||||
|
@ -34,6 +35,7 @@ namespace data
|
||||||
|
|
||||||
void SetCompressionLevel (int level);
|
void SetCompressionLevel (int level);
|
||||||
size_t Deflate (const uint8_t * in, size_t inLen, uint8_t * out, size_t outLen);
|
size_t Deflate (const uint8_t * in, size_t inLen, uint8_t * out, size_t outLen);
|
||||||
|
size_t Deflate (const std::vector<std::pair<const uint8_t *, size_t> >& bufs, uint8_t * out, size_t outLen);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue