#pragma once #include "endpoint_types.hpp" namespace llarp { namespace service { struct EndpointUtil { static void ExpireSNodeSessions(llarp_time_t now, SNodeSessions& sessions); static void ExpirePendingTx(llarp_time_t now, PendingLookups& lookups); static void ExpirePendingRouterLookups(llarp_time_t now, PendingRouters& routers); static void DeregisterDeadSessions(llarp_time_t now, Sessions& sessions); static void TickRemoteSessions( llarp_time_t now, Sessions& remoteSessions, Sessions& deadSessions, ConvoMap& sessions); static void ExpireConvoSessions(llarp_time_t now, ConvoMap& sessions); static void StopRemoteSessions(Sessions& remoteSessions); static void StopSnodeSessions(SNodeSessions& sessions); static bool HasPathToService(const Address& addr, const Sessions& remoteSessions); static bool GetConvoTagsForService( const ConvoMap& sessions, const Address& addr, std::set& tags); }; template static path::Path::UniqueEndpointSet_t GetManyPathsWithUniqueEndpoints( Endpoint_t* ep, size_t N, std::optional maybeLocation = std::nullopt, size_t tries = 10) { std::unordered_set exclude; path::Path::UniqueEndpointSet_t paths; do { --tries; path::Path_ptr path; if (maybeLocation) { path = ep->GetEstablishedPathClosestTo(RouterID{maybeLocation->as_array()}, exclude); } else { path = ep->PickRandomEstablishedPath(); } if (path and path->IsReady()) { paths.emplace(path); exclude.insert(path->Endpoint()); } } while (tries > 0 and paths.size() < N); return paths; } } // namespace service } // namespace llarp