From e29e23bf811aacadc58c6268d692d466bef6fb47 Mon Sep 17 00:00:00 2001 From: Thomas Winget Date: Tue, 14 Nov 2023 23:55:38 -0500 Subject: [PATCH] implement and use "gossip_rc" command TODO: refactor or remove RCGossiper and revisit RC regen and when-to-gossip logic. --- llarp/link/link_manager.cpp | 27 ++++++++++++++++++++++--- llarp/link/link_manager.hpp | 2 +- llarp/nodedb.cpp | 40 ++++++++++++++++++++----------------- llarp/nodedb.hpp | 13 ++++++++---- llarp/router/router.cpp | 4 +++- 5 files changed, 59 insertions(+), 27 deletions(-) diff --git a/llarp/link/link_manager.cpp b/llarp/link/link_manager.cpp index 294a84b9a..4563a0e41 100644 --- a/llarp/link/link_manager.cpp +++ b/llarp/link/link_manager.cpp @@ -150,6 +150,11 @@ namespace llarp [this, &rid, msg = std::move(m)]() mutable { handle_path_control(std::move(msg), rid); }); }); + s->register_command("gossip_rc"s, [this, rid](oxen::quic::message m) { + _router.loop()->call( + [this, msg = std::move(m)]() mutable { handle_gossip_rc(std::move(msg)); }); + }); + for (auto& method : direct_requests) { s->register_command( @@ -386,10 +391,19 @@ namespace llarp } void - LinkManager::gossip_rc(const RemoteRC& rc) + LinkManager::gossip_rc(const RouterID& rc_rid, std::string serialized_rc) { for (auto& [rid, conn] : ep.conns) - send_control_message(rid, "gossip_rc", std::string{rc.view()}, nullptr); + { + // don't send back to the owner... + if (rid == rc_rid) + continue; + // don't gossip RCs to clients + if (not conn->remote_is_relay) + continue; + + send_control_message(rid, "gossip_rc", serialized_rc, nullptr); + } } void @@ -398,11 +412,18 @@ namespace llarp try { RemoteRC rc{m.body()}; + + if (node_db->put_rc_if_newer(rc)) + { + log::info(link_cat, "Received updated RC, forwarding to relay peers."); + gossip_rc(rc.router_id(), m.body_str()); + } + else + log::debug(link_cat, "Received known or old RC, not storing or forwarding."); } catch (const std::exception& e) { log::info(link_cat, "Recieved invalid RC, dropping on the floor."); - return; } } diff --git a/llarp/link/link_manager.hpp b/llarp/link/link_manager.hpp index 6a456b064..c2be7dcd6 100644 --- a/llarp/link/link_manager.hpp +++ b/llarp/link/link_manager.hpp @@ -221,7 +221,7 @@ namespace llarp } void - gossip_rc(const RemoteRC& rc); + gossip_rc(const RouterID& rc_rid, std::string serialized_rc); void handle_gossip_rc(oxen::quic::message m); diff --git a/llarp/nodedb.cpp b/llarp/nodedb.cpp index 5377b19c2..ffc6d268c 100644 --- a/llarp/nodedb.cpp +++ b/llarp/nodedb.cpp @@ -99,6 +99,14 @@ namespace llarp return m_Root / skiplistDir / fname; } + bool + NodeDB::want_rc(const RouterID& rid) const + { + if (not router.is_service_node()) + return true; + return registered_routers.count(rid); + } + void NodeDB::set_bootstrap_routers(const std::set& rcs) { @@ -284,14 +292,15 @@ namespace llarp }); } - void + bool NodeDB::put_rc(RemoteRC rc) { - router.loop()->call([this, rc]() { - const auto& rid = rc.router_id(); - entries.erase(rid); - entries.emplace(rid, rc); - }); + const auto& rid = rc.router_id(); + if (not want_rc(rid)) + return false; + entries.erase(rid); + entries.emplace(rid, rc); + return true; } size_t @@ -300,20 +309,15 @@ namespace llarp return router.loop()->call_get([this]() { return entries.size(); }); } - void + bool NodeDB::put_rc_if_newer(RemoteRC rc) { - router.loop()->call([this, rc]() { - auto itr = entries.find(rc.router_id()); - if (itr == entries.end() or itr->second.rc.other_is_newer(rc)) - { - // delete if existing - if (itr != entries.end()) - entries.erase(itr); - // add new entry - entries.emplace(rc.router_id(), rc); - } - }); + auto itr = entries.find(rc.router_id()); + if (itr == entries.end() or itr->second.rc.other_is_newer(rc)) + { + return put_rc(std::move(rc)); + } + return false; } void diff --git a/llarp/nodedb.hpp b/llarp/nodedb.hpp index 7d7c088eb..76a635316 100644 --- a/llarp/nodedb.hpp +++ b/llarp/nodedb.hpp @@ -64,6 +64,9 @@ namespace llarp // only ever use to specific edges as path first-hops std::unordered_set pinned_edges; + bool + want_rc(const RouterID& rid) const; + public: void set_bootstrap_routers(const std::set& rcs); @@ -243,12 +246,14 @@ namespace llarp void remove_stale_rcs(std::unordered_set keep, llarp_time_t cutoff); - /// put this rc into the cache if it is not there or newer than the one there already - void + /// if we consider it valid (want_rc), + /// put this rc into the cache if it is not there or is newer than the one there already + /// returns true if the rc was inserted + bool put_rc_if_newer(RemoteRC rc); - /// unconditional put of rc into cache - void + /// put (or replace) the RC if we consider it valid (want_rc). returns true if put. + bool put_rc(RemoteRC rc); }; } // namespace llarp diff --git a/llarp/router/router.cpp b/llarp/router/router.cpp index 4b26ff144..9ef2972cb 100644 --- a/llarp/router/router.cpp +++ b/llarp/router/router.cpp @@ -236,7 +236,9 @@ namespace llarp /// wait for random uptime if (std::chrono::milliseconds{Uptime()} < _randomStartDelay) return; - _rcGossiper.GossipRC(rc); + auto view = rc.view(); + _link_manager.gossip_rc( + pubkey(), std::string{reinterpret_cast(view.data()), view.size()}); } std::optional