use fewer allocations

pull/173/head
Jeff Becker 5 years ago
parent 42e09b8ab9
commit e7f5eeff51
No known key found for this signature in database
GPG Key ID: F357B3B42F6F9B05

@ -8,6 +8,12 @@ namespace llarp
{
}
void
DHTImmeidateMessage::Clear()
{
msgs.clear();
}
bool
DHTImmeidateMessage::DecodeKey(llarp_buffer_t key, llarp_buffer_t *buf)
{
@ -60,8 +66,9 @@ namespace llarp
bool
DHTImmeidateMessage::HandleMessage(llarp::Router *router) const
{
DHTImmeidateMessage reply(session);
bool result = true;
DHTImmeidateMessage reply;
reply.session = session;
bool result = true;
for(auto &msg : msgs)
{
result &= msg->HandleMessage(router->dht, reply.msgs);

@ -1 +1,5 @@
#include <encrypted.hpp>
#include <mem.hpp>
namespace llarp
{
} // namespace llarp

@ -4,6 +4,7 @@
#include <aligned.hpp>
#include <bencode.h>
#include <buffer.h>
#include <mem.hpp>
#include <link_layer.hpp>
#include <vector>
@ -12,14 +13,55 @@
namespace llarp
{
/// encrypted buffer base type
template < size_t bufsz = MAX_LINK_MSG_SIZE >
struct Encrypted
{
Encrypted(Encrypted&& other);
Encrypted(const Encrypted& other);
Encrypted();
Encrypted(const byte_t* buf, size_t sz);
Encrypted(size_t sz);
~Encrypted();
Encrypted(Encrypted&& other)
{
_sz = std::move(other._sz);
memcpy(_buf, other._buf, _sz);
UpdateBuffer();
}
Encrypted(const Encrypted& other) : Encrypted(other.data(), other.size())
{
UpdateBuffer();
}
Encrypted()
{
Clear();
}
void
Clear()
{
_sz = 0;
UpdateBuffer();
}
Encrypted(const byte_t* buf, size_t sz)
{
if(sz <= bufsz)
{
_sz = sz;
if(buf)
memcpy(_buf, buf, sz);
else
llarp::Zero(_buf, sz);
}
else
_sz = 0;
UpdateBuffer();
}
Encrypted(size_t sz) : Encrypted(nullptr, sz)
{
}
~Encrypted()
{
}
bool
BEncode(llarp_buffer_t* buf) const
@ -48,7 +90,7 @@ namespace llarp
Encrypted&
operator=(const llarp_buffer_t& buf)
{
if(buf.sz && buf.sz <= sizeof(_buf))
if(buf.sz <= sizeof(_buf))
{
_sz = buf.sz;
memcpy(_buf, buf.base, _sz);
@ -78,10 +120,11 @@ namespace llarp
llarp_buffer_t strbuf;
if(!bencode_read_string(buf, &strbuf))
return false;
if(strbuf.sz == 0 || strbuf.sz > sizeof(_buf))
if(strbuf.sz > sizeof(_buf))
return false;
_sz = strbuf.sz;
memcpy(_buf, strbuf.base, _sz);
if(_sz)
memcpy(_buf, strbuf.base, _sz);
UpdateBuffer();
return true;
}
@ -126,14 +169,14 @@ namespace llarp
void
UpdateBuffer()
{
m_Buffer.base = data();
m_Buffer.cur = data();
m_Buffer.sz = size();
m_Buffer.base = _buf;
m_Buffer.cur = _buf;
m_Buffer.sz = _sz;
}
byte_t _buf[MAX_LINK_MSG_SIZE];
byte_t _buf[bufsz];
size_t _sz;
llarp_buffer_t m_Buffer;
};
}; // namespace llarp
} // namespace llarp
#endif

@ -7,12 +7,6 @@ namespace llarp
{
struct Crypto;
struct EncryptedAck : public Encrypted
{
bool
DecryptInPlace(const byte_t* symkey, const byte_t* nonce,
llarp::Crypto* crypto);
};
} // namespace llarp
#endif

@ -5,41 +5,6 @@
namespace llarp
{
Encrypted::Encrypted()
{
_sz = 0;
UpdateBuffer();
}
Encrypted::Encrypted(Encrypted&& other)
{
_sz = std::move(other._sz);
memcpy(_buf, other._buf, _sz);
UpdateBuffer();
}
Encrypted::Encrypted(const Encrypted& other)
: Encrypted(other.data(), other.size())
{
}
Encrypted::Encrypted(const byte_t* buf, size_t sz) : _sz(sz)
{
if(buf)
memcpy(_buf, buf, sz);
else
llarp::Zero(_buf, sz);
UpdateBuffer();
}
Encrypted::~Encrypted()
{
}
Encrypted::Encrypted(size_t sz) : Encrypted(nullptr, sz)
{
}
bool
EncryptedFrame::EncryptInPlace(const byte_t* ourSecretKey,
const byte_t* otherPubkey,
@ -65,7 +30,7 @@ namespace llarp
llarp_buffer_t buf;
buf.base = body;
buf.cur = buf.base;
buf.sz = size() - EncryptedFrame::OverheadSize;
buf.sz = size() - EncryptedFrameOverheadSize;
// set our pubkey
memcpy(pubkey, llarp::seckey_topublic(ourSecretKey), PUBKEYSIZE);
@ -103,12 +68,6 @@ namespace llarp
EncryptedFrame::DecryptInPlace(const byte_t* ourSecretKey,
llarp::Crypto* crypto)
{
if(size() <= size_t(EncryptedFrame::OverheadSize))
{
llarp::LogWarn("encrypted frame too small, ", size(),
" <= ", size_t(EncryptedFrame::OverheadSize));
return false;
}
// format of frame is
// <32 bytes keyed hash of following data>
// <32 bytes nonce>
@ -153,7 +112,7 @@ namespace llarp
buf.base = body;
buf.cur = body;
buf.sz = size() - EncryptedFrame::OverheadSize;
buf.sz = size() - EncryptedFrameOverheadSize;
if(!Decrypt(buf, shared, nonce))
{

@ -3,38 +3,37 @@
#include <crypto.h>
#include <encrypted.hpp>
#include <buffer.hpp>
#include <mem.h>
#include <threadpool.h>
namespace llarp
{
struct EncryptedFrame : public Encrypted
{
static constexpr size_t OverheadSize =
PUBKEYSIZE + TUNNONCESIZE + SHORTHASHSIZE;
EncryptedFrame() : EncryptedFrame(256)
{
}
static constexpr size_t EncryptedFrameOverheadSize =
PUBKEYSIZE + TUNNONCESIZE + SHORTHASHSIZE;
static constexpr size_t EncryptedFrameBodySize = 512;
static constexpr size_t EncryptedFrameSize =
EncryptedFrameOverheadSize + EncryptedFrameBodySize;
EncryptedFrame(const EncryptedFrame& other)
: EncryptedFrame(other.data(), other.size())
struct EncryptedFrame : public Encrypted< EncryptedFrameSize >
{
EncryptedFrame() : EncryptedFrame(EncryptedFrameBodySize)
{
}
EncryptedFrame(const byte_t* buf, size_t sz) : Encrypted(buf, sz)
{
}
EncryptedFrame(size_t sz)
: Encrypted(sz + PUBKEYSIZE + TUNNONCESIZE + SHORTHASHSIZE)
: Encrypted< EncryptedFrameSize >(std::min(sz, EncryptedFrameBodySize)
+ EncryptedFrameOverheadSize)
{
UpdateBuffer();
}
EncryptedFrame&
operator=(const EncryptedFrame& other)
{
_sz = other.size();
_sz = other._sz;
memcpy(data(), other.data(), size());
UpdateBuffer();
return *this;
}
@ -58,8 +57,8 @@ namespace llarp
AsyncFrameEncrypter< User >* ctx =
static_cast< AsyncFrameEncrypter< User >* >(user);
if(ctx->frame->EncryptInPlace(ctx->seckey, ctx->otherKey, ctx->crypto))
ctx->handler(ctx->frame, ctx->user);
if(ctx->frame.EncryptInPlace(ctx->seckey, ctx->otherKey, ctx->crypto))
ctx->handler(&ctx->frame, ctx->user);
else
{
ctx->handler(nullptr, ctx->user);
@ -69,7 +68,7 @@ namespace llarp
llarp::Crypto* crypto;
byte_t* secretkey;
EncryptHandler handler;
EncryptedFrame* frame;
EncryptedFrame frame;
User* user;
byte_t* otherKey;
@ -84,9 +83,10 @@ namespace llarp
{
// TODO: should we own otherKey?
otherKey = other;
frame = new EncryptedFrame(buf.sz);
memcpy(frame->data() + PUBKEYSIZE + TUNNONCESIZE + SHORTHASHSIZE,
buf.base, buf.sz);
if(buf.sz > EncryptedFrameBodySize)
return;
memcpy(frame.data() + PUBKEYSIZE + TUNNONCESIZE + SHORTHASHSIZE, buf.base,
buf.sz);
user = u;
llarp_threadpool_queue_job(worker, {this, &Encrypt});
}
@ -104,10 +104,10 @@ namespace llarp
AsyncFrameDecrypter< User >* ctx =
static_cast< AsyncFrameDecrypter< User >* >(user);
if(ctx->target->DecryptInPlace(ctx->seckey, ctx->crypto))
if(ctx->target.DecryptInPlace(ctx->seckey, ctx->crypto))
{
auto buf = ctx->target->Buffer();
buf->cur = buf->base + EncryptedFrame::OverheadSize;
auto buf = ctx->target.Buffer();
buf->cur = buf->base + EncryptedFrameOverheadSize;
ctx->result(buf, ctx->context);
}
else
@ -124,10 +124,11 @@ namespace llarp
User* context;
llarp::Crypto* crypto;
const byte_t* seckey;
EncryptedFrame* target;
EncryptedFrame target;
void
AsyncDecrypt(llarp_threadpool* worker, EncryptedFrame* frame, User* user)
AsyncDecrypt(llarp_threadpool* worker, const EncryptedFrame& frame,
User* user)
{
target = frame;
context = user;

@ -121,6 +121,12 @@ namespace llarp
return session->GotLIM(this);
}
void
LinkIntroMessage::Clear()
{
rc.Clear();
}
bool
LinkIntroMessage::Sign(llarp::Crypto* c, const SecretKey& k)
{

@ -2,6 +2,7 @@
#include <logger.hpp>
#include <messages.hpp>
#include <router_contact.hpp>
#include <link_message_parser.hpp>
namespace llarp
{
@ -45,29 +46,29 @@ namespace llarp
switch(*strbuf.cur)
{
case 'i':
handler->msg = std::make_unique< LinkIntroMessage >(handler->from);
handler->msg = &handler->holder.i;
break;
case 'd':
handler->msg =
std::make_unique< RelayDownstreamMessage >(handler->from);
handler->msg = &handler->holder.d;
break;
case 'u':
handler->msg =
std::make_unique< RelayUpstreamMessage >(handler->from);
handler->msg = &handler->holder.u;
break;
case 'm':
handler->msg = std::make_unique< DHTImmeidateMessage >(handler->from);
handler->msg = &handler->holder.m;
break;
case 'c':
handler->msg = std::make_unique< LR_CommitMessage >(handler->from);
handler->msg = &handler->holder.c;
break;
case 'x':
handler->msg = std::make_unique< DiscardMessage >(handler->from);
handler->msg = &handler->holder.x;
break;
default:
return false;
}
handler->firstkey = false;
handler->msg->Clear();
handler->msg->session = handler->from;
handler->firstkey = false;
return true;
}
// check for last element
@ -107,6 +108,6 @@ namespace llarp
void
InboundMessageParser::Reset()
{
msg.reset(nullptr);
msg = nullptr;
}
} // namespace llarp

@ -19,55 +19,22 @@ namespace llarp
struct ILinkMessage : public IBEncodeMessage
{
/// who did this message come from or is going to
ILinkSession* session;
uint64_t version = 0;
ILinkSession* session = nullptr;
uint64_t version = 0;
ILinkMessage() : ILinkMessage(nullptr)
{
}
ILinkMessage() = default;
ILinkMessage(ILinkSession* from) : session(from)
{
}
virtual ~ILinkMessage()
{
}
virtual bool
HandleMessage(Router* router) const = 0;
};
struct InboundMessageParser
{
InboundMessageParser(Router* router);
dict_reader reader;
static bool
OnKey(dict_reader* r, llarp_buffer_t* buf);
/// start processig message from a link session
bool
ProcessFrom(ILinkSession* from, llarp_buffer_t buf);
/// called when the message is fully read
/// return true when the message was accepted otherwise returns false
bool
MessageDone();
/// resets internal state
void
Reset();
private:
RouterID
GetCurrentFrom();
private:
bool firstkey;
Router* router;
ILinkSession* from = nullptr;
std::unique_ptr< ILinkMessage > msg;
virtual void
Clear() = 0;
};
} // namespace llarp
#endif

@ -0,0 +1,52 @@
#ifndef LLARP_LINK_MESSAGE_PARSER_HPP
#define LLARP_LINK_MESSAGE_PARSER_HPP
#include <link_message.hpp>
#include <messages.hpp>
namespace llarp
{
struct InboundMessageParser
{
InboundMessageParser(Router* router);
dict_reader reader;
static bool
OnKey(dict_reader* r, llarp_buffer_t* buf);
/// start processig message from a link session
bool
ProcessFrom(ILinkSession* from, llarp_buffer_t buf);
/// called when the message is fully read
/// return true when the message was accepted otherwise returns false
bool
MessageDone();
/// resets internal state
void
Reset();
private:
RouterID
GetCurrentFrom();
private:
bool firstkey;
Router* router;
ILinkSession* from = nullptr;
ILinkMessage* msg = nullptr;
struct msg_holder_t
{
LinkIntroMessage i;
RelayDownstreamMessage d;
RelayUpstreamMessage u;
DHTImmeidateMessage m;
LR_CommitMessage c;
DiscardMessage x;
};
msg_holder_t holder;
};
} // namespace llarp
#endif

@ -9,10 +9,6 @@ namespace llarp
{
struct DHTImmeidateMessage : public ILinkMessage
{
DHTImmeidateMessage(ILinkSession* parent) : ILinkMessage(parent)
{
}
DHTImmeidateMessage() : ILinkMessage()
{
}
@ -29,6 +25,9 @@ namespace llarp
bool
HandleMessage(llarp::Router* router) const;
void
Clear() override;
};
} // namespace llarp

@ -10,17 +10,7 @@ namespace llarp
{
struct DiscardMessage final : public ILinkMessage
{
/// who did this message come from or is going to
DiscardMessage() : ILinkMessage(nullptr)
{
}
DiscardMessage(ILinkSession* from) : ILinkMessage(from)
{
}
~DiscardMessage()
DiscardMessage() : ILinkMessage()
{
}
@ -36,6 +26,11 @@ namespace llarp
return bencode_end(buf);
}
void
Clear() override
{
}
bool
DecodeKey(__attribute__((unused)) llarp_buffer_t key,
__attribute__((unused)) llarp_buffer_t* buf) override

@ -16,10 +16,6 @@ namespace llarp
{
}
LinkIntroMessage(ILinkSession* s) : ILinkMessage(s)
{
}
~LinkIntroMessage();
RouterContact rc;
@ -44,6 +40,9 @@ namespace llarp
bool
Verify(llarp::Crypto* c) const;
void
Clear() override;
};
} // namespace llarp

@ -13,7 +13,7 @@ namespace llarp
struct RelayUpstreamMessage : public ILinkMessage
{
PathID_t pathid;
Encrypted X;
Encrypted< MAX_LINK_MSG_SIZE - 128 > X;
TunnelNonce Y;
RelayUpstreamMessage();
@ -21,32 +21,38 @@ namespace llarp
~RelayUpstreamMessage();
bool
DecodeKey(llarp_buffer_t key, llarp_buffer_t* buf);
DecodeKey(llarp_buffer_t key, llarp_buffer_t* buf) override;
bool
BEncode(llarp_buffer_t* buf) const;
BEncode(llarp_buffer_t* buf) const override;
bool
HandleMessage(llarp::Router* router) const;
HandleMessage(llarp::Router* router) const override;
void
Clear() override;
};
struct RelayDownstreamMessage : public ILinkMessage
{
PathID_t pathid;
Encrypted X;
Encrypted< MAX_LINK_MSG_SIZE - 128 > X;
TunnelNonce Y;
RelayDownstreamMessage();
RelayDownstreamMessage(ILinkSession* from);
~RelayDownstreamMessage();
bool
DecodeKey(llarp_buffer_t key, llarp_buffer_t* buf);
DecodeKey(llarp_buffer_t key, llarp_buffer_t* buf) override;
bool
BEncode(llarp_buffer_t* buf) const;
BEncode(llarp_buffer_t* buf) const override;
bool
HandleMessage(llarp::Router* router) const;
HandleMessage(llarp::Router* router) const override;
void
Clear() override;
};
} // namespace llarp

@ -53,10 +53,6 @@ namespace llarp
{
}
LR_CommitMessage(ILinkSession *from) : ILinkMessage(from)
{
}
~LR_CommitMessage();
void

@ -11,11 +11,12 @@ namespace llarp
{
namespace routing
{
constexpr size_t ExitPadSize = 512 - 48;
constexpr size_t MaxExitMTU = 1500;
constexpr size_t ExitPadSize = 512 - 48;
constexpr size_t MaxExitMTU = 1500;
constexpr size_t ExitOverhead = sizeof(uint64_t);
struct TransferTrafficMessage final : public IMessage
{
std::vector< llarp::Encrypted > X;
std::vector< llarp::Encrypted< MaxExitMTU + ExitOverhead > > X;
size_t _size = 0;
size_t

@ -80,12 +80,13 @@ namespace llarp
record.commkey = llarp::seckey_topublic(hop.commkey);
auto buf = frame.Buffer();
buf->cur = buf->base + EncryptedFrame::OverheadSize;
buf->cur = buf->base + EncryptedFrameOverheadSize;
// encode record
if(!record.BEncode(buf))
{
// failed to encode?
llarp::LogError("Failed to generate Commit Record");
llarp::DumpBuffer(*buf);
delete ctx;
return;
}

@ -27,6 +27,19 @@ namespace llarp
return read;
}
void
LR_CommitMessage::Clear()
{
frames[0].Clear();
frames[1].Clear();
frames[2].Clear();
frames[3].Clear();
frames[4].Clear();
frames[5].Clear();
frames[6].Clear();
frames[7].Clear();
}
bool
LR_CommitMessage::BEncode(llarp_buffer_t* buf) const
{
@ -235,7 +248,7 @@ namespace llarp
delete self;
return;
}
buf->cur = buf->base + EncryptedFrame::OverheadSize;
buf->cur = buf->base + EncryptedFrameOverheadSize;
llarp::LogDebug("decrypted LRCM from ", info.downstream);
// successful decrypt
if(!self->record.BDecode(buf))
@ -295,7 +308,7 @@ namespace llarp
frames[5] = self->frames[6];
frames[6] = self->frames[7];
// put our response on the end
frames[7] = EncryptedFrame(sz - EncryptedFrame::OverheadSize);
frames[7] = EncryptedFrame(sz - EncryptedFrameOverheadSize);
// random junk for now
frames[7].Randomize();
self->frames = std::move(frames);
@ -325,7 +338,7 @@ namespace llarp
LRCMFrameDecrypt* frames = new LRCMFrameDecrypt(context, decrypter, this);
// decrypt frames async
decrypter->AsyncDecrypt(context->Worker(), &frames->frames[0], frames);
decrypter->AsyncDecrypt(context->Worker(), frames->frames[0], frames);
return true;
}
} // namespace llarp

@ -4,17 +4,18 @@
namespace llarp
{
RelayUpstreamMessage::RelayUpstreamMessage(ILinkSession *from)
: ILinkMessage(from)
RelayUpstreamMessage::RelayUpstreamMessage() : ILinkMessage()
{
}
RelayUpstreamMessage::RelayUpstreamMessage() : ILinkMessage()
RelayUpstreamMessage::~RelayUpstreamMessage()
{
}
RelayUpstreamMessage::~RelayUpstreamMessage()
void
RelayUpstreamMessage::Clear()
{
X.Clear();
}
bool
@ -63,18 +64,20 @@ namespace llarp
return false;
}
RelayDownstreamMessage::RelayDownstreamMessage(ILinkSession *from)
: ILinkMessage(from)
RelayDownstreamMessage::RelayDownstreamMessage() : ILinkMessage()
{
}
RelayDownstreamMessage::RelayDownstreamMessage() : ILinkMessage()
RelayDownstreamMessage::~RelayDownstreamMessage()
{
}
RelayDownstreamMessage::~RelayDownstreamMessage()
void
RelayDownstreamMessage::Clear()
{
X.Clear();
}
bool
RelayDownstreamMessage::BEncode(llarp_buffer_t *buf) const
{

@ -12,7 +12,7 @@
#include <fs.hpp>
#include <handlers/tun.hpp>
#include <link_layer.hpp>
#include <link_message.hpp>
#include <link_message_parser.hpp>
#include <logic.hpp>
#include <mem.hpp>
#include <nodedb.hpp>

@ -157,8 +157,8 @@ namespace llarp
const byte_t* sharedkey,
ProtocolMessage& msg) const
{
Encrypted tmp = D;
auto buf = tmp.Buffer();
Encrypted_t tmp = D;
auto buf = tmp.Buffer();
crypto->xchacha20(*buf, sharedkey, N);
return msg.BDecode(buf);
}

@ -59,8 +59,9 @@ namespace llarp
/// outer message
struct ProtocolFrame final : public llarp::routing::IMessage
{
using Encrypted_t = llarp::Encrypted< 2048 >;
llarp::PQCipherBlock C;
llarp::Encrypted D;
Encrypted_t D;
llarp::KeyExchangeNonce N;
llarp::Signature Z;
llarp::service::ConvoTag T;

@ -11,11 +11,10 @@ using LRCR = llarp::LR_CommitRecord;
class FrameTest : public ::testing::Test
{
public:
llarp::Crypto crypto;
llarp::Crypto crypto;
SecretKey alice, bob;
FrameTest()
: crypto(llarp::Crypto::sodium{})
FrameTest() : crypto(llarp::Crypto::sodium{})
{
}
@ -47,12 +46,12 @@ TEST_F(FrameTest, TestFrameCrypto)
record.txid.Fill(4);
auto buf = f.Buffer();
buf->cur = buf->base + EncryptedFrame::OverheadSize;
buf->cur = buf->base + llarp::EncryptedFrameOverheadSize;
ASSERT_TRUE(record.BEncode(buf));
// rewind buffer
buf->cur = buf->base + EncryptedFrame::OverheadSize;
buf->cur = buf->base + llarp::EncryptedFrameOverheadSize;
// encrypt to alice
ASSERT_TRUE(f.EncryptInPlace(alice, llarp::seckey_topublic(bob), &crypto));
// decrypt from alice

Loading…
Cancel
Save