From 89975a0b013b72392857a12e70e0fe0d677f092c Mon Sep 17 00:00:00 2001 From: dr7ana Date: Fri, 15 Dec 2023 08:43:58 -0800 Subject: [PATCH] gossip fetch and response handling implemented --- llarp/link/link_manager.cpp | 50 ++++++++++++++++++++++++++----------- llarp/link/link_manager.hpp | 2 +- llarp/messages/fetch.hpp | 22 ++++++++++++++++ llarp/nodedb.cpp | 20 ++++++++++++--- llarp/nodedb.hpp | 8 +++++- llarp/router/router.cpp | 6 ++--- 6 files changed, 86 insertions(+), 22 deletions(-) diff --git a/llarp/link/link_manager.cpp b/llarp/link/link_manager.cpp index 76fec975c..42810637c 100644 --- a/llarp/link/link_manager.cpp +++ b/llarp/link/link_manager.cpp @@ -668,20 +668,28 @@ namespace llarp } void - LinkManager::gossip_rc(const RouterID& rc_rid, std::string serialized_rc) + LinkManager::gossip_rc( + const RouterID& gossip_src, const RouterID& last_sender, std::string serialized_rc) { for (auto& [rid, conn] : ep.active_conns) { - // don't send back to the owner... - if (rid == rc_rid) + // don't send back to the gossip source or the last sender + if (rid == gossip_src or rid == last_sender) continue; + // don't gossip RCs to clients if (not conn->remote_is_relay) continue; - send_control_message(rid, "gossip_rc", serialized_rc, [](oxen::quic::message) mutable { - log::critical(logcat, "PLACEHOLDER FOR GOSSIP RC RESPONSE HANDLER"); - }); + log::critical(logcat, "Dispatching gossip_rc to {}", rid); + + send_control_message( + rid, + "gossip_rc"s, + GossipRCMessage::serialize(gossip_src, last_sender, serialized_rc), + [](oxen::quic::message) mutable { + log::critical(logcat, "PLACEHOLDER FOR GOSSIP RC RESPONSE HANDLER"); + }); } } @@ -689,15 +697,31 @@ namespace llarp LinkManager::handle_gossip_rc(oxen::quic::message m) { // RemoteRC constructor wraps deserialization in a try/catch - RemoteRC rc{m.body()}; + RemoteRC rc; + RouterID src, sender; + + try + { + oxenc::bt_dict_consumer btdc{m.body()}; + + btdc.required("rc"); + rc = RemoteRC{btdc.consume_dict_data()}; + src.from_string(btdc.require("sender")); + sender.from_string(btdc.require("src")); + } + catch (const std::exception& e) + { + log::info(link_cat, "Exception handling GossipRC request: {}", e.what()); + return; + } - if (node_db->put_rc_if_newer(rc)) + if (node_db->verify_store_gossip_rc(rc)) { - log::info(link_cat, "Received updated RC, forwarding to relay peers."); - gossip_rc(rc.router_id(), m.body_str()); + log::critical(link_cat, "Received updated RC, forwarding to relay peers."); + gossip_rc(src, _router.local_rid(), std::string{rc.view()}); } else - log::debug(link_cat, "Received known or old RC, not storing or forwarding."); + log::critical(link_cat, "Received known or old RC, not storing or forwarding."); } void @@ -744,9 +768,7 @@ namespace llarp { oxenc::bt_dict_consumer btdc{m.body()}; btdc.required("local"); - auto rc_dict = btdc.consume_dict_data(); - // log::critical(logcat, "incoming dict data: {}", oxenc::to_hex(rc_dict)); - remote = RemoteRC{rc_dict}; + remote = RemoteRC{btdc.consume_dict_data()}; quantity = btdc.require("quantity"); } catch (const std::exception& e) diff --git a/llarp/link/link_manager.hpp b/llarp/link/link_manager.hpp index 5c1ae69cd..2e85e83d4 100644 --- a/llarp/link/link_manager.hpp +++ b/llarp/link/link_manager.hpp @@ -234,7 +234,7 @@ namespace llarp } void - gossip_rc(const RouterID& rc_rid, std::string serialized_rc); + gossip_rc(const RouterID& gossip_src, const RouterID& last_sender, std::string serialized_rc); void handle_gossip_rc(oxen::quic::message m); diff --git a/llarp/messages/fetch.hpp b/llarp/messages/fetch.hpp index 8981b6dde..af804f161 100644 --- a/llarp/messages/fetch.hpp +++ b/llarp/messages/fetch.hpp @@ -6,6 +6,28 @@ namespace llarp { + namespace GossipRCMessage + { + inline static std::string + serialize(const RouterID& gossip_src, const RouterID& last_sender, std::string rc) + { + oxenc::bt_dict_producer btdp; + + try + { + btdp.append_encoded("rc", rc); + btdp.append("sender", last_sender.ToView()); + btdp.append("src", gossip_src.ToView()); + } + catch (...) + { + log::error(link_cat, "Error: GossipRCMessage failed to bt encode contents"); + } + + return std::move(btdp).str(); + } + } // namespace GossipRCMessage + namespace FetchRCMessage { inline const auto INVALID_REQUEST = diff --git a/llarp/nodedb.cpp b/llarp/nodedb.cpp index f393fa17e..7bfb62aae 100644 --- a/llarp/nodedb.cpp +++ b/llarp/nodedb.cpp @@ -945,7 +945,13 @@ namespace llarp } bool - NodeDB::has_rc(RouterID pk) const + NodeDB::has_rc(const RemoteRC& rc) const + { + return known_rcs.count(rc); + } + + bool + NodeDB::has_rc(const RouterID& pk) const { return rc_lookup.count(pk); } @@ -1020,11 +1026,19 @@ namespace llarp return known_rids.size(); } + bool + NodeDB::verify_store_gossip_rc(const RemoteRC& rc) + { + if (not router_whitelist.count(rc.router_id())) + return put_rc_if_newer(rc); + + return false; + } + bool NodeDB::put_rc_if_newer(RemoteRC rc, rc_time now) { - if (auto itr = rc_lookup.find(rc.router_id()); - itr == rc_lookup.end() or itr->second.other_is_newer(rc)) + if (not has_rc(rc)) return put_rc(std::move(rc), now); return false; diff --git a/llarp/nodedb.hpp b/llarp/nodedb.hpp index 09880ca17..90f45f73c 100644 --- a/llarp/nodedb.hpp +++ b/llarp/nodedb.hpp @@ -425,7 +425,10 @@ namespace llarp /// return true if we have an rc by its ident pubkey bool - has_rc(RouterID pk) const; + has_rc(const RouterID& pk) const; + + bool + has_rc(const RemoteRC& rc) const; /// maybe get an rc by its ident pubkey std::optional @@ -584,6 +587,9 @@ namespace llarp /// returns true if the rc was inserted bool put_rc_if_newer(RemoteRC rc, rc_time now = time_point_now()); + + bool + verify_store_gossip_rc(const RemoteRC& rc); }; } // namespace llarp diff --git a/llarp/router/router.cpp b/llarp/router/router.cpp index 205f9f5f9..68426852e 100644 --- a/llarp/router/router.cpp +++ b/llarp/router/router.cpp @@ -869,10 +869,10 @@ namespace llarp router_contact.resign(); save_rc(); - auto view = router_contact.view(); - _link_manager->gossip_rc( - pubkey(), std::string{reinterpret_cast(view.data()), view.size()}); + router_contact.router_id(), + router_contact.router_id(), + std::string{oxen::quic::to_sv(router_contact.view())}); last_rc_gossip = now_timepoint;