diff --git a/llarp/ev/ev.hpp b/llarp/ev/ev.hpp index c46449450..b759f25d7 100644 --- a/llarp/ev/ev.hpp +++ b/llarp/ev/ev.hpp @@ -712,7 +712,6 @@ struct llarp_fd_promise struct llarp_ev_loop { byte_t readbuf[EV_READ_BUF_SZ] = {0}; - llarp_time_t _now = 0; virtual bool init() = 0; @@ -726,13 +725,12 @@ struct llarp_ev_loop virtual void update_time() { - _now = llarp::time_now_ms(); } virtual llarp_time_t time_now() const { - return _now; + return llarp::time_now_ms(); } virtual void diff --git a/llarp/ev/ev_libuv.cpp b/llarp/ev/ev_libuv.cpp index 7ea06f025..b003e76bb 100644 --- a/llarp/ev/ev_libuv.cpp +++ b/llarp/ev/ev_libuv.cpp @@ -798,6 +798,7 @@ namespace libuv void Loop::update_time() { + llarp_ev_loop::update_time(); uv_update_time(&m_Impl); } @@ -807,12 +808,6 @@ namespace libuv return m_Run.load(); } - llarp_time_t - Loop::time_now() const - { - return llarp::time_now_ms(); - } - bool Loop::tcp_connect(llarp_tcp_connecter* tcp, const sockaddr* addr) { diff --git a/llarp/ev/ev_libuv.hpp b/llarp/ev/ev_libuv.hpp index 2a75c9977..d5c86845b 100644 --- a/llarp/ev/ev_libuv.hpp +++ b/llarp/ev/ev_libuv.hpp @@ -26,9 +26,6 @@ namespace libuv void update_time() override; - llarp_time_t - time_now() const override; - /// return false on socket error (non blocking) bool tcp_connect(llarp_tcp_connecter* tcp, const sockaddr* addr) override; diff --git a/llarp/path/path.cpp b/llarp/path/path.cpp index 4f1014f81..975ba028b 100644 --- a/llarp/path/path.cpp +++ b/llarp/path/path.cpp @@ -320,11 +320,14 @@ namespace llarp if(_status == ePathBuilding) { + if(buildStarted == 0) + return; if(now >= buildStarted) { - auto dlt = now - buildStarted; + const auto dlt = now - buildStarted; if(dlt >= path::build_timeout) { + LogWarn(Name(), " waited for ", dlt, "ms and no path was built"); r->routerProfiling().MarkPathFail(this); EnterState(ePathExpired, now); return; @@ -350,6 +353,7 @@ namespace llarp const auto delay = now - m_LastRecvMessage; if(m_CheckForDead && m_CheckForDead(shared_from_this(), delay)) { + LogWarn(Name(), " waited for ", dlt, "ms and path is unresponsive"); r->routerProfiling().MarkPathFail(this); EnterState(ePathTimeout, now); } @@ -358,6 +362,7 @@ namespace llarp { if(m_CheckForDead && m_CheckForDead(shared_from_this(), dlt)) { + LogWarn(Name(), " waited for ", dlt, "ms and path looks dead"); r->routerProfiling().MarkPathFail(this); EnterState(ePathTimeout, now); } @@ -433,11 +438,12 @@ namespace llarp { if(_status == ePathFailed) return true; - if(_status == ePathEstablished || _status == ePathTimeout) - return now >= ExpireTime(); if(_status == ePathBuilding) return false; - + if(_status == ePathEstablished || _status == ePathTimeout) + { + return now >= ExpireTime(); + } return true; } @@ -574,7 +580,7 @@ namespace llarp Path::HandlePathConfirmMessage(AbstractRouter* r) { LogDebug("Path Build Confirm, path: ", HopsString()); - auto now = r->Now(); + const auto now = llarp::time_now_ms(); if(_status == ePathBuilding) { // finish initializing introduction diff --git a/llarp/path/path.hpp b/llarp/path/path.hpp index a2705e0fe..966e2f399 100644 --- a/llarp/path/path.hpp +++ b/llarp/path/path.hpp @@ -94,7 +94,7 @@ namespace llarp service::Introduction intro; - llarp_time_t buildStarted; + llarp_time_t buildStarted = 0; Path(const std::vector< RouterContact >& routers, PathSet* parent, PathRole startingRoles); diff --git a/llarp/path/path_context.cpp b/llarp/path/path_context.cpp index ff2c02622..f48dc4382 100644 --- a/llarp/path/path_context.cpp +++ b/llarp/path/path_context.cpp @@ -295,15 +295,8 @@ namespace llarp ++itr; } } - { - SyncOwnedPathsMap_t::Lock_t lock(&m_OurPaths.first); - auto& map = m_OurPaths.second; - for(auto& item : map) - { - item.second->ExpirePaths(now); - } - } } + routing::MessageHandler_ptr PathContext::GetHandler(const PathID_t& id) { diff --git a/llarp/path/pathbuilder.cpp b/llarp/path/pathbuilder.cpp index b67b018d4..c4f67c565 100644 --- a/llarp/path/pathbuilder.cpp +++ b/llarp/path/pathbuilder.cpp @@ -162,13 +162,13 @@ namespace llarp lastBuild = 0; } - void - Builder::Tick(llarp_time_t now) + void Builder::Tick(llarp_time_t) { + const auto now = llarp::time_now_ms(); ExpirePaths(now); if(ShouldBuildMore(now)) BuildOne(); - TickPaths(now, m_router); + TickPaths(m_router); if(m_BuildStats.attempts > 50) { if(m_BuildStats.SuccsessRatio() <= BuildStats::MinGoodRatio @@ -281,7 +281,9 @@ namespace llarp { if(IsStopped()) return false; - return PathSet::ShouldBuildMore(now) && !BuildCooldownHit(now); + if(BuildCooldownHit(now)) + return false; + return PathSet::ShouldBuildMore(now); } void @@ -426,11 +428,12 @@ namespace llarp // async generate keys auto ctx = std::make_shared< AsyncPathKeyExchangeContext >(); ctx->router = m_router; - ctx->pathset = GetSelf(); - auto path = std::make_shared< path::Path >(hops, this, roles); + auto self = GetSelf(); + ctx->pathset = self; + auto path = std::make_shared< path::Path >(hops, self.get(), roles); LogInfo(Name(), " build ", path->HopsString()); path->SetBuildResultHook( - [this](Path_ptr p) { this->HandlePathBuilt(p); }); + [self](Path_ptr p) { self->HandlePathBuilt(p); }); ctx->AsyncGenerateKeys(path, m_router->logic(), m_router->threadpool(), &PathBuilderKeysGenerated); } diff --git a/llarp/path/pathset.cpp b/llarp/path/pathset.cpp index b7555e895..d8929866f 100644 --- a/llarp/path/pathset.cpp +++ b/llarp/path/pathset.cpp @@ -3,6 +3,7 @@ #include #include #include +#include namespace llarp { @@ -17,10 +18,10 @@ namespace llarp { (void)now; const auto building = NumInStatus(ePathBuilding); - if(building > numPaths) + if(building >= numPaths) return false; const auto established = NumInStatus(ePathEstablished); - return established <= numPaths; + return established < numPaths; } bool @@ -61,8 +62,9 @@ namespace llarp } void - PathSet::TickPaths(llarp_time_t now, AbstractRouter* r) + PathSet::TickPaths(AbstractRouter* r) { + const auto now = llarp::time_now_ms(); Lock_t l(&m_PathsMutex); for(auto& item : m_Paths) { @@ -80,7 +82,9 @@ namespace llarp while(itr != m_Paths.end()) { if(itr->second->Expired(now)) + { itr = m_Paths.erase(itr); + } else ++itr; } @@ -221,9 +225,14 @@ namespace llarp PathSet::AddPath(Path_ptr path) { Lock_t l(&m_PathsMutex); - auto upstream = path->Upstream(); // RouterID - auto RXID = path->RXID(); // PathID - m_Paths.emplace(std::make_pair(upstream, RXID), std::move(path)); + const auto upstream = path->Upstream(); // RouterID + const auto RXID = path->RXID(); // PathID + if(not m_Paths.emplace(std::make_pair(upstream, RXID), path).second) + { + LogError(Name(), + " failed to add own path, duplicate info wtf? upstream=", + upstream, " rxid=", RXID); + } } void diff --git a/llarp/path/pathset.hpp b/llarp/path/pathset.hpp index 13bb13aa2..1da9a30ce 100644 --- a/llarp/path/pathset.hpp +++ b/llarp/path/pathset.hpp @@ -287,7 +287,7 @@ namespace llarp BuildStats m_BuildStats; void - TickPaths(llarp_time_t now, AbstractRouter* r); + TickPaths(AbstractRouter* r); using PathInfo_t = std::pair< RouterID, PathID_t >; @@ -299,10 +299,20 @@ namespace llarp return RouterID::Hash()(i.first) ^ PathID_t::Hash()(i.second); } }; - using Mtx_t = util::NullMutex; - using Lock_t = util::NullLock; - using PathMap_t = - std::unordered_map< PathInfo_t, Path_ptr, PathInfoHash >; + + struct PathInfoEquals + { + bool + operator()(const PathInfo_t& left, const PathInfo_t& right) const + { + return left.first == right.first && left.second == right.second; + } + }; + + using Mtx_t = util::NullMutex; + using Lock_t = util::NullLock; + using PathMap_t = std::unordered_map< PathInfo_t, Path_ptr, PathInfoHash, + PathInfoEquals >; mutable Mtx_t m_PathsMutex; PathMap_t m_Paths; }; diff --git a/llarp/router/router.cpp b/llarp/router/router.cpp index ea5c95e3d..20c06cefb 100644 --- a/llarp/router/router.cpp +++ b/llarp/router/router.cpp @@ -668,7 +668,7 @@ namespace llarp if(_stopping) return; // LogDebug("tick router"); - auto now = Now(); + const auto now = Now(); routerProfiling().Tick(); @@ -698,8 +698,6 @@ namespace llarp return !_rcLookupHandler.RemoteIsAllowed(rc.pubkey); }); } - // expire paths - paths.ExpirePaths(now); _linkManager.CheckPersistingSessions(now); @@ -726,12 +724,9 @@ namespace llarp _outboundSessionMaker.ConnectToRandomRouters(dlt, now); } - if(!isSvcNode) - { - _hiddenServiceContext.Tick(now); - } - + _hiddenServiceContext.Tick(now); _exitContext.Tick(now); + if(rpcCaller) rpcCaller->Tick(now); // save profiles async @@ -752,6 +747,8 @@ namespace llarp _dht->impl->Nodes()->RemoveIf([&peersWeHave](const dht::Key_t &k) -> bool { return peersWeHave.count(k) == 0; }); + // expire paths + paths.ExpirePaths(now); } // namespace llarp bool diff --git a/llarp/service/endpoint.cpp b/llarp/service/endpoint.cpp index b39414e98..327d2a6cf 100644 --- a/llarp/service/endpoint.cpp +++ b/llarp/service/endpoint.cpp @@ -67,13 +67,13 @@ namespace llarp } void - Endpoint::RegenAndPublishIntroSet(llarp_time_t now, bool forceRebuild) + Endpoint::RegenAndPublishIntroSet(bool forceRebuild) { + const auto now = llarp::time_now_ms(); std::set< Introduction > I; if(!GetCurrentIntroductionsWithFilter( I, [now](const service::Introduction& intro) -> bool { - return now < intro.expiresAt - && intro.expiresAt - now > (2 * 60 * 1000); + return not intro.ExpiresSoon(now, 2 * 60 * 1000); })) { LogWarn("could not publish descriptors for endpoint ", Name(), @@ -169,13 +169,14 @@ namespace llarp } void - Endpoint::Tick(llarp_time_t now) + Endpoint::Tick(llarp_time_t) { + const auto now = llarp::time_now_ms(); path::Builder::Tick(now); // publish descriptors if(ShouldPublishDescriptors(now)) { - RegenAndPublishIntroSet(now); + RegenAndPublishIntroSet(); } // expire snode sessions @@ -542,7 +543,7 @@ namespace llarp auto now = Now(); if(ShouldPublishDescriptors(now)) { - RegenAndPublishIntroSet(now); + RegenAndPublishIntroSet(); } else if(NumInStatus(path::ePathEstablished) < 3) { @@ -581,8 +582,6 @@ namespace llarp bool Endpoint::ShouldPublishDescriptors(llarp_time_t now) const { - if(NumInStatus(path::ePathEstablished) < 3) - return false; // make sure we have all paths that are established // in our introset size_t numNotInIntroset = 0; @@ -597,7 +596,7 @@ namespace llarp ++numNotInIntroset; }); - auto lastpub = m_state->m_LastPublishAttempt; + const auto lastpub = m_state->m_LastPublishAttempt; if(m_state->m_IntroSet.HasExpiredIntros(now) || numNotInIntroset > 1) { return now - lastpub >= INTROSET_PUBLISH_RETRY_INTERVAL; @@ -905,7 +904,7 @@ namespace llarp void Endpoint::HandlePathDied(path::Path_ptr) { - RegenAndPublishIntroSet(Now(), true); + RegenAndPublishIntroSet(true); } bool @@ -1227,6 +1226,8 @@ namespace llarp bool Endpoint::ShouldBuildMore(llarp_time_t now) const { + if(path::Builder::BuildCooldownHit(now)) + return false; const bool should = path::Builder::ShouldBuildMore(now); // determine newest intro Introduction intro; @@ -1235,12 +1236,13 @@ namespace llarp // time from now that the newest intro expires at if(intro.ExpiresSoon(now)) return should; + const auto dlt = now - (intro.expiresAt - path::default_lifetime); + return should || ( // try spacing tunnel builds out evenly in time (dlt >= (path::default_lifetime / 4)) - && (NumInStatus(path::ePathBuilding) < numPaths) - && !path::Builder::BuildCooldownHit(now)); + && (NumInStatus(path::ePathBuilding) < numPaths)); } std::shared_ptr< Logic > diff --git a/llarp/service/endpoint.hpp b/llarp/service/endpoint.hpp index 68b088e01..0dd858cc7 100644 --- a/llarp/service/endpoint.hpp +++ b/llarp/service/endpoint.hpp @@ -377,7 +377,7 @@ namespace llarp SupportsV6() const = 0; void - RegenAndPublishIntroSet(llarp_time_t now, bool forceRebuild = false); + RegenAndPublishIntroSet(bool forceRebuild = false); IServiceLookup* GenerateLookupByTag(const Tag& tag); diff --git a/llarp/service/intro.cpp b/llarp/service/intro.cpp index fbebce544..deaf49e86 100644 --- a/llarp/service/intro.cpp +++ b/llarp/service/intro.cpp @@ -67,6 +67,7 @@ namespace llarp { Printer printer(stream, level, spaces); printer.printAttribute("k", RouterID(router)); + printer.printAttribute("l", latency); printer.printAttribute("p", pathID); printer.printAttribute("v", version); printer.printAttribute("x", expiresAt); diff --git a/llarp/util/time.cpp b/llarp/util/time.cpp index 74ce674ae..db199ef41 100644 --- a/llarp/util/time.cpp +++ b/llarp/util/time.cpp @@ -1,7 +1,11 @@ #include +#include +#include namespace llarp { + using Clock_t = std::chrono::system_clock; + template < typename Res > static llarp_time_t time_since_epoch() @@ -18,6 +22,28 @@ namespace llarp llarp_time_t time_now_ms() { - return llarp::time_since_epoch< std::chrono::milliseconds >(); + static llarp_time_t lastTime = 0; + auto t = llarp::time_since_epoch< std::chrono::milliseconds >(); + if(t <= lastTime) + { + return lastTime; + } + if(lastTime == 0) + { + lastTime = t; + } + const auto dlt = t - lastTime; + if(dlt > 5000) + { + // big timeskip + printf("big timeskip %ld ms\n", dlt); + t = lastTime; + lastTime = 0; + } + else + { + lastTime = t; + } + return t; } } // namespace llarp diff --git a/llarp/util/time.hpp b/llarp/util/time.hpp index f29c50ff4..17820190f 100644 --- a/llarp/util/time.hpp +++ b/llarp/util/time.hpp @@ -3,12 +3,8 @@ #include -#include - namespace llarp { - using Clock_t = std::chrono::system_clock; - llarp_time_t time_now_ms(); } // namespace llarp