Remove find/lookup router

We're removing the notion of find/lookup a singular RC, so this gets rid
of all functions which did that and replaces their usages with something
sensible.
This commit is contained in:
Thomas Winget 2023-11-14 22:49:37 -05:00 committed by dr7ana
parent 611d277d28
commit f6594a33bc
14 changed files with 24 additions and 399 deletions

View File

@ -272,35 +272,8 @@ namespace llarp::exit
if (numHops == 1)
{
auto r = router;
if (const auto maybe = r->node_db()->get_rc(exit_router); maybe.has_value())
r->connect_to(*maybe);
else
r->lookup_router(exit_router, [r](oxen::quic::message m) mutable {
if (m)
{
std::string payload;
try
{
oxenc::bt_dict_consumer btdc{m.body()};
payload = btdc.require<std::string>("RC");
}
catch (...)
{
log::warning(link_cat, "Failed to parse Find Router response!");
throw;
}
RemoteRC result{std::move(payload)};
r->node_db()->put_rc_if_newer(result);
r->connect_to(result);
}
else
{
r->link_manager().handle_find_router_error(std::move(m));
}
});
if (const auto maybe = router->node_db()->get_rc(exit_router); maybe.has_value())
router->connect_to(*maybe);
}
else if (UrgentBuild(now))
BuildOneAlignedTo(exit_router);

View File

@ -606,34 +606,11 @@ namespace llarp::handlers
RouterID snode;
if (snode.FromString(qname))
{
router()->lookup_router(
snode, [r = router(), msg = std::move(msg), reply](oxen::quic::message m) mutable {
if (m)
{
std::string payload;
try
{
oxenc::bt_dict_consumer btdc{m.body()};
payload = btdc.require<std::string>("RC");
}
catch (...)
{
log::warning(link_cat, "Failed to parse Find Router response!");
throw;
}
r->node_db()->put_rc_if_newer(RemoteRC{payload});
msg.AddTXTReply(payload);
}
else
{
msg.AddNXReply();
r->link_manager().handle_find_router_error(std::move(m));
}
reply(msg);
});
if (auto rc = router()->node_db()->get_rc(snode))
msg.AddTXTReply(std::string{rc->view()});
else
msg.AddNXReply();
reply(msg);
return true;
}

View File

@ -71,13 +71,6 @@ namespace llarp
return obj;
}
bool
Contacts::lookup_router(const RouterID& rid, std::function<void(oxen::quic::message)> func)
{
return _router.send_control_message(
rid, "find_router", FindRouterMessage::serialize(rid, false, false), std::move(func));
}
void
Contacts::put_rc_node_async(const dht::RCNode& val)
{

View File

@ -45,9 +45,6 @@ namespace llarp
util::StatusObject
ExtractStatus() const;
bool
lookup_router(const RouterID&, std::function<void(oxen::quic::message)> = nullptr);
void
put_rc_node_async(const dht::RCNode& val);

View File

@ -601,226 +601,6 @@ namespace llarp
}
}
void
LinkManager::handle_find_router(std::string_view body, std::function<void(std::string)> respond)
{
std::string target_key;
bool is_exploratory, is_iterative;
try
{
oxenc::bt_dict_consumer btdc{body};
is_exploratory = btdc.require<bool>("E");
is_iterative = btdc.require<bool>("I");
target_key = btdc.require<std::string>("K");
}
catch (const std::exception& e)
{
log::warning(link_cat, "Exception: {}", e.what());
respond(messages::ERROR_RESPONSE);
return;
}
// TODO: do we need a replacement for dht.AllowTransit() etc here?
RouterID target_rid;
target_rid.FromString(target_key);
const auto target_addr = dht::Key_t{reinterpret_cast<uint8_t*>(target_key.data())};
const auto& local_rid = _router.rc().router_id();
const auto local_key = dht::Key_t{local_rid};
if (is_exploratory)
{
std::string neighbors{};
// TODO: constant replaced with 4 (what the constant it referred to was) for compilation,
// pending removal
const auto closest_rcs = _router.node_db()->find_many_closest_to(target_addr, 4);
for (const auto& rc : closest_rcs)
{
const auto& rid = rc.router_id();
if (_router.router_profiling().IsBadForConnect(rid) || target_rid == rid
|| local_rid == rid)
continue;
neighbors += rid.bt_encode();
}
respond(serialize_response(
{{messages::STATUS_KEY, FindRouterMessage::RETRY_EXP}, {"TARGET", neighbors}}));
}
else
{
const auto closest_rc = _router.node_db()->find_closest_to(target_addr);
const auto& closest_rid = closest_rc.router_id();
const auto closest_key = dht::Key_t{closest_rid};
if (target_addr == closest_key)
{
if (closest_rc.expires_within_delta(llarp::time_now_ms()))
{
send_control_message(
target_rid,
"find_router",
FindRouterMessage::serialize(target_rid, false, false),
[respond = std::move(respond)](oxen::quic::message msg) mutable {
respond(msg.body_str());
});
}
else
{
respond(serialize_response({{"RC", closest_rc.view()}}));
}
}
else if (not is_iterative)
{
if ((closest_key ^ target_addr) < (local_key ^ target_addr))
{
send_control_message(
closest_rid,
"find_router",
FindRouterMessage::serialize(closest_rid, false, false),
[respond = std::move(respond)](oxen::quic::message msg) mutable {
respond(msg.body_str());
});
}
else
{
respond(serialize_response(
{{messages::STATUS_KEY, FindRouterMessage::RETRY_ITER},
{"TARGET", reinterpret_cast<const char*>(target_addr.data())}}));
}
}
else
{
respond(serialize_response(
{{messages::STATUS_KEY, FindRouterMessage::RETRY_NEW},
{"TARGET", reinterpret_cast<const char*>(closest_rid.data())}}));
}
}
}
void
LinkManager::handle_find_router_response(oxen::quic::message m)
{
if (m.timed_out)
{
log::info(link_cat, "FindRouterMessage timed out!");
return;
}
std::string status, payload;
try
{
oxenc::bt_dict_consumer btdc{m.body()};
if (m)
payload = btdc.require<std::string>("RC");
else
{
payload = btdc.require<std::string>("RECIPIENT");
status = btdc.require<std::string>("TARGET");
}
}
catch (const std::exception& e)
{
log::warning(link_cat, "Exception: {}", e.what());
return;
}
if (m)
{
_router.node_db()->put_rc_if_newer(RemoteRC{payload});
}
else
{
if (status == "ERROR")
{
log::info(link_cat, "FindRouterMessage failed with remote exception!");
// Do something smart here probably
return;
}
RouterID target{reinterpret_cast<uint8_t*>(payload.data())};
if (status == FindRouterMessage::RETRY_EXP)
{
log::info(link_cat, "FindRouterMessage failed, retrying as exploratory!");
send_control_message(
target, "find_router", FindRouterMessage::serialize(target, false, true));
}
else if (status == FindRouterMessage::RETRY_ITER)
{
log::info(link_cat, "FindRouterMessage failed, retrying as iterative!");
send_control_message(
target, "find_router", FindRouterMessage::serialize(target, true, false));
}
else if (status == FindRouterMessage::RETRY_NEW)
{
log::info(link_cat, "FindRouterMessage failed, retrying with new recipient!");
send_control_message(
target, "find_router", FindRouterMessage::serialize(target, false, false));
}
}
}
void
LinkManager::handle_find_router_error(oxen::quic::message&& m)
{
if (m.timed_out)
{
log::info(link_cat, "FindRouterMessage timed out!");
return;
}
std::string status, payload;
try
{
oxenc::bt_dict_consumer btdc{m.body()};
payload = btdc.require<std::string>("RECIPIENT");
status = btdc.require<std::string>("TARGET");
}
catch (const std::exception& e)
{
log::warning(link_cat, "Exception: {}", e.what());
return;
}
if (status == "ERROR")
{
log::info(link_cat, "FindRouterMessage failed with remote exception!");
// Do something smart here probably
return;
}
RouterID target{reinterpret_cast<uint8_t*>(payload.data())};
if (status == FindRouterMessage::RETRY_EXP)
{
log::info(link_cat, "FindRouterMessage failed, retrying as exploratory!");
send_control_message(
target, "find_router", FindRouterMessage::serialize(target, false, true));
}
else if (status == FindRouterMessage::RETRY_ITER)
{
log::info(link_cat, "FindRouterMessage failed, retrying as iterative!");
send_control_message(
target, "find_router", FindRouterMessage::serialize(target, true, false));
}
else if (status == FindRouterMessage::RETRY_NEW)
{
log::info(link_cat, "FindRouterMessage failed, retrying with new recipient!");
send_control_message(
target, "find_router", FindRouterMessage::serialize(target, false, false));
}
}
void
LinkManager::handle_publish_intro(std::string_view body, std::function<void(std::string)> respond)
{
@ -1612,7 +1392,7 @@ namespace llarp
if (not hop)
return;
// if terminal hop, payload should contain a request (e.g. "find_router"); handle and respond.
// if terminal hop, payload should contain a request (e.g. "find_name"); handle and respond.
if (hop->terminal_hop)
{
hop->onion(payload, nonce, false);

View File

@ -293,9 +293,6 @@ namespace llarp
handle_find_intro(std::string_view body, std::function<void(std::string)> respond); // relay
void
handle_publish_intro(std::string_view body, std::function<void(std::string)> respond); // relay
void
handle_find_router(
std::string_view body, std::function<void(std::string)> respond); // relay + path
// Path messages
void
@ -319,7 +316,6 @@ namespace llarp
void (LinkManager::*)(std::string_view body, std::function<void(std::string)> respond)>
path_requests = {
{"find_name"sv, &LinkManager::handle_find_name},
{"find_router"sv, &LinkManager::handle_find_router},
{"publish_intro"sv, &LinkManager::handle_publish_intro},
{"find_intro"sv, &LinkManager::handle_find_intro}};
/*
@ -332,14 +328,12 @@ namespace llarp
*/
// these requests are direct, i.e. not over a path;
// only "find_router" makes sense client->relay,
// the rest are relay->relay
// TODO: new RC fetch endpoint (which will be both client->relay and relay->relay)
std::unordered_map<
std::string_view,
void (LinkManager::*)(std::string_view body, std::function<void(std::string)> respond)>
direct_requests = {
{"find_router"sv, &LinkManager::handle_find_router},
{"publish_intro"sv, &LinkManager::handle_publish_intro},
{"find_intro"sv, &LinkManager::handle_find_intro}};
@ -355,7 +349,6 @@ namespace llarp
void handle_find_name_response(oxen::quic::message);
void handle_find_intro_response(oxen::quic::message);
void handle_publish_intro_response(oxen::quic::message);
void handle_find_router_response(oxen::quic::message);
// Path responses
void handle_path_latency_response(oxen::quic::message);
@ -368,18 +361,11 @@ namespace llarp
std::unordered_map<std::string, void (LinkManager::*)(oxen::quic::message)> rpc_responses = {
{"find_name", &LinkManager::handle_find_name_response},
{"find_router", &LinkManager::handle_find_router_response},
{"publish_intro", &LinkManager::handle_publish_intro_response},
{"find_intro", &LinkManager::handle_find_intro_response},
{"update_exit", &LinkManager::handle_update_exit_response},
{"obtain_exit", &LinkManager::handle_obtain_exit_response},
{"close_exit", &LinkManager::handle_close_exit_response}};
public:
// Public response functions and error handling functions invoked elsehwere. These take
// r-value references s.t. that message is taken out of calling scope
void
handle_find_router_error(oxen::quic::message&& m);
};
namespace link
@ -443,7 +429,6 @@ namespace llarp
std::unordered_map<std::string, void (llarp::link::LinkManager::*)(oxen::quic::message)>
rpc_commands = {
{"find_name", &handle_find_name},
{"find_router", &handle_find_router},
// ...
};

View File

@ -240,8 +240,7 @@ namespace llarp
bool
NodeDB::has_router(RouterID pk) const
{
return router.loop()->call_get(
[this, pk]() -> bool { return entries.find(pk) != entries.end(); });
return entries.count(pk);
}
std::optional<RemoteRC>

View File

@ -82,13 +82,6 @@ namespace llarp::path
"find_name", FindNameMessage::serialize(std::move(name)), std::move(func));
}
bool
Path::find_router(std::string rid, std::function<void(std::string)> func)
{
return send_path_control_message(
"find_router", FindRouterMessage::serialize(std::move(rid), false, false), std::move(func));
}
bool
Path::send_path_control_message(
std::string method, std::string body, std::function<void(std::string)> func)

View File

@ -176,9 +176,6 @@ namespace llarp
bool
find_name(std::string name, std::function<void(std::string)> func = nullptr);
bool
find_router(std::string rid, std::function<void(std::string)> func = nullptr);
bool
find_intro(
const dht::Key_t& location,

View File

@ -272,16 +272,6 @@ namespace llarp
_link_manager.connect_to(rc);
}
void
Router::lookup_router(RouterID rid, std::function<void(oxen::quic::message)> func)
{
_link_manager.send_control_message(
rid,
"find_router",
FindRouterMessage::serialize(std::move(rid), false, false),
std::move(func));
}
bool
Router::send_data_message(const RouterID& remote, std::string payload)
{
@ -997,14 +987,6 @@ namespace llarp
_node_db->Tick(now);
std::set<dht::Key_t> peer_keys;
for_each_connection(
[&peer_keys](link::Connection& conn) { peer_keys.emplace(conn.remote_rc.router_id()); });
_contacts->rc_nodes()->RemoveIf(
[&peer_keys](const dht::Key_t& k) -> bool { return peer_keys.count(k) == 0; });
paths.ExpirePaths(now);
// update tick timestamp

View File

@ -160,9 +160,6 @@ namespace llarp
void
for_each_connection(std::function<void(link::Connection&)> func);
void
lookup_router(RouterID rid, std::function<void(oxen::quic::message)> = nullptr);
void
connect_to(const RouterID& rid);

View File

@ -846,56 +846,6 @@ namespace llarp::service
}
}
void
Endpoint::EnsureRouterIsKnown(const RouterID& rid)
{
if (rid.IsZero())
return;
if (!router()->node_db()->has_router(rid))
{
lookup_router(rid);
}
}
bool
Endpoint::lookup_router(RouterID rid, std::function<void(RouterContact rc, bool success)> func)
{
(void)rid;
(void)func;
return false;
/* RC refactor pending, this will likely go away entirely
*
*
auto path = GetEstablishedPathClosestTo(rid);
auto response_cb = [func = std::move(func)](std::string resp, bool timeout) {
if (timeout)
func(RouterContact{}, false);
std::string payload;
try
{
oxenc::bt_dict_consumer btdc{resp};
payload = btdc.require<std::string>("RC");
}
catch (...)
{
log::warning(link_cat, "Failed to parse Find Router response!");
func(RouterContact{}, false);
return;
}
RouterContact result{std::move(payload)};
func(result, true);
};
path->find_router("find_router", std::move(response_cb));
return true;
*/
}
void
Endpoint::HandlePathBuilt(path::Path_ptr p)
{
@ -1279,7 +1229,8 @@ namespace llarp::service
this);
_state->snode_sessions[snode] = session;
}
EnsureRouterIsKnown(snode);
if (not router()->node_db()->has_router(snode))
return false;
auto range = nodeSessions.equal_range(snode);
auto itr = range.first;
while (itr != range.second)

View File

@ -229,14 +229,6 @@ namespace llarp
bool
ProcessDataMessage(std::shared_ptr<ProtocolMessage> msg);
/// ensure that we know a router, looks up if it doesn't
void
EnsureRouterIsKnown(const RouterID& router);
// "find router" via closest path
bool
lookup_router(RouterID router, std::function<void(RouterContact, bool)> func = nullptr);
// "find name"
void
lookup_name(std::string name, std::function<void(std::string, bool)> func = nullptr) override;

View File

@ -5,6 +5,7 @@
#include "endpoint_util.hpp"
#include "protocol_type.hpp"
#include <llarp/nodedb.hpp>
#include <llarp/router/router.hpp>
#include <algorithm>
@ -316,9 +317,6 @@ namespace llarp::service
}
}
}
// lookup router in intro if set and unknown
if (not next_intro.router.IsZero())
ep.EnsureRouterIsKnown(next_intro.router);
if (ReadyToSend())
{
@ -407,6 +405,18 @@ namespace llarp::service
std::vector<Introduction> intros = current_intro.intros;
// don't consider intros for which we don't have the RC for the pivot
auto itr = intros.begin();
while (itr != intros.end())
{
if (not ep.router()->node_db()->has_router(itr->router))
{
itr = intros.erase(itr);
continue;
}
itr++;
}
if (intros.size() > 1)
{
std::shuffle(intros.begin(), intros.end(), llarp::csrng);
@ -435,7 +445,6 @@ namespace llarp::service
{
if (ep.SnodeBlacklist().count(intro.router))
continue;
ep.EnsureRouterIsKnown(intro.router);
if (intro.ExpiresSoon(now))
continue;
if (next_intro != intro)