lokinet/llarp/router/rc_gossiper.cpp

103 lines
2.4 KiB
C++
Raw Normal View History

2020-01-30 17:23:16 +00:00
#include <router/rc_gossiper.hpp>
#include <messages/dht_immediate.hpp>
#include <dht/messages/gotrouter.hpp>
#include <util/time.hpp>
2020-02-05 16:04:11 +00:00
#include <constants/link_layer.hpp>
2020-01-30 17:23:16 +00:00
namespace llarp
{
// 30 minutes
static constexpr auto RCGossipFilterDecayInterval = 30min;
2020-02-05 16:04:11 +00:00
// (30 minutes * 2) - 5 minutes
static constexpr auto GossipOurRCInterval =
(RCGossipFilterDecayInterval * 2) - (5min);
2020-01-30 17:23:16 +00:00
RCGossiper::RCGossiper()
: I_RCGossiper()
, m_Filter(
std::chrono::duration_cast< Time_t >(RCGossipFilterDecayInterval))
2020-01-30 17:23:16 +00:00
{
}
void
RCGossiper::Init(ILinkManager* l, const RouterID& ourID)
2020-01-30 17:23:16 +00:00
{
m_OurRouterID = ourID;
2020-01-30 17:23:16 +00:00
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;
}
2020-01-30 17:23:16 +00:00
void
RCGossiper::Decay(Time_t now)
2020-01-30 17:23:16 +00:00
{
m_Filter.Decay(now);
2020-01-30 17:23:16 +00:00
}
bool
RCGossiper::GossipRC(const RouterContact& rc)
{
// only distribute public routers
if(not rc.IsPublicRouter())
return false;
if(m_LinkManager == nullptr)
return false;
2020-02-05 16:04:11 +00:00
const RouterID pubkey(rc.pubkey);
// filter check
2020-02-05 16:04:11 +00:00
if(m_Filter.Contains(pubkey))
2020-01-30 17:23:16 +00:00
return false;
2020-02-05 16:04:11 +00:00
m_Filter.Insert(pubkey);
const auto now = time_now_ms();
// 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;
}
2020-02-12 17:53:53 +00:00
// send a GRCM as gossip method
DHTImmediateMessage gossip;
gossip.msgs.emplace_back(
2020-01-30 17:23:16 +00:00
new dht::GotRouterMessage(dht::Key_t{}, 0, {rc}, false));
2020-02-05 16:04:11 +00:00
// send it to everyone
2020-02-05 16:04:11 +00:00
m_LinkManager->ForEachPeer([&](ILinkSession* peerSession) {
2020-01-30 17:23:16 +00:00
// ensure connected session
2020-02-05 16:04:11 +00:00
if(not(peerSession && peerSession->IsEstablished()))
2020-01-30 17:23:16 +00:00
return;
// check if public router
2020-02-05 16:04:11 +00:00
const auto other_rc = peerSession->GetRemoteRC();
2020-01-30 17:23:16 +00:00
if(not other_rc.IsPublicRouter())
return;
// encode message
ILinkSession::Message_t msg;
2020-03-03 20:25:18 +00:00
msg.resize(MAX_LINK_MSG_SIZE / 2);
2020-01-30 17:23:16 +00:00
llarp_buffer_t buf(msg);
2020-02-12 17:53:53 +00:00
if(not gossip.BEncode(&buf))
2020-01-30 17:23:16 +00:00
return;
msg.resize(buf.cur - buf.base);
// send message
2020-02-05 16:04:11 +00:00
peerSession->SendMessageBuffer(std::move(msg), nullptr);
2020-01-30 17:23:16 +00:00
});
return true;
2020-01-30 17:23:16 +00:00
}
} // namespace llarp