@ -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