diff --git a/llarp/exit/session.cpp b/llarp/exit/session.cpp index f35c3a0f0..f4aca95ce 100644 --- a/llarp/exit/session.cpp +++ b/llarp/exit/session.cpp @@ -32,11 +32,15 @@ namespace llarp BaseSession::ShouldBuildMore(llarp_time_t now) const { const size_t expect = (1 + (m_NumPaths / 2)); - if(NumPathsExistingAt(now + (10 * 1000)) < expect) - return path::Builder::ShouldBuildMore(now); + // check 30 seconds into the future and see if we need more paths + const llarp_time_t future = now + (30 * 1000); + if(NumPathsExistingAt(future) < expect) + return llarp::randint() % 4 == 0; // 25% chance for build if we will run out soon + // if we don't have the expended number of paths right now try building some if the cooldown timer isn't hit if(AvailablePaths(llarp::path::ePathRoleExit) < expect) - return path::Builder::ShouldBuildMore(now); - return false; + return !path::Builder::BuildCooldownHit(now); + // maintain regular number of paths + return path::Builder::ShouldBuildMore(now); } bool @@ -179,25 +183,30 @@ namespace llarp { auto now = router->Now(); auto path = PickRandomEstablishedPath(llarp::path::ePathRoleExit); - if(!path) + if(path) { - // discard for(auto& item : m_Upstream) - item.second.clear(); - return false; - } - for(auto& item : m_Upstream) - { - auto& queue = item.second; - while(queue.size()) { - auto& msg = queue.front(); - msg.S = path->NextSeqNo(); - if(path->SendRoutingMessage(&msg, router)) - m_LastUse = now; - queue.pop_front(); + auto& queue = item.second; + while(queue.size()) + { + auto& msg = queue.front(); + msg.S = path->NextSeqNo(); + if(path->SendRoutingMessage(&msg, router)) + m_LastUse = now; + queue.pop_front(); + } } } + else + { + if(m_Upstream.size()) + llarp::LogWarn("no path for exit session"); + // discard upstream + for(auto& item : m_Upstream) + item.second.clear(); + m_Upstream.clear(); + } while(m_Downstream.size()) { if(m_WritePacket) diff --git a/llarp/pathbuilder.cpp b/llarp/pathbuilder.cpp index e121989c2..8ee359598 100644 --- a/llarp/pathbuilder.cpp +++ b/llarp/pathbuilder.cpp @@ -216,11 +216,17 @@ namespace llarp return enckey; } + bool + Builder::BuildCooldownHit(llarp_time_t now) const + { + return now < lastBuild + || now - lastBuild < buildIntervalLimit; + } + bool Builder::ShouldBuildMore(llarp_time_t now) const { - return llarp::path::PathSet::ShouldBuildMore(now) && now > lastBuild - && now - lastBuild > buildIntervalLimit; + return PathSet::ShouldBuildMore(now) && !BuildCooldownHit(now); } void diff --git a/llarp/pathbuilder.hpp b/llarp/pathbuilder.hpp index 91e14f991..8719a0fde 100644 --- a/llarp/pathbuilder.hpp +++ b/llarp/pathbuilder.hpp @@ -47,6 +47,10 @@ namespace llarp virtual bool ShouldBuildMore(llarp_time_t now) const override; + /// return true if we hit our soft limit for building paths too fast + bool + BuildCooldownHit(llarp_time_t now) const; + virtual bool Stop() override; diff --git a/llarp/pathset.cpp b/llarp/pathset.cpp index 7b88af693..28e876b9b 100644 --- a/llarp/pathset.cpp +++ b/llarp/pathset.cpp @@ -279,7 +279,7 @@ namespace llarp void PathSet::HandlePathBuildTimeout(Path* p) { - llarp::LogInfo("path ", p->Name(), " has timed out"); + llarp::LogInfo("path build for ", p->Name(), " has timed out"); } bool