Convert llarp::AlignedBuffer to be backed by std::array

pull/172/head
Michael 6 years ago
parent d9495dfc0a
commit 037cb87523
No known key found for this signature in database
GPG Key ID: 2D51757B47E2434C

@ -73,7 +73,7 @@ namespace llarp
size_t size_t
operator()(const AddressInfo& addr) const operator()(const AddressInfo& addr) const
{ {
return *addr.pubkey.data_l(); return AlignedBuffer< PUBKEYSIZE >::Hash()(addr.pubkey);
} }
}; };
}; };

@ -5,8 +5,13 @@
#include <encode.hpp> #include <encode.hpp>
#include <logger.hpp> #include <logger.hpp>
#include <array>
#include <cstddef>
#include <iomanip> #include <iomanip>
#include <iostream> #include <iostream>
#include <memory>
#include <numeric>
#include <type_traits>
extern "C" extern "C"
{ {
@ -19,29 +24,44 @@ extern "C"
} }
namespace llarp namespace llarp
{ {
/// aligned buffer that is sz bytes long and aligns to the nears Long_t /// aligned buffer that is sz bytes long and aligns to the nearest Alignment
template < size_t sz, bool randomize = false, typename Long_t = uint64_t > template < size_t sz >
struct AlignedBuffer struct AlignedBuffer
{ {
static constexpr size_t SIZE = sz;
using Data = std::array< byte_t, SIZE >;
AlignedBuffer() AlignedBuffer()
{ {
if(randomize) new(&val) Data;
Randomize(); Zero();
else
Zero();
} }
AlignedBuffer(const byte_t* data) AlignedBuffer(const byte_t* data)
{ {
new(&val) Data;
auto& b = as_array();
for(size_t idx = 0; idx < sz; ++idx) for(size_t idx = 0; idx < sz; ++idx)
{
b[idx] = data[idx]; b[idx] = data[idx];
}
}
AlignedBuffer(const std::array< byte_t, SIZE >& buf)
{
new(&val) Data;
std::copy(buf.begin(), buf.end(), as_array().begin());
} }
AlignedBuffer& AlignedBuffer&
operator=(const byte_t* data) operator=(const byte_t* data)
{ {
auto& b = as_array();
for(size_t idx = 0; idx < sz; ++idx) for(size_t idx = 0; idx < sz; ++idx)
{
b[idx] = data[idx]; b[idx] = data[idx];
}
return *this; return *this;
} }
@ -57,75 +77,72 @@ namespace llarp
operator~() const operator~() const
{ {
AlignedBuffer< sz > ret; AlignedBuffer< sz > ret;
size_t idx = 0; std::transform(as_array().begin(), as_array().end(),
while(idx < sz / sizeof(Long_t)) ret.as_array().begin(), [](byte_t a) { return ~a; });
{
ret.data_l()[idx] = ~data_l()[idx];
++idx;
}
return ret; return ret;
} }
bool bool
operator==(const AlignedBuffer& other) const operator==(const AlignedBuffer& other) const
{ {
return memcmp(b, other.b, sz) == 0; return as_array() == other.as_array();
} }
bool bool
operator!=(const AlignedBuffer& other) const operator!=(const AlignedBuffer& other) const
{ {
return !(*this == other); return as_array() != other.as_array();
} }
bool bool
operator<(const AlignedBuffer& other) const operator<(const AlignedBuffer& other) const
{ {
return memcmp(l, other.l, sz) < 0; return as_array() < other.as_array();
} }
bool bool
operator>(const AlignedBuffer& other) const operator>(const AlignedBuffer& other) const
{ {
return memcmp(l, other.l, sz) > 0; return as_array() > other.as_array();
} }
bool bool
operator<=(const AlignedBuffer& other) const operator<=(const AlignedBuffer& other) const
{ {
return memcmp(l, other.l, sz) <= 0; return as_array() <= other.as_array();
} }
bool bool
operator>=(const AlignedBuffer& other) const operator>=(const AlignedBuffer& other) const
{ {
return memcmp(l, other.l, sz) >= 0; return as_array() >= other.as_array();
} }
AlignedBuffer AlignedBuffer
operator^(const AlignedBuffer& other) const operator^(const AlignedBuffer& other) const
{ {
AlignedBuffer< sz > ret; AlignedBuffer< sz > ret;
for(size_t idx = 0; idx < sz / sizeof(Long_t); ++idx) std::transform(as_array().begin(), as_array().end(),
ret.l[idx] = l[idx] ^ other.l[idx]; other.as_array().begin(), ret.as_array().begin(),
std::bit_xor< byte_t >());
return ret; return ret;
} }
AlignedBuffer& AlignedBuffer&
operator^=(const AlignedBuffer& other) operator^=(const AlignedBuffer& other)
{ {
for(size_t idx = 0; idx < sz / sizeof(Long_t); ++idx) // Mutate in place instead.
l[idx] ^= other.l[idx]; // Well defined for std::transform,
return *this;
}
size_t for(size_t i = 0; i < as_array().size(); ++i)
size() const {
{ as_array()[i] ^= other.as_array()[i];
return sz; }
return *this;
} }
size_t static constexpr size_t
size() size()
{ {
return sz; return sz;
@ -134,66 +151,63 @@ namespace llarp
void void
Fill(byte_t f) Fill(byte_t f)
{ {
for(size_t idx = 0; idx < sz; ++idx) as_array().fill(f);
b[idx] = f;
} }
bool bool
IsZero() const IsZero() const
{ {
return sodium_is_zero(b, sz) != 0; return sodium_is_zero(as_array().data(), SIZE) != 0;
} }
void void
Zero() Zero()
{ {
sodium_memzero(l, sz); as_array().fill(0);
} }
void void
Randomize() Randomize()
{ {
randombytes(b, sz); randombytes(as_array().data(), SIZE);
} }
byte_t* byte_t*
data() data()
{ {
return b; return as_array().data();
} }
const byte_t* const byte_t*
data() const data() const
{ {
return b; return as_array().data();
} }
Long_t* operator const byte_t*() const
data_l()
{ {
return l; return as_array().data();
} }
const Long_t* operator byte_t*()
data_l() const
{ {
return l; return as_array().data();
} }
operator const byte_t*() const operator const Data&() const
{ {
return b; return as_array();
} }
operator byte_t*() operator Data&()
{ {
return b; return as_array();
} }
bool bool
BEncode(llarp_buffer_t* buf) const BEncode(llarp_buffer_t* buf) const
{ {
return bencode_write_bytestring(buf, b, sz); return bencode_write_bytestring(buf, as_array().data(), sz);
} }
bool bool
@ -201,13 +215,15 @@ namespace llarp
{ {
llarp_buffer_t strbuf; llarp_buffer_t strbuf;
if(!bencode_read_string(buf, &strbuf)) if(!bencode_read_string(buf, &strbuf))
{
return false; return false;
}
if(strbuf.sz != sz) if(strbuf.sz != sz)
{ {
llarp::LogError("bdecode buffer size missmatch ", strbuf.sz, "!=", sz); llarp::LogError("bdecode buffer size missmatch ", strbuf.sz, "!=", sz);
return false; return false;
} }
memcpy(b, strbuf.base, sz); memcpy(as_array().data(), strbuf.base, sz);
return true; return true;
} }
@ -221,17 +237,31 @@ namespace llarp
struct Hash struct Hash
{ {
size_t size_t
operator()(const AlignedBuffer< sz, randomize, Long_t >& buf) const operator()(const AlignedBuffer& buf) const
{ {
return buf.l[0]; return std::accumulate(buf.as_array().begin(), buf.as_array().end(), 0,
std::bit_xor< size_t >());
} }
}; };
private:
using AlignedStorage =
typename std::aligned_storage< sizeof(Data),
alignof(std::max_align_t) >::type;
AlignedStorage val;
protected: protected:
union { Data&
byte_t b[sz]; as_array()
Long_t l[(sz / sizeof(Long_t)) + (sz % sizeof(Long_t))]; {
}; return reinterpret_cast< Data& >(val);
}
const Data&
as_array() const
{
return reinterpret_cast< const Data& >(val);
}
}; };
} // namespace llarp } // namespace llarp

@ -3,17 +3,24 @@
#include <aligned.hpp> #include <aligned.hpp>
#include <array>
namespace llarp namespace llarp
{ {
namespace dht namespace dht
{ {
struct Key_t : public llarp::AlignedBuffer< 32 > struct Key_t : public llarp::AlignedBuffer< 32 >
{ {
Key_t(const byte_t* val) : llarp::AlignedBuffer< 32 >(val) Key_t(const byte_t* buf) : llarp::AlignedBuffer< SIZE >(buf)
{
}
Key_t(const std::array< byte_t, SIZE >& val)
: llarp::AlignedBuffer< SIZE >(val.data())
{ {
} }
Key_t() : llarp::AlignedBuffer< 32 >() Key_t() : llarp::AlignedBuffer< SIZE >()
{ {
} }
@ -21,33 +28,34 @@ namespace llarp
operator^(const Key_t& other) const operator^(const Key_t& other) const
{ {
Key_t dist; Key_t dist;
for(size_t idx = 0; idx < (size() / sizeof(l[0])); ++idx) std::transform(as_array().begin(), as_array().end(),
dist.l[idx] = l[idx] ^ other.l[idx]; other.as_array().begin(), dist.as_array().begin(),
std::bit_xor< byte_t >());
return dist; return dist;
} }
bool bool
operator==(const Key_t& other) const operator==(const Key_t& other) const
{ {
return memcmp(data(), other.data(), 32) == 0; return memcmp(data(), other.data(), SIZE) == 0;
} }
bool bool
operator!=(const Key_t& other) const operator!=(const Key_t& other) const
{ {
return memcmp(data(), other.data(), 32) != 0; return memcmp(data(), other.data(), SIZE) != 0;
} }
bool bool
operator<(const Key_t& other) const operator<(const Key_t& other) const
{ {
return memcmp(data(), other.data(), 32) < 0; return memcmp(data(), other.data(), SIZE) < 0;
} }
bool bool
operator>(const Key_t& other) const operator>(const Key_t& other) const
{ {
return memcmp(data(), other.data(), 32) > 0; return memcmp(data(), other.data(), SIZE) > 0;
} }
}; };
} // namespace dht } // namespace dht

@ -41,7 +41,7 @@ decode_request_name(const std::string &name, llarp::AlignedBuffer< 32 > &addr,
auto pos = name.find(".snode"); auto pos = name.find(".snode");
if(pos != std::string::npos) if(pos != std::string::npos)
{ {
if(!llarp::HexDecode(name.substr(0, pos).c_str(), serviceAddr.data(), if(!llarp::HexDecode(name.substr(0, pos).c_str(), serviceAddr.data().data(),
serviceAddr.size())) serviceAddr.size()))
{ {
return false; return false;
@ -55,7 +55,7 @@ decode_request_name(const std::string &name, llarp::AlignedBuffer< 32 > &addr,
{ {
return false; return false;
} }
addr = serviceAddr.data(); addr = serviceAddr.data().data();
isSNode = false; isSNode = false;
} }
return true; return true;

@ -211,9 +211,9 @@ namespace llarp
} }
else if(addr.FromString(qname, ".loki")) else if(addr.FromString(qname, ".loki"))
{ {
if(HasAddress(addr.data())) if(HasAddress(addr.data().data()))
{ {
huint32_t ip = ObtainIPForAddr(addr.data(), false); huint32_t ip = ObtainIPForAddr(addr.data().data(), false);
msg.AddINReply(ip); msg.AddINReply(ip);
} }
else else
@ -227,8 +227,8 @@ namespace llarp
else if(addr.FromString(qname, ".snode")) else if(addr.FromString(qname, ".snode"))
{ {
// TODO: add hook to EnsurePathToSNode // TODO: add hook to EnsurePathToSNode
EnsurePathToSNode(addr.data()); EnsurePathToSNode(addr.data().data());
huint32_t ip = ObtainIPForAddr(addr.data(), true); huint32_t ip = ObtainIPForAddr(addr.data().data(), true);
msg.AddINReply(ip); msg.AddINReply(ip);
} }
else else
@ -310,7 +310,7 @@ namespace llarp
{ {
if(ctx) if(ctx)
{ {
huint32_t ip = ObtainIPForAddr(addr.data(), false); huint32_t ip = ObtainIPForAddr(addr.data().data(), false);
request.AddINReply(ip); request.AddINReply(ip);
} }
else else
@ -333,9 +333,9 @@ namespace llarp
} }
llarp::LogInfo(Name() + " map ", addr.ToString(), " to ", ip); llarp::LogInfo(Name() + " map ", addr.ToString(), " to ", ip);
m_IPToAddr[ip] = addr.data(); m_IPToAddr[ip] = addr.data().data();
m_AddrToIP[addr.data()] = ip; m_AddrToIP[addr.data().data()] = ip;
m_SNodes[addr.data()] = SNode; m_SNodes[addr.data().data()] = SNode;
MarkIPActiveForever(ip); MarkIPActiveForever(ip);
return true; return true;
} }

@ -191,7 +191,7 @@ namespace llarp
size_t size_t
operator()(const PathInfo_t& i) const operator()(const PathInfo_t& i) const
{ {
return *i.first.data_l() ^ *i.second.data_l(); return RouterID::Hash()(i.first) ^ PathID_t::Hash()(i.second);
} }
}; };
using Mtx_t = llarp::util::NullMutex; using Mtx_t = llarp::util::NullMutex;

@ -7,11 +7,19 @@ namespace llarp
{ {
struct RouterID : public AlignedBuffer< 32 > struct RouterID : public AlignedBuffer< 32 >
{ {
RouterID() : AlignedBuffer< 32 >() static constexpr size_t SIZE = 32;
using Data = std::array< byte_t, SIZE >;
RouterID() : AlignedBuffer< SIZE >()
{
}
RouterID(const byte_t* buf) : AlignedBuffer< SIZE >(buf)
{ {
} }
RouterID(const byte_t* buf) : AlignedBuffer< 32 >(buf) RouterID(const Data& data) : AlignedBuffer< SIZE >(data)
{ {
} }
@ -24,7 +32,7 @@ namespace llarp
RouterID& RouterID&
operator=(const byte_t* ptr) operator=(const byte_t* ptr)
{ {
memcpy(data(), ptr, 32); memcpy(data(), ptr, SIZE);
return *this; return *this;
} }
@ -34,7 +42,7 @@ namespace llarp
return out << id.ToString(); return out << id.ToString();
} }
using Hash = AlignedBuffer< 32 >::Hash; using Hash = AlignedBuffer< SIZE >::Hash;
}; };
} // namespace llarp } // namespace llarp

@ -121,8 +121,7 @@ namespace llarp
} }
/// calculate our address /// calculate our address
bool bool CalculateAddress(std::array< byte_t, 32 >& data) const;
CalculateAddress(byte_t* buf) const;
bool bool
BDecode(llarp_buffer_t* buf) override BDecode(llarp_buffer_t* buf) override

@ -86,7 +86,7 @@ namespace llarp
size_t size_t
operator()(const Introduction& i) const operator()(const Introduction& i) const
{ {
return *i.router.data_l() ^ *i.pathID.data_l(); return PubKey::Hash()(i.router) ^ PathID_t::Hash()(i.pathID);
} }
}; };
}; };

@ -5,6 +5,8 @@
#include <dht/key.hpp> #include <dht/key.hpp>
#include <router_id.hpp> #include <router_id.hpp>
#include <functional>
#include <numeric>
#include <string> #include <string>
namespace llarp namespace llarp
@ -14,6 +16,10 @@ namespace llarp
/// Snapp/Snode Address /// Snapp/Snode Address
struct Address struct Address
{ {
static constexpr size_t SIZE = 32;
using Data = std::array< byte_t, SIZE >;
std::string std::string
ToString(const char* tld = ".loki") const; ToString(const char* tld = ".loki") const;
@ -27,12 +33,12 @@ namespace llarp
Address(const byte_t* buf) Address(const byte_t* buf)
{ {
memcpy(b, buf, 32); std::copy(buf, buf + SIZE, b.begin());
} }
Address(const Address& other) Address(const Address& other)
{ {
memcpy(b, other.b, 32); b = other.b;
} }
byte_t& operator[](size_t idx) byte_t& operator[](size_t idx)
@ -48,7 +54,7 @@ namespace llarp
bool bool
BEncode(llarp_buffer_t* buf) const BEncode(llarp_buffer_t* buf) const
{ {
return bencode_write_bytestring(buf, b, 32); return bencode_write_bytestring(buf, b.data(), SIZE);
} }
bool bool
@ -57,49 +63,39 @@ namespace llarp
llarp_buffer_t strbuf; llarp_buffer_t strbuf;
if(!bencode_read_string(buf, &strbuf)) if(!bencode_read_string(buf, &strbuf))
return false; return false;
if(strbuf.sz != 32) if(strbuf.sz != SIZE)
{ {
llarp::LogErrorTag("Address::BDecode", llarp::LogErrorTag("Address::BDecode",
"bdecode buffer size missmatch ", strbuf.sz, "bdecode buffer size missmatch ", strbuf.sz,
"!=32"); "!=32");
return false; return false;
} }
memcpy(b, strbuf.base, 32); std::copy(strbuf.base, strbuf.base + SIZE, b.begin());
return true; return true;
} }
size_t static constexpr size_t
size() const size()
{ {
return 32; return SIZE;
} }
bool bool
IsZero() const IsZero() const
{ {
size_t sz = 4; return b == Data{};
while(sz)
{
if(l[--sz])
return false;
}
return true;
} }
void void
Zero() Zero()
{ {
size_t sz = 4; b.fill(0);
while(sz)
{
l[--sz] = 0;
}
} }
bool bool
operator<(const Address& other) const operator<(const Address& other) const
{ {
return memcmp(data(), other.data(), 32) < 0; return data() < other.data();
} }
friend std::ostream& friend std::ostream&
@ -111,7 +107,7 @@ namespace llarp
bool bool
operator==(const Address& other) const operator==(const Address& other) const
{ {
return memcmp(data(), other.data(), 32) == 0; return data() == other.data();
} }
bool bool
@ -121,11 +117,7 @@ namespace llarp
} }
Address& Address&
operator=(const Address& other) operator=(const Address& other) = default;
{
memcpy(data(), other.data(), 32);
return *this;
}
const dht::Key_t const dht::Key_t
ToKey() const ToKey() const
@ -136,41 +128,33 @@ namespace llarp
const RouterID const RouterID
ToRouter() const ToRouter() const
{ {
return RouterID(data()); return RouterID(data().data());
} }
const byte_t* const Data&
data() const data() const
{ {
return b; return b;
} }
byte_t* Data&
data() data()
{ {
return b; return b;
} }
const uint64_t*
data_l() const
{
return l;
}
struct Hash struct Hash
{ {
size_t size_t
operator()(const Address& buf) const operator()(const Address& buf) const
{ {
return *buf.data_l(); return std::accumulate(buf.data().begin(), buf.data().end(), 0,
std::bit_xor< size_t >());
} }
}; };
private: private:
union { Data b;
byte_t b[32];
uint64_t l[4];
};
}; };
} // namespace service } // namespace service

@ -538,7 +538,7 @@ namespace llarp
Endpoint::PublishIntroSet(llarp::Router* r) Endpoint::PublishIntroSet(llarp::Router* r)
{ {
// publish via near router // publish via near router
RouterID location = m_Identity.pub.Addr().data(); RouterID location = m_Identity.pub.Addr().data().data();
auto path = GetEstablishedPathClosestTo(location); auto path = GetEstablishedPathClosestTo(location);
return path && PublishIntroSetVia(r, path); return path && PublishIntroSetVia(r, path);
} }
@ -827,9 +827,10 @@ namespace llarp
if(msg->proto == eProtocolTraffic) if(msg->proto == eProtocolTraffic)
{ {
auto buf = llarp::Buffer(msg->payload); auto buf = llarp::Buffer(msg->payload);
return HandleWriteIPPacket(buf, return HandleWriteIPPacket(
std::bind(&Endpoint::ObtainIPForAddr, this, buf,
msg->sender.Addr().data(), false)); std::bind(&Endpoint::ObtainIPForAddr, this,
msg->sender.Addr().data().data(), false));
} }
else if(msg->proto == eProtocolText) else if(msg->proto == eProtocolText)
{ {

@ -56,15 +56,14 @@ namespace llarp
return m_CachedAddr.ToString(); return m_CachedAddr.ToString();
} }
bool bool ServiceInfo::CalculateAddress(std::array< byte_t, 32 >& data) const
ServiceInfo::CalculateAddress(byte_t* addr) const
{ {
byte_t tmp[256] = {0}; byte_t tmp[256] = {0};
auto buf = llarp::StackBuffer< decltype(tmp) >(tmp); auto buf = llarp::StackBuffer< decltype(tmp) >(tmp);
if(!BEncode(&buf)) if(!BEncode(&buf))
return false; return false;
return crypto_generichash_blake2b(addr, 32, buf.base, buf.cur - buf.base, return crypto_generichash_blake2b(data.data(), data.size(), buf.base,
nullptr, 0) buf.cur - buf.base, nullptr, 0)
!= -1; != -1;
} }

@ -54,14 +54,7 @@ namespace llarp
return ToString().empty(); return ToString().empty();
} }
struct Hash using Hash = AlignedBuffer< SIZE >::Hash;
{
std::size_t
operator()(const Tag& t) const
{
return *t.data_l();
}
};
}; };
} // namespace service } // namespace service
} // namespace llarp } // namespace llarp

Loading…
Cancel
Save