handle path death better

pull/477/head
Jeff Becker 5 years ago
parent d14e214e28
commit b849ff9a94
No known key found for this signature in database
GPG Key ID: F357B3B42F6F9B05

@ -25,6 +25,12 @@ namespace llarp
{
}
void
BaseSession::HandlePathDied(path::Path* p)
{
RemovePath(p);
}
util::StatusObject
BaseSession::ExtractStatus() const
{

@ -32,6 +32,9 @@ namespace llarp
util::StatusObject
ExtractStatus() const override;
void
HandlePathDied(llarp::path::Path* p) override;
bool
SelectHop(llarp_nodedb* db, const RouterContact& prev, RouterContact& cur,
size_t hop, llarp::path::PathRole roles) override;

@ -462,7 +462,7 @@ namespace llarp
void
Path::EnterState(PathStatus st, llarp_time_t now)
{
if(st == ePathTimeout)
if(st == ePathTimeout && _status == ePathBuilding)
{
m_PathSet->HandlePathBuildTimeout(this);
}
@ -475,6 +475,11 @@ namespace llarp
{
LogInfo("path ", Name(), " is built, took ", now - buildStarted, " ms");
}
else if(st == ePathTimeout && _status == ePathEstablished)
{
m_PathSet->HandlePathDied(this);
return;
}
_status = st;
}

@ -231,6 +231,7 @@ namespace llarp
{
Lock_t l(&m_PathsMutex);
m_Paths.erase({path->Upstream(), path->RXID()});
delete path;
}
Path*

@ -81,6 +81,10 @@ namespace llarp
virtual void
HandlePathBuildTimeout(__attribute__((unused)) Path* path);
/// a path died now what?
virtual void
HandlePathDied(Path* path) = 0;
bool
GetNewestIntro(service::Introduction& intro) const;

@ -1050,25 +1050,80 @@ namespace llarp
}
void
Endpoint::HandlePathDead(void* user)
Endpoint::HandlePathDied(path::Path* p)
{
Endpoint* self = static_cast< Endpoint* >(user);
self->RegenAndPublishIntroSet(self->Now(), true);
RemovePath(p);
RegenAndPublishIntroSet(Now(), true);
}
void
Endpoint::OutboundContext::HandlePathDied(path::Path* p)
{
const RouterID endpoint(p->Endpoint());
RemovePath(p);
// if a path to our current intro died...
if(endpoint == remoteIntro.router)
{
// figure out how many paths to this router we have
size_t num = 0;
ForEachPath([&](path::Path* p) {
if(p->Endpoint() == endpoint && p->IsReady())
++num;
});
// if we have more than two then we are probably fine
if(num > 2)
return;
// if we have one working one ...
if(num == 1)
{
num = 0;
ForEachPath([&](path::Path* p) {
if(p->Endpoint() == endpoint)
++num;
});
// if we have 2 or more established or pending don't do anything
if(num > 2)
return;
BuildOneAlignedTo(endpoint);
}
else if(num == 0)
{
// we have no paths to this router right now
// hop off it
Introduction picked;
// get the latest intro that isn't on that endpoint
for(const auto& intro : currentIntroSet.I)
{
if(intro.router == endpoint)
continue;
if(intro.expiresAt > picked.expiresAt)
picked = intro;
}
// we got nothing
if(picked.router.IsZero())
{
UpdateIntroSet(true);
return;
}
m_NextIntro = picked;
// check if we have a path to this router
num = 0;
ForEachPath([&](path::Path* p) {
if(p->Endpoint() == m_NextIntro.router)
++num;
});
// build a path if one isn't already pending build or established
if(num == 0)
BuildOneAlignedTo(m_NextIntro.router);
SwapIntros();
}
}
}
bool
Endpoint::CheckPathIsDead(path::Path*, llarp_time_t dlt)
{
if(dlt <= 30000)
return false;
RouterLogic()->call_later(
{100, this, [](void* u, uint64_t, uint64_t left) {
if(left)
return;
HandlePathDead(u);
}});
return true;
return dlt > 20000;
}
bool

@ -102,6 +102,9 @@ namespace llarp
bool
ShouldPublishDescriptors(llarp_time_t now) const override;
void
HandlePathDied(path::Path* p) override;
void
EnsureReplyPath(const ServiceInfo& addr);
@ -283,6 +286,9 @@ namespace llarp
bool
HandleDataDrop(path::Path* p, const PathID_t& dst, uint64_t s);
void
HandlePathDied(path::Path* p) override;
/// set to true if we are updating the remote introset right now
bool updatingIntroSet;

Loading…
Cancel
Save