Untangle Endpoint::LookupServiceAsync

- .snodes don't need to support SRV records, so remove that
- untangle the mess of captured lambdas capturing other lambdas
  capturing other lambdas; we still need a chain of nested lambdas
  because we have a chain of callbacked events, but hiding the nesting
  by capturing them in other lambdas didn't improve anything.
pull/2218/head
Jason Rhinelander 7 months ago committed by dr7ana
parent fa4471f566
commit 8b70e0ad2b

@ -200,106 +200,63 @@ namespace llarp::service
});
}
// TODO: revisit once SRVRecords are straightened out
void
Endpoint::LookupServiceAsync(
std::string name,
std::string service,
std::function<void(std::vector<dns::SRVData>)> resultHandler)
{
// handles when we aligned to a loki address
auto handleGotPathToService = [resultHandler, service, this](auto addr) {
// we can probably get this info before we have a path to them but we do this after we
// have a path so when we send the response back they can send shit to them immediately
const auto& container = _state->remote_sessions;
if (auto itr = container.find(addr); itr != container.end())
{
// parse the stuff we need from this guy
resultHandler(itr->second->GetCurrentIntroSet().GetMatchingSRVRecords(service));
return;
}
resultHandler({});
};
// handles when we resolved a .snode
auto handleResolvedSNodeName = [resultHandler, nodedb = router()->node_db()](auto router_id) {
std::vector<dns::SRVData> result{};
if (auto maybe_rc = nodedb->get_rc(router_id))
{
// result = maybe_rc->srvRecords; // TODO: RouterContact has no SRV records
}
resultHandler(std::move(result));
};
// handles when we got a path to a remote thing
auto handleGotPathTo = [handleGotPathToService, handleResolvedSNodeName, resultHandler](
auto maybe_tag, auto address) {
if (not maybe_tag)
{
resultHandler({});
return;
}
if (auto* addr = std::get_if<Address>(&address))
{
// .loki case
handleGotPathToService(*addr);
}
else if (auto* router_id = std::get_if<RouterID>(&address))
{
// .snode case
handleResolvedSNodeName(*router_id);
}
else
{
// fallback case
// XXX: never should happen but we'll handle it anyways
resultHandler({});
}
};
// handles when we know a long address of a remote resource
auto handleGotAddress = [resultHandler, handleGotPathTo, this](AddressVariant_t address) {
// we will attempt a build to whatever we looked up
const auto result = EnsurePathTo(
address,
[address, handleGotPathTo](auto maybe_tag) { handleGotPathTo(maybe_tag, address); },
PathAlignmentTimeout());
// on path build start fail short circuit
if (not result)
resultHandler({});
};
// look up this name async and start the entire chain of events
lookup_name(name, [handleGotAddress, resultHandler](oxen::quic::message m) mutable {
if (m)
{
std::string name;
try
{
oxenc::bt_dict_consumer btdc{m.body()};
name = btdc.require<std::string>("NAME");
}
catch (...)
{
log::warning(link_cat, "Failed to parse find name response!");
throw;
}
// A lookup goes through a chain of events:
// - see if the name is ONS, and if so resolve it to a ADDR.loki
// - once we've resolved to ADDR.loki then initiate a path to it
// - once we have a path, consult the remote's introset to pull out the SRV records
// If we fail along the way (e.g. it's a .snode, we can't build a path, or whatever else) then
// we invoke the resultHandler with an empty vector.
lookup_name(
name, [this, resultHandler, service = std::move(service)](oxen::quic::message m) mutable {
if (!m)
return resultHandler({});
if (auto saddr = service::Address(); saddr.FromString(name))
handleGotAddress(saddr);
std::string name;
try
{
oxenc::bt_dict_consumer btdc{m.body()};
name = btdc.require<std::string>("NAME");
}
catch (...)
{
log::warning(link_cat, "Failed to parse find name response!");
throw;
}
if (auto rid = RouterID(); rid.FromString(name))
handleGotAddress(rid);
}
else
{
resultHandler({});
}
});
auto saddr = service::Address();
if (!saddr.FromString(name))
return resultHandler({}); // Not a regular ADDR.loki so doesn't support SRV
// initiate path build
const auto build_started = EnsurePathTo(
saddr,
[this, address = std::move(saddr), resultHandler, service = std::move(service)](
auto maybe_tag) {
if (not maybe_tag)
return resultHandler({});
// we can probably get this info before we have a path to them but we do this after
// we have a path so when we send the DNS response back they can talk to them
// immediately
const auto& container = _state->remote_sessions;
if (auto itr = container.find(address); itr != container.end())
// parse the stuff we need from this guy
resultHandler(itr->second->GetCurrentIntroSet().GetMatchingSRVRecords(service));
else
resultHandler({});
},
PathAlignmentTimeout());
// on path build start fail short circuit
if (not build_started)
resultHandler({});
});
}
bool

Loading…
Cancel
Save