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
Now() const override;
void
virtual void
Tick(llarp_time_t now) override;
void

@ -470,6 +470,7 @@ namespace llarp
if (itr == Sessions().end())
return false;
si = itr->second.remote;
si.UpdateAddr();
return true;
}
@ -1100,13 +1101,14 @@ namespace llarp
bool
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);
Introduction intro = msg->introReply;
if (HasInboundConvo(msg->sender.Addr()))
{
intro.pathID = from;
intro.router = p->Endpoint();
}
PutReplyIntroFor(msg->tag, intro);
ConvoTagRX(msg->tag);

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

@ -54,7 +54,7 @@ namespace llarp
return true;
}
constexpr auto OutboundContextNumPaths = 2;
constexpr auto OutboundContextNumPaths = 4;
OutboundContext::OutboundContext(const IntroSet& introset, Endpoint* parent)
: path::Builder{parent->Router(), OutboundContextNumPaths, parent->numHops}
@ -64,12 +64,17 @@ namespace llarp
, currentIntroSet{introset}
{
assert(not introset.intros.empty());
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)
m_NextIntro = intro;
CSRNG rng{};
it += std::uniform_int_distribution<size_t>{0, introset.intros.size() - 1}(rng);
}
m_NextIntro = *it;
currentConvoTag.Randomize();
lastShift = Now();
// add send and connect timeouts to the parent endpoints path alignment timeout
@ -333,6 +338,7 @@ namespace llarp
Encrypted<64> tmp;
tmp.Randomize();
SendPacketToRemote(tmp, ProtocolType::Control);
m_LastKeepAliveAt = Now();
}
bool
@ -348,7 +354,10 @@ namespace llarp
// expunge
SharedSecret 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;
}
}
if (m_GotInboundTraffic and m_LastInboundTraffic + sendTimeout <= now)
@ -404,21 +413,33 @@ namespace llarp
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);
if (lastGoodSend > 0s and now >= timeout + (sendTimeout / 2))
{
// send a keep alive to keep this session alive
KeepAlive();
if (markedBad)
{
LogWarn(Name(), " keepalive timeout hit");
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
return timeout > 0s ? (now >= timeout && now - timeout > sendTimeout)
: (now >= createdAt && now - createdAt > connectTimeout);
const bool removeIt = timeout > 0s ? (now >= timeout && now - timeout > sendTimeout)
: (now >= createdAt && now - createdAt > connectTimeout);
if (removeIt)
{
LogInfo(Name(), " session is stale");
return true;
}
return false;
}
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
OutboundContext::HandleHiddenServiceFrame(path::Path_ptr p, const ProtocolFrame& frame)
{

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

@ -45,7 +45,7 @@ namespace llarp
llarp_time_t lastGoodSend = 0s;
const llarp_time_t createdAt;
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 estimatedRTT = 0s;
bool markedBad = false;

Loading…
Cancel
Save