From df322e1149380e1cbf31a88851bbd7740b62ec74 Mon Sep 17 00:00:00 2001 From: Jeff Becker Date: Wed, 8 May 2019 10:01:31 -0400 Subject: [PATCH] don't include duplicate hops in paths --- llarp/exit/session.cpp | 11 ++++----- llarp/exit/session.hpp | 5 ++-- llarp/path/pathbuilder.cpp | 38 +++++++++++++----------------- llarp/path/pathbuilder.hpp | 4 ++-- llarp/path/pathset.hpp | 4 ++-- llarp/service/outbound_context.cpp | 12 ++++------ llarp/service/outbound_context.hpp | 4 ++-- 7 files changed, 34 insertions(+), 44 deletions(-) diff --git a/llarp/exit/session.cpp b/llarp/exit/session.cpp index b559a728e..34ff4e9c2 100644 --- a/llarp/exit/session.cpp +++ b/llarp/exit/session.cpp @@ -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 diff --git a/llarp/exit/session.hpp b/llarp/exit/session.hpp index 91265ceda..37736af6d 100644 --- a/llarp/exit/session.hpp +++ b/llarp/exit/session.hpp @@ -60,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; diff --git a/llarp/path/pathbuilder.cpp b/llarp/path/pathbuilder.cpp index f1012d579..7451f9ef1 100644 --- a/llarp/path/pathbuilder.cpp +++ b/llarp/path/pathbuilder.cpp @@ -213,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; @@ -232,7 +232,8 @@ namespace llarp if(s && s->IsEstablished() && isOutbound && !got) { const RouterContact rc = s->GetRemoteRC(); - if(got || router->IsBootstrapNode(rc.pubkey)) + if(got || router->IsBootstrapNode(rc.pubkey) + || exclude.count(rc.pubkey)) return; cur = rc; got = true; @@ -241,16 +242,16 @@ namespace llarp 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)) { if(!router->routerProfiling().IsBadForPath(cur.pubkey)) return true; - exclude.insert(cur.pubkey); + excluding.insert(cur.pubkey); } } while(tries > 0); return tries > 0; @@ -312,7 +313,7 @@ namespace llarp Builder::BuildOneAlignedTo(const RouterID remote) { std::vector< RouterContact > hops; - + std::set< RouterID > routers = {remote}; /// if we really need this path build it "dangerously" if(UrgentBuild(router->Now())) { @@ -345,7 +346,7 @@ namespace llarp { if(hop == 0) { - if(!SelectHop(nodedb, hops[0], hops[0], 0, path::ePathRoleAny)) + if(!SelectHop(nodedb, routers, hops[0], 0, path::ePathRoleAny)) return false; } else if(hop == numHops - 1) @@ -363,14 +364,14 @@ namespace llarp size_t tries = 5; do { - nodedb->select_random_hop_excluding( - hops[hop], {hops[hop - 1].pubkey, remote}); + nodedb->select_random_hop_excluding(hops[hop], routers); --tries; } while(router->routerProfiling().IsBadForPath(hops[hop].pubkey) && tries > 0); - return tries > 0; + if(tries == 0) + return false; } - return false; + routers.insert(hops[hop].pubkey); } } LogInfo(Name(), " building path to ", remote); @@ -384,25 +385,18 @@ namespace llarp { hops.resize(numHops); size_t idx = 0; + std::set< RouterID > exclude; while(idx < numHops) { 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; - } + while(tries > 0 && !SelectHop(nodedb, exclude, hops[idx], idx, roles)) + --tries; if(tries == 0) { LogWarn(Name(), " failed to select hop ", idx); return false; } + exclude.insert(hops[idx].pubkey); ++idx; } return true; diff --git a/llarp/path/pathbuilder.hpp b/llarp/path/pathbuilder.hpp index 4647c9b2f..0aeb170d0 100644 --- a/llarp/path/pathbuilder.hpp +++ b/llarp/path/pathbuilder.hpp @@ -42,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; diff --git a/llarp/path/pathset.hpp b/llarp/path/pathset.hpp index 94702fa5b..9e3e53784 100644 --- a/llarp/path/pathset.hpp +++ b/llarp/path/pathset.hpp @@ -221,8 +221,8 @@ namespace llarp 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; virtual bool BuildOneAlignedTo(const RouterID endpoint) = 0; diff --git a/llarp/service/outbound_context.cpp b/llarp/service/outbound_context.cpp index d9749d228..01fd6dcef 100644 --- a/llarp/service/outbound_context.cpp +++ b/llarp/service/outbound_context.cpp @@ -293,7 +293,8 @@ 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) { @@ -302,6 +303,8 @@ namespace llarp if(!ShiftIntroduction(false)) return false; } + std::set< RouterID > exclude = prev; + exclude.insert(m_NextIntro.router); if(hop == numHops - 1) { m_Endpoint->EnsureRouterIsKnown(m_NextIntro.router); @@ -310,12 +313,7 @@ namespace llarp ++m_BuildFails; return false; } - else if(hop == numHops - 2) - { - return db->select_random_hop_excluding( - cur, {prev.pubkey, m_NextIntro.router}); - } - return path::Builder::SelectHop(db, prev, cur, hop, roles); + return path::Builder::SelectHop(db, exclude, cur, hop, roles); } bool diff --git a/llarp/service/outbound_context.hpp b/llarp/service/outbound_context.hpp index 62902676d..6cffa1296 100644 --- a/llarp/service/outbound_context.hpp +++ b/llarp/service/outbound_context.hpp @@ -86,8 +86,8 @@ namespace llarp 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);