From fa4471f56682d96ede0f025c55409c28d9a5a642 Mon Sep 17 00:00:00 2001 From: dr7ana Date: Thu, 2 Nov 2023 05:30:38 -0700 Subject: [PATCH] {Remote,Local}RC's - RemoteRC supplants most of the functionality throughout the code of RouterContact - Next step will be to sort out CI issues, then see if we can get rid of either LocalRC (and therefore RouterContact entirely) --- llarp/bootstrap-fallbacks.cpp.in | 13 ++- llarp/bootstrap.cpp | 71 ++++++------ llarp/bootstrap.hpp | 15 ++- llarp/bootstrap_fallbacks.cpp | 18 +-- llarp/config/config.cpp | 8 +- llarp/config/config.hpp | 2 +- llarp/config/key_manager.cpp | 4 +- llarp/context.cpp | 4 +- llarp/crypto/crypto.hpp | 3 +- llarp/crypto/types.cpp | 16 +-- llarp/crypto/types.hpp | 3 - llarp/exit/session.cpp | 6 +- llarp/exit/session.hpp | 2 +- llarp/handlers/exit.cpp | 28 +---- llarp/handlers/tun.cpp | 4 +- llarp/link/connection.cpp | 2 +- llarp/link/connection.hpp | 4 +- llarp/link/link_manager.cpp | 16 +-- llarp/link/link_manager.hpp | 14 +-- llarp/messages/path.hpp | 4 +- llarp/messages/relay.cpp | 4 +- llarp/nodedb.cpp | 46 ++++---- llarp/nodedb.hpp | 18 +-- llarp/path/path.cpp | 26 +++-- llarp/path/path.hpp | 2 +- llarp/path/path_types.hpp | 2 +- llarp/path/pathbuilder.cpp | 53 +++++---- llarp/path/pathbuilder.hpp | 8 +- llarp/path/pathset.hpp | 4 +- llarp/profiling.cpp | 2 +- llarp/router/rc_gossiper.cpp | 4 +- llarp/router/rc_gossiper.hpp | 6 +- llarp/router/rc_lookup_handler.cpp | 40 ++----- llarp/router/rc_lookup_handler.hpp | 13 +-- llarp/router/route_poker.cpp | 2 +- llarp/router/router.cpp | 168 +++++++++------------------- llarp/router/router.hpp | 33 ++---- llarp/router_contact.cpp | 71 +++++------- llarp/router_contact.hpp | 143 ++++++++++++++--------- llarp/router_contact_local.cpp | 60 +++++++--- llarp/router_contact_remote.cpp | 77 +++++++++---- llarp/rpc/lokid_rpc_client.cpp | 2 +- llarp/rpc/rpc_server.cpp | 4 +- llarp/service/endpoint.cpp | 15 +-- llarp/service/endpoint.hpp | 4 +- llarp/service/identity.cpp | 2 +- llarp/service/outbound_context.cpp | 2 +- llarp/service/outbound_context.hpp | 2 +- llarp/service/router_lookup_job.cpp | 13 +-- llarp/service/router_lookup_job.hpp | 49 ++++---- llarp/util/bencode.hpp | 2 +- llarp/util/file.cpp | 2 +- llarp/util/file.hpp | 6 +- 53 files changed, 533 insertions(+), 589 deletions(-) diff --git a/llarp/bootstrap-fallbacks.cpp.in b/llarp/bootstrap-fallbacks.cpp.in index baeb4be3a..9cc96008f 100644 --- a/llarp/bootstrap-fallbacks.cpp.in +++ b/llarp/bootstrap-fallbacks.cpp.in @@ -9,17 +9,18 @@ namespace llarp load_bootstrap_fallbacks() { std::unordered_map fallbacks; - using init_list = std::initializer_list>; - // clang-format off - for (const auto& [network, bootstrap] : init_list{ + + for (const auto& [network, bootstrap] : std::initializer_list>{ @BOOTSTRAP_FALLBACKS@ }) - // clang-format on { - llarp_buffer_t buf{bootstrap.data(), bootstrap.size()}; + if (network != RouterContact::ACTIVE_NETID) + continue; + auto& bsl = fallbacks[network]; - bsl.BDecode(&buf); + bsl.bt_decode(bootstrap); } + return fallbacks; } } // namespace llarp diff --git a/llarp/bootstrap.cpp b/llarp/bootstrap.cpp index f5a795ea0..c51da6dee 100644 --- a/llarp/bootstrap.cpp +++ b/llarp/bootstrap.cpp @@ -6,66 +6,65 @@ namespace llarp { - void - BootstrapList::Clear() + bool + BootstrapList::bt_decode(std::string_view buf) { - clear(); + try + { + oxenc::bt_list_consumer btlc{buf}; + + while (not btlc.is_finished()) + emplace(btlc.consume_dict_consumer()); + } + catch (...) + { + log::warning(logcat, "Unable to decode bootstrap RemoteRC"); + return false; + } + + return true; } - bool - BootstrapList::BDecode(llarp_buffer_t* buf) + std::string_view + BootstrapList::bt_encode() const { - return bencode_read_list( - [&](llarp_buffer_t* b, bool more) -> bool { - if (more) - { - RouterContact rc{}; - if (not rc.BDecode(b)) - { - LogError("invalid rc in bootstrap list: ", llarp::buffer_printer{*b}); - return false; - } - emplace(std::move(rc)); - } - return true; - }, - buf); - } + oxenc::bt_list_producer btlp{}; - bool - BootstrapList::BEncode(llarp_buffer_t* buf) const - { - return BEncodeWriteList(begin(), end(), buf); + for (const auto& it : *this) + btlp.append(it.bt_encode()); + + return btlp.view(); } void - BootstrapList::AddFromFile(fs::path fpath) + BootstrapList::read_from_file(const fs::path& fpath) { bool isListFile = false; + + if (std::ifstream inf(fpath.c_str(), std::ios::binary); inf.is_open()) { - std::ifstream inf(fpath.c_str(), std::ios::binary); - if (inf.is_open()) - { - const char ch = inf.get(); - isListFile = ch == 'l'; - } + const char ch = inf.get(); + isListFile = ch == 'l'; } + if (isListFile) { - if (not BDecodeReadFile(fpath, *this)) + auto content = util::file_to_string(fpath); + + if (not bt_decode(content)) { throw std::runtime_error{fmt::format("failed to read bootstrap list file '{}'", fpath)}; } } else { - RouterContact rc; + RemoteRC rc; if (not rc.read(fpath)) { throw std::runtime_error{ - fmt::format("failed to decode bootstrap RC, file='{}', rc={}", fpath, rc)}; + fmt::format("failed to decode bootstrap RC, file='{}', rc={}", fpath, rc.to_string())}; } - this->insert(rc); + insert(rc); } } } // namespace llarp diff --git a/llarp/bootstrap.hpp b/llarp/bootstrap.hpp index e72e12fcc..11e8286d3 100644 --- a/llarp/bootstrap.hpp +++ b/llarp/bootstrap.hpp @@ -9,19 +9,22 @@ namespace llarp { - struct BootstrapList final : public std::set + struct BootstrapList final : public std::set { bool - BDecode(llarp_buffer_t* buf); + bt_decode(std::string_view buf); - bool - BEncode(llarp_buffer_t* buf) const; + std::string_view + bt_encode() const; void - AddFromFile(fs::path fpath); + read_from_file(const fs::path& fpath); void - Clear(); + clear_list() + { + clear(); + } }; std::unordered_map diff --git a/llarp/bootstrap_fallbacks.cpp b/llarp/bootstrap_fallbacks.cpp index 458444f63..79f6f646f 100644 --- a/llarp/bootstrap_fallbacks.cpp +++ b/llarp/bootstrap_fallbacks.cpp @@ -10,17 +10,19 @@ namespace llarp load_bootstrap_fallbacks() { std::unordered_map fallbacks; - using init_list = std::initializer_list>; - // clang-format off - for (const auto& [network, bootstrap] : init_list{ - // - }) - // clang-format on + + for (const auto& [network, bootstrap] : + std::initializer_list>{ + // + }) { - llarp_buffer_t buf{bootstrap.data(), bootstrap.size()}; + if (network != RouterContact::ACTIVE_NETID) + continue; + auto& bsl = fallbacks[network]; - bsl.BDecode(&buf); + bsl.bt_decode(bootstrap); } + return fallbacks; } } // namespace llarp diff --git a/llarp/config/config.cpp b/llarp/config/config.cpp index 64d473564..c4d3035da 100644 --- a/llarp/config/config.cpp +++ b/llarp/config/config.cpp @@ -64,9 +64,9 @@ namespace llarp + "' for mainnet, 'gamma' for testnet.", }, [this](std::string arg) { - if (arg.size() > NetID::size()) + if (arg.size() > NETID_SIZE) throw std::invalid_argument{ - fmt::format("netid is too long, max length is {}", NetID::size())}; + fmt::format("netid is too long, max length is {}", NETID_SIZE)}; m_netId = std::move(arg); }); @@ -1322,7 +1322,7 @@ namespace llarp } bool - PeerSelectionConfig::Acceptable(const std::set& rcs) const + PeerSelectionConfig::Acceptable(const std::set& rcs) const { if (m_UniqueHopsNetmaskSize == 0) return true; @@ -1530,7 +1530,7 @@ namespace llarp // open a filestream try { - util::dump_file(confFile, confStr); + util::buffer_to_file(confFile, confStr); } catch (const std::exception& e) { diff --git a/llarp/config/config.hpp b/llarp/config/config.hpp index f91c131c2..9ee7f2e6b 100644 --- a/llarp/config/config.hpp +++ b/llarp/config/config.hpp @@ -100,7 +100,7 @@ namespace llarp /// return true if this set of router contacts is acceptable against this config bool - Acceptable(const std::set& hops) const; + Acceptable(const std::set& hops) const; }; struct NetworkConfig diff --git a/llarp/config/key_manager.cpp b/llarp/config/key_manager.cpp index 3df244dea..f5b05c0f8 100644 --- a/llarp/config/key_manager.cpp +++ b/llarp/config/key_manager.cpp @@ -51,7 +51,7 @@ namespace llarp m_encKeyPath = deriveFile(our_enc_key_filename, config.router.m_encryptionKeyFile); m_transportKeyPath = deriveFile(our_transport_key_filename, config.router.m_transportKeyFile); - RouterContact rc; + RemoteRC rc; bool exists = rc.read(m_rcPath); if (not exists and not genIfAbsent) { @@ -61,7 +61,7 @@ namespace llarp // we need to back up keys if our self.signed doesn't appear to have a // valid signature - m_needBackup = (isSNode and not rc.verify_signature()); + m_needBackup = (isSNode and not rc.verify()); // if our RC file can't be verified, assume it is out of date (e.g. uses // older encryption) and needs to be regenerated. before doing so, backup diff --git a/llarp/context.cpp b/llarp/context.cpp index ab8ae70f9..cffea417f 100644 --- a/llarp/context.cpp +++ b/llarp/context.cpp @@ -19,8 +19,6 @@ namespace llarp { - static auto logcat = llarp::log::Cat("llarp-context"); - bool Context::CallSafe(std::function f) { @@ -163,7 +161,7 @@ namespace llarp #ifndef _WIN32 if (sig == SIGUSR1) { - if (router and not router->IsServiceNode()) + if (router and not router->is_service_node()) { LogInfo("SIGUSR1: resetting network state"); router->Thaw(); diff --git a/llarp/crypto/crypto.hpp b/llarp/crypto/crypto.hpp index 1b5c9a239..dba97aeed 100644 --- a/llarp/crypto/crypto.hpp +++ b/llarp/crypto/crypto.hpp @@ -67,8 +67,7 @@ namespace llarp verify(const PubKey&, ustring_view, ustring_view); bool verify(const PubKey&, uint8_t*, size_t, const Signature&); - bool - verify(ustring_view, ustring_view, ustring_view); + bool verify(ustring_view, ustring_view, ustring_view); bool verify(uint8_t*, uint8_t*, size_t, uint8_t*); diff --git a/llarp/crypto/types.cpp b/llarp/crypto/types.cpp index c7a141bbd..092698e81 100644 --- a/llarp/crypto/types.cpp +++ b/llarp/crypto/types.cpp @@ -57,12 +57,6 @@ namespace llarp return lhs.as_array() == rhs.as_array(); } - bool - operator==(const RouterID& lhs, const PubKey& rhs) - { - return lhs.as_array() == rhs.as_array(); - } - bool SecretKey::LoadFromFile(const fs::path& fname) { @@ -124,17 +118,13 @@ namespace llarp bool SecretKey::SaveToFile(const fs::path& fname) const { - std::string tmp(128, 0); - llarp_buffer_t buf(tmp); - if (!bt_encode(&buf)) - return false; + auto bte = bt_encode(); - tmp.resize(buf.cur - buf.base); try { - util::dump_file(fname, tmp); + util::buffer_to_file(fname, bte); } - catch (const std::exception&) + catch (const std::exception& e) { return false; } diff --git a/llarp/crypto/types.hpp b/llarp/crypto/types.hpp index a91192770..6e723fae5 100644 --- a/llarp/crypto/types.hpp +++ b/llarp/crypto/types.hpp @@ -50,9 +50,6 @@ namespace llarp bool operator==(const PubKey& lhs, const RouterID& rhs); - bool - operator==(const RouterID& lhs, const PubKey& rhs); - struct PrivateKey; /// Stores a sodium "secret key" value, which is actually the seed diff --git a/llarp/exit/session.cpp b/llarp/exit/session.cpp index c6bdc009b..ecdafff65 100644 --- a/llarp/exit/session.cpp +++ b/llarp/exit/session.cpp @@ -69,13 +69,13 @@ namespace llarp::exit snode_blacklist.insert(std::move(snode)); } - std::optional> + std::optional> BaseSession::GetHopsForBuild() { if (numHops == 1) { if (auto maybe = router->node_db()->get_rc(exit_router)) - return std::vector{*maybe}; + return std::vector{*maybe}; return std::nullopt; } @@ -292,7 +292,7 @@ namespace llarp::exit throw; } - RouterContact result{std::move(payload)}; + RemoteRC result{std::move(payload)}; r->node_db()->put_rc_if_newer(result); r->connect_to(result); } diff --git a/llarp/exit/session.hpp b/llarp/exit/session.hpp index ac5da8f84..6410bc2be 100644 --- a/llarp/exit/session.hpp +++ b/llarp/exit/session.hpp @@ -72,7 +72,7 @@ namespace llarp bool CheckPathDead(path::Path_ptr p, llarp_time_t dlt); - std::optional> + std::optional> GetHopsForBuild() override; bool diff --git a/llarp/handlers/exit.cpp b/llarp/handlers/exit.cpp index 008e12b26..b9a46b1a8 100644 --- a/llarp/handlers/exit.cpp +++ b/llarp/handlers/exit.cpp @@ -578,33 +578,7 @@ namespace llarp::handlers void ExitEndpoint::SRVRecordsChanged() { - router->modify_rc( - [srvRecords = SRVRecords()](RouterContact rc) -> std::optional { - // TODO: update this RouterContact handling - - // check if there are any new srv records - // bool shouldUpdate = false; - - // for (const auto& rcSrv : rc.srvRecords) - // { - // if (srvRecords.count(rcSrv) == 0) - // shouldUpdate = true; - // } - - // // no new records so don't modify - // if (not shouldUpdate) - // return std::nullopt; - - // // we got new entries so we clear the whole vector on the rc and recreate it - // rc.srvRecords.clear(); - - // for (auto& record : srvRecords) - // rc.srvRecords.emplace_back(record); - - // // set the verssion to 1 because we have srv records - // rc.version = 1; - return rc; - }); + // TODO: Investigate the usage or the term exit RE: service nodes acting as exits } std::optional diff --git a/llarp/handlers/tun.cpp b/llarp/handlers/tun.cpp index 468e138a7..e530da4e0 100644 --- a/llarp/handlers/tun.cpp +++ b/llarp/handlers/tun.cpp @@ -623,7 +623,7 @@ namespace llarp::handlers throw; } - r->node_db()->put_rc_if_newer(RouterContact{payload}); + r->node_db()->put_rc_if_newer(RemoteRC{payload}); msg.AddTXTReply(payload); } else @@ -658,7 +658,7 @@ namespace llarp::handlers } else if (subdomain == "netid") { - msg.AddTXTReply(fmt::format("netid={};", router()->rc().netID)); + msg.AddTXTReply(fmt::format("netid={};", RouterContact::ACTIVE_NETID)); } else { diff --git a/llarp/link/connection.cpp b/llarp/link/connection.cpp index 01aaa4fc8..dace3d299 100644 --- a/llarp/link/connection.cpp +++ b/llarp/link/connection.cpp @@ -5,7 +5,7 @@ namespace llarp::link Connection::Connection( std::shared_ptr& c, std::shared_ptr& s, - const RouterContact& rc) + const RemoteRC& rc) : conn{c}, control_stream{s}, remote_rc{std::move(rc)} {} diff --git a/llarp/link/connection.hpp b/llarp/link/connection.hpp index fe8b0961a..46aef9328 100644 --- a/llarp/link/connection.hpp +++ b/llarp/link/connection.hpp @@ -11,7 +11,7 @@ namespace llarp::link { std::shared_ptr conn; std::shared_ptr control_stream; - RouterContact remote_rc; + RemoteRC remote_rc; // one side of a connection will be responsible for some things, e.g. heartbeat bool inbound{false}; @@ -20,7 +20,7 @@ namespace llarp::link Connection( std::shared_ptr& c, std::shared_ptr& s, - const RouterContact& rc); + const RemoteRC& rc); }; } // namespace llarp::link diff --git a/llarp/link/link_manager.cpp b/llarp/link/link_manager.cpp index e6515b7f4..2e80cb603 100644 --- a/llarp/link/link_manager.cpp +++ b/llarp/link/link_manager.cpp @@ -18,7 +18,7 @@ namespace llarp namespace link { std::shared_ptr - Endpoint::get_conn(const RouterContact& rc) const + Endpoint::get_conn(const RemoteRC& rc) const { if (auto itr = conns.find(rc.router_id()); itr != conns.end()) return itr->second; @@ -83,7 +83,7 @@ namespace llarp } bool - Endpoint::get_random_connection(RouterContact& router) const + Endpoint::get_random_connection(RemoteRC& router) const { if (const auto size = conns.size(); size) { @@ -301,7 +301,7 @@ namespace llarp // This function assumes the RC has already had its signature verified and connection is allowed. void - LinkManager::connect_to(const RouterContact& rc) + LinkManager::connect_to(const RemoteRC& rc) { if (auto conn = ep.get_conn(rc.router_id()); conn) { @@ -451,7 +451,7 @@ namespace llarp } bool - LinkManager::get_random_connected(RouterContact& router) const + LinkManager::get_random_connected(RemoteRC& router) const { return ep.get_random_connection(router); } @@ -487,7 +487,9 @@ namespace llarp do { - auto filter = [exclude](const auto& rc) -> bool { return exclude.count(rc.pubkey) == 0; }; + auto filter = [exclude](const auto& rc) -> bool { + return exclude.count(rc.router_id()) == 0; + }; if (auto maybe_other = node_db->GetRandom(filter)) { @@ -654,7 +656,7 @@ namespace llarp } else { - m.respond(serialize_response({{"RC", closest_rc.bt_encode()}})); + m.respond(serialize_response({{"RC", closest_rc.view()}})); } } else if (not is_iterative) @@ -720,7 +722,7 @@ namespace llarp if (m) { - _router.node_db()->put_rc_if_newer(RouterContact{payload}); + _router.node_db()->put_rc_if_newer(RemoteRC{payload}); } else { diff --git a/llarp/link/link_manager.hpp b/llarp/link/link_manager.hpp index 66cde4bb7..d99e2face 100644 --- a/llarp/link/link_manager.hpp +++ b/llarp/link/link_manager.hpp @@ -52,7 +52,8 @@ namespace llarp // TODO: see which of these is actually useful and delete the other std::shared_ptr - get_conn(const RouterContact&) const; + get_conn(const RemoteRC&) const; + std::shared_ptr get_conn(const RouterID&) const; @@ -66,12 +67,11 @@ namespace llarp num_connected(bool clients_only) const; bool - get_random_connection(RouterContact& router) const; + get_random_connection(RemoteRC& router) const; template bool - establish_connection( - const oxen::quic::Address& remote, const RouterContact& rc, Opt&&... opts); + establish_connection(const oxen::quic::Address& remote, const RemoteRC& rc, Opt&&... opts); void for_each_connection(std::function func); @@ -239,7 +239,7 @@ namespace llarp connect_to(const RouterID& router); void - connect_to(const RouterContact& rc); + connect_to(const RemoteRC& rc); void close_connection(RouterID rid); @@ -257,7 +257,7 @@ namespace llarp get_num_connected_clients() const; bool - get_random_connected(RouterContact& router) const; + get_random_connected(RemoteRC& router) const; void check_persisting_conns(llarp_time_t now); @@ -364,7 +364,7 @@ namespace llarp template bool Endpoint::establish_connection( - const oxen::quic::Address& remote, const RouterContact& rc, Opt&&... opts) + const oxen::quic::Address& remote, const RemoteRC& rc, Opt&&... opts) { try { diff --git a/llarp/messages/path.hpp b/llarp/messages/path.hpp index 17bd63ba3..ca10a0f84 100644 --- a/llarp/messages/path.hpp +++ b/llarp/messages/path.hpp @@ -22,7 +22,7 @@ namespace llarp hop.nonce.Randomize(); // do key exchange - if (!crypto::dh_client(hop.shared, hop.rc._pubkey, hop.commkey, hop.nonce)) + if (!crypto::dh_client(hop.shared, hop.rc.router_id(), hop.commkey, hop.nonce)) { auto err = fmt::format("Failed to generate shared key for path build!"); log::warning(path_cat, err); @@ -60,7 +60,7 @@ namespace llarp outer_nonce.Randomize(); // derive (outer) shared key - if (!crypto::dh_client(shared, hop.rc._pubkey, framekey, outer_nonce)) + if (!crypto::dh_client(shared, hop.rc.router_id(), framekey, outer_nonce)) { log::warning(path_cat, "DH client failed during hop info encryption!"); throw std::runtime_error{"DH failed during hop info encryption"}; diff --git a/llarp/messages/relay.cpp b/llarp/messages/relay.cpp index 7f816d61b..8bfab3a0b 100644 --- a/llarp/messages/relay.cpp +++ b/llarp/messages/relay.cpp @@ -54,7 +54,7 @@ namespace llarp bool RelayUpstreamMessage::handle_message(Router* r) const { - auto path = r->path_context().GetByDownstream(conn->remote_rc._pubkey, pathid); + auto path = r->path_context().GetByDownstream(conn->remote_rc.router_id(), pathid); if (path) { return path->HandleUpstream(llarp_buffer_t(enc), nonce, r); @@ -110,7 +110,7 @@ namespace llarp bool RelayDownstreamMessage::handle_message(Router* r) const { - auto path = r->path_context().GetByUpstream(conn->remote_rc._pubkey, pathid); + auto path = r->path_context().GetByUpstream(conn->remote_rc.router_id(), pathid); if (path) { return path->HandleDownstream(llarp_buffer_t(enc), nonce, r); diff --git a/llarp/nodedb.cpp b/llarp/nodedb.cpp index d3b7ee02c..a5955003d 100644 --- a/llarp/nodedb.cpp +++ b/llarp/nodedb.cpp @@ -14,7 +14,7 @@ static const std::string RC_FILE_EXT = ".signed"; namespace llarp { - NodeDB::Entry::Entry(RouterContact value) : rc(std::move(value)), insertedAt(llarp::time_now_ms()) + NodeDB::Entry::Entry(RemoteRC value) : rc(std::move(value)), insertedAt(llarp::time_now_ms()) {} static void @@ -70,9 +70,11 @@ namespace llarp router.loop()->call([this]() { m_NextFlushAt += FlushInterval; // make copy of all rcs - std::vector copy; + std::vector copy; + for (const auto& item : entries) copy.push_back(item.second.rc); + // flush them to disk in one big job // TODO: split this up? idk maybe some day... disk([this, data = std::move(copy)]() { @@ -119,7 +121,7 @@ namespace llarp if (not(fs::is_regular_file(f) and f.extension() == RC_FILE_EXT)) return true; - RouterContact rc{}; + RemoteRC rc{}; if (not rc.read(f)) { @@ -137,7 +139,7 @@ namespace llarp // validate signature and purge entries with invalid signatures // load ones with valid signatures - if (rc.verify_signature()) // TODO: fix this after RouterContact -> RemoteRC + if (rc.verify()) entries.emplace(rc.router_id(), rc); else purge.emplace(f); @@ -175,10 +177,10 @@ namespace llarp [this, pk]() -> bool { return entries.find(pk) != entries.end(); }); } - std::optional + std::optional NodeDB::get_rc(RouterID pk) const { - return router.loop()->call_get([this, pk]() -> std::optional { + return router.loop()->call_get([this, pk]() -> std::optional { const auto itr = entries.find(pk); if (itr == entries.end()) @@ -219,11 +221,12 @@ namespace llarp } void - NodeDB::put_rc(RouterContact rc) + NodeDB::put_rc(RemoteRC rc) { router.loop()->call([this, rc]() { - entries.erase(rc.router_id()); - entries.emplace(rc.router_id(), rc); + const auto& rid = rc.router_id(); + entries.erase(rid); + entries.emplace(rid, rc); }); } @@ -234,7 +237,7 @@ namespace llarp } void - NodeDB::put_rc_if_newer(RouterContact rc) + NodeDB::put_rc_if_newer(RemoteRC rc) { router.loop()->call([this, rc]() { auto itr = entries.find(rc.router_id()); @@ -267,32 +270,31 @@ namespace llarp }); } - llarp::RouterContact + RemoteRC NodeDB::find_closest_to(llarp::dht::Key_t location) const { - return router.loop()->call_get([this, location]() { - llarp::RouterContact rc; + return router.loop()->call_get([this, location]() -> RemoteRC { + RemoteRC rc; const llarp::dht::XorMetric compare(location); + VisitAll([&rc, compare](const auto& otherRC) { - if (rc.router_id().IsZero()) + const auto& rid = rc.router_id(); + + if (rid.IsZero() || compare(dht::Key_t{otherRC.router_id()}, dht::Key_t{rid})) { rc = otherRC; return; } - if (compare( - llarp::dht::Key_t{otherRC.pubkey.as_array()}, - llarp::dht::Key_t{rc.router_id().as_array()})) - rc = otherRC; }); return rc; }); } - std::vector + std::vector NodeDB::find_many_closest_to(llarp::dht::Key_t location, uint32_t numRouters) const { - return router.loop()->call_get([this, location, numRouters]() { - std::vector all; + return router.loop()->call_get([this, location, numRouters]() -> std::vector { + std::vector all; all.reserve(entries.size()); for (auto& entry : entries) @@ -306,7 +308,7 @@ namespace llarp return compare(*a, *b); }); - std::vector closest; + std::vector closest; closest.reserve(numRouters); for (auto it = all.begin(); it != it_mid; ++it) closest.push_back(**it); diff --git a/llarp/nodedb.hpp b/llarp/nodedb.hpp index 17fe4ffbd..7552fc6fd 100644 --- a/llarp/nodedb.hpp +++ b/llarp/nodedb.hpp @@ -26,9 +26,9 @@ namespace llarp { struct Entry { - const RouterContact rc; + const RemoteRC rc; llarp_time_t insertedAt; - explicit Entry(RouterContact rc); + explicit Entry(RemoteRC rc); }; using NodeMap = std::unordered_map; @@ -73,11 +73,11 @@ namespace llarp Tick(llarp_time_t now); /// find the absolute closets router to a dht location - RouterContact + RemoteRC find_closest_to(dht::Key_t location) const; /// find many routers closest to dht key - std::vector + std::vector find_many_closest_to(dht::Key_t location, uint32_t numRouters) const; /// return true if we have an rc by its ident pubkey @@ -85,14 +85,14 @@ namespace llarp has_router(RouterID pk) const; /// maybe get an rc by its ident pubkey - std::optional + std::optional get_rc(RouterID pk) const; template - std::optional + std::optional GetRandom(Filter visit) const { - return router.loop()->call_get([visit]() -> std::optional { + return router.loop()->call_get([visit]() -> std::optional { std::vector entries; for (const auto& entry : entries) entries.push_back(entry); @@ -167,10 +167,10 @@ namespace llarp /// put this rc into the cache if it is not there or newer than the one there already void - put_rc_if_newer(RouterContact rc); + put_rc_if_newer(RemoteRC rc); /// unconditional put of rc into cache void - put_rc(RouterContact rc); + put_rc(RemoteRC rc); }; } // namespace llarp diff --git a/llarp/path/path.cpp b/llarp/path/path.cpp index e5760c1a2..3fb7ad8fa 100644 --- a/llarp/path/path.cpp +++ b/llarp/path/path.cpp @@ -10,7 +10,7 @@ namespace llarp::path { Path::Path( Router* rtr, - const std::vector& h, + const std::vector& h, std::weak_ptr pathset, PathRole startingRoles, std::string shortName) @@ -40,7 +40,7 @@ namespace llarp::path hops[idx].txID = hops[idx + 1].rxID; } // initialize parts of the introduction - intro.router = hops[hsz - 1].rc._router_id; + intro.router = hops[hsz - 1].rc.router_id(); intro.path_id = hops[hsz - 1].txID; if (auto parent = m_PathSet.lock()) EnterState(ePathBuilding, parent->Now()); @@ -152,13 +152,13 @@ namespace llarp::path RouterID Path::Endpoint() const { - return hops[hops.size() - 1].rc._router_id; + return hops[hops.size() - 1].rc.router_id(); } PubKey Path::EndpointPubKey() const { - return hops[hops.size() - 1].rc._router_id; + return hops[hops.size() - 1].rc.router_id(); } PathID_t @@ -184,13 +184,13 @@ namespace llarp::path bool Path::is_endpoint(const RouterID& r, const PathID_t& id) const { - return hops[hops.size() - 1].rc._router_id == r && hops[hops.size() - 1].txID == id; + return hops[hops.size() - 1].rc.router_id() == r && hops[hops.size() - 1].txID == id; } RouterID Path::upstream() const { - return hops[0].rc._router_id; + return hops[0].rc.router_id(); } const std::string& @@ -208,7 +208,7 @@ namespace llarp::path { if (!hops.empty()) hops_str += " -> "; - hops_str += RouterID(hop.rc._router_id).ToString(); + hops_str += hop.rc.router_id().ToView(); } return hops_str; } @@ -262,9 +262,9 @@ namespace llarp::path PathHopConfig::ExtractStatus() const { util::StatusObject obj{ - {"ip", rc._addr.to_string()}, + {"ip", rc.addr().to_string()}, {"lifetime", to_json(lifetime)}, - {"router", rc._router_id.ToHex()}, + {"router", rc.router_id().ToHex()}, {"txid", txID.ToHex()}, {"rxid", rxID.ToHex()}}; return obj; @@ -330,11 +330,13 @@ namespace llarp::path { if (auto parent = m_PathSet.lock()) { - std::vector newHops; + std::vector new_hops; + for (const auto& hop : hops) - newHops.emplace_back(hop.rc); + new_hops.emplace_back(hop.rc); + LogInfo(name(), " rebuilding on ", ShortName()); - parent->Build(newHops); + parent->Build(new_hops); } } diff --git a/llarp/path/path.hpp b/llarp/path/path.hpp index 4af30f54f..e427997ef 100644 --- a/llarp/path/path.hpp +++ b/llarp/path/path.hpp @@ -69,7 +69,7 @@ namespace llarp Path( Router* rtr, - const std::vector& routers, + const std::vector& routers, std::weak_ptr parent, PathRole startingRoles, std::string shortName); diff --git a/llarp/path/path_types.hpp b/llarp/path/path_types.hpp index 374660e55..47401033e 100644 --- a/llarp/path/path_types.hpp +++ b/llarp/path/path_types.hpp @@ -26,7 +26,7 @@ namespace llarp /// path id PathID_t txID, rxID; // router contact of router - RouterContact rc; + RemoteRC rc; // temp public encryption key SecretKey commkey; /// shared secret at this hop diff --git a/llarp/path/pathbuilder.cpp b/llarp/path/pathbuilder.cpp index ec4d3fa3d..2f831bf06 100644 --- a/llarp/path/pathbuilder.cpp +++ b/llarp/path/pathbuilder.cpp @@ -83,7 +83,7 @@ namespace llarp hop.nonce.Randomize(); // do key exchange - if (!crypto::dh_client(hop.shared, hop.rc._pubkey, hop.commkey, hop.nonce)) + if (!crypto::dh_client(hop.shared, hop.rc.router_id(), hop.commkey, hop.nonce)) { auto err = fmt::format("{} failed to generate shared key for path build!", Name()); log::error(path_cat, err); @@ -121,7 +121,7 @@ namespace llarp outer_nonce.Randomize(); // derive (outer) shared key - if (!crypto::dh_client(shared, hop.rc._pubkey, framekey, outer_nonce)) + if (!crypto::dh_client(shared, hop.rc.router_id(), framekey, outer_nonce)) { log::error(path_cat, "DH client failed during hop info encryption!"); throw std::runtime_error{"DH failed during hop info encryption"}; @@ -211,23 +211,25 @@ namespace llarp return obj; } - std::optional + std::optional Builder::SelectFirstHop(const std::set& exclude) const { - std::optional found = std::nullopt; + std::optional found = std::nullopt; router->for_each_connection([&](link::Connection& conn) { const auto& rc = conn.remote_rc; + const auto& rid = rc.router_id(); + #ifndef TESTNET - if (router->IsBootstrapNode(rc._pubkey)) + if (router->IsBootstrapNode(rid)) return; #endif - if (exclude.count(rc._pubkey)) + if (exclude.count(rid)) return; - if (BuildCooldownHit(rc._pubkey)) + if (BuildCooldownHit(rid)) return; - if (router->router_profiling().IsBadForPath(rc._pubkey)) + if (router->router_profiling().IsBadForPath(rid)) return; found = rc; @@ -235,15 +237,15 @@ namespace llarp return found; } - std::optional> + std::optional> Builder::GetHopsForBuild() { auto filter = [r = router](const auto& rc) -> bool { - return not r->router_profiling().IsBadForPath(rc.pubkey, 1); + return not r->router_profiling().IsBadForPath(rc.router_id(), 1); }; if (const auto maybe = router->node_db()->GetRandom(filter)) { - return GetHopsAlignedToForBuild(maybe->_pubkey); + return GetHopsAlignedToForBuild(maybe->router_id()); } return std::nullopt; } @@ -308,12 +310,12 @@ namespace llarp return buildIntervalLimit > MIN_PATH_BUILD_INTERVAL * 4; } - std::optional> + std::optional> Builder::GetHopsAlignedToForBuild(RouterID endpoint, const std::set& exclude) { const auto pathConfig = router->config()->paths; - std::vector hops; + std::vector hops; { const auto maybe = SelectFirstHop(exclude); if (not maybe.has_value()) @@ -324,7 +326,7 @@ namespace llarp hops.emplace_back(*maybe); }; - RouterContact endpointRC; + RemoteRC endpointRC; if (const auto maybe = router->node_db()->get_rc(endpoint)) { endpointRC = *maybe; @@ -341,19 +343,21 @@ namespace llarp else { auto filter = - [&hops, r = router, endpointRC, pathConfig, exclude](const auto& rc) -> bool { - if (exclude.count(rc.pubkey)) + [&hops, r = router, endpointRC, pathConfig, exclude](const RemoteRC& rc) -> bool { + const auto& rid = rc.router_id(); + + if (exclude.count(rid)) return false; - std::set hopsSet; + std::set hopsSet; hopsSet.insert(endpointRC); hopsSet.insert(hops.begin(), hops.end()); - if (r->router_profiling().IsBadForPath(rc.pubkey, 1)) + if (r->router_profiling().IsBadForPath(rid, 1)) return false; for (const auto& hop : hopsSet) { - if (hop._pubkey == rc.pubkey) + if (hop.router_id() == rid) return false; } @@ -362,7 +366,7 @@ namespace llarp if (not pathConfig.Acceptable(hopsSet)) return false; #endif - return rc.pubkey != endpointRC._pubkey; + return rc.router_id() != endpointRC.router_id(); }; if (const auto maybe = router->node_db()->GetRandom(filter)) @@ -393,7 +397,7 @@ namespace llarp } void - Builder::Build(std::vector hops, PathRole roles) + Builder::Build(std::vector hops, PathRole roles) { if (IsStopped()) { @@ -402,7 +406,7 @@ namespace llarp } lastBuild = llarp::time_now_ms(); - const RouterID edge{hops[0]._pubkey}; + const auto& edge = hops[0].router_id(); if (not router->pathbuild_limiter().Attempt(edge)) { @@ -429,7 +433,8 @@ namespace llarp { bool lastHop = (i == (n_hops - 1)); - const auto& nextHop = lastHop ? path_hops[i].rc._pubkey : path_hops[i + 1].rc._pubkey; + const auto& nextHop = + lastHop ? path_hops[i].rc.router_id() : path_hops[i + 1].rc.router_id(); PathBuildMessage::setup_hop_keys(path_hops[i], nextHop); auto frame_str = PathBuildMessage::serialize(path_hops[i]); @@ -533,7 +538,7 @@ namespace llarp DoPathBuildBackoff(); for (const auto& hop : p->hops) { - const RouterID target{hop.rc._pubkey}; + const auto& target = hop.rc.router_id(); // look up router and see if it's still on the network log::info(path_cat, "Looking up RouterID {} due to path build timeout", target); diff --git a/llarp/path/pathbuilder.hpp b/llarp/path/pathbuilder.hpp index 480f7df6d..35fbdb1dc 100644 --- a/llarp/path/pathbuilder.hpp +++ b/llarp/path/pathbuilder.hpp @@ -115,17 +115,17 @@ namespace llarp::path bool BuildOneAlignedTo(const RouterID endpoint) override; - std::optional> + std::optional> GetHopsAlignedToForBuild(RouterID endpoint, const std::set& exclude = {}); void - Build(std::vector hops, PathRole roles = ePathRoleAny) override; + Build(std::vector hops, PathRole roles = ePathRoleAny) override; /// pick a first hop - std::optional + std::optional SelectFirstHop(const std::set& exclude = {}) const; - std::optional> + std::optional> GetHopsForBuild() override; void diff --git a/llarp/path/pathset.hpp b/llarp/path/pathset.hpp index 914c97da1..c228823ac 100644 --- a/llarp/path/pathset.hpp +++ b/llarp/path/pathset.hpp @@ -122,7 +122,7 @@ namespace llarp /// manual build on these hops virtual void - Build(std::vector hops, PathRole roles = ePathRoleAny) = 0; + Build(std::vector hops, PathRole roles = ePathRoleAny) = 0; /// tick owned paths virtual void @@ -252,7 +252,7 @@ namespace llarp virtual void send_packet_to_remote(std::string buf) = 0; - virtual std::optional> + virtual std::optional> GetHopsForBuild() = 0; void diff --git a/llarp/profiling.cpp b/llarp/profiling.cpp index a8da6cec1..ee0428c1e 100644 --- a/llarp/profiling.cpp +++ b/llarp/profiling.cpp @@ -260,7 +260,7 @@ namespace llarp try { - util::dump_file(fpath, buf); + util::buffer_to_file(fpath, buf); } catch (const std::exception& e) { diff --git a/llarp/router/rc_gossiper.cpp b/llarp/router/rc_gossiper.cpp index a380a54b1..a5da35bd3 100644 --- a/llarp/router/rc_gossiper.cpp +++ b/llarp/router/rc_gossiper.cpp @@ -28,7 +28,7 @@ namespace llarp } bool - RCGossiper::IsOurRC(const RouterContact& rc) const + RCGossiper::IsOurRC(const LocalRC& rc) const { return rc.router_id() == rid; } @@ -64,7 +64,7 @@ namespace llarp } bool - RCGossiper::GossipRC(const RouterContact& rc) + RCGossiper::GossipRC(const LocalRC& rc) { // only distribute public routers if (not rc.is_public_router()) diff --git a/llarp/router/rc_gossiper.hpp b/llarp/router/rc_gossiper.hpp index 3678f0632..a0c72fc80 100644 --- a/llarp/router/rc_gossiper.hpp +++ b/llarp/router/rc_gossiper.hpp @@ -12,7 +12,7 @@ namespace llarp /// The maximum number of peers we will flood a gossiped RC to when propagating an RC constexpr size_t MaxGossipPeers = 20; struct LinkManager; - struct RouterContact; + struct LocalRC; struct RCGossiper { @@ -23,7 +23,7 @@ namespace llarp ~RCGossiper() = default; bool - GossipRC(const RouterContact& rc); + GossipRC(const LocalRC& rc); void Decay(Time_t now); @@ -32,7 +32,7 @@ namespace llarp ShouldGossipOurRC(Time_t now) const; bool - IsOurRC(const RouterContact& rc) const; + IsOurRC(const LocalRC& rc) const; void Init(LinkManager*, const RouterID&, Router*); diff --git a/llarp/router/rc_lookup_handler.cpp b/llarp/router/rc_lookup_handler.cpp index 4c26d748b..8723f1bbe 100644 --- a/llarp/router/rc_lookup_handler.cpp +++ b/llarp/router/rc_lookup_handler.cpp @@ -66,7 +66,7 @@ namespace llarp void RCLookupHandler::get_rc(const RouterID& rid, RCRequestCallback callback, bool forceLookup) { - RouterContact remoteRC; + RemoteRC remoteRC; if (not forceLookup) { @@ -101,8 +101,7 @@ namespace llarp throw; } - // TODO: replace this with construction of RemoteRC - RouterContact result{std::move(payload)}; + RemoteRC result{std::move(payload)}; if (callback) callback(result.router_id(), result, true); @@ -203,7 +202,7 @@ namespace llarp } bool - RCLookupHandler::check_rc(const RouterContact& rc) const + RCLookupHandler::check_rc(const RemoteRC& rc) const { if (not is_session_allowed(rc.router_id())) { @@ -211,16 +210,16 @@ namespace llarp return false; } - if (not rc.verify(llarp::time_now_ms())) // TODO: fix this call after RouterContact -> RemoteRC + if (not rc.verify()) { - LogWarn("RC for ", RouterID(rc.router_id()), " is invalid"); + log::info(link_cat, "Invalid RC (rid: {})", rc.router_id()); return false; } // update nodedb if required if (rc.is_public_router()) { - LogDebug("Adding or updating RC for ", RouterID(rc.router_id()), " to nodedb and dht."); + log::info(link_cat, "Adding or updating RC (rid: {}) to nodeDB and DHT", rc.router_id()); node_db->put_rc_if_newer(rc); contacts->put_rc_node_async(rc); } @@ -249,29 +248,6 @@ namespace llarp }); } - bool - RCLookupHandler::check_renegotiate_valid(RouterContact newrc, RouterContact oldrc) - { - // mismatch of identity ? - if (newrc.router_id() != oldrc.router_id()) - return false; - - if (!is_session_allowed(newrc.router_id())) - return false; - - auto func = [this, newrc] { check_rc(newrc); }; - work_func(func); - - // update dht if required - if (contacts->rc_nodes()->HasNode(dht::Key_t{newrc.router_id()})) - { - contacts->rc_nodes()->PutNode(newrc); - } - - // TODO: check for other places that need updating the RC - return true; - } - void RCLookupHandler::periodic_update(llarp_time_t now) { @@ -337,7 +313,7 @@ namespace llarp return; } // service nodes gossip, not explore - if (contacts->router()->IsServiceNode()) + if (contacts->router()->is_service_node()) return; // explore via every connected peer @@ -368,7 +344,7 @@ namespace llarp LinkManager* linkManager, service::Context* hiddenServiceContext, const std::unordered_set& strictConnectPubkeys, - const std::set& bootstrapRCList, + const std::set& bootstrapRCList, bool isServiceNode_arg) { contacts = c; diff --git a/llarp/router/rc_lookup_handler.hpp b/llarp/router/rc_lookup_handler.hpp index 7802a2597..f7b3f01f4 100644 --- a/llarp/router/rc_lookup_handler.hpp +++ b/llarp/router/rc_lookup_handler.hpp @@ -1,5 +1,6 @@ #pragma once +#include #include #include @@ -24,7 +25,6 @@ namespace llarp struct Contacts; struct LinkManager; - struct RouterContact; enum class RCRequestResult { @@ -35,7 +35,7 @@ namespace llarp }; using RCRequestCallback = - std::function, bool success)>; + std::function, bool success)>; struct RCLookupHandler { @@ -80,14 +80,11 @@ namespace llarp is_registered(const RouterID& remote) const; bool - check_rc(const RouterContact& rc) const; + check_rc(const RemoteRC& rc) const; bool get_random_whitelist_router(RouterID& router) const; - bool - check_renegotiate_valid(RouterContact newrc, RouterContact oldrc); - void periodic_update(llarp_time_t now); @@ -106,7 +103,7 @@ namespace llarp LinkManager* linkManager, service::Context* hiddenServiceContext, const std::unordered_set& strictConnectPubkeys, - const std::set& bootstrapRCList, + const std::set& bootstrapRCList, bool isServiceNode_arg); std::unordered_set @@ -128,7 +125,7 @@ namespace llarp /// service nodes) std::unordered_set strict_connect_pubkeys; - std::set bootstrap_rc_list; + std::set bootstrap_rc_list; std::unordered_set boostrap_rid_list; // Now that all calls are made through the event loop, any access to these diff --git a/llarp/router/route_poker.cpp b/llarp/router/route_poker.cpp index b64ff9e9e..782fd7d18 100644 --- a/llarp/router/route_poker.cpp +++ b/llarp/router/route_poker.cpp @@ -117,7 +117,7 @@ namespace llarp bool RoutePoker::is_enabled() const { - if (router.IsServiceNode()) + if (router.is_service_node()) return false; if (const auto& conf = router.config()) return conf->network.m_EnableRoutePoker; diff --git a/llarp/router/router.cpp b/llarp/router/router.cpp index 885e3fcf5..1b88b6f43 100644 --- a/llarp/router/router.cpp +++ b/llarp/router/router.cpp @@ -199,7 +199,7 @@ namespace llarp void Router::Freeze() { - if (IsServiceNode()) + if (is_service_node()) return; for_each_connection( @@ -209,7 +209,7 @@ namespace llarp void Router::Thaw() { - if (IsServiceNode()) + if (is_service_node()) return; std::unordered_set peer_pubkeys; @@ -231,10 +231,10 @@ namespace llarp } void - Router::GossipRCIfNeeded(const RouterContact rc) + Router::GossipRCIfNeeded(const LocalRC rc) { /// if we are not a service node forget about gossip - if (not IsServiceNode()) + if (not is_service_node()) return; /// wait for random uptime if (std::chrono::milliseconds{Uptime()} < _randomStartDelay) @@ -245,7 +245,7 @@ namespace llarp bool Router::GetRandomGoodRouter(RouterID& router) { - if (IsServiceNode()) + if (is_service_node()) { return _rc_lookup_handler.get_random_whitelist_router(router); } @@ -271,7 +271,7 @@ namespace llarp } void - Router::connect_to(const RouterContact& rc) + Router::connect_to(const RemoteRC& rc) { _link_manager.connect_to(rc); } @@ -314,7 +314,7 @@ namespace llarp { _encryption = _key_manager->encryptionKey; - if (IsServiceNode()) + if (is_service_node()) { #if defined(ANDROID) || defined(IOS) LogError("running a service node on mobile device is not possible."); @@ -396,9 +396,9 @@ namespace llarp log::debug(logcat, "Configuring router"); - is_service_node = conf.router.m_isRelay; + _is_service_node = conf.router.m_isRelay; - if (is_service_node) + if (_is_service_node) { rpc_addr = oxenmq::address(conf.lokid.lokidRPCAddr); _rpc_client = std::make_shared(_lmq, weak_from_this()); @@ -417,9 +417,9 @@ namespace llarp _node_db = std::move(nodedb); log::debug( - logcat, is_service_node ? "Running as a relay (service node)" : "Running as a client"); + logcat, _is_service_node ? "Running as a relay (service node)" : "Running as a client"); - if (is_service_node) + if (_is_service_node) { _rpc_client->ConnectAsync(rpc_addr); } @@ -438,34 +438,10 @@ namespace llarp return true; } - /// called in disk worker thread - void - Router::HandleSaveRC() const - { - std::string fname = our_rc_file.string(); - router_contact.write(fname.c_str()); - } - bool - Router::SaveRC() + Router::is_service_node() const { - LogDebug("verify RC signature"); - if (!router_contact.verify(now())) // TODO: RouterContact -> RemoteRC - { - Dump(rc()); - LogError("RC is invalid, not saving"); - return false; - } - if (is_service_node) - _node_db->put_rc(router_contact); - queue_disk_io([&]() { HandleSaveRC(); }); - return true; - } - - bool - Router::IsServiceNode() const - { - return is_service_node; + return _is_service_node; } bool @@ -507,7 +483,7 @@ namespace llarp bool Router::have_snode_whitelist() const { - return IsServiceNode() and _rc_lookup_handler.has_received_whitelist(); + return is_service_node() and _rc_lookup_handler.has_received_whitelist(); } bool @@ -566,13 +542,13 @@ namespace llarp bool Router::update_rc() { - SecretKey nextOnionKey; - RouterContact nextRC = router_contact; - if (!nextRC.sign(identity())) // TODO: RouterContact -> LocalRC - return false; - router_contact = std::move(nextRC); - if (IsServiceNode()) - return SaveRC(); + router_contact.resign(); + if (is_service_node()) + { + _node_db->put_rc(router_contact.view()); + queue_disk_io([&]() { router_contact.write(our_rc_file); }); + } + return true; } @@ -626,12 +602,13 @@ namespace llarp auto& networkConfig = conf.network; - /// build a set of strictConnectPubkeys ( + /// build a set of strictConnectPubkeys std::unordered_set strictConnectPubkeys; + if (not networkConfig.m_strictConnect.empty()) { const auto& val = networkConfig.m_strictConnect; - if (IsServiceNode()) + if (is_service_node()) throw std::runtime_error("cannot use strict-connect option as service node"); if (val.size() < 2) throw std::runtime_error( @@ -660,7 +637,7 @@ namespace llarp for (const auto& router : configRouters) { log::debug(logcat, "Loading bootstrap router list from {}", defaultBootstrapFile); - bootstrap_rc_list.AddFromFile(router); + bootstrap_rc_list.read_from_file(router); } for (const auto& rc : conf.bootstrap.routers) @@ -668,37 +645,10 @@ namespace llarp bootstrap_rc_list.emplace(rc); } - // in case someone has an old bootstrap file and is trying to use a bootstrap - // that no longer exists - auto clearBadRCs = [this]() { - for (auto it = bootstrap_rc_list.begin(); it != bootstrap_rc_list.end();) - { - if (it->is_obsolete_bootstrap()) - log::warning(logcat, "ignoring obsolete boostrap RC: {}", RouterID{it->router_id()}); - else if (not it->verify(now())) // TODO: RouterContact -> RemoteRC - log::warning(logcat, "ignoring invalid bootstrap RC: {}", RouterID{it->router_id()}); - else - { - ++it; - continue; - } - // we are in one of the above error cases that we warned about: - it = bootstrap_rc_list.erase(it); - } - }; - - clearBadRCs(); - if (bootstrap_rc_list.empty() and not conf.bootstrap.seednode) { auto fallbacks = llarp::load_bootstrap_fallbacks(); - if (auto itr = fallbacks.find(router_contact.netID.ToString()); itr != fallbacks.end()) - { - bootstrap_rc_list = itr->second; - log::debug( - logcat, "loaded {} default fallback bootstrap routers", bootstrap_rc_list.size()); - clearBadRCs(); - } + if (bootstrap_rc_list.empty() and not conf.bootstrap.seednode) { // empty after trying fallback, if set @@ -711,6 +661,24 @@ namespace llarp } } + // in case someone has an old bootstrap file and is trying to use a bootstrap + // that no longer exists + for (auto it = bootstrap_rc_list.begin(); it != bootstrap_rc_list.end();) + { + if (it->is_obsolete_bootstrap()) + log::warning(logcat, "ignoring obsolete boostrap RC: {}", it->router_id()); + else if (not it->verify()) + log::warning(logcat, "ignoring invalid bootstrap RC: {}", it->router_id()); + else + { + ++it; + continue; + } + + // we are in one of the above error cases that we warned about: + it = bootstrap_rc_list.erase(it); + } + if (conf.bootstrap.seednode) LogInfo("we are a seed node"); else @@ -727,10 +695,10 @@ namespace llarp &_hidden_service_context, strictConnectPubkeys, bootstrap_rc_list, - is_service_node); + _is_service_node); // FIXME: kludge for now, will be part of larger cleanup effort. - if (is_service_node) + if (_is_service_node) InitInboundLinks(); else InitOutboundLinks(); @@ -759,7 +727,7 @@ namespace llarp } // API config - if (not IsServiceNode()) + if (not is_service_node()) { hidden_service_context().AddEndpoint(conf); } @@ -767,19 +735,13 @@ namespace llarp return true; } - bool - Router::CheckRenegotiateValid(RouterContact newrc, RouterContact oldrc) - { - return _rc_lookup_handler.check_renegotiate_valid(newrc, oldrc); - } - bool Router::IsBootstrapNode(const RouterID r) const { return std::count_if( bootstrap_rc_list.begin(), bootstrap_rc_list.end(), - [r](const RouterContact& rc) -> bool { return rc.router_id() == r; }) + [r](const RemoteRC& rc) -> bool { return rc.router_id() == r; }) > 0; } @@ -797,7 +759,7 @@ namespace llarp LogInfo(node_db()->num_loaded(), " RCs loaded"); LogInfo(bootstrap_rc_list.size(), " bootstrap peers"); LogInfo(NumberOfConnectedRouters(), " router connections"); - if (IsServiceNode()) + if (is_service_node()) { LogInfo(NumberOfConnectedClients(), " client connections"); LogInfo(ToString(router_contact.age(now)), " since we last updated our RC"); @@ -814,7 +776,7 @@ namespace llarp std::string status; auto out = std::back_inserter(status); fmt::format_to(out, "v{}", fmt::join(llarp::LOKINET_VERSION, ".")); - if (IsServiceNode()) + if (is_service_node()) { fmt::format_to( out, @@ -890,7 +852,7 @@ namespace llarp _rc_lookup_handler.periodic_update(now); const bool has_whitelist = _rc_lookup_handler.has_received_whitelist(); - const bool is_snode = IsServiceNode(); + const bool is_snode = is_service_node(); const bool is_decommed = appears_decommed(); bool should_gossip = appears_funded(); @@ -916,7 +878,7 @@ namespace llarp GossipRCIfNeeded(router_contact); } // remove RCs for nodes that are no longer allowed by network policy - node_db()->RemoveIf([&](const RouterContact& rc) -> bool { + node_db()->RemoveIf([&](const RemoteRC& rc) -> bool { // don't purge bootstrap nodes from nodedb if (IsBootstrapNode(rc.router_id())) { @@ -1057,32 +1019,12 @@ namespace llarp _last_tick = llarp::time_now_ms(); } - void - Router::modify_rc(std::function(RouterContact)> modify) - { - if (auto maybe = modify(rc())) - { - router_contact = *maybe; - update_rc(); - _rcGossiper.GossipRC(rc()); - } - } - bool - Router::GetRandomConnectedRouter(RouterContact& result) const + Router::GetRandomConnectedRouter(RemoteRC& result) const { return _link_manager.get_random_connected(result); } - void - Router::HandleDHTLookupForExplore(RouterID /*remote*/, const std::vector& results) - { - for (const auto& rc : results) - { - _rc_lookup_handler.check_rc(rc); - } - } - void Router::set_router_whitelist( const std::vector& whitelist, @@ -1200,7 +1142,7 @@ namespace llarp _route_poker->start(); is_running.store(true); _started_at = now(); - if (IsServiceNode()) + if (is_service_node()) { // do service node testing if we are in service node whitelist mode _loop->call_every(consensus::REACHABILITY_TESTING_TIMER_INTERVAL, weak_from_this(), [this] { @@ -1428,7 +1370,7 @@ namespace llarp bool Router::HasClientExit() const { - if (IsServiceNode()) + if (is_service_node()) return false; const auto& ep = hidden_service_context().GetDefault(); return ep and ep->HasExit(); diff --git a/llarp/router/router.hpp b/llarp/router/router.hpp index c20a3e57e..0abbf5dd2 100644 --- a/llarp/router/router.hpp +++ b/llarp/router/router.hpp @@ -85,7 +85,7 @@ namespace llarp // use file based logging? bool use_file_logging = false; // our router contact - RouterContact router_contact; + LocalRC router_contact; std::shared_ptr _lmq; path::BuildLimiter _pathbuild_limiter; std::shared_ptr loop_wakeup; @@ -94,7 +94,7 @@ namespace llarp std::atomic is_running; int _outbound_udp_socket = -1; - bool is_service_node = false; + bool _is_service_node = false; std::optional _ourAddress; oxen::quic::Address _local_addr; @@ -167,7 +167,7 @@ namespace llarp connect_to(const RouterID& rid); void - connect_to(const RouterContact& rc); + connect_to(const RemoteRC& rc); Contacts* contacts() const @@ -274,7 +274,7 @@ namespace llarp return paths; } - const RouterContact& + const LocalRC& rc() const { return router_contact; @@ -295,9 +295,6 @@ namespace llarp return _rc_lookup_handler.whitelist(); } - void - modify_rc(std::function(RouterContact)> modify); - void set_router_whitelist( const std::vector& whitelist, @@ -381,7 +378,7 @@ namespace llarp status_line(); void - GossipRCIfNeeded(const RouterContact rc); + GossipRCIfNeeded(const LocalRC rc); void InitInboundLinks(); @@ -402,7 +399,7 @@ namespace llarp /// return true if we are running in service node mode bool - IsServiceNode() const; + is_service_node() const; std::optional OxendErrorState() const; @@ -452,12 +449,6 @@ namespace llarp bool PathToRouterAllowed(const RouterID& router) const; - void - HandleSaveRC() const; - - bool - SaveRC(); - /// return true if we are a client with an exit configured bool HasClientExit() const; @@ -489,13 +480,6 @@ namespace llarp bool IsBootstrapNode(RouterID) const; - /// check if newRc matches oldRC and update local rc for this remote contact - /// if valid - /// returns true on valid and updated - /// returns false otherwise - bool - CheckRenegotiateValid(RouterContact newRc, RouterContact oldRC); - /// call internal router ticker void Tick(); @@ -525,10 +509,7 @@ namespace llarp NumberOfConnectedClients() const; bool - GetRandomConnectedRouter(RouterContact& result) const; - - void - HandleDHTLookupForExplore(RouterID remote, const std::vector& results); + GetRandomConnectedRouter(RemoteRC& result) const; bool HasSessionTo(const RouterID& remote) const; diff --git a/llarp/router_contact.cpp b/llarp/router_contact.cpp index 01a9d5f64..f7c1211fd 100644 --- a/llarp/router_contact.cpp +++ b/llarp/router_contact.cpp @@ -30,13 +30,13 @@ namespace llarp // } // } - std::string - RouterContact::bt_encode() const - { - oxenc::bt_dict_producer btdp; - bt_encode(btdp); - return std::move(btdp).str(); - } + // std::string + // RouterContact::bt_encode() const + // { + // oxenc::bt_dict_producer btdp; + // bt_encode(btdp); + // return std::move(btdp).str(); + // } void RouterContact::bt_load(oxenc::bt_dict_consumer& data) @@ -107,6 +107,23 @@ namespace llarp _router_version[i] = ver[i]; } + bool + RouterContact::write(const fs::path& fname) const + { + auto bte = bt_encode(); + + try + { + util::buffer_to_file(fname, bte.data(), bte.size()); + } + catch (const std::exception& e) + { + log::error(logcat, "Failed to write RC to {}: {}", fname, e.what()); + return false; + } + return true; + } + // std::string // RouterContact::bencode_signed_section() const // { @@ -208,7 +225,7 @@ namespace llarp (void)key; // TOFIX: fuck everything about llarp_buffer_t - + // if (!BEncodeMaybeReadDictEntry("a", addr, read, key, buf)) // return false; @@ -299,42 +316,4 @@ namespace llarp } return false; } - - bool - RouterContact::write(const fs::path& fname) const - { - std::array tmp; - llarp_buffer_t buf(tmp); - - auto bte = bt_encode(); - buf.write(bte.begin(), bte.end()); - - try - { - util::dump_file(fname, tmp.data(), buf.cur - buf.base); - } - catch (const std::exception& e) - { - log::error(logcat, "Failed to write RC to {}: {}", fname, e.what()); - return false; - } - return true; - } - - bool - RouterContact::read(const fs::path& fname) - { - std::array tmp; - llarp_buffer_t buf(tmp); - try - { - util::file_to_buffer(fname, tmp.data(), tmp.size()); - } - catch (const std::exception& e) - { - log::error(logcat, "Failed to read RC from {}: {}", fname, e.what()); - return false; - } - return BDecode(&buf); - } } // namespace llarp diff --git a/llarp/router_contact.hpp b/llarp/router_contact.hpp index d2a0f54a6..1d8f737b0 100644 --- a/llarp/router_contact.hpp +++ b/llarp/router_contact.hpp @@ -18,10 +18,10 @@ #include #include -namespace oxenc -{ - class bt_list_consumer; -} // namespace oxenc +// namespace oxenc +// { +// class bt_list_consumer; +// } // namespace oxenc /* - figure out where we do bt_encoding of RC's @@ -42,17 +42,20 @@ namespace llarp using rc_time = std::chrono::time_point; + static inline constexpr size_t NETID_SIZE{8}; + /// 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() = default; + + // RouterContact(std::string) + // { + // log::error(logcat, "ERROR: SUPPLANT THIS CONSTRUCTOR"); + // } // RouterContact(std::string buf); @@ -119,12 +122,19 @@ namespace llarp // Lokinet version at the time the RC was produced std::array _router_version; + // In both Remote and Local RC's, the entire bt-encoded payload given at construction is + // emplaced here. + // + // In a RemoteRC, this value will be held for the lifetime of the object + // s.t. it can be returned upon calls to ::bt_encode. + // In a LocalRC, this value will be supplanted any time a mutator is invoked, requiring + // the re-signing of the payload. + ustring _payload; + public: /// should we serialize the exit info? const static bool serializeExit = true; - ustring _signed_payload; - util::StatusObject extract_status() const; @@ -138,13 +148,16 @@ namespace llarp to_string() const { return fmt::format( - "[RC k={} updated={} v={} addr={}]", - _router_id, - _timestamp, - RC_VERSION, - _addr.to_string()); + "[RC k={} updated={} v={} addr={}]", + _router_id.ToView(), + _timestamp.time_since_epoch().count(), + RC_VERSION, + _addr.to_string()); } + 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 @@ -161,13 +174,11 @@ namespace llarp /// "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" - std::string - bt_encode() const; - - virtual void - bt_encode(oxenc::bt_dict_producer& btdp) const + virtual ustring_view + bt_encode() const { - (void)btdp; + log::warning(logcat, "ERROR: SUPPLANT THIS METHOD"); + return {}; } bool @@ -190,7 +201,7 @@ namespace llarp } virtual void - clear() + clear() {} bool @@ -224,21 +235,13 @@ namespace llarp return _timestamp < other._timestamp; } - bool - read(const fs::path& fname); - - bool - write(const fs::path& fname) const; - bool is_obsolete_bootstrap() const; void bt_load(oxenc::bt_dict_consumer& data); - }; - /// Extension of RouterContact used to store a local "RC," and inserts a RouterContact by /// re-parsing and sending it out. This sub-class contains a pubkey and all the other attributes /// required for signing and serialization @@ -246,24 +249,35 @@ namespace llarp /// Note: this class may be entirely superfluous, so it is used here as a placeholder until its /// marginal utility is determined. It may end up as a free-floating method that reads in /// parameters and outputs a bt-serialized string - struct LocalRC : public RouterContact + struct LocalRC final : public RouterContact { private: ustring _signature; - const SecretKey _secret_key; + // TODO: fix these parameters void - bt_sign(oxenc::bt_dict_consumer& btdc); - + bt_sign(oxenc::bt_dict_producer& btdp); + + void + bt_encode(oxenc::bt_dict_producer& btdp) const; + + public: + LocalRC() = default; + explicit LocalRC(std::string payload, const SecretKey sk); + ~LocalRC() = default; + void resign(); - public: - LocalRC(std::string payload, const SecretKey sk); + ustring_view + bt_encode() const override; - void - bt_encode(oxenc::bt_dict_producer& btdp) const override; + ustring_view + view() const + { + return _payload; + } void clear() override @@ -289,22 +303,22 @@ namespace llarp void set_addr(oxen::quic::Address new_addr) { - resign(); _addr = std::move(new_addr); + resign(); } void set_addr6(oxen::quic::Address new_addr) { - resign(); _addr6 = std::move(new_addr); + resign(); } void set_router_id(RouterID rid) { - resign(); _router_id = std::move(rid); + resign(); } void @@ -328,24 +342,44 @@ namespace llarp } }; - /// Extension of RouterContact used in a "read-only" fashion. Parses the incoming RC to query /// the data in the constructor, eliminating the need for a ::verify method/ - struct RemoteRC : public RouterContact + struct RemoteRC final : public RouterContact { private: - // - + // TODO: fix these parameters void - bt_verify(oxenc::bt_dict_consumer& data, bool reject_expired = false); + bt_verify(oxenc::bt_dict_consumer& data, bool reject_expired = false) const; - public: - RemoteRC(std::string payload); + public: + RemoteRC() = default; + RemoteRC(std::string_view data) : RemoteRC{oxenc::bt_dict_consumer{data}} + {} + RemoteRC(ustring_view data) : RemoteRC{oxenc::bt_dict_consumer{data}} + { + _payload = data; + } + explicit RemoteRC(oxenc::bt_dict_consumer btdc); + ~RemoteRC() = default; + + ustring_view + bt_encode() const override + { + return _payload; + } + + std::string_view + view() const + { + return {reinterpret_cast(_payload.data()), _payload.size()}; + } + + bool + verify() const; + + bool + read(const fs::path& fname); - // TODO: this method could use oxenc's append_encoded - void - bt_encode(oxenc::bt_dict_producer& btdp) const override; - void clear() override { @@ -355,7 +389,6 @@ namespace llarp _timestamp = {}; _router_version.fill(0); } - }; template <> @@ -365,7 +398,7 @@ namespace llarp template <> constexpr inline bool IsToStringFormattable = true; - using RouterLookupHandler = std::function&)>; + using RouterLookupHandler = std::function&)>; } // namespace llarp namespace std diff --git a/llarp/router_contact_local.cpp b/llarp/router_contact_local.cpp index 275b3c64e..71537692d 100644 --- a/llarp/router_contact_local.cpp +++ b/llarp/router_contact_local.cpp @@ -11,8 +11,7 @@ namespace llarp { - LocalRC::LocalRC(std::string payload, const SecretKey sk) : - _secret_key{std::move(sk)} + LocalRC::LocalRC(std::string payload, const SecretKey sk) : _secret_key{std::move(sk)} { _router_id = llarp::seckey_to_pubkey(_secret_key); @@ -20,7 +19,27 @@ namespace llarp { oxenc::bt_dict_consumer btdc{payload}; bt_load(btdc); - bt_sign(btdc); + + btdc.require_signature("~", [this](ustring_view msg, ustring_view sig) { + if (sig.size() != 64) + throw std::runtime_error{"Invalid signature: not 64 bytes"}; + + if (is_expired(time_now_ms())) + throw std::runtime_error{"Unable to verify expired RemoteRC!"}; + + // TODO: revisit if this is needed; detail from previous implementation + const auto* net = net::Platform::Default_ptr(); + + if (net->IsBogon(addr().in4()) and BLOCK_BOGONS) + { + auto err = "Unable to verify expired RemoteRC!"; + log::info(logcat, err); + throw std::runtime_error{err}; + } + + if (not crypto::verify(router_id(), msg, sig)) + throw std::runtime_error{"Failed to verify RemoteRC"}; + }); } catch (const std::exception& e) { @@ -30,17 +49,29 @@ namespace llarp } void - LocalRC::bt_sign(oxenc::bt_dict_consumer& btdc) + LocalRC::bt_sign(oxenc::bt_dict_producer& btdp) { _signature.clear(); - btdc.require_signature("~", [&](ustring_view msg, ustring_view s) { - if (!crypto::sign(const_cast(s.data()), _secret_key, msg)) + btdp.append_signature("~", [this](ustring_view to_sign) { + std::array sig; + + if (!crypto::sign(const_cast(sig.data()), _secret_key, to_sign)) throw std::runtime_error{"Failed to sign RC"}; - _signature = s; - _signed_payload = msg; + _signature = {sig.data(), sig.size()}; + return sig; }); + + _payload = btdp.view(); + } + + ustring_view + LocalRC::bt_encode() const + { + oxenc::bt_dict_producer btdp; + bt_encode(btdp); + return btdp.view(); } void @@ -86,12 +117,12 @@ namespace llarp btdp.append( "v", std::string_view{reinterpret_cast(llarp::LOKINET_VERSION.data()), 3}); - btdp.append_signature("~", [&](ustring_view to_sign) { + 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; }); } @@ -99,10 +130,9 @@ namespace llarp void LocalRC::resign() { - oxenc::bt_dict_consumer btdc{_signed_payload}; - bt_sign(btdc); - - // DISCUSS: should we also update the timestamp when we re-sign? - // -> Is the timestamp referring to signing time or time the RC was originally created? + set_systime_timestamp(); + oxenc::bt_dict_producer btdp; + bt_encode(btdp); + bt_sign(btdp); } } // namespace llarp diff --git a/llarp/router_contact_remote.cpp b/llarp/router_contact_remote.cpp index f17100310..8cb127d4c 100644 --- a/llarp/router_contact_remote.cpp +++ b/llarp/router_contact_remote.cpp @@ -11,13 +11,32 @@ namespace llarp { - RemoteRC::RemoteRC(std::string payload) + RemoteRC::RemoteRC(oxenc::bt_dict_consumer btdc) { try { - oxenc::bt_dict_consumer btdc{payload}; bt_load(btdc); - bt_verify(btdc); + + btdc.require_signature("~", [this](ustring_view msg, ustring_view sig) { + if (sig.size() != 64) + throw std::runtime_error{"Invalid signature: not 64 bytes"}; + + if (is_expired(time_now_ms())) + throw std::runtime_error{"Unable to verify expired RemoteRC!"}; + + // TODO: revisit if this is needed; detail from previous implementation + const auto* net = net::Platform::Default_ptr(); + + if (net->IsBogon(addr().in4()) and BLOCK_BOGONS) + { + auto err = "Unable to verify expired RemoteRC!"; + log::info(logcat, err); + throw std::runtime_error{err}; + } + + if (not crypto::verify(router_id(), msg, sig)) + throw std::runtime_error{"Failed to verify RemoteRC"}; + }); } catch (const std::exception& e) { @@ -27,21 +46,7 @@ namespace llarp } void - RemoteRC::bt_encode(oxenc::bt_dict_producer& btdp) const - { - (void)btdp; - - // TODO: implement append_encoded in oxenc so we can finish this implementation. - // It is almost identical to the implementation of LocalRC::bt_encode, except the - // call to append_signature is append_encoded. - // - // When that is done, we can take the common logic and move it into the base class - // ::bt_encode, and then have each derived class call into a different virtual method - // that calls append_signature in the LocalRC and append_encoded in the RemoteRC - } - - void - RemoteRC::bt_verify(oxenc::bt_dict_consumer& data, bool reject_expired) + RemoteRC::bt_verify(oxenc::bt_dict_consumer& data, bool reject_expired) const { data.require_signature("~", [this, reject_expired](ustring_view msg, ustring_view sig) { if (sig.size() != 64) @@ -62,8 +67,40 @@ namespace llarp if (not crypto::verify(router_id(), msg, sig)) throw std::runtime_error{"Failed to verify RemoteRC"}; - - _signed_payload = msg; }); } + + bool + RemoteRC::read(const fs::path& fname) + { + ustring buf; + buf.reserve(MAX_RC_SIZE); + + try + { + util::file_to_buffer(fname, buf.data(), MAX_RC_SIZE); + } + catch (const std::exception& e) + { + log::error(logcat, "Failed to read RC from {}: {}", fname, e.what()); + return false; + } + + oxenc::bt_dict_consumer btdc{buf}; + bt_load(btdc); + bt_verify(btdc); + + _payload = buf; + + return true; + } + + bool + RemoteRC::verify() const + { + oxenc::bt_dict_consumer btdc{_payload}; + bt_verify(btdc); + return true; + } + } // namespace llarp diff --git a/llarp/rpc/lokid_rpc_client.cpp b/llarp/rpc/lokid_rpc_client.cpp index c9390b3b7..aa4e3f3ad 100644 --- a/llarp/rpc/lokid_rpc_client.cpp +++ b/llarp/rpc/lokid_rpc_client.cpp @@ -51,7 +51,7 @@ namespace llarp::rpc { if (auto router = m_Router.lock()) { - if (not router->IsServiceNode()) + if (not router->is_service_node()) { throw std::runtime_error("we cannot talk to lokid while not a service node"); } diff --git a/llarp/rpc/rpc_server.cpp b/llarp/rpc/rpc_server.cpp index 92a7d71b3..598dd36f1 100644 --- a/llarp/rpc/rpc_server.cpp +++ b/llarp/rpc/rpc_server.cpp @@ -74,7 +74,7 @@ namespace llarp::rpc std::shared_ptr GetEndpointByName(Router& r, std::string name) { - if (r.IsServiceNode()) + if (r.is_service_node()) { return r.exitContext().GetExitEndpoint(name); } @@ -309,7 +309,7 @@ namespace llarp::rpc void RPCServer::invoke(LookupSnode& lookupsnode) { - if (not m_Router.IsServiceNode()) + if (not m_Router.is_service_node()) { SetJSONError("Not supported", lookupsnode.response); return; diff --git a/llarp/service/endpoint.cpp b/llarp/service/endpoint.cpp index 7b5451612..83afaf944 100644 --- a/llarp/service/endpoint.cpp +++ b/llarp/service/endpoint.cpp @@ -200,6 +200,7 @@ namespace llarp::service }); } + // TODO: revisit once SRVRecords are straightened out void Endpoint::LookupServiceAsync( std::string name, @@ -226,9 +227,9 @@ namespace llarp::service if (auto maybe_rc = nodedb->get_rc(router_id)) { - result = maybe_rc->srvRecords; // TODO: RouterContact has no SRV records + // result = maybe_rc->srvRecords; // TODO: RouterContact has no SRV records } - + resultHandler(std::move(result)); }; @@ -756,22 +757,22 @@ namespace llarp::service return now >= next_pub; } - std::optional> + std::optional> Endpoint::GetHopsForBuild() { std::unordered_set exclude; ForEachPath([&exclude](auto path) { exclude.insert(path->Endpoint()); }); const auto maybe = - router()->node_db()->GetRandom([exclude, r = router()](const auto& rc) -> bool { - return exclude.count(rc.pubkey) == 0 - and not r->router_profiling().IsBadForPath(rc.pubkey); + router()->node_db()->GetRandom([exclude, r = router()](const RemoteRC& rc) -> bool { + const auto& rid = rc.router_id(); + return exclude.count(rid) == 0 and not r->router_profiling().IsBadForPath(rid); }); if (not maybe.has_value()) return std::nullopt; return GetHopsForBuildWithEndpoint(maybe->router_id()); } - std::optional> + std::optional> Endpoint::GetHopsForBuildWithEndpoint(RouterID endpoint) { return path::Builder::GetHopsAlignedToForBuild(endpoint, SnodeBlacklist()); diff --git a/llarp/service/endpoint.hpp b/llarp/service/endpoint.hpp index 63bedc6d7..faa8b3f47 100644 --- a/llarp/service/endpoint.hpp +++ b/llarp/service/endpoint.hpp @@ -409,10 +409,10 @@ namespace llarp bool HasExit() const; - std::optional> + std::optional> GetHopsForBuild() override; - std::optional> + std::optional> GetHopsForBuildWithEndpoint(RouterID endpoint); void diff --git a/llarp/service/identity.cpp b/llarp/service/identity.cpp index b6333dcd7..05c6763f7 100644 --- a/llarp/service/identity.cpp +++ b/llarp/service/identity.cpp @@ -97,7 +97,7 @@ namespace llarp::service // write try { - util::dump_file(fname, tmp.data(), sz); + util::buffer_to_file(fname, tmp.data(), sz); } catch (const std::exception& e) { diff --git a/llarp/service/outbound_context.cpp b/llarp/service/outbound_context.cpp index 115394f57..c67c99551 100644 --- a/llarp/service/outbound_context.cpp +++ b/llarp/service/outbound_context.cpp @@ -350,7 +350,7 @@ namespace llarp::service return false; } - std::optional> + std::optional> OutboundContext::GetHopsForBuild() { if (next_intro.router.IsZero()) diff --git a/llarp/service/outbound_context.hpp b/llarp/service/outbound_context.hpp index d0381b0c7..8504efcd7 100644 --- a/llarp/service/outbound_context.hpp +++ b/llarp/service/outbound_context.hpp @@ -152,7 +152,7 @@ namespace llarp::service void HandlePathBuildFailedAt(path::Path_ptr path, RouterID hop) override; - std::optional> + std::optional> GetHopsForBuild() override; std::string diff --git a/llarp/service/router_lookup_job.cpp b/llarp/service/router_lookup_job.cpp index 3c988a73b..c08a139f2 100644 --- a/llarp/service/router_lookup_job.cpp +++ b/llarp/service/router_lookup_job.cpp @@ -4,13 +4,10 @@ #include -namespace llarp +namespace llarp::service { - namespace service - { - RouterLookupJob::RouterLookupJob(Endpoint* p, RouterLookupHandler h) - : handler(std::move(h)), txid(p->GenTXID()), started(p->Now()) - {} + RouterLookupJob::RouterLookupJob(Endpoint* p, RouterLookupHandler h) + : handler(std::move(h)), txid(p->GenTXID()), started(p->Now()) + {} - } // namespace service -} // namespace llarp +} // namespace llarp::service diff --git a/llarp/service/router_lookup_job.hpp b/llarp/service/router_lookup_job.hpp index 58228107b..d9dce7246 100644 --- a/llarp/service/router_lookup_job.hpp +++ b/llarp/service/router_lookup_job.hpp @@ -2,34 +2,31 @@ #include -namespace llarp +namespace llarp::service { - namespace service + struct Endpoint; + + struct RouterLookupJob { - struct Endpoint; + RouterLookupJob(Endpoint* p, RouterLookupHandler h); - struct RouterLookupJob + RouterLookupHandler handler; + uint64_t txid; + llarp_time_t started; + + bool + IsExpired(llarp_time_t now) const { - RouterLookupJob(Endpoint* p, RouterLookupHandler h); + if (now < started) + return false; + return now - started > 30s; + } - RouterLookupHandler handler; - uint64_t txid; - llarp_time_t started; - - bool - IsExpired(llarp_time_t now) const - { - if (now < started) - return false; - return now - started > 30s; - } - - void - InformResult(std::vector result) - { - if (handler) - handler(result); - } - }; - } // namespace service -} // namespace llarp + void + InformResult(std::vector result) + { + if (handler) + handler(result); + } + }; +} // namespace llarp::service diff --git a/llarp/util/bencode.hpp b/llarp/util/bencode.hpp index fcde4efbc..be616717e 100644 --- a/llarp/util/bencode.hpp +++ b/llarp/util/bencode.hpp @@ -389,7 +389,7 @@ namespace llarp tmp.resize(buf.cur - buf.base); try { - util::dump_file(fpath, tmp); + util::buffer_to_file(fpath, tmp); } catch (const std::exception& e) { diff --git a/llarp/util/file.cpp b/llarp/util/file.cpp index 26b21d987..9b482852a 100644 --- a/llarp/util/file.cpp +++ b/llarp/util/file.cpp @@ -52,7 +52,7 @@ namespace llarp::util } void - dump_file(const fs::path& filename, std::string_view contents) + buffer_to_file(const fs::path& filename, std::string_view contents) { fs::ofstream out; out.exceptions(std::ifstream::failbit | std::ifstream::badbit); diff --git a/llarp/util/file.hpp b/llarp/util/file.hpp index 82ff2bfbc..39c140673 100644 --- a/llarp/util/file.hpp +++ b/llarp/util/file.hpp @@ -34,14 +34,14 @@ namespace llarp::util /// Dumps binary string contents to disk. The file is overwritten if it already exists. Throws /// on error. void - dump_file(const fs::path& filename, std::string_view contents); + buffer_to_file(const fs::path& filename, std::string_view contents); /// Same as above, but works via char-like buffer template = 0> inline void - dump_file(const fs::path& filename, const Char* buffer, size_t buffer_size) + buffer_to_file(const fs::path& filename, const Char* buffer, size_t buffer_size) { - return dump_file( + return buffer_to_file( filename, std::string_view{reinterpret_cast(buffer), buffer_size}); }