rc gossiping

pull/1073/head
Jeff Becker 4 years ago
parent 1403cff805
commit ea3851d15f
No known key found for this signature in database
GPG Key ID: F357B3B42F6F9B05

@ -216,6 +216,8 @@ set(LIB_SRC
router/outbound_session_maker.cpp
router/i_rc_lookup_handler.cpp
router/rc_lookup_handler.cpp
router/i_gossiper.cpp
router/rc_gossiper.cpp
router/router.cpp
router_contact.cpp
router_id.cpp

@ -124,10 +124,9 @@ namespace llarp
{
if(not dht.GetRouter()->rcLookupHandler().CheckRC(rc))
return false;
if(txid == 0 and foundRCs.size() == 1)
if(txid == 0)
{
// flood as needed
dht.FloodRCLater(From, rc);
dht.GetRouter()->GossipRCIfNeeded(rc);
}
}
return true;

@ -5,6 +5,7 @@
#include <util/thread/logic.hpp>
#include <util/types.hpp>
#include <unordered_set>
#include <functional>
struct llarp_buffer_t;

@ -250,6 +250,10 @@ namespace llarp
virtual util::StatusObject
ExtractStatus() const = 0;
/// gossip an rc if required
virtual void
GossipRCIfNeeded(const RouterContact rc) = 0;
};
} // namespace llarp

@ -0,0 +1 @@
#include <router/i_gossiper.hpp>

@ -0,0 +1,21 @@
#ifndef LLARP_GOSSIPER_HPP
#define LLARP_GOSSIPER_HPP
#include <router_contact.hpp>
namespace llarp
{
struct I_RCGossiper
{
virtual ~I_RCGossiper() = default;
/// try goissping RC
/// return false if we hit a cooldown for this rc
/// return true if we gossiped this rc to at least 1 peer
virtual bool
GossipRC(const RouterContact &rc) = 0;
virtual void
Decay(llarp_time_t now) = 0;
};
} // namespace llarp
#endif

@ -0,0 +1,68 @@
#include <router/rc_gossiper.hpp>
#include <messages/dht_immediate.hpp>
#include <dht/messages/gotrouter.hpp>
namespace llarp
{
RCGossiper::RCGossiper()
: I_RCGossiper(), m_Filter(RouterContact::UpdateInterval)
{
}
void
RCGossiper::Init(ILinkManager* l)
{
m_LinkManager = l;
}
void
RCGossiper::Decay(llarp_time_t now)
{
m_Filter.Decay(now);
}
bool
RCGossiper::GossipRC(const RouterContact& rc)
{
// only distribute public routers
if(not rc.IsPublicRouter())
return false;
if(m_LinkManager == nullptr)
return false;
// check for filter hit
if(not m_Filter.Insert(rc.pubkey))
return false;
bool sent = false;
// unwarrented GRCM
DHTImmediateMessage m;
m.msgs.emplace_back(
new dht::GotRouterMessage(dht::Key_t{}, 0, {rc}, false));
m_LinkManager->ForEachPeer([&](ILinkSession* s) {
// ensure connected session
if(not(s && s->IsEstablished()))
return;
// check if public router
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);
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;
}
});
return sent;
}
} // namespace llarp

@ -0,0 +1,32 @@
#ifndef LLARP_RC_GOSSIPER_HPP
#define LLARP_RC_GOSSIPER_HPP
#include <util/decaying_hashset.hpp>
#include <router/i_gossiper.hpp>
#include <router/i_outbound_message_handler.hpp>
#include <link/i_link_manager.hpp>
namespace llarp
{
struct RCGossiper : public I_RCGossiper
{
RCGossiper();
~RCGossiper() override = default;
bool
GossipRC(const RouterContact &rc) override;
void
Decay(llarp_time_t now) override;
void
Init(ILinkManager *);
private:
ILinkManager *m_LinkManager = nullptr;
util::DecayingHashSet< RouterID > m_Filter;
};
} // namespace llarp
#endif

@ -50,6 +50,7 @@ namespace llarp
, _dht(llarp_dht_context_new(this))
, inbound_link_msg_parser(this)
, _hiddenServiceContext(this)
, _randomStartDelay(1000 * (llarp::randint() % 30) + 10)
{
m_keyManager = std::make_shared< KeyManager >();
@ -109,6 +110,18 @@ namespace llarp
_linkManager.PersistSessionUntil(remote, until);
}
void
Router::GossipRCIfNeeded(const RouterContact rc)
{
/// if we are not a service node forget about gossip
if(not IsServiceNode())
return;
/// wait for random uptime
if(Uptime() < _randomStartDelay)
return;
_rcGossiper.GossipRC(rc);
}
bool
Router::GetRandomGoodRouter(RouterID &router)
{
@ -505,6 +518,7 @@ namespace llarp
_rcLookupHandler.Init(_dht, _nodedb, threadpool(), &_linkManager,
&_hiddenServiceContext, strictConnectPubkeys,
bootstrapRCList, whitelistRouters, m_isServiceNode);
_rcGossiper.Init(&_linkManager);
if(!usingSNSeed)
{
@ -673,6 +687,8 @@ namespace llarp
ReportStats();
}
_rcGossiper.Decay(now);
_rcLookupHandler.PeriodicUpdate(now);
const bool isSvcNode = IsServiceNode();
@ -684,6 +700,10 @@ namespace llarp
if(!UpdateOurRC(false))
LogError("Failed to update our RC");
}
else
{
GossipRCIfNeeded(_rc);
}
if(isSvcNode && _rcLookupHandler.HaveReceivedWhitelist())
{

@ -20,6 +20,7 @@
#include <router_contact.hpp>
#include <router/outbound_message_handler.hpp>
#include <router/outbound_session_maker.hpp>
#include <router/rc_gossiper.hpp>
#include <router/rc_lookup_handler.hpp>
#include <routing/handler.hpp>
#include <routing/message_parser.hpp>
@ -259,6 +260,7 @@ namespace llarp
bool enableRPCServer = false;
std::unique_ptr< rpc::Server > rpcServer;
std::string rpcBindAddr = DefaultRPCBindAddr;
const llarp_time_t _randomStartDelay;
/// lokid caller
std::unique_ptr< rpc::Caller > rpcCaller;
@ -273,6 +275,7 @@ namespace llarp
OutboundSessionMaker _outboundSessionMaker;
LinkManager _linkManager;
RCLookupHandler _rcLookupHandler;
RCGossiper _rcGossiper;
using Clock_t = std::chrono::steady_clock;
using TimePoint_t = Clock_t::time_point;
@ -303,6 +306,9 @@ namespace llarp
return _rcLookupHandler;
}
void
GossipRCIfNeeded(const RouterContact rc) override;
Router(std::shared_ptr< llarp::thread::ThreadPool > worker,
llarp_ev_loop_ptr __netloop, std::shared_ptr< Logic > logic);

Loading…
Cancel
Save