diff --git a/llarp/router/i_gossiper.hpp b/llarp/router/i_gossiper.hpp index 9485f49df..fff35fb13 100644 --- a/llarp/router/i_gossiper.hpp +++ b/llarp/router/i_gossiper.hpp @@ -14,7 +14,15 @@ namespace llarp GossipRC(const RouterContact &rc) = 0; virtual void - Decay(llarp_time_t now) = 0; + Decay(Time_t now) = 0; + + /// return true if we should gossip our RC now + virtual bool + ShouldGossipOurRC(Time_t now) const = 0; + + /// return true if that rc is owned by us + virtual bool + IsOurRC(const RouterContact &rc) const = 0; }; } // namespace llarp diff --git a/llarp/router/rc_gossiper.cpp b/llarp/router/rc_gossiper.cpp index 114dcf7ad..2dd992423 100644 --- a/llarp/router/rc_gossiper.cpp +++ b/llarp/router/rc_gossiper.cpp @@ -1,24 +1,47 @@ #include #include #include +#include namespace llarp { + // 30 minutes + static constexpr auto RCGossipFilterDecayInterval = 30min; + // 60 - 5 minutes + static constexpr auto GossipOurRCInterval = + (RCGossipFilterDecayInterval * 2) - (5min); + RCGossiper::RCGossiper() - : I_RCGossiper(), m_Filter(RouterContact::UpdateInterval) + : I_RCGossiper() + , m_Filter( + std::chrono::duration_cast< Time_t >(RCGossipFilterDecayInterval)) { } void - RCGossiper::Init(ILinkManager* l) + RCGossiper::Init(ILinkManager* l, const RouterID& ourID) { + m_OurRouterID = ourID; m_LinkManager = l; } + bool + RCGossiper::ShouldGossipOurRC(Time_t now) const + { + return now >= (m_LastGossipedOurRC + GossipOurRCInterval); + } + + bool + RCGossiper::IsOurRC(const RouterContact& rc) const + { + return rc.pubkey == m_OurRouterID; + } + void - RCGossiper::Decay(llarp_time_t now) + RCGossiper::Decay(Time_t now) { - m_Filter.Decay(now); + LogDebug("decay filter at ", now.count()); + m_Filter.Decay(now.count()); } bool @@ -29,15 +52,31 @@ namespace llarp return false; if(m_LinkManager == nullptr) return false; - // check for filter hit - if(not m_Filter.Insert(rc.pubkey)) + const RouterID k(rc.pubkey); + // filter check + if(m_Filter.Contains(k)) return false; - bool sent = false; - // unwarrented GRCM + m_Filter.Insert(k); + + const auto now = time_now(); + // is this our rc? + if(IsOurRC(rc)) + { + // should we gossip our rc? + if(not ShouldGossipOurRC(now)) + { + // nah drop it + return false; + } + // ya pop it + m_LastGossipedOurRC = now; + } + + // send unwarrented GRCM as gossip method DHTImmediateMessage m; m.msgs.emplace_back( new dht::GotRouterMessage(dht::Key_t{}, 0, {rc}, false)); - + // send it to everyone m_LinkManager->ForEachPeer([&](ILinkSession* s) { // ensure connected session if(not(s && s->IsEstablished())) @@ -46,23 +85,17 @@ namespace llarp const auto other_rc = s->GetRemoteRC(); if(not other_rc.IsPublicRouter()) return; - // dont send it to the owner - if(other_rc.pubkey == rc.pubkey) - return; // encode message ILinkSession::Message_t msg; - msg.resize(1024); + msg.reserve(1024); llarp_buffer_t buf(msg); if(not m.BEncode(&buf)) return; msg.resize(buf.cur - buf.base); // send message - if(s->SendMessageBuffer(std::move(msg), nullptr)) - { - sent = true; - } + s->SendMessageBuffer(std::move(msg), nullptr); }); - return sent; + return true; } } // namespace llarp diff --git a/llarp/router/rc_gossiper.hpp b/llarp/router/rc_gossiper.hpp index c9495106d..e0758032d 100644 --- a/llarp/router/rc_gossiper.hpp +++ b/llarp/router/rc_gossiper.hpp @@ -18,12 +18,20 @@ namespace llarp GossipRC(const RouterContact &rc) override; void - Decay(llarp_time_t now) override; + Decay(Time_t now) override; + + bool + ShouldGossipOurRC(Time_t now) const override; + + bool + IsOurRC(const RouterContact &rc) const override; void - Init(ILinkManager *); + Init(ILinkManager *, const RouterID &); private: + RouterID m_OurRouterID; + Time_t m_LastGossipedOurRC = 0s; ILinkManager *m_LinkManager = nullptr; util::DecayingHashSet< RouterID > m_Filter; }; diff --git a/llarp/router/rc_lookup_handler.cpp b/llarp/router/rc_lookup_handler.cpp index 41b92f32f..50718c0af 100644 --- a/llarp/router/rc_lookup_handler.cpp +++ b/llarp/router/rc_lookup_handler.cpp @@ -288,7 +288,10 @@ namespace llarp GetRC(r, nullptr, true); return; } - // TODO: only explore via random subset + // service nodes gossip, not explore + if(_dht->impl->GetRouter()->IsServiceNode()) + return; + // explore via every connected peer _linkManager->ForEachPeer([&](ILinkSession *s) { if(!s->IsEstablished()) diff --git a/llarp/router/router.cpp b/llarp/router/router.cpp index db63fe453..2cf85a573 100644 --- a/llarp/router/router.cpp +++ b/llarp/router/router.cpp @@ -518,7 +518,6 @@ namespace llarp _rcLookupHandler.Init(_dht, _nodedb, threadpool(), &_linkManager, &_hiddenServiceContext, strictConnectPubkeys, bootstrapRCList, whitelistRouters, m_isServiceNode); - _rcGossiper.Init(&_linkManager); if(!usingSNSeed) { @@ -687,7 +686,7 @@ namespace llarp ReportStats(); } - _rcGossiper.Decay(now); + _rcGossiper.Decay(time_now()); _rcLookupHandler.PeriodicUpdate(now); @@ -1012,9 +1011,10 @@ namespace llarp LogError("Failed to initialize service node"); return false; } - RouterID us = pubkey(); + const RouterID us = pubkey(); LogInfo("initalized service node: ", us); - + // init gossiper here + _rcGossiper.Init(&_linkManager, us); // relays do not use profiling routerProfiling().Disable(); } diff --git a/llarp/util/decaying_hashset.hpp b/llarp/util/decaying_hashset.hpp index e0b289031..fb876095a 100644 --- a/llarp/util/decaying_hashset.hpp +++ b/llarp/util/decaying_hashset.hpp @@ -11,11 +11,11 @@ namespace llarp template < typename Val_t, typename Hash_t = typename Val_t::Hash > struct DecayingHashSet { - DecayingHashSet(std::chrono::milliseconds cacheInterval) + DecayingHashSet(Time_t cacheInterval) : DecayingHashSet(cacheInterval.count()) { } - DecayingHashSet(llarp_time_t cacheInterval = 5000) + explicit DecayingHashSet(llarp_time_t cacheInterval = 5000) : m_CacheInterval(cacheInterval) { } diff --git a/llarp/util/time.cpp b/llarp/util/time.cpp index eb2d1b668..282a658f8 100644 --- a/llarp/util/time.cpp +++ b/llarp/util/time.cpp @@ -29,6 +29,12 @@ namespace llarp - started_at_steady; } + Time_t + time_now() + { + return Time_t(time_now_ms()); + } + llarp_time_t time_now_ms() { diff --git a/llarp/util/time.hpp b/llarp/util/time.hpp index fd01b2bf2..e8370afef 100644 --- a/llarp/util/time.hpp +++ b/llarp/util/time.hpp @@ -4,11 +4,21 @@ #include #include +#include +using namespace std::chrono_literals; + namespace llarp { /// get time right now as milliseconds, this is monotonic llarp_time_t time_now_ms(); + + using Time_t = std::chrono::milliseconds; + + /// get time right now as a Time_t, monotonic + Time_t + time_now(); + } // namespace llarp #endif