#pragma once #include #include #include #include #include #include #include struct llarp_dht_context; namespace llarp { class NodeDB; class EventLoop; namespace dht { struct AbstractDHTMessageHandler; } // namespace dht namespace service { struct Context; } // namespace service struct Contacts; struct LinkManager; struct RouterContact; enum class RCRequestResult { Success, InvalidRouter, RouterNotFound, BadRC }; using RCRequestCallback = std::function; struct RCLookupHandler { public: using worker_func = std::function)>; using callback_que = std::list; ~RCLookupHandler() = default; void add_valid_router(const RouterID& router) EXCLUDES(_mutex); void remove_valid_router(const RouterID& router) EXCLUDES(_mutex); void set_router_whitelist( const std::vector& whitelist, const std::vector& greylist, const std::vector& greenlist ) EXCLUDES(_mutex); bool has_received_whitelist() const; void get_rc(const RouterID& router, RCRequestCallback callback, bool forceLookup = false) EXCLUDES(_mutex); bool is_path_allowed(const RouterID& remote) const EXCLUDES(_mutex); bool is_session_allowed(const RouterID& remote) const EXCLUDES(_mutex); bool is_grey_listed(const RouterID& remote) const EXCLUDES(_mutex); // "greenlist" = new routers (i.e. "green") that aren't fully funded yet bool is_green_listed(const RouterID& remote) const EXCLUDES(_mutex); // registered just means that there is at least an operator stake, but doesn't require the node // be fully funded, active, or not decommed. (In other words: it is any of the white, grey, or // green list). bool is_registered(const RouterID& remote) const EXCLUDES(_mutex); bool check_rc(const RouterContact& rc) const; bool get_random_whitelist_router(RouterID& router) const EXCLUDES(_mutex); bool check_renegotiate_valid(RouterContact newrc, RouterContact oldrc); void periodic_update(llarp_time_t now); void explore_network(); size_t num_strict_connect_routers() const; void init( std::shared_ptr contacts, std::shared_ptr nodedb, std::shared_ptr loop, worker_func dowork, LinkManager* linkManager, service::Context* hiddenServiceContext, const std::unordered_set& strictConnectPubkeys, const std::set& bootstrapRCList, bool useWhitelist_arg, bool isServiceNode_arg); std::unordered_set whitelist() const { util::Lock lock{_mutex}; return router_whitelist; } private: void handle_dht_lookup_result(RouterID remote, const std::vector& results); bool has_pending_lookup(RouterID remote) const EXCLUDES(_mutex); bool is_remote_in_bootstrap(const RouterID& remote) const; void finalize_request(const RouterID& router, const RouterContact* const rc, RCRequestResult result) EXCLUDES(_mutex); mutable util::Mutex _mutex; // protects pendingCallbacks, whitelistRouters std::shared_ptr contacts = nullptr; std::shared_ptr node_db; std::shared_ptr loop; worker_func work_func = nullptr; service::Context* hidden_service_context = nullptr; LinkManager* link_manager = nullptr; /// explicit whitelist of routers we will connect to directly (not for /// service nodes) std::unordered_set strict_connect_pubkeys; std::set bootstrap_rc_list; std::unordered_set boostrap_rid_list; std::unordered_map pending_callbacks GUARDED_BY(_mutex); bool useWhitelist = false; bool isServiceNode = false; // whitelist = active routers std::unordered_set router_whitelist GUARDED_BY(_mutex); // greylist = fully funded, but decommissioned routers std::unordered_set router_greylist GUARDED_BY(_mutex); // greenlist = registered but not fully-staked routers std::unordered_set router_greenlist GUARDED_BY(_mutex); using TimePoint = std::chrono::steady_clock::time_point; std::unordered_map router_lookup_times; }; } // namespace llarp