diff --git a/llarp/path/path.cpp b/llarp/path/path.cpp index 43761a923..c3585cff1 100644 --- a/llarp/path/path.cpp +++ b/llarp/path/path.cpp @@ -106,7 +106,7 @@ namespace llarp Path::HandleLRSM(uint64_t status, std::array< EncryptedFrame, 8 >& frames, AbstractRouter* r) { - uint64_t currentStatus = LR_StatusRecord::SUCCESS; + uint64_t currentStatus = status; size_t index = 0; while(index < hops.size()) @@ -143,7 +143,7 @@ namespace llarp ++index; } - if((currentStatus & LR_StatusRecord::SUCCESS) == 1) + if(currentStatus & LR_StatusRecord::SUCCESS) { llarp::LogDebug("LR_Status message processed, path build successful"); auto self = shared_from_this(); @@ -153,7 +153,7 @@ namespace llarp { r->routerProfiling().MarkPathFail(this); - llarp::LogInfo("LR_Status message processed, path build failed"); + llarp::LogDebug("LR_Status message processed, path build failed"); if(currentStatus & LR_StatusRecord::FAIL_TIMEOUT) { @@ -197,8 +197,9 @@ namespace llarp { llarp::LogDebug("Path build failed for an unspecified reason"); } - - EnterState(ePathFailed, r->Now()); + auto self = shared_from_this(); + r->logic()->queue_func( + [=]() { self->EnterState(ePathFailed, r->Now()); }); } // TODO: meaningful return value? @@ -211,6 +212,8 @@ namespace llarp if(st == ePathFailed) { _status = st; + m_PathSet->HandlePathBuildFailed(shared_from_this()); + return; } else if(st == ePathExpired && _status == ePathBuilding) { diff --git a/llarp/path/pathbuilder.cpp b/llarp/path/pathbuilder.cpp index 6a94a356c..e0d1b4b11 100644 --- a/llarp/path/pathbuilder.cpp +++ b/llarp/path/pathbuilder.cpp @@ -442,15 +442,29 @@ namespace llarp } void - Builder::HandlePathBuildTimeout(Path_ptr p) + Builder::HandlePathBuildFailed(Path_ptr p) + { + router->routerProfiling().MarkPathFail(p.get()); + PathSet::HandlePathBuildFailed(p); + DoPathBuildBackoff(); + } + + void + Builder::DoPathBuildBackoff() { // linear backoff static constexpr llarp_time_t MaxBuildInterval = 30 * 1000; buildIntervalLimit = std::min( MIN_PATH_BUILD_INTERVAL + buildIntervalLimit, MaxBuildInterval); + LogWarn(Name(), " build interval is now ", buildIntervalLimit); + } + + void + Builder::HandlePathBuildTimeout(Path_ptr p) + { router->routerProfiling().MarkPathFail(p.get()); PathSet::HandlePathBuildTimeout(p); - LogWarn(Name(), " build interval is now ", buildIntervalLimit); + DoPathBuildBackoff(); } void diff --git a/llarp/path/pathbuilder.hpp b/llarp/path/pathbuilder.hpp index 5d47b3801..9d17ea561 100644 --- a/llarp/path/pathbuilder.hpp +++ b/llarp/path/pathbuilder.hpp @@ -27,6 +27,9 @@ namespace llarp UrgentBuild(llarp_time_t now) const; private: + void + DoPathBuildBackoff(); + bool DoUrgentBuildAlignedTo(const RouterID remote, std::vector< RouterContact >& hops); @@ -115,6 +118,9 @@ namespace llarp virtual void HandlePathBuildTimeout(Path_ptr p) override; + + virtual void + HandlePathBuildFailed(Path_ptr p) override; }; using Builder_ptr = std::shared_ptr< Builder >; diff --git a/llarp/path/pathset.cpp b/llarp/path/pathset.cpp index a752ed4f6..122948a4f 100644 --- a/llarp/path/pathset.cpp +++ b/llarp/path/pathset.cpp @@ -291,6 +291,14 @@ namespace llarp m_BuildStats.timeouts++; } + void + PathSet::HandlePathBuildFailed(Path_ptr p) + { + LogWarn(Name(), " path build ", p->HopsString(), " failed"); + m_BuildStats.fails ++; + } + + void PathSet::PathBuildStarted(Path_ptr p) { diff --git a/llarp/path/pathset.hpp b/llarp/path/pathset.hpp index e8ddd6e5c..1acb8e7ca 100644 --- a/llarp/path/pathset.hpp +++ b/llarp/path/pathset.hpp @@ -128,6 +128,9 @@ namespace llarp virtual void HandlePathBuildTimeout(Path_ptr path); + virtual void + HandlePathBuildFailed(Path_ptr path); + virtual void PathBuildStarted(Path_ptr path);