#pragma once #include "pathset.hpp" #include #include #include #include namespace llarp { namespace path { // milliseconds waiting between builds on a path per router static constexpr auto MIN_PATH_BUILD_INTERVAL = 500ms; static constexpr auto PATH_BUILD_RATE = 100ms; /// limiter for path builds /// prevents overload and such class BuildLimiter { util::DecayingHashSet m_EdgeLimiter; public: /// attempt a build /// return true if we are allowed to continue bool Attempt(const RouterID& router); /// decay limit entries void Decay(llarp_time_t now); /// return true if this router is currently limited bool Limited(const RouterID& router) const; }; struct Builder : public PathSet { private: llarp_time_t m_LastWarn = 0s; protected: /// flag for PathSet::Stop() std::atomic _run; virtual bool UrgentBuild(llarp_time_t now) const; /// return true if we hit our soft limit for building paths too fast on a first hop bool BuildCooldownHit(RouterID edge) const; private: void DoPathBuildBackoff(); public: AbstractRouter* const m_router; SecretKey enckey; size_t numHops; llarp_time_t lastBuild = 0s; llarp_time_t buildIntervalLimit = MIN_PATH_BUILD_INTERVAL; /// construct Builder(AbstractRouter* p_router, size_t numDesiredPaths, size_t numHops); virtual ~Builder() = default; util::StatusObject ExtractStatus() const; bool ShouldBuildMore(llarp_time_t now) const override; /// should we bundle RCs in builds? virtual bool ShouldBundleRC() const = 0; void ResetInternalState() override; /// return true if we hit our soft limit for building paths too fast bool BuildCooldownHit(llarp_time_t now) const; /// get roles for this path builder virtual PathRole GetRoles() const { return ePathRoleAny; } BuildStats CurrentBuildStats() const { return m_BuildStats; } bool Stop() override; bool IsStopped() const override; bool ShouldRemove() const override; llarp_time_t Now() const override; virtual void Tick(llarp_time_t now) override; void BuildOne(PathRole roles = ePathRoleAny) override; bool BuildOneAlignedTo(const RouterID endpoint) override; std::optional> GetHopsAlignedToForBuild(RouterID endpoint, const std::set& exclude = {}); void Build(std::vector hops, PathRole roles = ePathRoleAny) override; /// pick a first hop std::optional SelectFirstHop(const std::set& exclude = {}) const; virtual std::optional> GetHopsForBuild() override; void ManualRebuild(size_t N, PathRole roles = ePathRoleAny); virtual const SecretKey& GetTunnelEncryptionSecretKey() const; virtual void HandlePathBuilt(Path_ptr p) override; virtual void HandlePathBuildTimeout(Path_ptr p) override; virtual void HandlePathBuildFailedAt(Path_ptr p, RouterID hop) override; }; using Builder_ptr = std::shared_ptr; } // namespace path } // namespace llarp