try better handover logic

pull/20/head
Jeff Becker 6 years ago
parent a3001dfe1d
commit f19f78b573
No known key found for this signature in database
GPG Key ID: F357B3B42F6F9B05

@ -339,13 +339,14 @@ namespace llarp
{ {
txitr->second->SendReply(); txitr->second->SendReply();
tx.erase(txitr); tx.erase(txitr);
itr = waiting.erase(itr);
continue;
} }
} }
++itr; ++itr;
} }
if(sendreply)
waiting.erase(key);
if(removeTimeouts) if(removeTimeouts)
timeouts.erase(key); timeouts.erase(key);
} }

@ -289,6 +289,10 @@ namespace llarp
Name() const; Name() const;
private: private:
/// swap remoteIntro with next intro
void
SwapIntros();
void void
OnGeneratedIntroFrame(AsyncKeyExchange* k, PathID_t p); OnGeneratedIntroFrame(AsyncKeyExchange* k, PathID_t p);
@ -297,6 +301,7 @@ namespace llarp
uint64_t m_UpdateIntrosetTX = 0; uint64_t m_UpdateIntrosetTX = 0;
IntroSet currentIntroSet; IntroSet currentIntroSet;
Introduction m_NextIntro;
std::unordered_map< Introduction, llarp_time_t, Introduction::Hash > std::unordered_map< Introduction, llarp_time_t, Introduction::Hash >
m_BadIntros; m_BadIntros;
llarp_time_t lastShift = 0; llarp_time_t lastShift = 0;

@ -133,8 +133,8 @@ namespace llarp
void void
pathbuilder_generated_keys(AsyncPathKeyExchangeContext< path::Builder >* ctx) pathbuilder_generated_keys(AsyncPathKeyExchangeContext< path::Builder >* ctx)
{ {
auto remote = ctx->path->Upstream(); RouterID remote = ctx->path->Upstream();
auto router = ctx->user->router; auto router = ctx->user->router;
if(!router->SendToOrQueue(remote, &ctx->LRCM)) if(!router->SendToOrQueue(remote, &ctx->LRCM))
{ {
llarp::LogError("failed to send LRCM"); llarp::LogError("failed to send LRCM");

@ -900,22 +900,34 @@ namespace llarp
return false; return false;
} }
Endpoint::OutboundContext::OutboundContext(const IntroSet& intro, Endpoint::OutboundContext::OutboundContext(const IntroSet& introset,
Endpoint* parent) Endpoint* parent)
: path::Builder(parent->m_Router, parent->m_Router->dht, 3, 4) : path::Builder(parent->m_Router, parent->m_Router->dht, 3, 4)
, SendContext(intro.A, {}, this, parent) , SendContext(introset.A, {}, this, parent)
, currentIntroSet(intro) , currentIntroSet(introset)
{ {
updatingIntroSet = false; updatingIntroSet = false;
if(intro.I.size()) for(const auto intro : introset.I)
remoteIntro = intro.I[0]; {
if(intro.expiresAt > m_NextIntro.expiresAt)
{
m_NextIntro = intro;
remoteIntro = intro;
}
}
} }
Endpoint::OutboundContext::~OutboundContext() Endpoint::OutboundContext::~OutboundContext()
{ {
} }
void
Endpoint::OutboundContext::SwapIntros()
{
remoteIntro = m_NextIntro;
}
bool bool
Endpoint::OutboundContext::OnIntroSetUpdate(const Address& addr, Endpoint::OutboundContext::OnIntroSetUpdate(const Address& addr,
const IntroSet* i) const IntroSet* i)
@ -934,8 +946,10 @@ namespace llarp
{ {
llarp::LogWarn("failed to pick new intro during introset update"); llarp::LogWarn("failed to pick new intro during introset update");
} }
if(GetPathByRouter(remoteIntro.router) == nullptr) if(GetPathByRouter(m_NextIntro.router) == nullptr)
BuildOneAlignedTo(remoteIntro.router); BuildOneAlignedTo(m_NextIntro.router);
else
SwapIntros();
} }
updatingIntroSet = false; updatingIntroSet = false;
return true; return true;
@ -944,7 +958,8 @@ namespace llarp
bool bool
Endpoint::OutboundContext::ReadyToSend() const Endpoint::OutboundContext::ReadyToSend() const
{ {
return GetPathByRouter(remoteIntro.router) != nullptr; return (!remoteIntro.router.IsZero())
&& GetPathByRouter(remoteIntro.router) != nullptr;
} }
bool bool
@ -1087,10 +1102,10 @@ namespace llarp
continue; continue;
} }
auto itr = m_BadIntros.find(intro); auto itr = m_BadIntros.find(intro);
if(itr == m_BadIntros.end() && intro.router == remoteIntro.router) if(itr == m_BadIntros.end() && intro.router == m_NextIntro.router)
{ {
shiftedIntro = true; shiftedIntro = true;
remoteIntro = intro; m_NextIntro = intro;
break; break;
} }
} }
@ -1105,9 +1120,9 @@ namespace llarp
if(itr == m_BadIntros.end()) if(itr == m_BadIntros.end())
{ {
// TODO: this should always be true but idk if it really is // TODO: this should always be true but idk if it really is
shiftedRouter = remoteIntro.router != intro.router; shiftedRouter = m_NextIntro.router != intro.router;
shiftedIntro = true; shiftedIntro = true;
remoteIntro = intro; m_NextIntro = intro;
break; break;
} }
} }
@ -1115,7 +1130,7 @@ namespace llarp
if(shiftedRouter) if(shiftedRouter)
{ {
lastShift = now; lastShift = now;
ManualRebuild(1); BuildOneAlignedTo(m_NextIntro.router);
} }
return shiftedIntro; return shiftedIntro;
} }
@ -1136,7 +1151,7 @@ namespace llarp
if(m_BadIntros.find(intro) == m_BadIntros.end() if(m_BadIntros.find(intro) == m_BadIntros.end()
&& remoteIntro.router == intro.router) && remoteIntro.router == intro.router)
{ {
remoteIntro = intro; m_NextIntro = intro;
return true; return true;
} }
} }
@ -1145,13 +1160,13 @@ namespace llarp
m_Endpoint->EnsureRouterIsKnown(intro.router); m_Endpoint->EnsureRouterIsKnown(intro.router);
if(intro.ExpiresSoon(now)) if(intro.ExpiresSoon(now))
continue; continue;
if(m_BadIntros.find(intro) == m_BadIntros.end() && remoteIntro != intro) if(m_BadIntros.find(intro) == m_BadIntros.end() && m_NextIntro != intro)
{ {
shifted = intro.router != remoteIntro.router shifted = intro.router != m_NextIntro.router
|| (now < intro.expiresAt || (now < intro.expiresAt
&& intro.expiresAt - now && intro.expiresAt - now
> 10 * 1000); // TODO: hardcoded value > 10 * 1000); // TODO: hardcoded value
remoteIntro = intro; m_NextIntro = intro;
success = true; success = true;
break; break;
} }
@ -1159,7 +1174,7 @@ namespace llarp
if(shifted) if(shifted)
{ {
lastShift = now; lastShift = now;
ManualRebuild(1); BuildOneAlignedTo(m_NextIntro.router);
} }
return success; return success;
} }
@ -1372,6 +1387,14 @@ namespace llarp
// shift intro if it expires "soon" // shift intro if it expires "soon"
ShiftIntroduction(); ShiftIntroduction();
} }
if(remoteIntro != m_NextIntro)
{
if(GetPathByRouter(m_NextIntro.router) != nullptr)
{
// we can safely set remoteIntro to the next one
SwapIntros();
}
}
// lookup router in intro if set and unknown // lookup router in intro if set and unknown
if(!remoteIntro.router.IsZero()) if(!remoteIntro.router.IsZero())
m_Endpoint->EnsureRouterIsKnown(remoteIntro.router); m_Endpoint->EnsureRouterIsKnown(remoteIntro.router);
@ -1395,11 +1418,11 @@ namespace llarp
const RouterContact& prev, const RouterContact& prev,
RouterContact& cur, size_t hop) RouterContact& cur, size_t hop)
{ {
if(remoteIntro.router.IsZero()) if(m_NextIntro.router.IsZero())
return false; return false;
if(hop == numHops - 1) if(hop == numHops - 1)
{ {
if(llarp_nodedb_get_rc(db, remoteIntro.router, cur)) if(llarp_nodedb_get_rc(db, m_NextIntro.router, cur))
{ {
return true; return true;
} }
@ -1409,8 +1432,8 @@ namespace llarp
llarp::LogError( llarp::LogError(
"cannot build aligned path, don't have router for " "cannot build aligned path, don't have router for "
"introduction ", "introduction ",
remoteIntro); m_NextIntro);
m_Endpoint->EnsureRouterIsKnown(remoteIntro.router); m_Endpoint->EnsureRouterIsKnown(m_NextIntro.router);
return false; return false;
} }
} }

Loading…
Cancel
Save