mirror of https://github.com/oxen-io/lokinet
commit
e93c7559f0
|
@ -154,8 +154,8 @@ extern "C"
|
|||
// For utp_writev, to writes data from multiple buffers
|
||||
struct utp_iovec
|
||||
{
|
||||
void *iov_base;
|
||||
size_t iov_len;
|
||||
void *iov_base = nullptr;
|
||||
size_t iov_len = 0;
|
||||
};
|
||||
|
||||
// Public Functions
|
||||
|
|
|
@ -348,8 +348,16 @@ __ ___ ____ _ _ ___ _ _ ____
|
|||
llarp::LogInfo("SIGHUP");
|
||||
if(router)
|
||||
{
|
||||
router->hiddenServiceContext().ForEachService(
|
||||
[](const std::string &name,
|
||||
const llarp::service::Endpoint_ptr &ep) -> bool {
|
||||
ep->ResetInternalState();
|
||||
llarp::LogInfo("Reset internal state for ", name);
|
||||
return true;
|
||||
});
|
||||
router->PumpLL();
|
||||
Config newconfig;
|
||||
if(newconfig.Load(configfile.c_str()))
|
||||
if(!newconfig.Load(configfile.c_str()))
|
||||
{
|
||||
llarp::LogError("failed to load config file ", configfile);
|
||||
return;
|
||||
|
|
|
@ -138,8 +138,10 @@ namespace llarp
|
|||
src = pkt.src();
|
||||
pkt.UpdateIPv4PacketOnDst(src, m_IP);
|
||||
const llarp_buffer_t& pktbuf = pkt.Buffer(); // life time extension
|
||||
uint8_t queue_idx = pktbuf.sz / llarp::routing::ExitPadSize;
|
||||
auto& queue = m_DownstreamQueues[queue_idx];
|
||||
const uint8_t queue_idx = pktbuf.sz / llarp::routing::ExitPadSize;
|
||||
if(m_DownstreamQueues.find(queue_idx) == m_DownstreamQueues.end())
|
||||
m_DownstreamQueues.emplace(queue_idx, InboundTrafficQueue_t{});
|
||||
auto& queue = m_DownstreamQueues.at(queue_idx);
|
||||
if(queue.size() == 0)
|
||||
{
|
||||
queue.emplace_back();
|
||||
|
|
|
@ -58,10 +58,12 @@ namespace llarp
|
|||
}
|
||||
|
||||
bool
|
||||
BaseSession::SelectHop(llarp_nodedb* db, const RouterContact& prev,
|
||||
BaseSession::SelectHop(llarp_nodedb* db, const std::set< RouterID >& prev,
|
||||
RouterContact& cur, size_t hop,
|
||||
llarp::path::PathRole roles)
|
||||
{
|
||||
std::set< RouterID > exclude = prev;
|
||||
exclude.insert(m_ExitRouter);
|
||||
if(hop == numHops - 1)
|
||||
{
|
||||
if(db->Get(m_ExitRouter, cur))
|
||||
|
@ -69,13 +71,8 @@ namespace llarp
|
|||
router->LookupRouter(m_ExitRouter, nullptr);
|
||||
return false;
|
||||
}
|
||||
else if(hop == numHops - 2)
|
||||
{
|
||||
return db->select_random_hop_excluding(cur,
|
||||
{prev.pubkey, m_ExitRouter});
|
||||
}
|
||||
else
|
||||
return path::Builder::SelectHop(db, prev, cur, hop, roles);
|
||||
return path::Builder::SelectHop(db, exclude, cur, hop, roles);
|
||||
}
|
||||
|
||||
bool
|
||||
|
@ -151,6 +148,29 @@ namespace llarp
|
|||
m_PendingCallbacks.clear();
|
||||
}
|
||||
|
||||
void
|
||||
BaseSession::ResetInternalState()
|
||||
{
|
||||
auto sendExitClose = [&](const llarp::path::Path_ptr p) {
|
||||
const static auto roles =
|
||||
llarp::path::ePathRoleExit | llarp::path::ePathRoleSVC;
|
||||
if(p->SupportsAnyRoles(roles))
|
||||
{
|
||||
llarp::LogInfo(p->Name(), " closing exit path");
|
||||
llarp::routing::CloseExitMessage msg;
|
||||
if(msg.Sign(router->crypto(), m_ExitIdentity)
|
||||
&& p->SendExitClose(msg, router))
|
||||
{
|
||||
p->ClearRoles(roles);
|
||||
}
|
||||
else
|
||||
llarp::LogWarn(p->Name(), " failed to send exit close message");
|
||||
}
|
||||
};
|
||||
ForEachPath(sendExitClose);
|
||||
path::Builder::ResetInternalState();
|
||||
}
|
||||
|
||||
bool
|
||||
BaseSession::Stop()
|
||||
{
|
||||
|
@ -234,6 +254,14 @@ namespace llarp
|
|||
return m_LastUse && now > m_LastUse && now - m_LastUse > LifeSpan;
|
||||
}
|
||||
|
||||
bool
|
||||
BaseSession::UrgentBuild(llarp_time_t now) const
|
||||
{
|
||||
if(!IsReady())
|
||||
return NumInStatus(path::ePathBuilding) < m_NumPaths;
|
||||
return path::Builder::UrgentBuild(now);
|
||||
}
|
||||
|
||||
bool
|
||||
BaseSession::FlushUpstream()
|
||||
{
|
||||
|
@ -248,9 +276,11 @@ namespace llarp
|
|||
{
|
||||
auto& msg = queue.front();
|
||||
msg.S = path->NextSeqNo();
|
||||
if(path->SendRoutingMessage(msg, router))
|
||||
if(path && path->SendRoutingMessage(msg, router))
|
||||
m_LastUse = now;
|
||||
queue.pop_front();
|
||||
// spread across all paths
|
||||
path = PickRandomEstablishedPath(llarp::path::ePathRoleExit);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -275,6 +305,8 @@ namespace llarp
|
|||
r->TryConnectAsync(results[0], 5);
|
||||
});
|
||||
}
|
||||
else if(UrgentBuild(now))
|
||||
BuildOneAlignedTo(m_ExitRouter);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -48,6 +48,11 @@ namespace llarp
|
|||
return m_BundleRC;
|
||||
}
|
||||
|
||||
virtual void
|
||||
ResetInternalState() override;
|
||||
|
||||
bool UrgentBuild(llarp_time_t) const override;
|
||||
|
||||
void
|
||||
HandlePathDied(llarp::path::Path_ptr p) override;
|
||||
|
||||
|
@ -55,8 +60,9 @@ namespace llarp
|
|||
CheckPathDead(path::Path_ptr p, llarp_time_t dlt);
|
||||
|
||||
bool
|
||||
SelectHop(llarp_nodedb* db, const RouterContact& prev, RouterContact& cur,
|
||||
size_t hop, llarp::path::PathRole roles) override;
|
||||
SelectHop(llarp_nodedb* db, const std::set< RouterID >& prev,
|
||||
RouterContact& cur, size_t hop,
|
||||
llarp::path::PathRole roles) override;
|
||||
|
||||
bool
|
||||
ShouldBuildMore(llarp_time_t now) const override;
|
||||
|
|
|
@ -185,6 +185,22 @@ namespace llarp
|
|||
return m_Router->Now();
|
||||
}
|
||||
|
||||
bool
|
||||
ExitEndpoint::VisitEndpointsFor(
|
||||
const PubKey &pk, std::function< bool(exit::Endpoint *const) > visit)
|
||||
{
|
||||
auto range = m_ActiveExits.equal_range(pk);
|
||||
auto itr = range.first;
|
||||
while(itr != range.second)
|
||||
{
|
||||
if(visit(itr->second.get()))
|
||||
++itr;
|
||||
else
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void
|
||||
ExitEndpoint::Flush()
|
||||
{
|
||||
|
@ -213,21 +229,22 @@ namespace llarp
|
|||
return;
|
||||
}
|
||||
}
|
||||
exit::Endpoint *ep = m_ChosenExits[pk];
|
||||
|
||||
if(ep == nullptr)
|
||||
{
|
||||
// we may have all dead sessions, wtf now?
|
||||
LogWarn(Name(), " dropped inbound traffic for session ", pk,
|
||||
" as we have no working endpoints");
|
||||
}
|
||||
else
|
||||
{
|
||||
auto tryFlushingTraffic = [&](exit::Endpoint *const ep) -> bool {
|
||||
if(!ep->QueueInboundTraffic(ManagedBuffer{pkt.Buffer()}))
|
||||
{
|
||||
LogWarn(Name(), " dropped inbound traffic for session ", pk,
|
||||
" as we are overloaded (probably)");
|
||||
// continue iteration
|
||||
return true;
|
||||
}
|
||||
// break iteration
|
||||
return false;
|
||||
};
|
||||
if(!VisitEndpointsFor(pk, tryFlushingTraffic))
|
||||
{
|
||||
// we may have all dead sessions, wtf now?
|
||||
LogWarn(Name(), " dropped inbound traffic for session ", pk,
|
||||
" as we have no working endpoints");
|
||||
}
|
||||
});
|
||||
{
|
||||
|
|
|
@ -25,6 +25,10 @@ namespace llarp
|
|||
std::string
|
||||
Name() const;
|
||||
|
||||
bool
|
||||
VisitEndpointsFor(const PubKey& pk,
|
||||
std::function< bool(exit::Endpoint* const) > visit);
|
||||
|
||||
util::StatusObject
|
||||
ExtractStatus() const;
|
||||
|
||||
|
|
|
@ -433,6 +433,14 @@ namespace llarp
|
|||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
TunEndpoint::ResetInternalState()
|
||||
{
|
||||
service::Endpoint::ResetInternalState();
|
||||
if(m_Exit)
|
||||
m_Exit->ResetInternalState();
|
||||
}
|
||||
|
||||
// FIXME: pass in which question it should be addressing
|
||||
bool
|
||||
TunEndpoint::ShouldHookDNSMessage(const dns::Message &msg) const
|
||||
|
|
|
@ -153,6 +153,9 @@ namespace llarp
|
|||
void
|
||||
Flush();
|
||||
|
||||
virtual void
|
||||
ResetInternalState() override;
|
||||
|
||||
protected:
|
||||
using PacketQueue_t = llarp::util::CoDelQueue<
|
||||
net::IPv4Packet, net::IPv4Packet::GetTime, net::IPv4Packet::PutTime,
|
||||
|
|
|
@ -5,6 +5,8 @@
|
|||
|
||||
namespace llarp
|
||||
{
|
||||
static constexpr size_t MaxSessionsPerKey = 16;
|
||||
|
||||
ILinkLayer::ILinkLayer(const SecretKey& routerEncSecret, GetRCFunc getrc,
|
||||
LinkMessageHandler handler, SignBufferFunc signbuf,
|
||||
SessionEstablishedHandler establishedSession,
|
||||
|
@ -152,7 +154,6 @@ namespace llarp
|
|||
bool
|
||||
ILinkLayer::MapAddr(const RouterID& pk, ILinkSession* s)
|
||||
{
|
||||
static constexpr size_t MaxSessionsPerKey = 16;
|
||||
Lock l_authed(&m_AuthedLinksMutex);
|
||||
Lock l_pending(&m_PendingMutex);
|
||||
llarp::Addr addr = s->GetRemoteEndpoint();
|
||||
|
@ -220,10 +221,20 @@ namespace llarp
|
|||
bool
|
||||
ILinkLayer::TryEstablishTo(RouterContact rc)
|
||||
{
|
||||
{
|
||||
Lock l(&m_AuthedLinksMutex);
|
||||
if(m_AuthedLinks.count(rc.pubkey) >= MaxSessionsPerKey)
|
||||
return false;
|
||||
}
|
||||
llarp::AddressInfo to;
|
||||
if(!PickAddress(rc, to))
|
||||
return false;
|
||||
llarp::Addr addr(to);
|
||||
{
|
||||
Lock l(&m_PendingMutex);
|
||||
if(m_Pending.count(addr) >= MaxSessionsPerKey)
|
||||
return false;
|
||||
}
|
||||
std::shared_ptr< ILinkSession > s = NewOutboundSession(rc, to);
|
||||
if(PutSession(s))
|
||||
{
|
||||
|
|
|
@ -202,6 +202,13 @@ namespace llarp
|
|||
SessionClosedHandler SessionClosed;
|
||||
SessionRenegotiateHandler SessionRenegotiate;
|
||||
|
||||
bool
|
||||
operator<(const ILinkLayer& other) const
|
||||
{
|
||||
return Rank() < other.Rank() || Name() < other.Name()
|
||||
|| m_ourAddr < other.m_ourAddr;
|
||||
}
|
||||
|
||||
/// called by link session to remove a pending session who is timed out
|
||||
// void
|
||||
// RemovePending(ILinkSession* s) LOCKS_EXCLUDED(m_PendingMutex);
|
||||
|
|
|
@ -47,7 +47,7 @@ namespace llarp
|
|||
|
||||
/// return true if we are established
|
||||
virtual bool
|
||||
IsEstablished() = 0;
|
||||
IsEstablished() const = 0;
|
||||
|
||||
/// return true if this session has timed out
|
||||
virtual bool
|
||||
|
|
|
@ -37,7 +37,7 @@ operator==(const sockaddr& a, const sockaddr& b)
|
|||
bool
|
||||
operator<(const sockaddr_in6& a, const sockaddr_in6& b)
|
||||
{
|
||||
return memcmp(&a, &b, sizeof(sockaddr_in6)) < 0;
|
||||
return a.sin6_addr < b.sin6_addr || a.sin6_port < b.sin6_port;
|
||||
}
|
||||
|
||||
bool
|
||||
|
|
|
@ -82,6 +82,19 @@ namespace llarp
|
|||
k.begin());
|
||||
}
|
||||
|
||||
PathContext::EndpointPathPtrSet
|
||||
PathContext::FindOwnedPathsWithEndpoint(const RouterID& r)
|
||||
{
|
||||
EndpointPathPtrSet found;
|
||||
m_OurPaths.ForEach([&](const PathSet_ptr& set) {
|
||||
set->ForEachPath([&](const Path_ptr& p) {
|
||||
if(p->Endpoint() == r && p->IsReady())
|
||||
found.insert(p);
|
||||
});
|
||||
});
|
||||
return found;
|
||||
}
|
||||
|
||||
bool
|
||||
PathContext::ForwardLRCM(const RouterID& nextHop,
|
||||
const std::array< EncryptedFrame, 8 >& frames)
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
#include <routing/message.hpp>
|
||||
#include <service/intro.hpp>
|
||||
#include <util/aligned.hpp>
|
||||
#include <util/compare_ptr.hpp>
|
||||
#include <util/threading.hpp>
|
||||
#include <util/time.hpp>
|
||||
|
||||
|
@ -271,6 +272,8 @@ namespace llarp
|
|||
AbstractRouter* r) override;
|
||||
};
|
||||
|
||||
using TransitHop_ptr = std::shared_ptr< TransitHop >;
|
||||
|
||||
inline std::ostream&
|
||||
operator<<(std::ostream& out, const TransitHop& h)
|
||||
{
|
||||
|
@ -302,6 +305,14 @@ namespace llarp
|
|||
|
||||
util::StatusObject
|
||||
ExtractStatus() const;
|
||||
|
||||
bool
|
||||
operator<(const PathHopConfig& other) const
|
||||
{
|
||||
return std::tie(txID, rxID, rc, upstream, lifetime)
|
||||
< std::tie(other.txID, other.rxID, other.rc, other.upstream,
|
||||
other.lifetime);
|
||||
}
|
||||
};
|
||||
|
||||
/// A path we made
|
||||
|
@ -343,6 +354,12 @@ namespace llarp
|
|||
return _role;
|
||||
}
|
||||
|
||||
bool
|
||||
operator<(const Path& other) const
|
||||
{
|
||||
return hops < other.hops;
|
||||
}
|
||||
|
||||
void
|
||||
MarkActive(llarp_time_t now)
|
||||
{
|
||||
|
@ -360,7 +377,14 @@ namespace llarp
|
|||
bool
|
||||
SupportsAnyRoles(PathRole roles) const
|
||||
{
|
||||
return roles == ePathRoleAny || (_role & roles) != 0;
|
||||
return roles == ePathRoleAny || (_role | roles) != 0;
|
||||
}
|
||||
|
||||
/// clear role bits
|
||||
void
|
||||
ClearRoles(PathRole roles)
|
||||
{
|
||||
_role &= ~roles;
|
||||
}
|
||||
|
||||
PathStatus
|
||||
|
@ -624,6 +648,11 @@ namespace llarp
|
|||
routing::MessageHandler_ptr
|
||||
GetHandler(const PathID_t& id);
|
||||
|
||||
using EndpointPathPtrSet = std::set< Path_ptr, ComparePtr< Path_ptr > >;
|
||||
/// get a set of all paths that we own who's endpoint is r
|
||||
EndpointPathPtrSet
|
||||
FindOwnedPathsWithEndpoint(const RouterID& r);
|
||||
|
||||
bool
|
||||
ForwardLRCM(const RouterID& nextHop,
|
||||
const std::array< EncryptedFrame, 8 >& frames);
|
||||
|
@ -643,13 +672,20 @@ namespace llarp
|
|||
void
|
||||
RemovePathSet(PathSet_ptr set);
|
||||
|
||||
using TransitHopsMap_t =
|
||||
std::multimap< PathID_t, std::shared_ptr< TransitHop > >;
|
||||
using TransitHopsMap_t = std::multimap< PathID_t, TransitHop_ptr >;
|
||||
|
||||
struct SyncTransitMap_t
|
||||
{
|
||||
util::Mutex first; // protects second
|
||||
TransitHopsMap_t second GUARDED_BY(first);
|
||||
|
||||
void
|
||||
ForEach(std::function< void(const TransitHop_ptr&) > visit)
|
||||
{
|
||||
util::Lock lock(&first);
|
||||
for(const auto& item : second)
|
||||
visit(item.second);
|
||||
}
|
||||
};
|
||||
|
||||
// maps path id -> pathset owner of path
|
||||
|
@ -659,6 +695,14 @@ namespace llarp
|
|||
{
|
||||
util::Mutex first; // protects second
|
||||
OwnedPathsMap_t second GUARDED_BY(first);
|
||||
|
||||
void
|
||||
ForEach(std::function< void(const PathSet_ptr&) > visit)
|
||||
{
|
||||
util::Lock lock(&first);
|
||||
for(const auto& item : second)
|
||||
visit(item.second);
|
||||
}
|
||||
};
|
||||
|
||||
llarp_threadpool*
|
||||
|
|
|
@ -181,6 +181,13 @@ namespace llarp
|
|||
{
|
||||
}
|
||||
|
||||
void
|
||||
Builder::ResetInternalState()
|
||||
{
|
||||
buildIntervalLimit = MIN_PATH_BUILD_INTERVAL;
|
||||
lastBuild = 0;
|
||||
}
|
||||
|
||||
void
|
||||
Builder::Tick(llarp_time_t now)
|
||||
{
|
||||
|
@ -206,7 +213,7 @@ namespace llarp
|
|||
}
|
||||
|
||||
bool
|
||||
Builder::SelectHop(llarp_nodedb* db, const RouterContact& prev,
|
||||
Builder::SelectHop(llarp_nodedb* db, const std::set< RouterID >& exclude,
|
||||
RouterContact& cur, size_t hop, PathRole roles)
|
||||
{
|
||||
(void)roles;
|
||||
|
@ -214,29 +221,37 @@ namespace llarp
|
|||
if(hop == 0)
|
||||
{
|
||||
if(router->NumberOfConnectedRouters() == 0)
|
||||
{
|
||||
// persist connection
|
||||
router->ConnectToRandomRouters(1);
|
||||
return false;
|
||||
}
|
||||
bool got = false;
|
||||
router->ForEachPeer(
|
||||
[&](const ILinkSession* s, bool) {
|
||||
const PubKey k(s->GetPubKey());
|
||||
if(got || router->IsBootstrapNode(k))
|
||||
return;
|
||||
cur = s->GetRemoteRC();
|
||||
got = true;
|
||||
[&](const ILinkSession* s, bool isOutbound) {
|
||||
if(s && s->IsEstablished() && isOutbound && !got)
|
||||
{
|
||||
const RouterContact rc = s->GetRemoteRC();
|
||||
if(got || router->IsBootstrapNode(rc.pubkey)
|
||||
|| exclude.count(rc.pubkey))
|
||||
return;
|
||||
cur = rc;
|
||||
got = true;
|
||||
}
|
||||
},
|
||||
true);
|
||||
return got;
|
||||
}
|
||||
std::set< RouterID > exclude = {prev.pubkey};
|
||||
do
|
||||
{
|
||||
cur.Clear();
|
||||
--tries;
|
||||
if(db->select_random_hop_excluding(cur, exclude))
|
||||
std::set< RouterID > excluding = exclude;
|
||||
if(db->select_random_hop_excluding(cur, excluding))
|
||||
{
|
||||
excluding.insert(cur.pubkey);
|
||||
if(!router->routerProfiling().IsBadForPath(cur.pubkey))
|
||||
return true;
|
||||
exclude.insert(cur.pubkey);
|
||||
}
|
||||
} while(tries > 0);
|
||||
return tries > 0;
|
||||
|
@ -284,36 +299,98 @@ namespace llarp
|
|||
void
|
||||
Builder::BuildOne(PathRole roles)
|
||||
{
|
||||
std::vector< RouterContact > hops;
|
||||
std::vector< RouterContact > hops(numHops);
|
||||
if(SelectHops(router->nodedb(), hops, roles))
|
||||
Build(hops, roles);
|
||||
}
|
||||
|
||||
bool Builder::UrgentBuild(llarp_time_t) const
|
||||
{
|
||||
return buildIntervalLimit > MIN_PATH_BUILD_INTERVAL * 4;
|
||||
}
|
||||
|
||||
bool
|
||||
Builder::BuildOneAlignedTo(const RouterID remote)
|
||||
{
|
||||
std::vector< RouterContact > hops(0);
|
||||
std::set< RouterID > routers = {remote};
|
||||
/// if we really need this path build it "dangerously"
|
||||
if(UrgentBuild(router->Now()))
|
||||
{
|
||||
const auto aligned =
|
||||
router->pathContext().FindOwnedPathsWithEndpoint(remote);
|
||||
/// pick the lowest latency path that aligns to remote
|
||||
/// note: peer exuastion is made worse happen here
|
||||
Path_ptr p;
|
||||
llarp_time_t min = std::numeric_limits< llarp_time_t >::max();
|
||||
for(const auto& path : aligned)
|
||||
{
|
||||
if(path->intro.latency < min && path->hops.size() == numHops)
|
||||
{
|
||||
p = path;
|
||||
min = path->intro.latency;
|
||||
}
|
||||
}
|
||||
if(p)
|
||||
{
|
||||
for(const auto& hop : p->hops)
|
||||
{
|
||||
if(hop.rc.pubkey.IsZero())
|
||||
return false;
|
||||
hops.emplace_back(hop.rc);
|
||||
}
|
||||
}
|
||||
}
|
||||
if(hops.size() == 0)
|
||||
{
|
||||
hops.resize(numHops);
|
||||
|
||||
auto nodedb = router->nodedb();
|
||||
for(size_t idx = 0; idx < hops.size(); idx++)
|
||||
{
|
||||
hops[idx].Clear();
|
||||
if(idx == numHops - 1)
|
||||
{
|
||||
// last hop
|
||||
if(!nodedb->Get(remote, hops[idx]))
|
||||
{
|
||||
router->LookupRouter(remote, nullptr);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(!SelectHop(nodedb, routers, hops[idx], idx, path::ePathRoleAny))
|
||||
return false;
|
||||
}
|
||||
if(hops[idx].pubkey.IsZero())
|
||||
return false;
|
||||
routers.insert(hops[idx].pubkey);
|
||||
}
|
||||
}
|
||||
LogInfo(Name(), " building path to ", remote);
|
||||
Build(hops);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
Builder::SelectHops(llarp_nodedb* nodedb,
|
||||
std::vector< RouterContact >& hops, PathRole roles)
|
||||
{
|
||||
hops.resize(numHops);
|
||||
size_t idx = 0;
|
||||
while(idx < numHops)
|
||||
std::set< RouterID > exclude;
|
||||
while(idx < hops.size())
|
||||
{
|
||||
hops[idx].Clear();
|
||||
size_t tries = 4;
|
||||
if(idx == 0)
|
||||
{
|
||||
while(tries > 0 && !SelectHop(nodedb, hops[0], hops[0], 0, roles))
|
||||
--tries;
|
||||
}
|
||||
else
|
||||
{
|
||||
while(tries > 0
|
||||
&& !SelectHop(nodedb, hops[idx - 1], hops[idx], idx, roles))
|
||||
--tries;
|
||||
}
|
||||
if(tries == 0)
|
||||
while(tries > 0 && !SelectHop(nodedb, exclude, hops[idx], idx, roles))
|
||||
--tries;
|
||||
if(tries == 0 || hops[idx].pubkey.IsZero())
|
||||
{
|
||||
LogWarn(Name(), " failed to select hop ", idx);
|
||||
return false;
|
||||
}
|
||||
exclude.insert(hops[idx].pubkey);
|
||||
++idx;
|
||||
}
|
||||
return true;
|
||||
|
@ -337,6 +414,7 @@ namespace llarp
|
|||
ctx->router = router;
|
||||
ctx->pathset = GetSelf();
|
||||
auto path = std::make_shared< path::Path >(hops, this, roles);
|
||||
LogInfo(Name(), " build ", path->HopsString());
|
||||
path->SetBuildResultHook(
|
||||
[this](Path_ptr p) { this->HandlePathBuilt(p); });
|
||||
ctx->AsyncGenerateKeys(path, router->logic(), router->threadpool(), this,
|
||||
|
@ -356,8 +434,8 @@ namespace llarp
|
|||
{
|
||||
// linear backoff
|
||||
static constexpr llarp_time_t MaxBuildInterval = 30 * 1000;
|
||||
buildIntervalLimit =
|
||||
std::min(MIN_PATH_BUILD_INTERVAL + buildIntervalLimit, MaxBuildInterval);
|
||||
buildIntervalLimit = std::min(
|
||||
MIN_PATH_BUILD_INTERVAL + buildIntervalLimit, MaxBuildInterval);
|
||||
router->routerProfiling().MarkPathFail(p.get());
|
||||
PathSet::HandlePathBuildTimeout(p);
|
||||
LogWarn(Name(), " build interval is now ", buildIntervalLimit);
|
||||
|
|
|
@ -21,6 +21,9 @@ namespace llarp
|
|||
/// flag for PathSet::Stop()
|
||||
std::atomic< bool > _run;
|
||||
|
||||
virtual bool
|
||||
UrgentBuild(llarp_time_t now) const;
|
||||
|
||||
public:
|
||||
AbstractRouter* router;
|
||||
llarp_dht_context* dht;
|
||||
|
@ -39,8 +42,8 @@ namespace llarp
|
|||
ExtractStatus() const;
|
||||
|
||||
virtual bool
|
||||
SelectHop(llarp_nodedb* db, const RouterContact& prev, RouterContact& cur,
|
||||
size_t hop, PathRole roles) override;
|
||||
SelectHop(llarp_nodedb* db, const std::set< RouterID >& prev,
|
||||
RouterContact& cur, size_t hop, PathRole roles) override;
|
||||
|
||||
virtual bool
|
||||
ShouldBuildMore(llarp_time_t now) const override;
|
||||
|
@ -49,6 +52,9 @@ namespace llarp
|
|||
virtual bool
|
||||
ShouldBundleRC() const = 0;
|
||||
|
||||
virtual void
|
||||
ResetInternalState() override;
|
||||
|
||||
/// return true if we hit our soft limit for building paths too fast
|
||||
bool
|
||||
BuildCooldownHit(llarp_time_t now) const;
|
||||
|
@ -78,6 +84,9 @@ namespace llarp
|
|||
void
|
||||
BuildOne(PathRole roles = ePathRoleAny) override;
|
||||
|
||||
bool
|
||||
BuildOneAlignedTo(const RouterID endpoint) override;
|
||||
|
||||
void
|
||||
Build(const std::vector< RouterContact >& hops,
|
||||
PathRole roles = ePathRoleAny) override;
|
||||
|
|
|
@ -216,15 +216,16 @@ namespace llarp
|
|||
return false;
|
||||
}
|
||||
|
||||
/// reset all cooldown timers
|
||||
virtual void
|
||||
ResetInternalState() = 0;
|
||||
|
||||
virtual bool
|
||||
SelectHop(llarp_nodedb* db, const RouterContact& prev, RouterContact& cur,
|
||||
size_t hop, PathRole roles) = 0;
|
||||
SelectHop(llarp_nodedb* db, const std::set< RouterID >& prev,
|
||||
RouterContact& cur, size_t hop, PathRole roles) = 0;
|
||||
|
||||
protected:
|
||||
size_t m_NumPaths;
|
||||
|
||||
void
|
||||
TickPaths(llarp_time_t now, AbstractRouter* r);
|
||||
virtual bool
|
||||
BuildOneAlignedTo(const RouterID endpoint) = 0;
|
||||
|
||||
void
|
||||
ForEachPath(std::function< void(const Path_ptr&) > visit) const
|
||||
|
@ -238,6 +239,12 @@ namespace llarp
|
|||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
size_t m_NumPaths;
|
||||
|
||||
void
|
||||
TickPaths(llarp_time_t now, AbstractRouter* r);
|
||||
|
||||
using PathInfo_t = std::pair< RouterID, PathID_t >;
|
||||
|
||||
struct PathInfoHash
|
||||
|
|
|
@ -193,16 +193,22 @@ namespace llarp
|
|||
TransitHop::HandleCloseExitMessage(
|
||||
const llarp::routing::CloseExitMessage& msg, AbstractRouter* r)
|
||||
{
|
||||
llarp::routing::DataDiscardMessage discard(info.rxID, msg.S);
|
||||
const llarp::routing::DataDiscardMessage discard(info.rxID, msg.S);
|
||||
auto ep = r->exitContext().FindEndpointForPath(info.rxID);
|
||||
if(ep && msg.Verify(r->crypto(), ep->PubKey()))
|
||||
{
|
||||
ep->Close();
|
||||
// ep is now gone af
|
||||
llarp::routing::CloseExitMessage reply;
|
||||
reply.Y = msg.Y;
|
||||
reply.S = NextSeqNo();
|
||||
if(reply.Sign(r->crypto(), r->identity()))
|
||||
return SendRoutingMessage(reply, r);
|
||||
{
|
||||
if(SendRoutingMessage(reply, r))
|
||||
{
|
||||
r->PumpLL();
|
||||
ep->Close();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return SendRoutingMessage(discard, r);
|
||||
}
|
||||
|
|
|
@ -188,11 +188,16 @@ namespace llarp
|
|||
Profiling::MarkPathFail(path::Path* p)
|
||||
{
|
||||
lock_t lock(&m_ProfilesMutex);
|
||||
size_t idx = 0;
|
||||
for(const auto& hop : p->hops)
|
||||
{
|
||||
// TODO: also mark bad?
|
||||
m_Profiles[hop.rc.pubkey].pathFailCount += 1;
|
||||
m_Profiles[hop.rc.pubkey].lastUpdated = llarp::time_now_ms();
|
||||
// don't mark first hop as failure because we are connected to it directly
|
||||
if(idx)
|
||||
{
|
||||
m_Profiles[hop.rc.pubkey].pathFailCount += 1;
|
||||
m_Profiles[hop.rc.pubkey].lastUpdated = llarp::time_now_ms();
|
||||
}
|
||||
++idx;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -358,8 +358,7 @@ namespace llarp
|
|||
if(nodedb()->Get(remote, remoteRC))
|
||||
{
|
||||
// try connecting directly as the rc is loaded from disk
|
||||
TryConnectAsync(remoteRC, 10);
|
||||
return true;
|
||||
return TryConnectAsync(remoteRC, 10);
|
||||
}
|
||||
|
||||
// we don't have the RC locally so do a dht lookup
|
||||
|
@ -1796,9 +1795,8 @@ namespace llarp
|
|||
}
|
||||
return want > 0;
|
||||
});
|
||||
if(wanted != want)
|
||||
LogInfo("connecting to ", abs(want - wanted), " out of ", wanted,
|
||||
" random routers");
|
||||
LogInfo("connecting to ", abs(want - wanted), " out of ", wanted,
|
||||
" random routers");
|
||||
}
|
||||
|
||||
bool
|
||||
|
|
|
@ -55,19 +55,6 @@ struct TryConnectJob;
|
|||
|
||||
namespace llarp
|
||||
{
|
||||
template < typename T >
|
||||
struct CompareLinks
|
||||
{
|
||||
bool
|
||||
operator()(const std::unique_ptr< T > &left,
|
||||
const std::unique_ptr< T > &right) const
|
||||
{
|
||||
const std::string leftName = left->Name();
|
||||
const std::string rightName = right->Name();
|
||||
return left->Rank() < right->Rank() || leftName < rightName;
|
||||
}
|
||||
};
|
||||
|
||||
struct Router final : public AbstractRouter
|
||||
{
|
||||
bool ready;
|
||||
|
@ -292,10 +279,11 @@ namespace llarp
|
|||
std::string lokidRPCUser = "";
|
||||
std::string lokidRPCPassword = "";
|
||||
|
||||
std::set< std::unique_ptr< ILinkLayer >, CompareLinks< ILinkLayer > >
|
||||
outboundLinks;
|
||||
std::set< std::unique_ptr< ILinkLayer >, CompareLinks< ILinkLayer > >
|
||||
inboundLinks;
|
||||
using LinkLayer_ptr = std::unique_ptr< ILinkLayer >;
|
||||
using LinkSet = std::set< LinkLayer_ptr, ComparePtr< LinkLayer_ptr > >;
|
||||
|
||||
LinkSet outboundLinks;
|
||||
LinkSet inboundLinks;
|
||||
|
||||
Profiling _routerProfiling;
|
||||
std::string routerProfilesFile = "profiles.dat";
|
||||
|
|
|
@ -596,6 +596,18 @@ namespace llarp
|
|||
return false;
|
||||
}
|
||||
|
||||
void
|
||||
Endpoint::ResetInternalState()
|
||||
{
|
||||
path::Builder::ResetInternalState();
|
||||
static auto resetState = [](auto& container) {
|
||||
std::for_each(container.begin(), container.end(),
|
||||
[](auto& item) { item.second->ResetInternalState(); });
|
||||
};
|
||||
resetState(m_RemoteSessions);
|
||||
resetState(m_SNodeSessions);
|
||||
}
|
||||
|
||||
bool
|
||||
Endpoint::ShouldPublishDescriptors(llarp_time_t now) const
|
||||
{
|
||||
|
|
|
@ -82,6 +82,9 @@ namespace llarp
|
|||
return huint32_t{0};
|
||||
}
|
||||
|
||||
virtual void
|
||||
ResetInternalState() override;
|
||||
|
||||
/// router's logic
|
||||
/// use when sending any data on a path
|
||||
Logic*
|
||||
|
|
|
@ -47,6 +47,9 @@ namespace llarp
|
|||
llarp_time_t
|
||||
GetNewestIntroExpiration() const;
|
||||
|
||||
bool
|
||||
GetNewestIntro(Introduction& intro) const;
|
||||
|
||||
bool
|
||||
HasExpiredIntros(llarp_time_t now) const;
|
||||
|
||||
|
|
|
@ -38,7 +38,7 @@ namespace llarp
|
|||
|
||||
/// determine if this request has timed out
|
||||
bool
|
||||
IsTimedOut(llarp_time_t now, llarp_time_t timeout = 15000) const
|
||||
IsTimedOut(llarp_time_t now, llarp_time_t timeout = 60000) const
|
||||
{
|
||||
if(now <= m_created)
|
||||
return false;
|
||||
|
|
|
@ -104,10 +104,9 @@ namespace llarp
|
|||
{
|
||||
LogWarn("failed to pick new intro during introset update");
|
||||
}
|
||||
if(GetPathByRouter(m_NextIntro.router) == nullptr)
|
||||
if(GetPathByRouter(m_NextIntro.router) == nullptr
|
||||
&& !BuildCooldownHit(Now()))
|
||||
BuildOneAlignedTo(m_NextIntro.router);
|
||||
else
|
||||
SwapIntros();
|
||||
}
|
||||
else
|
||||
++m_LookupFails;
|
||||
|
@ -134,52 +133,18 @@ namespace llarp
|
|||
p->SetDropHandler(std::bind(&OutboundContext::HandleDataDrop, this,
|
||||
std::placeholders::_1, std::placeholders::_2,
|
||||
std::placeholders::_3));
|
||||
}
|
||||
|
||||
bool
|
||||
OutboundContext::BuildOneAlignedTo(const RouterID& remote)
|
||||
{
|
||||
LogInfo(Name(), " building path to ", remote);
|
||||
auto nodedb = m_Endpoint->Router()->nodedb();
|
||||
std::vector< RouterContact > hops;
|
||||
hops.resize(numHops);
|
||||
for(size_t hop = 0; hop < numHops; ++hop)
|
||||
{
|
||||
if(hop == 0)
|
||||
{
|
||||
if(!SelectHop(nodedb, hops[0], hops[0], 0, path::ePathRoleAny))
|
||||
return false;
|
||||
}
|
||||
else if(hop == numHops - 1)
|
||||
{
|
||||
// last hop
|
||||
if(!nodedb->Get(remote, hops[hop]))
|
||||
return false;
|
||||
}
|
||||
// middle hop
|
||||
else
|
||||
{
|
||||
size_t tries = 5;
|
||||
do
|
||||
{
|
||||
nodedb->select_random_hop_excluding(hops[hop],
|
||||
{hops[hop - 1].pubkey, remote});
|
||||
--tries;
|
||||
} while(m_Endpoint->Router()->routerProfiling().IsBadForPath(
|
||||
hops[hop].pubkey)
|
||||
&& tries > 0);
|
||||
return tries > 0;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
Build(hops);
|
||||
return true;
|
||||
// we now have a path to the next intro, swap intros
|
||||
if(p->Endpoint() == m_NextIntro.router && remoteIntro != m_NextIntro)
|
||||
SwapIntros();
|
||||
}
|
||||
|
||||
void
|
||||
OutboundContext::AsyncGenIntro(const llarp_buffer_t& payload,
|
||||
ProtocolType t)
|
||||
{
|
||||
if(remoteIntro.router.IsZero())
|
||||
SwapIntros();
|
||||
|
||||
auto path = m_PathSet->GetNewestPathByRouter(remoteIntro.router);
|
||||
if(path == nullptr)
|
||||
{
|
||||
|
@ -187,7 +152,8 @@ namespace llarp
|
|||
path = m_Endpoint->GetPathByRouter(remoteIntro.router);
|
||||
if(path == nullptr)
|
||||
{
|
||||
BuildOneAlignedTo(remoteIntro.router);
|
||||
if(!BuildCooldownHit(Now()))
|
||||
BuildOneAlignedTo(remoteIntro.router);
|
||||
LogWarn(Name(), " dropping intro frame, no path to ",
|
||||
remoteIntro.router);
|
||||
return;
|
||||
|
@ -287,16 +253,6 @@ namespace llarp
|
|||
// shift intro if it expires "soon"
|
||||
ShiftIntroduction();
|
||||
}
|
||||
// swap if we can
|
||||
if(remoteIntro != m_NextIntro)
|
||||
{
|
||||
if(GetPathByRouter(m_NextIntro.router) != nullptr)
|
||||
{
|
||||
// we can safely set remoteIntro to the next one
|
||||
SwapIntros();
|
||||
LogInfo(Name(), " swapped intro");
|
||||
}
|
||||
}
|
||||
// lookup router in intro if set and unknown
|
||||
m_Endpoint->EnsureRouterIsKnown(remoteIntro.router);
|
||||
// expire bad intros
|
||||
|
@ -315,15 +271,19 @@ namespace llarp
|
|||
{
|
||||
if(!GetNewestPathByRouter(remoteIntro.router))
|
||||
{
|
||||
BuildOneAlignedTo(remoteIntro.router);
|
||||
if(!BuildCooldownHit(now))
|
||||
BuildOneAlignedTo(remoteIntro.router);
|
||||
}
|
||||
else
|
||||
{
|
||||
Encrypted< 64 > tmp;
|
||||
tmp.Randomize();
|
||||
llarp_buffer_t buf(tmp.data(), tmp.size());
|
||||
AsyncEncryptAndSendTo(buf, eProtocolControl);
|
||||
if(currentConvoTag.IsZero())
|
||||
return false;
|
||||
return !m_DataHandler->HasConvoTag(currentConvoTag);
|
||||
}
|
||||
Encrypted< 64 > tmp;
|
||||
tmp.Randomize();
|
||||
llarp_buffer_t buf(tmp.data(), tmp.size());
|
||||
AsyncEncryptAndSendTo(buf, eProtocolControl);
|
||||
if(currentConvoTag.IsZero())
|
||||
return false;
|
||||
return !m_DataHandler->HasConvoTag(currentConvoTag);
|
||||
}
|
||||
}
|
||||
// if we are dead return true so we are removed
|
||||
|
@ -333,28 +293,27 @@ namespace llarp
|
|||
}
|
||||
|
||||
bool
|
||||
OutboundContext::SelectHop(llarp_nodedb* db, const RouterContact& prev,
|
||||
OutboundContext::SelectHop(llarp_nodedb* db,
|
||||
const std::set< RouterID >& prev,
|
||||
RouterContact& cur, size_t hop,
|
||||
path::PathRole roles)
|
||||
{
|
||||
if(remoteIntro.router.IsZero())
|
||||
if(m_NextIntro.router.IsZero() || prev.count(m_NextIntro.router))
|
||||
{
|
||||
SwapIntros();
|
||||
if(!ShiftIntroduction(false))
|
||||
return false;
|
||||
}
|
||||
std::set< RouterID > exclude = prev;
|
||||
exclude.insert(m_NextIntro.router);
|
||||
if(hop == numHops - 1)
|
||||
{
|
||||
m_Endpoint->EnsureRouterIsKnown(remoteIntro.router);
|
||||
if(db->Get(remoteIntro.router, cur))
|
||||
m_Endpoint->EnsureRouterIsKnown(m_NextIntro.router);
|
||||
if(db->Get(m_NextIntro.router, cur))
|
||||
return true;
|
||||
++m_BuildFails;
|
||||
return false;
|
||||
}
|
||||
else if(hop == numHops - 2)
|
||||
{
|
||||
return db->select_random_hop_excluding(
|
||||
cur, {prev.pubkey, remoteIntro.router});
|
||||
}
|
||||
return path::Builder::SelectHop(db, prev, cur, hop, roles);
|
||||
return path::Builder::SelectHop(db, exclude, cur, hop, roles);
|
||||
}
|
||||
|
||||
bool
|
||||
|
@ -411,13 +370,10 @@ namespace llarp
|
|||
if(shiftedRouter)
|
||||
{
|
||||
lastShift = now;
|
||||
BuildOneAlignedTo(m_NextIntro.router);
|
||||
if(!BuildCooldownHit(now))
|
||||
BuildOneAlignedTo(m_NextIntro.router);
|
||||
}
|
||||
else if(shiftedIntro)
|
||||
{
|
||||
SwapIntros();
|
||||
}
|
||||
else
|
||||
else if(!shiftedIntro)
|
||||
{
|
||||
LogInfo(Name(), " updating introset");
|
||||
UpdateIntroSet(true);
|
||||
|
@ -433,7 +389,7 @@ namespace llarp
|
|||
if(now - lastShift < MIN_SHIFT_INTERVAL)
|
||||
return false;
|
||||
bool shifted = false;
|
||||
// to find a intro on the same router as before
|
||||
// to find a intro on the same router as before that is newer
|
||||
for(const auto& intro : currentIntroSet.I)
|
||||
{
|
||||
if(intro.ExpiresSoon(now))
|
||||
|
@ -441,10 +397,14 @@ namespace llarp
|
|||
if(m_BadIntros.find(intro) == m_BadIntros.end()
|
||||
&& remoteIntro.router == intro.router)
|
||||
{
|
||||
m_NextIntro = intro;
|
||||
return true;
|
||||
if(intro.expiresAt > m_NextIntro.expiresAt)
|
||||
{
|
||||
m_NextIntro = intro;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
/// pick newer intro not on same router
|
||||
for(const auto& intro : currentIntroSet.I)
|
||||
{
|
||||
m_Endpoint->EnsureRouterIsKnown(intro.router);
|
||||
|
@ -452,19 +412,21 @@ namespace llarp
|
|||
continue;
|
||||
if(m_BadIntros.find(intro) == m_BadIntros.end() && m_NextIntro != intro)
|
||||
{
|
||||
shifted = intro.router != m_NextIntro.router
|
||||
|| (now < intro.expiresAt
|
||||
&& intro.expiresAt - now
|
||||
> 10 * 1000); // TODO: hardcoded value
|
||||
m_NextIntro = intro;
|
||||
success = true;
|
||||
break;
|
||||
shifted = intro.router != m_NextIntro.router;
|
||||
if(intro.expiresAt > m_NextIntro.expiresAt)
|
||||
{
|
||||
m_NextIntro = intro;
|
||||
success = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(shifted && rebuild)
|
||||
if(m_NextIntro.router.IsZero())
|
||||
return false;
|
||||
if(shifted)
|
||||
{
|
||||
lastShift = now;
|
||||
BuildOneAlignedTo(m_NextIntro.router);
|
||||
if(rebuild && !BuildCooldownHit(Now()))
|
||||
BuildOneAlignedTo(m_NextIntro.router);
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
@ -526,9 +488,7 @@ namespace llarp
|
|||
++num;
|
||||
});
|
||||
// build a path if one isn't already pending build or established
|
||||
if(num == 0)
|
||||
BuildOneAlignedTo(m_NextIntro.router);
|
||||
SwapIntros();
|
||||
BuildOneAlignedTo(m_NextIntro.router);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -82,15 +82,12 @@ namespace llarp
|
|||
void
|
||||
UpdateIntroSet(bool randomizePath) override;
|
||||
|
||||
bool
|
||||
BuildOneAlignedTo(const RouterID& remote);
|
||||
|
||||
void
|
||||
HandlePathBuilt(path::Path_ptr path) override;
|
||||
|
||||
bool
|
||||
SelectHop(llarp_nodedb* db, const RouterContact& prev, RouterContact& cur,
|
||||
size_t hop, path::PathRole roles) override;
|
||||
SelectHop(llarp_nodedb* db, const std::set< RouterID >& prev,
|
||||
RouterContact& cur, size_t hop, path::PathRole roles) override;
|
||||
|
||||
bool
|
||||
HandleHiddenServiceFrame(path::Path_ptr p, const ProtocolFrame& frame);
|
||||
|
|
|
@ -0,0 +1,22 @@
|
|||
#ifndef LLARP_UTIL_COMPARE_PTR_HPP
|
||||
#define LLARP_UTIL_COMPARE_PTR_HPP
|
||||
#include <functional>
|
||||
|
||||
namespace llarp
|
||||
{
|
||||
/// type for comparing smart pointer's managed values
|
||||
template < typename Ptr_t, typename Compare = std::less<> >
|
||||
struct ComparePtr
|
||||
{
|
||||
bool
|
||||
operator()(const Ptr_t& left, const Ptr_t& right) const
|
||||
{
|
||||
if(left && right)
|
||||
return Compare()(*left, *right);
|
||||
else
|
||||
return Compare()(left, right);
|
||||
}
|
||||
};
|
||||
} // namespace llarp
|
||||
|
||||
#endif
|
|
@ -32,15 +32,15 @@ namespace llarp
|
|||
if(!sock)
|
||||
return;
|
||||
ssize_t expect = 0;
|
||||
std::vector< utp_iovec > vecs;
|
||||
std::vector< utp_iovec > send;
|
||||
for(const auto& vec : vecq)
|
||||
{
|
||||
expect += vec.iov_len;
|
||||
vecs.push_back(vec);
|
||||
send.emplace_back(vec);
|
||||
}
|
||||
if(expect)
|
||||
{
|
||||
ssize_t s = utp_writev(sock, vecs.data(), vecs.size());
|
||||
ssize_t s = utp_writev(sock, send.data(), send.size());
|
||||
if(s < 0)
|
||||
return;
|
||||
if(s > 0)
|
||||
|
@ -189,7 +189,7 @@ namespace llarp
|
|||
bool
|
||||
Session::TimedOut(llarp_time_t now) const
|
||||
{
|
||||
if(state == eInitial)
|
||||
if(state == eInitial || state == eLinkEstablished)
|
||||
return false;
|
||||
if(sendq.size() >= MaxSendQueueSize)
|
||||
{
|
||||
|
@ -254,7 +254,16 @@ namespace llarp
|
|||
Session::SendMessageBuffer(const llarp_buffer_t& buf)
|
||||
{
|
||||
if(sendq.size() >= MaxSendQueueSize)
|
||||
{
|
||||
// pump write queue if we seem to be full
|
||||
PumpWrite();
|
||||
}
|
||||
if(sendq.size() >= MaxSendQueueSize)
|
||||
{
|
||||
// we didn't pump anything wtf
|
||||
// this means we're stalled
|
||||
return false;
|
||||
}
|
||||
size_t sz = buf.sz;
|
||||
byte_t* ptr = buf.base;
|
||||
uint32_t msgid = m_NextTXMsgID++;
|
||||
|
@ -270,7 +279,6 @@ namespace llarp
|
|||
ptr += s;
|
||||
sz -= s;
|
||||
}
|
||||
PumpWrite();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -120,9 +120,9 @@ namespace llarp
|
|||
SendKeepAlive() override;
|
||||
|
||||
bool
|
||||
IsEstablished() override
|
||||
IsEstablished() const override
|
||||
{
|
||||
return state == eSessionReady || state == eLinkEstablished;
|
||||
return state == eSessionReady;
|
||||
}
|
||||
|
||||
bool
|
||||
|
|
Loading…
Reference in New Issue