From 037cb87523abba5287e7dad83677f36cad6d73e7 Mon Sep 17 00:00:00 2001 From: Michael Date: Thu, 20 Dec 2018 14:18:03 +0000 Subject: [PATCH] Convert llarp::AlignedBuffer to be backed by std::array --- llarp/address_info.hpp | 2 +- llarp/aligned.hpp | 138 ++++++++++++++++++++++-------------- llarp/dht/key.hpp | 24 ++++--- llarp/dns_dotlokilookup.cpp | 4 +- llarp/handlers/tun.cpp | 16 ++--- llarp/pathset.hpp | 2 +- llarp/router_id.hpp | 16 +++-- llarp/service/Info.hpp | 3 +- llarp/service/Intro.hpp | 2 +- llarp/service/address.hpp | 66 +++++++---------- llarp/service/endpoint.cpp | 9 +-- llarp/service/info.cpp | 7 +- llarp/service/tag.hpp | 9 +-- 13 files changed, 160 insertions(+), 138 deletions(-) diff --git a/llarp/address_info.hpp b/llarp/address_info.hpp index 05081bf20..1a0c15e22 100644 --- a/llarp/address_info.hpp +++ b/llarp/address_info.hpp @@ -73,7 +73,7 @@ namespace llarp size_t operator()(const AddressInfo& addr) const { - return *addr.pubkey.data_l(); + return AlignedBuffer< PUBKEYSIZE >::Hash()(addr.pubkey); } }; }; diff --git a/llarp/aligned.hpp b/llarp/aligned.hpp index 2cee52b23..8b8f33b01 100644 --- a/llarp/aligned.hpp +++ b/llarp/aligned.hpp @@ -5,8 +5,13 @@ #include #include +#include +#include #include #include +#include +#include +#include extern "C" { @@ -19,29 +24,44 @@ extern "C" } namespace llarp { - /// aligned buffer that is sz bytes long and aligns to the nears Long_t - template < size_t sz, bool randomize = false, typename Long_t = uint64_t > + /// aligned buffer that is sz bytes long and aligns to the nearest Alignment + template < size_t sz > struct AlignedBuffer { + static constexpr size_t SIZE = sz; + + using Data = std::array< byte_t, SIZE >; + AlignedBuffer() { - if(randomize) - Randomize(); - else - Zero(); + new(&val) Data; + Zero(); } AlignedBuffer(const byte_t* data) { + new(&val) Data; + auto& b = as_array(); for(size_t idx = 0; idx < sz; ++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& operator=(const byte_t* data) { + auto& b = as_array(); for(size_t idx = 0; idx < sz; ++idx) + { b[idx] = data[idx]; + } return *this; } @@ -57,75 +77,72 @@ namespace llarp operator~() const { AlignedBuffer< sz > ret; - size_t idx = 0; - while(idx < sz / sizeof(Long_t)) - { - ret.data_l()[idx] = ~data_l()[idx]; - ++idx; - } + std::transform(as_array().begin(), as_array().end(), + ret.as_array().begin(), [](byte_t a) { return ~a; }); + return ret; } bool operator==(const AlignedBuffer& other) const { - return memcmp(b, other.b, sz) == 0; + return as_array() == other.as_array(); } bool operator!=(const AlignedBuffer& other) const { - return !(*this == other); + return as_array() != other.as_array(); } bool operator<(const AlignedBuffer& other) const { - return memcmp(l, other.l, sz) < 0; + return as_array() < other.as_array(); } bool operator>(const AlignedBuffer& other) const { - return memcmp(l, other.l, sz) > 0; + return as_array() > other.as_array(); } bool operator<=(const AlignedBuffer& other) const { - return memcmp(l, other.l, sz) <= 0; + return as_array() <= other.as_array(); } bool operator>=(const AlignedBuffer& other) const { - return memcmp(l, other.l, sz) >= 0; + return as_array() >= other.as_array(); } AlignedBuffer operator^(const AlignedBuffer& other) const { AlignedBuffer< sz > ret; - for(size_t idx = 0; idx < sz / sizeof(Long_t); ++idx) - ret.l[idx] = l[idx] ^ other.l[idx]; + std::transform(as_array().begin(), as_array().end(), + other.as_array().begin(), ret.as_array().begin(), + std::bit_xor< byte_t >()); return ret; } AlignedBuffer& operator^=(const AlignedBuffer& other) { - for(size_t idx = 0; idx < sz / sizeof(Long_t); ++idx) - l[idx] ^= other.l[idx]; - return *this; - } + // Mutate in place instead. + // Well defined for std::transform, - size_t - size() const - { - return sz; + for(size_t i = 0; i < as_array().size(); ++i) + { + as_array()[i] ^= other.as_array()[i]; + } + return *this; } - size_t + static constexpr size_t size() { return sz; @@ -134,66 +151,63 @@ namespace llarp void Fill(byte_t f) { - for(size_t idx = 0; idx < sz; ++idx) - b[idx] = f; + as_array().fill(f); } bool IsZero() const { - return sodium_is_zero(b, sz) != 0; + return sodium_is_zero(as_array().data(), SIZE) != 0; } void Zero() { - sodium_memzero(l, sz); + as_array().fill(0); } void Randomize() { - randombytes(b, sz); + randombytes(as_array().data(), SIZE); } byte_t* data() { - return b; + return as_array().data(); } const byte_t* data() const { - return b; + return as_array().data(); } - Long_t* - data_l() + operator const byte_t*() const { - return l; + return as_array().data(); } - const Long_t* - data_l() const + operator byte_t*() { - 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 BEncode(llarp_buffer_t* buf) const { - return bencode_write_bytestring(buf, b, sz); + return bencode_write_bytestring(buf, as_array().data(), sz); } bool @@ -201,13 +215,15 @@ namespace llarp { llarp_buffer_t strbuf; if(!bencode_read_string(buf, &strbuf)) + { return false; + } if(strbuf.sz != sz) { llarp::LogError("bdecode buffer size missmatch ", strbuf.sz, "!=", sz); return false; } - memcpy(b, strbuf.base, sz); + memcpy(as_array().data(), strbuf.base, sz); return true; } @@ -221,17 +237,31 @@ namespace llarp struct Hash { 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: - union { - byte_t b[sz]; - Long_t l[(sz / sizeof(Long_t)) + (sz % sizeof(Long_t))]; - }; + Data& + as_array() + { + return reinterpret_cast< Data& >(val); + } + + const Data& + as_array() const + { + return reinterpret_cast< const Data& >(val); + } }; } // namespace llarp diff --git a/llarp/dht/key.hpp b/llarp/dht/key.hpp index 17d9e1563..92547e965 100644 --- a/llarp/dht/key.hpp +++ b/llarp/dht/key.hpp @@ -3,17 +3,24 @@ #include +#include + namespace llarp { namespace dht { 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 { Key_t dist; - for(size_t idx = 0; idx < (size() / sizeof(l[0])); ++idx) - dist.l[idx] = l[idx] ^ other.l[idx]; + std::transform(as_array().begin(), as_array().end(), + other.as_array().begin(), dist.as_array().begin(), + std::bit_xor< byte_t >()); return dist; } bool operator==(const Key_t& other) const { - return memcmp(data(), other.data(), 32) == 0; + return memcmp(data(), other.data(), SIZE) == 0; } bool operator!=(const Key_t& other) const { - return memcmp(data(), other.data(), 32) != 0; + return memcmp(data(), other.data(), SIZE) != 0; } bool operator<(const Key_t& other) const { - return memcmp(data(), other.data(), 32) < 0; + return memcmp(data(), other.data(), SIZE) < 0; } bool operator>(const Key_t& other) const { - return memcmp(data(), other.data(), 32) > 0; + return memcmp(data(), other.data(), SIZE) > 0; } }; } // namespace dht diff --git a/llarp/dns_dotlokilookup.cpp b/llarp/dns_dotlokilookup.cpp index e8e279727..3fc87a18e 100644 --- a/llarp/dns_dotlokilookup.cpp +++ b/llarp/dns_dotlokilookup.cpp @@ -41,7 +41,7 @@ decode_request_name(const std::string &name, llarp::AlignedBuffer< 32 > &addr, auto pos = name.find(".snode"); 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())) { return false; @@ -55,7 +55,7 @@ decode_request_name(const std::string &name, llarp::AlignedBuffer< 32 > &addr, { return false; } - addr = serviceAddr.data(); + addr = serviceAddr.data().data(); isSNode = false; } return true; diff --git a/llarp/handlers/tun.cpp b/llarp/handlers/tun.cpp index 0ac88af47..514c3b7b4 100644 --- a/llarp/handlers/tun.cpp +++ b/llarp/handlers/tun.cpp @@ -211,9 +211,9 @@ namespace llarp } 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); } else @@ -227,8 +227,8 @@ namespace llarp else if(addr.FromString(qname, ".snode")) { // TODO: add hook to EnsurePathToSNode - EnsurePathToSNode(addr.data()); - huint32_t ip = ObtainIPForAddr(addr.data(), true); + EnsurePathToSNode(addr.data().data()); + huint32_t ip = ObtainIPForAddr(addr.data().data(), true); msg.AddINReply(ip); } else @@ -310,7 +310,7 @@ namespace llarp { if(ctx) { - huint32_t ip = ObtainIPForAddr(addr.data(), false); + huint32_t ip = ObtainIPForAddr(addr.data().data(), false); request.AddINReply(ip); } else @@ -333,9 +333,9 @@ namespace llarp } llarp::LogInfo(Name() + " map ", addr.ToString(), " to ", ip); - m_IPToAddr[ip] = addr.data(); - m_AddrToIP[addr.data()] = ip; - m_SNodes[addr.data()] = SNode; + m_IPToAddr[ip] = addr.data().data(); + m_AddrToIP[addr.data().data()] = ip; + m_SNodes[addr.data().data()] = SNode; MarkIPActiveForever(ip); return true; } diff --git a/llarp/pathset.hpp b/llarp/pathset.hpp index 8f66e4d1e..ab688a1d6 100644 --- a/llarp/pathset.hpp +++ b/llarp/pathset.hpp @@ -191,7 +191,7 @@ namespace llarp size_t 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; diff --git a/llarp/router_id.hpp b/llarp/router_id.hpp index ff052417f..733aa45ee 100644 --- a/llarp/router_id.hpp +++ b/llarp/router_id.hpp @@ -7,11 +7,19 @@ namespace llarp { 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& operator=(const byte_t* ptr) { - memcpy(data(), ptr, 32); + memcpy(data(), ptr, SIZE); return *this; } @@ -34,7 +42,7 @@ namespace llarp return out << id.ToString(); } - using Hash = AlignedBuffer< 32 >::Hash; + using Hash = AlignedBuffer< SIZE >::Hash; }; } // namespace llarp diff --git a/llarp/service/Info.hpp b/llarp/service/Info.hpp index 76ee02454..5b905d17d 100644 --- a/llarp/service/Info.hpp +++ b/llarp/service/Info.hpp @@ -121,8 +121,7 @@ namespace llarp } /// calculate our address - bool - CalculateAddress(byte_t* buf) const; + bool CalculateAddress(std::array< byte_t, 32 >& data) const; bool BDecode(llarp_buffer_t* buf) override diff --git a/llarp/service/Intro.hpp b/llarp/service/Intro.hpp index ee63b9918..a9b6eb2f7 100644 --- a/llarp/service/Intro.hpp +++ b/llarp/service/Intro.hpp @@ -86,7 +86,7 @@ namespace llarp size_t operator()(const Introduction& i) const { - return *i.router.data_l() ^ *i.pathID.data_l(); + return PubKey::Hash()(i.router) ^ PathID_t::Hash()(i.pathID); } }; }; diff --git a/llarp/service/address.hpp b/llarp/service/address.hpp index 4495406e8..ff2d369e7 100644 --- a/llarp/service/address.hpp +++ b/llarp/service/address.hpp @@ -5,6 +5,8 @@ #include #include +#include +#include #include namespace llarp @@ -14,6 +16,10 @@ namespace llarp /// Snapp/Snode Address struct Address { + static constexpr size_t SIZE = 32; + + using Data = std::array< byte_t, SIZE >; + std::string ToString(const char* tld = ".loki") const; @@ -27,12 +33,12 @@ namespace llarp Address(const byte_t* buf) { - memcpy(b, buf, 32); + std::copy(buf, buf + SIZE, b.begin()); } Address(const Address& other) { - memcpy(b, other.b, 32); + b = other.b; } byte_t& operator[](size_t idx) @@ -48,7 +54,7 @@ namespace llarp bool BEncode(llarp_buffer_t* buf) const { - return bencode_write_bytestring(buf, b, 32); + return bencode_write_bytestring(buf, b.data(), SIZE); } bool @@ -57,49 +63,39 @@ namespace llarp llarp_buffer_t strbuf; if(!bencode_read_string(buf, &strbuf)) return false; - if(strbuf.sz != 32) + if(strbuf.sz != SIZE) { llarp::LogErrorTag("Address::BDecode", "bdecode buffer size missmatch ", strbuf.sz, "!=32"); return false; } - memcpy(b, strbuf.base, 32); + std::copy(strbuf.base, strbuf.base + SIZE, b.begin()); return true; } - size_t - size() const + static constexpr size_t + size() { - return 32; + return SIZE; } bool IsZero() const { - size_t sz = 4; - while(sz) - { - if(l[--sz]) - return false; - } - return true; + return b == Data{}; } void Zero() { - size_t sz = 4; - while(sz) - { - l[--sz] = 0; - } + b.fill(0); } bool operator<(const Address& other) const { - return memcmp(data(), other.data(), 32) < 0; + return data() < other.data(); } friend std::ostream& @@ -111,7 +107,7 @@ namespace llarp bool operator==(const Address& other) const { - return memcmp(data(), other.data(), 32) == 0; + return data() == other.data(); } bool @@ -121,11 +117,7 @@ namespace llarp } Address& - operator=(const Address& other) - { - memcpy(data(), other.data(), 32); - return *this; - } + operator=(const Address& other) = default; const dht::Key_t ToKey() const @@ -136,41 +128,33 @@ namespace llarp const RouterID ToRouter() const { - return RouterID(data()); + return RouterID(data().data()); } - const byte_t* + const Data& data() const { return b; } - byte_t* + Data& data() { return b; } - const uint64_t* - data_l() const - { - return l; - } - struct Hash { size_t 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: - union { - byte_t b[32]; - uint64_t l[4]; - }; + Data b; }; } // namespace service diff --git a/llarp/service/endpoint.cpp b/llarp/service/endpoint.cpp index 6312d5b7b..058cb926e 100644 --- a/llarp/service/endpoint.cpp +++ b/llarp/service/endpoint.cpp @@ -538,7 +538,7 @@ namespace llarp Endpoint::PublishIntroSet(llarp::Router* r) { // publish via near router - RouterID location = m_Identity.pub.Addr().data(); + RouterID location = m_Identity.pub.Addr().data().data(); auto path = GetEstablishedPathClosestTo(location); return path && PublishIntroSetVia(r, path); } @@ -827,9 +827,10 @@ namespace llarp if(msg->proto == eProtocolTraffic) { auto buf = llarp::Buffer(msg->payload); - return HandleWriteIPPacket(buf, - std::bind(&Endpoint::ObtainIPForAddr, this, - msg->sender.Addr().data(), false)); + return HandleWriteIPPacket( + buf, + std::bind(&Endpoint::ObtainIPForAddr, this, + msg->sender.Addr().data().data(), false)); } else if(msg->proto == eProtocolText) { diff --git a/llarp/service/info.cpp b/llarp/service/info.cpp index 347b53bec..68dadb093 100644 --- a/llarp/service/info.cpp +++ b/llarp/service/info.cpp @@ -56,15 +56,14 @@ namespace llarp return m_CachedAddr.ToString(); } - bool - ServiceInfo::CalculateAddress(byte_t* addr) const + bool ServiceInfo::CalculateAddress(std::array< byte_t, 32 >& data) const { byte_t tmp[256] = {0}; auto buf = llarp::StackBuffer< decltype(tmp) >(tmp); if(!BEncode(&buf)) return false; - return crypto_generichash_blake2b(addr, 32, buf.base, buf.cur - buf.base, - nullptr, 0) + return crypto_generichash_blake2b(data.data(), data.size(), buf.base, + buf.cur - buf.base, nullptr, 0) != -1; } diff --git a/llarp/service/tag.hpp b/llarp/service/tag.hpp index e6d1fbb59..d365d3aba 100644 --- a/llarp/service/tag.hpp +++ b/llarp/service/tag.hpp @@ -54,14 +54,7 @@ namespace llarp return ToString().empty(); } - struct Hash - { - std::size_t - operator()(const Tag& t) const - { - return *t.data_l(); - } - }; + using Hash = AlignedBuffer< SIZE >::Hash; }; } // namespace service } // namespace llarp