diff --git a/llarp/CMakeLists.txt b/llarp/CMakeLists.txt index cce2e29b5..9b6635cb9 100644 --- a/llarp/CMakeLists.txt +++ b/llarp/CMakeLists.txt @@ -91,7 +91,6 @@ add_dependencies(lokinet-utils genversion) lokinet_add_library(lokinet-time-place ev/ev.cpp ev/libuv.cpp - net/exit_info.cpp # only router_contact net/ip.cpp net/ip_address.cpp net/ip_packet.cpp diff --git a/llarp/bootstrap.cpp b/llarp/bootstrap.cpp index c51da6dee..474052c30 100644 --- a/llarp/bootstrap.cpp +++ b/llarp/bootstrap.cpp @@ -31,7 +31,7 @@ namespace llarp oxenc::bt_list_producer btlp{}; for (const auto& it : *this) - btlp.append(it.bt_encode()); + btlp.append(it.view()); return btlp.view(); } diff --git a/llarp/link/link_manager.cpp b/llarp/link/link_manager.cpp index 2e80cb603..caa004a4e 100644 --- a/llarp/link/link_manager.cpp +++ b/llarp/link/link_manager.cpp @@ -628,8 +628,7 @@ namespace llarp || local_rid == rid) continue; - neighbors += - rid.bt_encode(); // TODO: refactor to use reference to bt_dict_producer subdict + neighbors += rid.bt_encode(); } m.respond( diff --git a/llarp/net/exit_info.cpp b/llarp/net/exit_info.cpp deleted file mode 100644 index 69d297cca..000000000 --- a/llarp/net/exit_info.cpp +++ /dev/null @@ -1,121 +0,0 @@ -#ifndef _WIN32 -#include -#endif - -#include "exit_info.hpp" - -#include - -#include - -namespace llarp -{ - bool - ExitInfo::bt_encode(llarp_buffer_t* buf) const - { - SockAddr exitaddr = ipAddress.createSockAddr(); - const auto* exitaddr6 = static_cast(exitaddr); - - SockAddr netmaskaddr = netmask.createSockAddr(); - const auto* netmaskaddr6 = static_cast(netmaskaddr); - - char tmp[128] = {0}; - if (!bencode_start_dict(buf)) - return false; - - if (!inet_ntop(AF_INET6, &exitaddr6->sin6_addr, tmp, sizeof(tmp))) - return false; - if (!BEncodeWriteDictString("a", std::string(tmp), buf)) - return false; - - if (!inet_ntop(AF_INET6, &netmaskaddr6->sin6_addr, tmp, sizeof(tmp))) - return false; - if (!BEncodeWriteDictString("b", std::string(tmp), buf)) - return false; - - if (!BEncodeWriteDictEntry("k", pubkey, buf)) - return false; - - if (!BEncodeWriteDictInt("v", version, buf)) - return false; - - return bencode_end(buf); - } - - static bool - bdecode_ip_string(llarp_buffer_t* buf, in6_addr& ip) - { - char tmp[128] = {0}; - llarp_buffer_t strbuf; - if (!bencode_read_string(buf, &strbuf)) - return false; - - if (strbuf.sz >= sizeof(tmp)) - return false; - - memcpy(tmp, strbuf.base, strbuf.sz); - tmp[strbuf.sz] = 0; - return inet_pton(AF_INET6, tmp, &ip.s6_addr[0]) == 1; - } - - bool - ExitInfo::decode_key(const llarp_buffer_t& k, llarp_buffer_t* buf) - { - bool read = false; - if (!BEncodeMaybeReadDictEntry("k", pubkey, read, k, buf)) - return false; - if (!BEncodeMaybeReadDictInt("v", version, read, k, buf)) - return false; - if (k.startswith("a")) - { - in6_addr tmp; - if (not bdecode_ip_string(buf, tmp)) - return false; - - SockAddr addr(tmp); - ipAddress = IpAddress(addr); - return true; - } - if (k.startswith("b")) - { - in6_addr tmp; - if (not bdecode_ip_string(buf, tmp)) - return false; - SockAddr addr(tmp); - netmask = IpAddress(addr); - return true; - } - return read; - } - - std::string - ExitInfo::ToString() const - { - /* - // TODO: derive these from ipAdress - throw std::runtime_error("FIXME: need in6_addr and netmask from IpAddress"); - in6_addr address; - in6_addr netmask; - - Printer printer(stream, level, spaces); - - std::ostringstream ss; - char tmp[128] = {0}; - - if (inet_ntop(AF_INET6, (void*)&address, tmp, sizeof(tmp))) - ss << tmp; - else - return stream; - ss << std::string("/"); -#if defined(ANDROID) - snprintf(tmp, sizeof(tmp), "%zu", llarp::bits::count_array_bits(netmask.s6_addr)); - ss << tmp; -#else - ss << std::to_string(llarp::bits::count_array_bits(netmask.s6_addr)); -#endif - printer.printValue(ss.str()); - */ - return fmt::format("[Exit {}]", ipAddress.ToString()); - } - -} // namespace llarp diff --git a/llarp/net/exit_info.hpp b/llarp/net/exit_info.hpp deleted file mode 100644 index 5c1c92736..000000000 --- a/llarp/net/exit_info.hpp +++ /dev/null @@ -1,51 +0,0 @@ -#pragma once - -#include "ip_address.hpp" - -#include -#include - -#include - -/** - * exit_info.h - * - * utilities for handling exits on the llarp network - */ - -/// Exit info model -namespace llarp -{ - /// deprecated don't use me , this is only for backwards compat - struct ExitInfo - { - IpAddress ipAddress; - IpAddress netmask; - PubKey pubkey; - uint64_t version = llarp::constants::proto_version; - - ExitInfo() = default; - - ExitInfo(const PubKey& pk, const IpAddress& address) : ipAddress(address), pubkey(pk) - {} - - bool - bt_encode(llarp_buffer_t* buf) const; - - bool - BDecode(llarp_buffer_t* buf) - { - return bencode_decode_dict(*this, buf); - } - - bool - decode_key(const llarp_buffer_t& k, llarp_buffer_t* buf); - - std::string - ToString() const; - }; - - template <> - constexpr inline bool IsToStringFormattable = true; - -} // namespace llarp diff --git a/llarp/router/rc_lookup_handler.cpp b/llarp/router/rc_lookup_handler.cpp index 8723f1bbe..b284b9562 100644 --- a/llarp/router/rc_lookup_handler.cpp +++ b/llarp/router/rc_lookup_handler.cpp @@ -278,7 +278,8 @@ namespace llarp { for (const auto& rc : bootstrap_rc_list) { - log::info(link_cat, "Doing explore via bootstrap node: {}", RouterID(rc.router_id())); + const auto& rid = rc.router_id(); + log::info(link_cat, "Doing explore via bootstrap node: {}", rid); // TODO: replace this concept // dht->ExploreNetworkVia(dht::Key_t{rc.pubkey}); diff --git a/llarp/router/router.cpp b/llarp/router/router.cpp index 1b88b6f43..3c6e44414 100644 --- a/llarp/router/router.cpp +++ b/llarp/router/router.cpp @@ -539,15 +539,19 @@ namespace llarp return _link_manager.get_num_connected_clients(); } + void + Router::save_rc() + { + _node_db->put_rc(router_contact.view()); + queue_disk_io([&]() { router_contact.write(our_rc_file); }); + } + bool Router::update_rc() { router_contact.resign(); if (is_service_node()) - { - _node_db->put_rc(router_contact.view()); - queue_disk_io([&]() { router_contact.write(our_rc_file); }); - } + save_rc(); return true; } @@ -756,17 +760,24 @@ namespace llarp Router::report_stats() { const auto now = llarp::time_now_ms(); - LogInfo(node_db()->num_loaded(), " RCs loaded"); - LogInfo(bootstrap_rc_list.size(), " bootstrap peers"); - LogInfo(NumberOfConnectedRouters(), " router connections"); + log::info( + logcat, + "{} RCs loaded with {} bootstrap peers and {} router connections!", + node_db()->num_loaded(), + bootstrap_rc_list.size(), + NumberOfConnectedRouters()); + if (is_service_node()) { - LogInfo(NumberOfConnectedClients(), " client connections"); - LogInfo(ToString(router_contact.age(now)), " since we last updated our RC"); - LogInfo(ToString(router_contact.time_to_expiry(now)), " until our RC expires"); + log::info( + logcat, + "Local service node has {} client connections since last RC update ({} to expiry)", + NumberOfConnectedClients(), + router_contact.age(now), + router_contact.time_to_expiry(now)); } if (_last_stats_report > 0s) - LogInfo(ToString(now - _last_stats_report), " last reported stats"); + log::info(logcat, "Last reported stats time {}", now - _last_stats_report); _last_stats_report = now; } @@ -939,7 +950,7 @@ namespace llarp // mark peers as de-registered for (auto& peer : close_peers) - _link_manager.deregister_peer(std::move(peer)); + _link_manager.deregister_peer(peer); } _link_manager.check_persisting_conns(now); @@ -1049,83 +1060,48 @@ namespace llarp if (is_running || is_stopping) return false; - // TODO: replace all this logic with construction of LocalRC + router_contact = LocalRC::make(identity(), public_ip()); - /* // set public signing key - router_contact._router_id = seckey_topublic(identity()); - // set router version if service node - if (IsServiceNode()) + if (is_service_node() and not router_contact.is_public_router()) { - router_contact.routerVersion = - RouterVersion(llarp::LOKINET_VERSION, llarp::constants::proto_version); - } - - if (IsServiceNode() and not router_contact.is_public_router()) - { - LogError("we are configured as relay but have no reachable addresses"); - return false; - } - - // set public encryption key - router_contact.enckey = seckey_topublic(encryption()); - - LogInfo("Signing rc..."); - if (!router_contact.sign(identity())) - { - LogError("failed to sign rc"); - return false; - } - - if (IsServiceNode()) - { - if (!SaveRC()) + if (not router_contact.is_public_router()) { - LogError("failed to save RC"); + log::error(logcat, "Router is configured as relay but has no reachable addresses!"); return false; } - } - if (IsServiceNode()) - { - // initialize as service node - if (!InitServiceNode()) + save_rc(); + + if (not init_service_node()) { - LogError("Failed to initialize service node"); + log::error(logcat, "Router failed to initialize service node!"); return false; } + + log::info(logcat, "Router initialized as service node!"); const RouterID us = pubkey(); - LogInfo("initalized service node: ", us); - // init gossiper here _rcGossiper.Init(&_link_manager, us, this); // relays do not use profiling router_profiling().Disable(); } else { - // we are a client - // regenerate keys and resign rc before everything else + // we are a client, regenerate keys and resign rc before everything else crypto::identity_keygen(_identity); crypto::encryption_keygen(_encryption); - router_contact._router_id = seckey_topublic(identity()); - router_contact.enckey = seckey_topublic(encryption()); - if (!router_contact.sign(identity())) - { - LogError("failed to regenerate keys and sign RC"); - return false; - } - } */ + router_contact.set_router_id(seckey_to_pubkey(identity())); // resigns RC + } + + log::info(logcat, "Starting hidden service context..."); - LogInfo("starting hidden service context..."); if (!hidden_service_context().StartAll()) { - LogError("Failed to start hidden service context"); + log::error(logcat, "Failed to start hidden service context!"); return false; } - { - LogInfo("Loading nodedb from disk..."); - _node_db->load_from_disk(); - } + log::info(logcat, "Loading NodeDB from disk..."); + _node_db->load_from_disk(); _contacts = std::make_shared(llarp::dht::Key_t(pubkey()), *this); @@ -1133,15 +1109,16 @@ namespace llarp { node_db()->put_rc(rc); _contacts->rc_nodes()->PutNode(rc); - LogInfo("added bootstrap node ", RouterID{rc.router_id()}); + log::info(logcat, "Added bootstrap node (rid: {})", rc.router_id()); } - LogInfo("have ", _node_db->num_loaded(), " routers"); + log::info(logcat, "Router populated NodeDB with {} routers", _node_db->num_loaded()); _loop->call_every(ROUTER_TICK_INTERVAL, weak_from_this(), [this] { Tick(); }); _route_poker->start(); is_running.store(true); _started_at = now(); + if (is_service_node()) { // do service node testing if we are in service node whitelist mode @@ -1163,13 +1140,16 @@ namespace llarp { if (not SessionToRouterAllowed(router)) { - LogDebug( - router, - " is no longer a registered service node so we remove it from the testing list"); + log::debug( + logcat, + "{} is no longer a registered service node; dropping from test list", + router); router_testing.remove_node_from_failing(router); continue; } - LogDebug("Establishing session to ", router, " for SN testing"); + + log::debug(logcat, "Establishing session to {} for service node testing", router); + // try to make a session to this random router // this will do a dht lookup if needed _link_manager.connect_to(router); @@ -1346,7 +1326,7 @@ namespace llarp } bool - Router::InitServiceNode() + Router::init_service_node() { LogInfo("accepting transit traffic"); paths.AllowTransit(); diff --git a/llarp/router/router.hpp b/llarp/router/router.hpp index 0abbf5dd2..9a2973477 100644 --- a/llarp/router/router.hpp +++ b/llarp/router/router.hpp @@ -147,6 +147,9 @@ namespace llarp void report_stats(); + void + save_rc(); + bool update_rc(); @@ -392,7 +395,7 @@ namespace llarp /// initialize us as a service node /// return true on success bool - InitServiceNode(); + init_service_node(); bool IsRunning() const; diff --git a/llarp/router_contact.cpp b/llarp/router_contact.cpp index f7c1211fd..68b8fcd90 100644 --- a/llarp/router_contact.cpp +++ b/llarp/router_contact.cpp @@ -110,7 +110,7 @@ namespace llarp bool RouterContact::write(const fs::path& fname) const { - auto bte = bt_encode(); + auto bte = view(); try { @@ -124,26 +124,6 @@ namespace llarp return true; } - // std::string - // RouterContact::bencode_signed_section() const - // { - // oxenc::bt_dict_producer btdp; - - // btdp.append("4", _addr.to_string()); - - // if (_addr6) - // btdp.append("6", _addr6->to_string()); - - // if (ACTIVE_NETID != llarp::LOKINET_DEFAULT_NETID) - // btdp.append("i", ACTIVE_NETID); - - // btdp.append("p", _router_id.bt_encode()); - // btdp.append("t", _timestamp.time_since_epoch().count()); - // btdp.append("v", _router_version.data()); - - // return std::move(btdp).str(); - // } - util::StatusObject RouterContact::extract_status() const { diff --git a/llarp/router_contact.hpp b/llarp/router_contact.hpp index 1d8f737b0..f863bbd67 100644 --- a/llarp/router_contact.hpp +++ b/llarp/router_contact.hpp @@ -6,7 +6,6 @@ #include #include #include -#include #include #include #include @@ -18,24 +17,6 @@ #include #include -// namespace oxenc -// { -// class bt_list_consumer; -// } // namespace oxenc - -/* - - figure out where we do bt_encoding of RC's - - maybe dump secret key from bt_encode - - it's weird to pass the secret key contextually - - suspicion we will need optional signature as an optional(?) string with serialized data - - resetting signature would be string::clear() instead - - ::sign() will cache serialized value - - do timestamp stuff - - bt_encode that takes bt_dict_producer requires reference to subdict - - presumably to be done in endpoints - - will be used for get_multi_rc endpoint -*/ - namespace llarp { static auto logcat = log::Cat("RC"); @@ -44,25 +25,28 @@ namespace llarp static inline constexpr size_t NETID_SIZE{8}; + /// On the wire we encode the data as a dict containing: + /// "" -- the RC format version, which must be == RouterContact::Version for us to attempt to + /// parse the reset of the fields. (Future versions might have backwards-compat support + /// for lower versions). + /// "4" -- 6 byte packed IPv4 address & port: 4 bytes of IPv4 address followed by 2 bytes of + /// port, both encoded in network (i.e. big-endian) order. + /// "6" -- optional 18 byte IPv6 address & port: 16 byte raw IPv6 address followed by 2 bytes + /// of port in network order. + /// "i" -- optional network ID string of up to 8 bytes; this is omitted for the default network + /// ID ("lokinet") but included for others (such as "gamma" for testnet). + /// "p" -- 32-byte router pubkey + /// "t" -- timestamp when this RC record was created (which also implicitly determines when it + /// goes stale and when it expires). + /// "v" -- lokinet version of the router; this is a three-byte packed value of + /// MAJOR, MINOR, PATCH, e.g. \x00\x0a\x03 for 0.10.3. + /// "~" -- signature of all of the previous serialized data, signed by "p" + /// RouterContact struct RouterContact { static constexpr uint8_t RC_VERSION = 0; - /// Constructs an empty RC - // RouterContact() = default; - - // RouterContact(std::string) - // { - // log::error(logcat, "ERROR: SUPPLANT THIS CONSTRUCTOR"); - // } - - // RouterContact(std::string buf); - - /// RC version that we support; we fail to load RCs that don't have the same version as that - /// means they are incompatible with us. - // static constexpr uint8_t VERSION = 0; - /// Unit tests disable this to allow private IP ranges in RCs, which normally get rejected. static inline bool BLOCK_BOGONS = true; @@ -85,6 +69,12 @@ namespace llarp /// changes i.e. just to push out a new confirmation of the details). static constexpr auto REPUBLISH = STALE / 2 - 5min; + ustring_view + view() const + { + return _payload; + } + /// Getters for private attributes const oxen::quic::Address& addr() const @@ -158,29 +148,6 @@ namespace llarp bool write(const fs::path& fname) const; - /// On the wire we encode the data as a dict containing: - /// "" -- the RC format version, which must be == RouterContact::Version for us to attempt to - /// parse the reset of the fields. (Future versions might have backwards-compat support - /// for lower versions). - /// "4" -- 6 byte packed IPv4 address & port: 4 bytes of IPv4 address followed by 2 bytes of - /// port, both encoded in network (i.e. big-endian) order. - /// "6" -- optional 18 byte IPv6 address & port: 16 byte raw IPv6 address followed by 2 bytes - /// of port in network order. - /// "i" -- optional network ID string of up to 8 bytes; this is omitted for the default network - /// ID ("lokinet") but included for others (such as "gamma" for testnet). - /// "p" -- 32-byte router pubkey - /// "t" -- timestamp when this RC record was created (which also implicitly determines when it - /// goes stale and when it expires). - /// "v" -- lokinet version of the router; this is a three-byte packed value of - /// MAJOR, MINOR, PATCH, e.g. \x00\x0a\x03 for 0.10.3. - /// "~" -- signature of all of the previous serialized data, signed by "p" - virtual ustring_view - bt_encode() const - { - log::warning(logcat, "ERROR: SUPPLANT THIS METHOD"); - return {}; - } - bool operator==(const RouterContact& other) const { @@ -251,16 +218,20 @@ namespace llarp /// parameters and outputs a bt-serialized string struct LocalRC final : public RouterContact { + static LocalRC + make(const SecretKey secret, oxen::quic::Address local); + private: ustring _signature; - const SecretKey _secret_key; + SecretKey _secret_key; - // TODO: fix these parameters void bt_sign(oxenc::bt_dict_producer& btdp); void - bt_encode(oxenc::bt_dict_producer& btdp) const; + bt_encode(oxenc::bt_dict_producer& btdp); + + LocalRC(const SecretKey secret, oxen::quic::Address local); public: LocalRC() = default; @@ -270,15 +241,6 @@ namespace llarp void resign(); - ustring_view - bt_encode() const override; - - ustring_view - view() const - { - return _payload; - } - void clear() override { @@ -347,7 +309,6 @@ namespace llarp struct RemoteRC final : public RouterContact { private: - // TODO: fix these parameters void bt_verify(oxenc::bt_dict_consumer& data, bool reject_expired = false) const; @@ -362,12 +323,6 @@ namespace llarp explicit RemoteRC(oxenc::bt_dict_consumer btdc); ~RemoteRC() = default; - ustring_view - bt_encode() const override - { - return _payload; - } - std::string_view view() const { diff --git a/llarp/router_contact_local.cpp b/llarp/router_contact_local.cpp index 71537692d..9b82551cc 100644 --- a/llarp/router_contact_local.cpp +++ b/llarp/router_contact_local.cpp @@ -11,6 +11,21 @@ namespace llarp { + LocalRC + LocalRC::make(const SecretKey secret, oxen::quic::Address local) + { + return *new LocalRC{secret, local}; + } + + LocalRC::LocalRC(const SecretKey secret, oxen::quic::Address local) + : _secret_key{std::move(secret)} + { + _router_id = llarp::seckey_to_pubkey(_secret_key); + _addr = std::move(local); + _addr6.emplace(&_addr.in6()); + resign(); + } + LocalRC::LocalRC(std::string payload, const SecretKey sk) : _secret_key{std::move(sk)} { _router_id = llarp::seckey_to_pubkey(_secret_key); @@ -66,16 +81,8 @@ namespace llarp _payload = btdp.view(); } - ustring_view - LocalRC::bt_encode() const - { - oxenc::bt_dict_producer btdp; - bt_encode(btdp); - return btdp.view(); - } - void - LocalRC::bt_encode(oxenc::bt_dict_producer& btdp) const + LocalRC::bt_encode(oxenc::bt_dict_producer& btdp) { btdp.append("", RC_VERSION); @@ -117,14 +124,7 @@ namespace llarp btdp.append( "v", std::string_view{reinterpret_cast(llarp::LOKINET_VERSION.data()), 3}); - btdp.append_signature("~", [this](ustring_view to_sign) { - std::array sig; - - if (!crypto::sign(sig.data(), _secret_key, to_sign)) - throw std::runtime_error{"Failed to sign LocalRC"}; - - return sig; - }); + bt_sign(btdp); } void diff --git a/llarp/service/identity.cpp b/llarp/service/identity.cpp index 05c6763f7..892faa90b 100644 --- a/llarp/service/identity.cpp +++ b/llarp/service/identity.cpp @@ -4,16 +4,32 @@ namespace llarp::service { - bool - Identity::BEncode(llarp_buffer_t* buf) const + std::string + Identity::bt_encode() const { - if (!bencode_start_dict(buf)) - return false; - if (!BEncodeWriteDictEntry("s", signkey, buf)) - return false; - if (!BEncodeWriteDictInt("v", version, buf)) - return false; - return bencode_end(buf); + oxenc::bt_dict_producer btdp; + + btdp.append("s", signkey.ToView()); + btdp.append("v", version); + + return std::move(btdp).str(); + } + + void + Identity::bt_decode(std::string buf) + { + try + { + oxenc::bt_dict_consumer btdc{buf}; + + signkey.from_string(btdc.require("s")); + version = btdc.require("v"); + } + catch (...) + { + log::warning(logcat, "Identity failed to parse bt-encoded contents!"); + throw; + } } bool @@ -74,7 +90,7 @@ namespace llarp::service // make sure we are empty Clear(); - std::array tmp; + std::string buf; // this can throw bool exists = fs::exists(fname); @@ -88,16 +104,15 @@ namespace llarp::service // check for file if (!exists) { - llarp_buffer_t buf{tmp}; // regen and encode RegenerateKeys(); - if (!BEncode(&buf)) - throw std::length_error("failed to encode new identity"); - const auto sz = buf.cur - buf.base; + + buf = bt_encode(); + // write try { - util::buffer_to_file(fname, tmp.data(), sz); + util::buffer_to_file(fname, buf.data(), buf.size()); } catch (const std::exception& e) { @@ -114,18 +129,15 @@ namespace llarp::service // read file try { - util::file_to_buffer(fname, tmp.data(), tmp.size()); + util::file_to_buffer(fname, buf.data(), buf.size()); } catch (const std::length_error&) { throw std::length_error{"service identity too big"}; } + // (don't catch io error exceptions) - { - llarp_buffer_t buf{tmp}; - if (!bencode_decode_dict(*this, &buf)) - throw std::length_error{"could not decode service identity"}; - } + bt_decode(buf); // ensure that the encryption key is set if (enckey.IsZero()) diff --git a/llarp/service/identity.hpp b/llarp/service/identity.hpp index 70b1919f3..3a8a34749 100644 --- a/llarp/service/identity.hpp +++ b/llarp/service/identity.hpp @@ -31,8 +31,10 @@ namespace llarp::service void RegenerateKeys(); - bool - BEncode(llarp_buffer_t* buf) const; + std::string + bt_encode() const; + + void bt_decode(std::string); /// @param needBackup determines whether existing keys will be cycled void diff --git a/llarp/service/protocol.hpp b/llarp/service/protocol.hpp index d3d656e2a..67e8ef91f 100644 --- a/llarp/service/protocol.hpp +++ b/llarp/service/protocol.hpp @@ -130,12 +130,6 @@ namespace llarp std::string bt_encode() const; - bool - BDecode(llarp_buffer_t* buf) - { - return bencode_decode_dict(*this, buf); - } - void clear() { diff --git a/llarp/util/bencode.hpp b/llarp/util/bencode.hpp index be616717e..16f08b9a8 100644 --- a/llarp/util/bencode.hpp +++ b/llarp/util/bencode.hpp @@ -17,16 +17,17 @@ namespace llarp { static auto ben_cat = log::Cat("stupid.bencode"); + template + T + decode_key(oxenc::bt_dict_consumer& btdp, const char* key) + { + return btdp.require(key); + } + template bool BEncodeReadList(List_t& result, llarp_buffer_t* buf); - inline bool - BEncodeWriteDictMsgType(llarp_buffer_t* buf, const char* k, const char* t) - { - return bencode_write_bytestring(buf, k, 1) && bencode_write_bytestring(buf, t, 1); - } - template bool BEncodeWriteDictString(const char* k, const Obj_t& str, llarp_buffer_t* buf) @@ -320,23 +321,6 @@ namespace llarp buffer); } - /// write an iterable container as a list - template - bool - BEncodeWriteSet(const Set_t& set, llarp_buffer_t* buffer) - { - if (not bencode_start_list(buffer)) - return false; - - for (const auto& item : set) - { - if (not item.bt_encode(buffer)) - return false; - } - - return bencode_end(buffer); - } - template bool BEncodeWriteDictList(const char* k, List_t& list, llarp_buffer_t* buf)