From 5d3833ef1aad5baf487488208dff45d00a0bfd53 Mon Sep 17 00:00:00 2001 From: Jeff Becker Date: Mon, 11 Mar 2019 09:58:31 -0400 Subject: [PATCH] fix dumb as shit path building that causes premature termiantion because of duplicate hops --- llarp/exit/session.cpp | 5 +++++ llarp/link/utp.cpp | 2 ++ llarp/nodedb.cpp | 44 ++++++++++++++++++++++++++++++++++++++ llarp/nodedb.hpp | 7 ++++++ llarp/path/path.cpp | 9 ++++++++ llarp/path/path.hpp | 3 +++ llarp/path/pathbuilder.cpp | 10 ++++++--- llarp/path/pathset.cpp | 2 +- llarp/profiling.cpp | 2 +- llarp/router_contact.hpp | 6 ++++++ llarp/service/endpoint.cpp | 5 +++++ 11 files changed, 90 insertions(+), 5 deletions(-) diff --git a/llarp/exit/session.cpp b/llarp/exit/session.cpp index 100e8a1e7..f4a5f2603 100644 --- a/llarp/exit/session.cpp +++ b/llarp/exit/session.cpp @@ -67,6 +67,11 @@ namespace llarp { return db->Get(m_ExitRouter, cur); } + 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); } diff --git a/llarp/link/utp.cpp b/llarp/link/utp.cpp index ac5ee31cc..ae030b35b 100644 --- a/llarp/link/utp.cpp +++ b/llarp/link/utp.cpp @@ -228,6 +228,8 @@ namespace llarp bool Session::IsTimedOut(llarp_time_t now) const { + if(state == eConnecting) + return false; if(state == eClose) return true; if(now <= lastActive) diff --git a/llarp/nodedb.cpp b/llarp/nodedb.cpp index bcef02c6c..897886f90 100644 --- a/llarp/nodedb.cpp +++ b/llarp/nodedb.cpp @@ -468,3 +468,47 @@ llarp_nodedb::select_random_hop(const llarp::RouterContact &prev, } return false; } + +bool +llarp_nodedb::select_random_hop_excluding( + llarp::RouterContact &result, const std::set< llarp::RouterID > &exclude) +{ + llarp::util::Lock lock(&access); + /// checking for "guard" status for N = 0 is done by caller inside of + /// pathbuilder's scope + size_t sz = entries.size(); + if(sz < 3) + return false; + llarp_time_t now = llarp::time_now_ms(); + + auto itr = entries.begin(); + size_t pos = llarp::randint() % sz; + std::advance(itr, pos); + auto start = itr; + while(itr == entries.end()) + { + if(exclude.count(itr->first) == 0) + { + if(itr->second.addrs.size() && !itr->second.IsExpired(now)) + { + result = itr->second; + return true; + } + } + itr++; + } + itr = entries.begin(); + while(itr != start) + { + if(exclude.count(itr->first) == 0) + { + if(itr->second.addrs.size() && !itr->second.IsExpired(now)) + { + result = itr->second; + return true; + } + } + ++itr; + } + return false; +} diff --git a/llarp/nodedb.hpp b/llarp/nodedb.hpp index 61109797e..b3c4a94fe 100644 --- a/llarp/nodedb.hpp +++ b/llarp/nodedb.hpp @@ -9,6 +9,8 @@ #include +#include + /** * nodedb.hpp * @@ -113,6 +115,11 @@ struct llarp_nodedb llarp::RouterContact &result, size_t N) LOCKS_EXCLUDED(access); + bool + select_random_hop_excluding(llarp::RouterContact &result, + const std::set< llarp::RouterID > &exclude) + LOCKS_EXCLUDED(access); + static bool ensure_dir(const char *dir); }; diff --git a/llarp/path/path.cpp b/llarp/path/path.cpp index f3d7931a5..dcd546cc9 100644 --- a/llarp/path/path.cpp +++ b/llarp/path/path.cpp @@ -450,6 +450,15 @@ namespace llarp return hops[0].rc.pubkey; } + std::string + Path::HopsString() const + { + std::stringstream ss; + for(const auto& hop : hops) + ss << RouterID(hop.rc.pubkey) << " -> "; + return ss.str(); + } + void Path::EnterState(PathStatus st, llarp_time_t now) { diff --git a/llarp/path/path.hpp b/llarp/path/path.hpp index 12fcaa510..ab1ee722b 100644 --- a/llarp/path/path.hpp +++ b/llarp/path/path.hpp @@ -362,6 +362,9 @@ namespace llarp return _status; } + std::string + HopsString() const; + llarp_time_t LastRemoteActivityAt() const override { diff --git a/llarp/path/pathbuilder.cpp b/llarp/path/pathbuilder.cpp index 5b2289f79..53433b005 100644 --- a/llarp/path/pathbuilder.cpp +++ b/llarp/path/pathbuilder.cpp @@ -213,11 +213,15 @@ namespace llarp size_t tries = 10; do { + cur.Clear(); --tries; if(db->select_random_hop(prev, cur, hop)) - return true; - } while(router->routerProfiling().IsBad(cur.pubkey) && tries > 0); - return false; + { + if(!router->routerProfiling().IsBad(cur.pubkey)) + return true; + } + } while(tries > 0); + return tries > 0; } bool diff --git a/llarp/path/pathset.cpp b/llarp/path/pathset.cpp index 469899eb1..54efeffd1 100644 --- a/llarp/path/pathset.cpp +++ b/llarp/path/pathset.cpp @@ -292,7 +292,7 @@ namespace llarp void PathSet::HandlePathBuildTimeout(Path* p) { - LogInfo("path build for ", p->Name(), " has timed out"); + LogInfo("path build ", p->HopsString(), " timed out"); } bool diff --git a/llarp/profiling.cpp b/llarp/profiling.cpp index 4bb7146a1..da2a1164d 100644 --- a/llarp/profiling.cpp +++ b/llarp/profiling.cpp @@ -70,7 +70,7 @@ namespace llarp bool RouterProfile::IsGood(uint64_t chances) const { - if(connectTimeoutCount > 3) + if(connectTimeoutCount > chances) return connectTimeoutCount <= connectGoodCount && (pathSuccessCount * chances) >= pathFailCount; else diff --git a/llarp/router_contact.hpp b/llarp/router_contact.hpp index 4ee9278e4..db7a0e9a3 100644 --- a/llarp/router_contact.hpp +++ b/llarp/router_contact.hpp @@ -131,6 +131,12 @@ namespace llarp && netID == other.netID; } + bool + operator<(const RouterContact &other) const + { + return pubkey < other.pubkey; + } + bool operator!=(const RouterContact &other) const { diff --git a/llarp/service/endpoint.cpp b/llarp/service/endpoint.cpp index d89520e78..d589c71ec 100644 --- a/llarp/service/endpoint.cpp +++ b/llarp/service/endpoint.cpp @@ -1854,6 +1854,11 @@ namespace llarp return false; } } + else if(hop == numHops - 2) + { + return db->select_random_hop_excluding( + cur, {prev.pubkey, m_NextIntro.router}); + } (void)roles; return path::Builder::SelectHop(db, prev, cur, hop, roles); }