2020-01-30 17:23:16 +00:00
|
|
|
#include <router/rc_gossiper.hpp>
|
|
|
|
#include <messages/dht_immediate.hpp>
|
|
|
|
#include <dht/messages/gotrouter.hpp>
|
2020-01-30 22:10:56 +00:00
|
|
|
#include <util/time.hpp>
|
2020-02-05 16:04:11 +00:00
|
|
|
#include <constants/link_layer.hpp>
|
2020-03-04 00:50:20 +00:00
|
|
|
#include <tooling/rc_event.hpp>
|
2020-01-30 17:23:16 +00:00
|
|
|
|
|
|
|
namespace llarp
|
|
|
|
{
|
2020-01-30 22:10:56 +00:00
|
|
|
// 30 minutes
|
|
|
|
static constexpr auto RCGossipFilterDecayInterval = 30min;
|
2020-02-05 16:04:11 +00:00
|
|
|
// (30 minutes * 2) - 5 minutes
|
2020-04-07 18:38:56 +00:00
|
|
|
static constexpr auto GossipOurRCInterval = (RCGossipFilterDecayInterval * 2) - (5min);
|
2020-01-30 22:10:56 +00:00
|
|
|
|
2020-01-30 17:23:16 +00:00
|
|
|
RCGossiper::RCGossiper()
|
2020-04-07 18:38:56 +00:00
|
|
|
: I_RCGossiper(), m_Filter(std::chrono::duration_cast<Time_t>(RCGossipFilterDecayInterval))
|
2020-01-30 17:23:16 +00:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2020-04-07 18:38:56 +00:00
|
|
|
RCGossiper::Init(ILinkManager* l, const RouterID& ourID, AbstractRouter* router)
|
2020-01-30 17:23:16 +00:00
|
|
|
{
|
2020-01-30 22:10:56 +00:00
|
|
|
m_OurRouterID = ourID;
|
2020-01-30 17:23:16 +00:00
|
|
|
m_LinkManager = l;
|
2020-04-07 18:38:56 +00:00
|
|
|
m_router = router;
|
2020-01-30 17:23:16 +00:00
|
|
|
}
|
|
|
|
|
2020-01-30 22:10:56 +00:00
|
|
|
bool
|
|
|
|
RCGossiper::ShouldGossipOurRC(Time_t now) const
|
|
|
|
{
|
2020-03-03 19:56:33 +00:00
|
|
|
bool should = now >= (m_LastGossipedOurRC + GossipOurRCInterval);
|
2020-03-07 01:20:11 +00:00
|
|
|
LogWarn("ShouldGossipOurRC: ", should);
|
2020-03-03 19:56:33 +00:00
|
|
|
return should;
|
2020-01-30 22:10:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
|
|
|
RCGossiper::IsOurRC(const RouterContact& rc) const
|
|
|
|
{
|
|
|
|
return rc.pubkey == m_OurRouterID;
|
|
|
|
}
|
|
|
|
|
2020-01-30 17:23:16 +00:00
|
|
|
void
|
2020-01-30 22:10:56 +00:00
|
|
|
RCGossiper::Decay(Time_t now)
|
2020-01-30 17:23:16 +00:00
|
|
|
{
|
2020-02-24 15:26:46 +00:00
|
|
|
m_Filter.Decay(now);
|
2020-01-30 17:23:16 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
|
|
|
RCGossiper::GossipRC(const RouterContact& rc)
|
|
|
|
{
|
|
|
|
// only distribute public routers
|
2020-04-07 18:38:56 +00:00
|
|
|
if (not rc.IsPublicRouter())
|
2020-01-30 17:23:16 +00:00
|
|
|
return false;
|
2020-04-07 18:38:56 +00:00
|
|
|
if (m_LinkManager == nullptr)
|
2020-01-30 17:23:16 +00:00
|
|
|
return false;
|
2020-02-05 16:04:11 +00:00
|
|
|
const RouterID pubkey(rc.pubkey);
|
2020-01-30 22:10:56 +00:00
|
|
|
// filter check
|
2020-04-07 18:38:56 +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);
|
2020-01-30 22:10:56 +00:00
|
|
|
|
2020-02-25 17:05:13 +00:00
|
|
|
const auto now = time_now_ms();
|
2020-01-30 22:10:56 +00:00
|
|
|
// is this our rc?
|
2020-04-07 18:38:56 +00:00
|
|
|
if (IsOurRC(rc))
|
2020-01-30 22:10:56 +00:00
|
|
|
{
|
|
|
|
// should we gossip our rc?
|
2020-04-07 18:38:56 +00:00
|
|
|
if (not ShouldGossipOurRC(now))
|
2020-01-30 22:10:56 +00:00
|
|
|
{
|
|
|
|
// 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;
|
2020-04-07 18:38:56 +00:00
|
|
|
gossip.msgs.emplace_back(new dht::GotRouterMessage(dht::Key_t{}, 0, {rc}, false));
|
2020-02-05 16:04:11 +00:00
|
|
|
|
2020-01-30 22:10:56 +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-04-07 18:38:56 +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-04-07 18:38:56 +00:00
|
|
|
if (not other_rc.IsPublicRouter())
|
2020-01-30 17:23:16 +00:00
|
|
|
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-04-07 18:38:56 +00:00
|
|
|
if (not gossip.BEncode(&buf))
|
2020-01-30 17:23:16 +00:00
|
|
|
return;
|
|
|
|
msg.resize(buf.cur - buf.base);
|
2020-03-04 00:50:20 +00:00
|
|
|
|
2020-04-07 18:38:56 +00:00
|
|
|
m_router->NotifyRouterEvent<tooling::RCGossipSentEvent>(m_router->pubkey(), rc);
|
2020-03-04 00:50:20 +00:00
|
|
|
|
2020-01-30 17:23:16 +00:00
|
|
|
// send message
|
2020-02-05 16:04:11 +00:00
|
|
|
peerSession->SendMessageBuffer(std::move(msg), nullptr);
|
2020-01-30 17:23:16 +00:00
|
|
|
});
|
2020-01-30 22:10:56 +00:00
|
|
|
return true;
|
2020-01-30 17:23:16 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
} // namespace llarp
|