implement and use "gossip_rc" command

TODO: refactor or remove RCGossiper and revisit RC regen and
when-to-gossip logic.
This commit is contained in:
Thomas Winget 2023-11-14 23:55:38 -05:00 committed by dr7ana
parent f6594a33bc
commit e29e23bf81
5 changed files with 59 additions and 27 deletions

View File

@ -150,6 +150,11 @@ namespace llarp
[this, &rid, msg = std::move(m)]() mutable { handle_path_control(std::move(msg), rid); }); [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) for (auto& method : direct_requests)
{ {
s->register_command( s->register_command(
@ -386,10 +391,19 @@ namespace llarp
} }
void void
LinkManager::gossip_rc(const RemoteRC& rc) LinkManager::gossip_rc(const RouterID& rc_rid, std::string serialized_rc)
{ {
for (auto& [rid, conn] : ep.conns) 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 void
@ -398,11 +412,18 @@ namespace llarp
try try
{ {
RemoteRC rc{m.body()}; 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) catch (const std::exception& e)
{ {
log::info(link_cat, "Recieved invalid RC, dropping on the floor."); log::info(link_cat, "Recieved invalid RC, dropping on the floor.");
return;
} }
} }

View File

@ -221,7 +221,7 @@ namespace llarp
} }
void void
gossip_rc(const RemoteRC& rc); gossip_rc(const RouterID& rc_rid, std::string serialized_rc);
void void
handle_gossip_rc(oxen::quic::message m); handle_gossip_rc(oxen::quic::message m);

View File

@ -99,6 +99,14 @@ namespace llarp
return m_Root / skiplistDir / fname; 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 void
NodeDB::set_bootstrap_routers(const std::set<RemoteRC>& rcs) NodeDB::set_bootstrap_routers(const std::set<RemoteRC>& rcs)
{ {
@ -284,14 +292,15 @@ namespace llarp
}); });
} }
void bool
NodeDB::put_rc(RemoteRC rc) NodeDB::put_rc(RemoteRC rc)
{ {
router.loop()->call([this, rc]() { const auto& rid = rc.router_id();
const auto& rid = rc.router_id(); if (not want_rc(rid))
entries.erase(rid); return false;
entries.emplace(rid, rc); entries.erase(rid);
}); entries.emplace(rid, rc);
return true;
} }
size_t size_t
@ -300,20 +309,15 @@ namespace llarp
return router.loop()->call_get([this]() { return entries.size(); }); return router.loop()->call_get([this]() { return entries.size(); });
} }
void bool
NodeDB::put_rc_if_newer(RemoteRC rc) NodeDB::put_rc_if_newer(RemoteRC rc)
{ {
router.loop()->call([this, rc]() { auto itr = entries.find(rc.router_id());
auto itr = entries.find(rc.router_id()); if (itr == entries.end() or itr->second.rc.other_is_newer(rc))
if (itr == entries.end() or itr->second.rc.other_is_newer(rc)) {
{ return put_rc(std::move(rc));
// delete if existing }
if (itr != entries.end()) return false;
entries.erase(itr);
// add new entry
entries.emplace(rc.router_id(), rc);
}
});
} }
void void

View File

@ -64,6 +64,9 @@ namespace llarp
// only ever use to specific edges as path first-hops // only ever use to specific edges as path first-hops
std::unordered_set<RouterID> pinned_edges; std::unordered_set<RouterID> pinned_edges;
bool
want_rc(const RouterID& rid) const;
public: public:
void void
set_bootstrap_routers(const std::set<RemoteRC>& rcs); set_bootstrap_routers(const std::set<RemoteRC>& rcs);
@ -243,12 +246,14 @@ namespace llarp
void void
remove_stale_rcs(std::unordered_set<RouterID> keep, llarp_time_t cutoff); remove_stale_rcs(std::unordered_set<RouterID> keep, llarp_time_t cutoff);
/// put this rc into the cache if it is not there or newer than the one there already /// if we consider it valid (want_rc),
void /// 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); put_rc_if_newer(RemoteRC rc);
/// unconditional put of rc into cache /// put (or replace) the RC if we consider it valid (want_rc). returns true if put.
void bool
put_rc(RemoteRC rc); put_rc(RemoteRC rc);
}; };
} // namespace llarp } // namespace llarp

View File

@ -236,7 +236,9 @@ namespace llarp
/// wait for random uptime /// wait for random uptime
if (std::chrono::milliseconds{Uptime()} < _randomStartDelay) if (std::chrono::milliseconds{Uptime()} < _randomStartDelay)
return; return;
_rcGossiper.GossipRC(rc); auto view = rc.view();
_link_manager.gossip_rc(
pubkey(), std::string{reinterpret_cast<const char*>(view.data()), view.size()});
} }
std::optional<RouterID> std::optional<RouterID>