prevent bizare half open state. (#1754)

* attempt path timeout bullshittery fix

* make sure ServiceInfo always has its address set up

* do not copy intros in constuctor, ammend logging and
add assert
pull/1769/head
Jeff 3 years ago committed by GitHub
parent 8989910881
commit 1846c3e3d8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -110,7 +110,7 @@ namespace llarp
llarp_time_t llarp_time_t
Now() const override; Now() const override;
void virtual void
Tick(llarp_time_t now) override; Tick(llarp_time_t now) override;
void void

@ -470,6 +470,7 @@ namespace llarp
if (itr == Sessions().end()) if (itr == Sessions().end())
return false; return false;
si = itr->second.remote; si = itr->second.remote;
si.UpdateAddr();
return true; return true;
} }
@ -1100,13 +1101,14 @@ namespace llarp
bool bool
Endpoint::HandleDataMessage( Endpoint::HandleDataMessage(
path::Path_ptr, const PathID_t from, std::shared_ptr<ProtocolMessage> msg) path::Path_ptr p, const PathID_t from, std::shared_ptr<ProtocolMessage> msg)
{ {
PutSenderFor(msg->tag, msg->sender, true); PutSenderFor(msg->tag, msg->sender, true);
Introduction intro = msg->introReply; Introduction intro = msg->introReply;
if (HasInboundConvo(msg->sender.Addr())) if (HasInboundConvo(msg->sender.Addr()))
{ {
intro.pathID = from; intro.pathID = from;
intro.router = p->Endpoint();
} }
PutReplyIntroFor(msg->tag, intro); PutReplyIntroFor(msg->tag, intro);
ConvoTagRX(msg->tag); ConvoTagRX(msg->tag);

@ -13,7 +13,7 @@ namespace llarp
{ {
struct Introduction struct Introduction
{ {
PubKey router; RouterID router;
PathID_t pathID; PathID_t pathID;
llarp_time_t latency = 0s; llarp_time_t latency = 0s;
llarp_time_t expiresAt = 0s; llarp_time_t expiresAt = 0s;

@ -54,7 +54,7 @@ namespace llarp
return true; return true;
} }
constexpr auto OutboundContextNumPaths = 2; constexpr auto OutboundContextNumPaths = 4;
OutboundContext::OutboundContext(const IntroSet& introset, Endpoint* parent) OutboundContext::OutboundContext(const IntroSet& introset, Endpoint* parent)
: path::Builder{parent->Router(), OutboundContextNumPaths, parent->numHops} : path::Builder{parent->Router(), OutboundContextNumPaths, parent->numHops}
@ -64,12 +64,17 @@ namespace llarp
, currentIntroSet{introset} , currentIntroSet{introset}
{ {
assert(not introset.intros.empty());
updatingIntroSet = false; updatingIntroSet = false;
for (const auto& intro : introset.intros)
// pick random first intro
auto it = introset.intros.begin();
if (introset.intros.size() > 1)
{ {
if (m_NextIntro.latency == 0s or m_NextIntro.latency > intro.latency) CSRNG rng{};
m_NextIntro = intro; it += std::uniform_int_distribution<size_t>{0, introset.intros.size() - 1}(rng);
} }
m_NextIntro = *it;
currentConvoTag.Randomize(); currentConvoTag.Randomize();
lastShift = Now(); lastShift = Now();
// add send and connect timeouts to the parent endpoints path alignment timeout // add send and connect timeouts to the parent endpoints path alignment timeout
@ -333,6 +338,7 @@ namespace llarp
Encrypted<64> tmp; Encrypted<64> tmp;
tmp.Randomize(); tmp.Randomize();
SendPacketToRemote(tmp, ProtocolType::Control); SendPacketToRemote(tmp, ProtocolType::Control);
m_LastKeepAliveAt = Now();
} }
bool bool
@ -348,7 +354,10 @@ namespace llarp
// expunge // expunge
SharedSecret discardme; SharedSecret discardme;
if (not m_DataHandler->GetCachedSessionKeyFor(currentConvoTag, discardme)) if (not m_DataHandler->GetCachedSessionKeyFor(currentConvoTag, discardme))
{
LogError(Name(), " no cached key after sending intro, we are in a fugged state, oh no");
return true; return true;
}
} }
if (m_GotInboundTraffic and m_LastInboundTraffic + sendTimeout <= now) if (m_GotInboundTraffic and m_LastInboundTraffic + sendTimeout <= now)
@ -404,21 +413,33 @@ namespace llarp
m_ReadyHooks.clear(); m_ReadyHooks.clear();
} }
if (m_LastInboundTraffic > 0s and lastGoodSend > 0s
and now >= sendTimeout + m_LastInboundTraffic)
return true;
const auto timeout = std::max(lastGoodSend, m_LastInboundTraffic); const auto timeout = std::max(lastGoodSend, m_LastInboundTraffic);
if (lastGoodSend > 0s and now >= timeout + (sendTimeout / 2)) if (lastGoodSend > 0s and now >= timeout + (sendTimeout / 2))
{ {
// send a keep alive to keep this session alive // send a keep alive to keep this session alive
KeepAlive(); KeepAlive();
if (markedBad) if (markedBad)
{
LogWarn(Name(), " keepalive timeout hit");
return true; return true;
}
}
// check for half open state where we can send but we get nothing back
if (m_LastInboundTraffic == 0s and now - createdAt > connectTimeout)
{
LogWarn(Name(), " half open state, we can send but we got nothing back");
return true;
} }
// if we are dead return true so we are removed // if we are dead return true so we are removed
return timeout > 0s ? (now >= timeout && now - timeout > sendTimeout) const bool removeIt = timeout > 0s ? (now >= timeout && now - timeout > sendTimeout)
: (now >= createdAt && now - createdAt > connectTimeout); : (now >= createdAt && now - createdAt > connectTimeout);
if (removeIt)
{
LogInfo(Name(), " session is stale");
return true;
}
return false;
} }
void void
@ -584,6 +605,25 @@ namespace llarp
} }
} }
bool
OutboundContext::ShouldKeepAlive(llarp_time_t now) const
{
const auto SendKeepAliveInterval = sendTimeout / 2;
if (not m_GotInboundTraffic)
return false;
if (m_LastInboundTraffic == 0s)
return false;
return (now - m_LastKeepAliveAt) >= SendKeepAliveInterval;
}
void
OutboundContext::Tick(llarp_time_t now)
{
path::Builder::Tick(now);
if (ShouldKeepAlive(now))
KeepAlive();
}
bool bool
OutboundContext::HandleHiddenServiceFrame(path::Path_ptr p, const ProtocolFrame& frame) OutboundContext::HandleHiddenServiceFrame(path::Path_ptr p, const ProtocolFrame& frame)
{ {

@ -23,6 +23,9 @@ namespace llarp
~OutboundContext() override; ~OutboundContext() override;
void
Tick(llarp_time_t now) override;
util::StatusObject util::StatusObject
ExtractStatus() const; ExtractStatus() const;
@ -129,6 +132,9 @@ namespace llarp
void void
KeepAlive(); KeepAlive();
bool
ShouldKeepAlive(llarp_time_t now) const;
const IntroSet& const IntroSet&
GetCurrentIntroSet() const GetCurrentIntroSet() const
{ {
@ -170,6 +176,7 @@ namespace llarp
bool sentIntro = false; bool sentIntro = false;
std::vector<std::function<void(OutboundContext*)>> m_ReadyHooks; std::vector<std::function<void(OutboundContext*)>> m_ReadyHooks;
llarp_time_t m_LastIntrosetUpdateAt = 0s; llarp_time_t m_LastIntrosetUpdateAt = 0s;
llarp_time_t m_LastKeepAliveAt = 0s;
}; };
} // namespace service } // namespace service

@ -45,7 +45,7 @@ namespace llarp
llarp_time_t lastGoodSend = 0s; llarp_time_t lastGoodSend = 0s;
const llarp_time_t createdAt; const llarp_time_t createdAt;
llarp_time_t sendTimeout = path::build_timeout; llarp_time_t sendTimeout = path::build_timeout;
llarp_time_t connectTimeout = path::build_timeout; llarp_time_t connectTimeout = path::build_timeout * 2;
llarp_time_t shiftTimeout = (path::build_timeout * 5) / 2; llarp_time_t shiftTimeout = (path::build_timeout * 5) / 2;
llarp_time_t estimatedRTT = 0s; llarp_time_t estimatedRTT = 0s;
bool markedBad = false; bool markedBad = false;

Loading…
Cancel
Save