mirror of https://github.com/oxen-io/lokinet
parent
ffb90e87dc
commit
aaf688cf81
File diff suppressed because it is too large
Load Diff
@ -1,72 +0,0 @@
|
||||
#include "iwp.hpp"
|
||||
#include "linklayer.hpp"
|
||||
#include <memory>
|
||||
#include <llarp/router/abstractrouter.hpp>
|
||||
|
||||
namespace llarp
|
||||
{
|
||||
namespace iwp
|
||||
{
|
||||
LinkLayer_ptr
|
||||
NewInboundLink(
|
||||
std::shared_ptr<KeyManager> keyManager,
|
||||
std::shared_ptr<EventLoop> loop,
|
||||
GetRCFunc getrc,
|
||||
LinkMessageHandler h,
|
||||
SignBufferFunc sign,
|
||||
BeforeConnectFunc_t before,
|
||||
SessionEstablishedHandler est,
|
||||
SessionRenegotiateHandler reneg,
|
||||
TimeoutHandler timeout,
|
||||
SessionClosedHandler closed,
|
||||
PumpDoneHandler pumpDone,
|
||||
WorkerFunc_t work)
|
||||
{
|
||||
return std::make_shared<LinkLayer>(
|
||||
keyManager,
|
||||
loop,
|
||||
getrc,
|
||||
h,
|
||||
sign,
|
||||
before,
|
||||
est,
|
||||
reneg,
|
||||
timeout,
|
||||
closed,
|
||||
pumpDone,
|
||||
work,
|
||||
true);
|
||||
}
|
||||
|
||||
LinkLayer_ptr
|
||||
NewOutboundLink(
|
||||
std::shared_ptr<KeyManager> keyManager,
|
||||
std::shared_ptr<EventLoop> loop,
|
||||
GetRCFunc getrc,
|
||||
LinkMessageHandler h,
|
||||
SignBufferFunc sign,
|
||||
BeforeConnectFunc_t before,
|
||||
SessionEstablishedHandler est,
|
||||
SessionRenegotiateHandler reneg,
|
||||
TimeoutHandler timeout,
|
||||
SessionClosedHandler closed,
|
||||
PumpDoneHandler pumpDone,
|
||||
WorkerFunc_t work)
|
||||
{
|
||||
return std::make_shared<LinkLayer>(
|
||||
keyManager,
|
||||
loop,
|
||||
getrc,
|
||||
h,
|
||||
sign,
|
||||
before,
|
||||
est,
|
||||
reneg,
|
||||
timeout,
|
||||
closed,
|
||||
pumpDone,
|
||||
work,
|
||||
false);
|
||||
}
|
||||
} // namespace iwp
|
||||
} // namespace llarp
|
@ -1,40 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <llarp/link/server.hpp>
|
||||
#include "linklayer.hpp"
|
||||
#include <memory>
|
||||
#include <llarp/config/key_manager.hpp>
|
||||
|
||||
namespace llarp::iwp
|
||||
{
|
||||
LinkLayer_ptr
|
||||
NewInboundLink(
|
||||
std::shared_ptr<KeyManager> keyManager,
|
||||
std::shared_ptr<EventLoop> loop,
|
||||
GetRCFunc getrc,
|
||||
LinkMessageHandler h,
|
||||
SignBufferFunc sign,
|
||||
BeforeConnectFunc_t before,
|
||||
SessionEstablishedHandler est,
|
||||
SessionRenegotiateHandler reneg,
|
||||
TimeoutHandler timeout,
|
||||
SessionClosedHandler closed,
|
||||
PumpDoneHandler pumpDone,
|
||||
WorkerFunc_t work);
|
||||
|
||||
LinkLayer_ptr
|
||||
NewOutboundLink(
|
||||
std::shared_ptr<KeyManager> keyManager,
|
||||
std::shared_ptr<EventLoop> loop,
|
||||
GetRCFunc getrc,
|
||||
LinkMessageHandler h,
|
||||
SignBufferFunc sign,
|
||||
BeforeConnectFunc_t before,
|
||||
SessionEstablishedHandler est,
|
||||
SessionRenegotiateHandler reneg,
|
||||
TimeoutHandler timeout,
|
||||
SessionClosedHandler closed,
|
||||
PumpDoneHandler pumpDone,
|
||||
WorkerFunc_t work);
|
||||
|
||||
} // namespace llarp::iwp
|
@ -1,115 +0,0 @@
|
||||
#include "linklayer.hpp"
|
||||
#include "session.hpp"
|
||||
#include <llarp/config/key_manager.hpp>
|
||||
#include <memory>
|
||||
#include <unordered_set>
|
||||
|
||||
namespace llarp::iwp
|
||||
{
|
||||
LinkLayer::LinkLayer(
|
||||
std::shared_ptr<KeyManager> keyManager,
|
||||
std::shared_ptr<EventLoop> ev,
|
||||
GetRCFunc getrc,
|
||||
LinkMessageHandler h,
|
||||
SignBufferFunc sign,
|
||||
BeforeConnectFunc_t before,
|
||||
SessionEstablishedHandler est,
|
||||
SessionRenegotiateHandler reneg,
|
||||
TimeoutHandler timeout,
|
||||
SessionClosedHandler closed,
|
||||
PumpDoneHandler pumpDone,
|
||||
WorkerFunc_t worker,
|
||||
bool allowInbound)
|
||||
: ILinkLayer(
|
||||
keyManager, getrc, h, sign, before, est, reneg, timeout, closed, pumpDone, worker)
|
||||
, m_Wakeup{ev->make_waker([this]() { HandleWakeupPlaintext(); })}
|
||||
, m_Inbound{allowInbound}
|
||||
{}
|
||||
|
||||
std::string_view
|
||||
LinkLayer::Name() const
|
||||
{
|
||||
return "iwp";
|
||||
}
|
||||
|
||||
std::string
|
||||
LinkLayer::PrintableName() const
|
||||
{
|
||||
if (m_Inbound)
|
||||
return "inbound iwp link";
|
||||
else
|
||||
return "outbound iwp link";
|
||||
}
|
||||
|
||||
uint16_t
|
||||
LinkLayer::Rank() const
|
||||
{
|
||||
return 2;
|
||||
}
|
||||
|
||||
void
|
||||
LinkLayer::RecvFrom(const SockAddr& from, AbstractLinkSession::Packet_t pkt)
|
||||
{
|
||||
std::shared_ptr<AbstractLinkSession> session;
|
||||
auto itr = m_AuthedAddrs.find(from);
|
||||
bool isNewSession = false;
|
||||
if (itr == m_AuthedAddrs.end())
|
||||
{
|
||||
Lock_t lock{m_PendingMutex};
|
||||
auto it = m_Pending.find(from);
|
||||
if (it == m_Pending.end())
|
||||
{
|
||||
if (not m_Inbound)
|
||||
return;
|
||||
isNewSession = true;
|
||||
it = m_Pending.emplace(from, std::make_shared<Session>(this, from)).first;
|
||||
}
|
||||
session = it->second;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (auto s_itr = m_AuthedLinks.find(itr->second); s_itr != m_AuthedLinks.end())
|
||||
session = s_itr->second;
|
||||
}
|
||||
if (session)
|
||||
{
|
||||
bool success = session->Recv_LL(std::move(pkt));
|
||||
if (not success and isNewSession)
|
||||
{
|
||||
LogDebug("Brand new session failed; removing from pending sessions list");
|
||||
m_Pending.erase(from);
|
||||
}
|
||||
WakeupPlaintext();
|
||||
}
|
||||
}
|
||||
|
||||
std::shared_ptr<AbstractLinkSession>
|
||||
LinkLayer::NewOutboundSession(const RouterContact& rc, const AddressInfo& ai)
|
||||
{
|
||||
if (m_Inbound)
|
||||
throw std::logic_error{"inbound link cannot make outbound sessions"};
|
||||
return std::make_shared<Session>(this, rc, ai);
|
||||
}
|
||||
|
||||
void
|
||||
LinkLayer::WakeupPlaintext()
|
||||
{
|
||||
m_Wakeup->Trigger();
|
||||
}
|
||||
|
||||
void
|
||||
LinkLayer::HandleWakeupPlaintext()
|
||||
{
|
||||
// Copy bare pointers out first because HandlePlaintext can end up removing themselves from the
|
||||
// structures.
|
||||
m_WakingUp.clear(); // Reused to minimize allocations.
|
||||
for (const auto& [router_id, session] : m_AuthedLinks)
|
||||
m_WakingUp.push_back(session.get());
|
||||
for (const auto& [addr, session] : m_Pending)
|
||||
m_WakingUp.push_back(session.get());
|
||||
for (auto* session : m_WakingUp)
|
||||
session->HandlePlaintext();
|
||||
PumpDone();
|
||||
}
|
||||
|
||||
} // namespace llarp::iwp
|
@ -1,63 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <llarp/constants/link_layer.hpp>
|
||||
#include <llarp/crypto/crypto.hpp>
|
||||
#include <llarp/crypto/encrypted.hpp>
|
||||
#include <llarp/crypto/types.hpp>
|
||||
#include <llarp/link/server.hpp>
|
||||
#include <llarp/config/key_manager.hpp>
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include <llarp/ev/ev.hpp>
|
||||
|
||||
namespace llarp::iwp
|
||||
{
|
||||
struct Session;
|
||||
|
||||
struct LinkLayer final : public ILinkLayer
|
||||
{
|
||||
LinkLayer(
|
||||
std::shared_ptr<KeyManager> keyManager,
|
||||
std::shared_ptr<EventLoop> ev,
|
||||
GetRCFunc getrc,
|
||||
LinkMessageHandler h,
|
||||
SignBufferFunc sign,
|
||||
BeforeConnectFunc_t before,
|
||||
SessionEstablishedHandler est,
|
||||
SessionRenegotiateHandler reneg,
|
||||
TimeoutHandler timeout,
|
||||
SessionClosedHandler closed,
|
||||
PumpDoneHandler pumpDone,
|
||||
WorkerFunc_t dowork,
|
||||
bool permitInbound);
|
||||
|
||||
std::shared_ptr<AbstractLinkSession>
|
||||
NewOutboundSession(const RouterContact& rc, const AddressInfo& ai) override;
|
||||
|
||||
std::string_view
|
||||
Name() const override;
|
||||
|
||||
uint16_t
|
||||
Rank() const override;
|
||||
|
||||
void
|
||||
RecvFrom(const SockAddr& from, AbstractLinkSession::Packet_t pkt) override;
|
||||
|
||||
void
|
||||
WakeupPlaintext();
|
||||
|
||||
std::string
|
||||
PrintableName() const;
|
||||
|
||||
private:
|
||||
void
|
||||
HandleWakeupPlaintext();
|
||||
|
||||
const std::shared_ptr<EventLoopWakeup> m_Wakeup;
|
||||
std::vector<AbstractLinkSession*> m_WakingUp;
|
||||
const bool m_Inbound;
|
||||
};
|
||||
|
||||
using LinkLayer_ptr = std::shared_ptr<LinkLayer>;
|
||||
} // namespace llarp::iwp
|
@ -1,194 +0,0 @@
|
||||
#include "message_buffer.hpp"
|
||||
#include "session.hpp"
|
||||
#include <llarp/crypto/crypto.hpp>
|
||||
|
||||
namespace llarp
|
||||
{
|
||||
namespace iwp
|
||||
{
|
||||
OutboundMessage::OutboundMessage(
|
||||
uint64_t msgid,
|
||||
AbstractLinkSession::Message_t msg,
|
||||
llarp_time_t now,
|
||||
AbstractLinkSession::CompletionHandler handler,
|
||||
uint16_t priority)
|
||||
: m_Data{std::move(msg)}
|
||||
, m_MsgID{msgid}
|
||||
, m_Completed{handler}
|
||||
, m_LastFlush{now}
|
||||
, m_StartedAt{now}
|
||||
, m_ResendPriority{priority}
|
||||
{
|
||||
const llarp_buffer_t buf(m_Data);
|
||||
CryptoManager::instance()->shorthash(m_Digest, buf);
|
||||
m_Acks.set(0);
|
||||
}
|
||||
|
||||
AbstractLinkSession::Packet_t
|
||||
OutboundMessage::XMIT() const
|
||||
{
|
||||
size_t extra = std::min(m_Data.size(), FragmentSize);
|
||||
auto xmit = CreatePacket(Command::eXMIT, 10 + 32 + extra, 0, 0);
|
||||
oxenc::write_host_as_big(
|
||||
static_cast<uint16_t>(m_Data.size()), xmit.data() + CommandOverhead + PacketOverhead);
|
||||
oxenc::write_host_as_big(m_MsgID, xmit.data() + 2 + CommandOverhead + PacketOverhead);
|
||||
std::copy_n(
|
||||
m_Digest.begin(), m_Digest.size(), xmit.data() + 10 + CommandOverhead + PacketOverhead);
|
||||
std::copy_n(m_Data.data(), extra, xmit.data() + 10 + CommandOverhead + PacketOverhead + 32);
|
||||
return xmit;
|
||||
}
|
||||
|
||||
void
|
||||
OutboundMessage::Completed()
|
||||
{
|
||||
if (m_Completed)
|
||||
{
|
||||
m_Completed(AbstractLinkSession::DeliveryStatus::eDeliverySuccess);
|
||||
}
|
||||
m_Completed = nullptr;
|
||||
}
|
||||
|
||||
bool
|
||||
OutboundMessage::ShouldFlush(llarp_time_t now) const
|
||||
{
|
||||
return now - m_LastFlush >= TXFlushInterval;
|
||||
}
|
||||
|
||||
void
|
||||
OutboundMessage::Ack(byte_t bitmask)
|
||||
{
|
||||
m_Acks = std::bitset<8>(bitmask);
|
||||
}
|
||||
|
||||
void
|
||||
OutboundMessage::FlushUnAcked(
|
||||
std::function<void(AbstractLinkSession::Packet_t)> sendpkt, llarp_time_t now)
|
||||
{
|
||||
/// overhead for a data packet in plaintext
|
||||
static constexpr size_t Overhead = 10;
|
||||
uint16_t idx = 0;
|
||||
const auto datasz = m_Data.size();
|
||||
while (idx < datasz)
|
||||
{
|
||||
if (not m_Acks[idx / FragmentSize])
|
||||
{
|
||||
const size_t fragsz = idx + FragmentSize < datasz ? FragmentSize : datasz - idx;
|
||||
auto frag = CreatePacket(Command::eDATA, fragsz + Overhead, 0, 0);
|
||||
oxenc::write_host_as_big(idx, frag.data() + 2 + PacketOverhead);
|
||||
oxenc::write_host_as_big(m_MsgID, frag.data() + 4 + PacketOverhead);
|
||||
std::copy(
|
||||
m_Data.begin() + idx,
|
||||
m_Data.begin() + idx + fragsz,
|
||||
frag.data() + PacketOverhead + Overhead + 2);
|
||||
sendpkt(std::move(frag));
|
||||
}
|
||||
idx += FragmentSize;
|
||||
}
|
||||
m_LastFlush = now;
|
||||
}
|
||||
|
||||
bool
|
||||
OutboundMessage::IsTransmitted() const
|
||||
{
|
||||
const auto sz = m_Data.size();
|
||||
for (uint16_t idx = 0; idx < sz; idx += FragmentSize)
|
||||
{
|
||||
if (not m_Acks.test(idx / FragmentSize))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
OutboundMessage::IsTimedOut(const llarp_time_t now) const
|
||||
{
|
||||
// TODO: make configurable by outbound message deliverer
|
||||
return now > m_StartedAt && now - m_StartedAt > DeliveryTimeout;
|
||||
}
|
||||
|
||||
void
|
||||
OutboundMessage::InformTimeout()
|
||||
{
|
||||
if (m_Completed)
|
||||
{
|
||||
m_Completed(AbstractLinkSession::DeliveryStatus::eDeliveryDropped);
|
||||
}
|
||||
m_Completed = nullptr;
|
||||
}
|
||||
|
||||
InboundMessage::InboundMessage(uint64_t msgid, uint16_t sz, ShortHash h, llarp_time_t now)
|
||||
: m_Data(size_t{sz}), m_Digset{std::move(h)}, m_MsgID(msgid), m_LastActiveAt{now}
|
||||
{}
|
||||
|
||||
void
|
||||
InboundMessage::HandleData(uint16_t idx, const llarp_buffer_t& buf, llarp_time_t now)
|
||||
{
|
||||
if (idx + buf.sz > m_Data.size())
|
||||
{
|
||||
LogWarn("invalid fragment offset ", idx);
|
||||
return;
|
||||
}
|
||||
byte_t* dst = m_Data.data() + idx;
|
||||
std::copy_n(buf.base, buf.sz, dst);
|
||||
m_Acks.set(idx / FragmentSize);
|
||||
LogTrace("got fragment ", idx / FragmentSize);
|
||||
m_LastActiveAt = now;
|
||||
}
|
||||
|
||||
AbstractLinkSession::Packet_t
|
||||
InboundMessage::ACKS() const
|
||||
{
|
||||
auto acks = CreatePacket(Command::eACKS, 9);
|
||||
oxenc::write_host_as_big(m_MsgID, acks.data() + CommandOverhead + PacketOverhead);
|
||||
acks[PacketOverhead + 10] = AcksBitmask();
|
||||
return acks;
|
||||
}
|
||||
|
||||
byte_t
|
||||
InboundMessage::AcksBitmask() const
|
||||
{
|
||||
return byte_t{(byte_t)m_Acks.to_ulong()};
|
||||
}
|
||||
|
||||
bool
|
||||
InboundMessage::IsCompleted() const
|
||||
{
|
||||
const auto sz = m_Data.size();
|
||||
for (size_t idx = 0; idx < sz; idx += FragmentSize)
|
||||
{
|
||||
if (not m_Acks.test(idx / FragmentSize))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
InboundMessage::ShouldSendACKS(llarp_time_t now) const
|
||||
{
|
||||
return now > m_LastACKSent + ACKResendInterval;
|
||||
}
|
||||
|
||||
bool
|
||||
InboundMessage::IsTimedOut(const llarp_time_t now) const
|
||||
{
|
||||
return now > m_LastActiveAt && now - m_LastActiveAt > DeliveryTimeout;
|
||||
}
|
||||
|
||||
void
|
||||
InboundMessage::SendACKS(
|
||||
std::function<void(AbstractLinkSession::Packet_t)> sendpkt, llarp_time_t now)
|
||||
{
|
||||
sendpkt(ACKS());
|
||||
m_LastACKSent = now;
|
||||
}
|
||||
|
||||
bool
|
||||
InboundMessage::Verify() const
|
||||
{
|
||||
ShortHash gotten;
|
||||
const llarp_buffer_t buf(m_Data);
|
||||
CryptoManager::instance()->shorthash(gotten, buf);
|
||||
return gotten == m_Digset;
|
||||
}
|
||||
} // namespace iwp
|
||||
} // namespace llarp
|
@ -1,127 +0,0 @@
|
||||
#pragma once
|
||||
#include <vector>
|
||||
#include <llarp/constants/link_layer.hpp>
|
||||
#include <llarp/link/session.hpp>
|
||||
#include <llarp/util/aligned.hpp>
|
||||
#include <llarp/util/buffer.hpp>
|
||||
#include <llarp/util/types.hpp>
|
||||
|
||||
namespace llarp
|
||||
{
|
||||
namespace iwp
|
||||
{
|
||||
enum Command
|
||||
{
|
||||
/// keep alive message
|
||||
ePING = 0,
|
||||
/// begin transission
|
||||
eXMIT = 1,
|
||||
/// fragment data
|
||||
eDATA = 2,
|
||||
/// acknolege fragments
|
||||
eACKS = 3,
|
||||
/// negative ack
|
||||
eNACK = 4,
|
||||
/// multiack
|
||||
eMACK = 5,
|
||||
/// close session
|
||||
eCLOS = 0xff,
|
||||
};
|
||||
|
||||
/// max size of data fragments
|
||||
static constexpr size_t FragmentSize = 1024;
|
||||
/// plaintext header overhead size
|
||||
static constexpr size_t CommandOverhead = 2;
|
||||
|
||||
struct OutboundMessage
|
||||
{
|
||||
OutboundMessage() = default;
|
||||
OutboundMessage(
|
||||
uint64_t msgid,
|
||||
AbstractLinkSession::Message_t data,
|
||||
llarp_time_t now,
|
||||
AbstractLinkSession::CompletionHandler handler,
|
||||
uint16_t priority);
|
||||
|
||||
AbstractLinkSession::Message_t m_Data;
|
||||
uint64_t m_MsgID = 0;
|
||||
std::bitset<MAX_LINK_MSG_SIZE / FragmentSize> m_Acks;
|
||||
AbstractLinkSession::CompletionHandler m_Completed;
|
||||
llarp_time_t m_LastFlush = 0s;
|
||||
ShortHash m_Digest;
|
||||
llarp_time_t m_StartedAt = 0s;
|
||||
uint16_t m_ResendPriority;
|
||||
|
||||
bool
|
||||
operator<(const OutboundMessage& other) const
|
||||
{
|
||||
// yes, the first order is reversed as higher means more important
|
||||
// second part is for queue order
|
||||
int prioA = -m_ResendPriority, prioB = -other.m_ResendPriority;
|
||||
return std::tie(prioA, m_MsgID) < std::tie(prioB, other.m_MsgID);
|
||||
}
|
||||
|
||||
AbstractLinkSession::Packet_t
|
||||
XMIT() const;
|
||||
|
||||
void
|
||||
Ack(byte_t bitmask);
|
||||
|
||||
void
|
||||
FlushUnAcked(std::function<void(AbstractLinkSession::Packet_t)> sendpkt, llarp_time_t now);
|
||||
|
||||
bool
|
||||
ShouldFlush(llarp_time_t now) const;
|
||||
|
||||
void
|
||||
Completed();
|
||||
|
||||
bool
|
||||
IsTransmitted() const;
|
||||
|
||||
bool
|
||||
IsTimedOut(llarp_time_t now) const;
|
||||
|
||||
void
|
||||
InformTimeout();
|
||||
};
|
||||
|
||||
struct InboundMessage
|
||||
{
|
||||
InboundMessage() = default;
|
||||
InboundMessage(uint64_t msgid, uint16_t sz, ShortHash h, llarp_time_t now);
|
||||
|
||||
AbstractLinkSession::Message_t m_Data;
|
||||
ShortHash m_Digset;
|
||||
uint64_t m_MsgID = 0;
|
||||
llarp_time_t m_LastACKSent = 0s;
|
||||
llarp_time_t m_LastActiveAt = 0s;
|
||||
std::bitset<MAX_LINK_MSG_SIZE / FragmentSize> m_Acks;
|
||||
|
||||
void
|
||||
HandleData(uint16_t idx, const llarp_buffer_t& buf, llarp_time_t now);
|
||||
|
||||
bool
|
||||
IsCompleted() const;
|
||||
|
||||
bool
|
||||
IsTimedOut(llarp_time_t now) const;
|
||||
|
||||
bool
|
||||
Verify() const;
|
||||
|
||||
byte_t
|
||||
AcksBitmask() const;
|
||||
|
||||
bool
|
||||
ShouldSendACKS(llarp_time_t now) const;
|
||||
|
||||
void
|
||||
SendACKS(std::function<void(AbstractLinkSession::Packet_t)> sendpkt, llarp_time_t now);
|
||||
|
||||
AbstractLinkSession::Packet_t
|
||||
ACKS() const;
|
||||
};
|
||||
|
||||
} // namespace iwp
|
||||
} // namespace llarp
|
File diff suppressed because it is too large
Load Diff
@ -1,275 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <llarp/link/session.hpp>
|
||||
#include "linklayer.hpp"
|
||||
#include "message_buffer.hpp"
|
||||
#include <llarp/net/ip_address.hpp>
|
||||
|
||||
#include <map>
|
||||
#include <unordered_set>
|
||||
#include <deque>
|
||||
|
||||
#include <llarp/util/priority_queue.hpp>
|
||||
#include <llarp/util/thread/queue.hpp>
|
||||
|
||||
namespace llarp::iwp
|
||||
{
|
||||
/// packet crypto overhead size
|
||||
static constexpr size_t PacketOverhead = HMACSIZE + TUNNONCESIZE;
|
||||
/// creates a packet with plaintext size + wire overhead + random pad
|
||||
AbstractLinkSession::Packet_t
|
||||
CreatePacket(Command cmd, size_t plainsize, size_t min_pad = 16, size_t pad_variance = 16);
|
||||
/// Time how long we try delivery for
|
||||
static constexpr std::chrono::milliseconds DeliveryTimeout = 500ms;
|
||||
/// Time how long we wait to recieve a message
|
||||
static constexpr auto ReceivalTimeout = (DeliveryTimeout * 8) / 5;
|
||||
/// How long to keep a replay window for
|
||||
static constexpr auto ReplayWindow = (ReceivalTimeout * 3) / 2;
|
||||
/// How often to acks RX messages
|
||||
static constexpr auto ACKResendInterval = DeliveryTimeout / 2;
|
||||
/// How often to retransmit TX fragments
|
||||
static constexpr auto TXFlushInterval = (DeliveryTimeout / 5) * 4;
|
||||
/// How often we send a keepalive
|
||||
static constexpr std::chrono::milliseconds PingInterval = 5s;
|
||||
/// How long we wait for a session to die with no tx from them
|
||||
static constexpr auto SessionAliveTimeout = PingInterval * 5;
|
||||
|
||||
struct Session : public AbstractLinkSession, public std::enable_shared_from_this<Session>
|
||||
{
|
||||
using Time_t = std::chrono::milliseconds;
|
||||
|
||||
/// maximum number of messages we can ack in a multiack
|
||||
static constexpr std::size_t MaxACKSInMACK = 1024 / sizeof(uint64_t);
|
||||
|
||||
/// outbound session
|
||||
Session(LinkLayer* parent, const RouterContact& rc, const AddressInfo& ai);
|
||||
/// inbound session
|
||||
Session(LinkLayer* parent, const SockAddr& from);
|
||||
|
||||
// Signal the event loop that a pump is needed (idempotent)
|
||||
void
|
||||
TriggerPump();
|
||||
|
||||
// Does the actual pump
|
||||
void
|
||||
Pump() override;
|
||||
|
||||
void
|
||||
Tick(llarp_time_t now) override;
|
||||
|
||||
bool
|
||||
SendMessageBuffer(
|
||||
AbstractLinkSession::Message_t msg,
|
||||
CompletionHandler resultHandler,
|
||||
uint16_t priority = 0) override;
|
||||
|
||||
void
|
||||
Send_LL(const byte_t* buf, size_t sz);
|
||||
|
||||
void EncryptAndSend(AbstractLinkSession::Packet_t);
|
||||
|
||||
void
|
||||
Start() override;
|
||||
|
||||
void
|
||||
Close() override;
|
||||
|
||||
bool Recv_LL(AbstractLinkSession::Packet_t) override;
|
||||
|
||||
bool
|
||||
SendKeepAlive() override;
|
||||
|
||||
bool
|
||||
IsEstablished() const override;
|
||||
|
||||
bool
|
||||
TimedOut(llarp_time_t now) const override;
|
||||
|
||||
PubKey
|
||||
GetPubKey() const override
|
||||
{
|
||||
return m_RemoteRC.pubkey;
|
||||
}
|
||||
|
||||
const SockAddr&
|
||||
GetRemoteEndpoint() const override
|
||||
{
|
||||
return m_RemoteAddr;
|
||||
}
|
||||
|
||||
RouterContact
|
||||
GetRemoteRC() const override
|
||||
{
|
||||
return m_RemoteRC;
|
||||
}
|
||||
|
||||
size_t
|
||||
SendQueueBacklog() const override
|
||||
{
|
||||
return m_TXMsgs.size();
|
||||
}
|
||||
|
||||
ILinkLayer*
|
||||
GetLinkLayer() const override
|
||||
{
|
||||
return m_Parent;
|
||||
}
|
||||
|
||||
bool
|
||||
RenegotiateSession() override;
|
||||
|
||||
bool
|
||||
ShouldPing() const override;
|
||||
|
||||
SessionStats
|
||||
GetSessionStats() const override;
|
||||
|
||||
util::StatusObject
|
||||
ExtractStatus() const override;
|
||||
|
||||
bool
|
||||
IsInbound() const override
|
||||
{
|
||||
return m_Inbound;
|
||||
}
|
||||
void
|
||||
HandlePlaintext() override;
|
||||
|
||||
private:
|
||||
enum class State
|
||||
{
|
||||
/// we have no data recv'd
|
||||
Initial,
|
||||
/// we are in introduction phase
|
||||
Introduction,
|
||||
/// we sent our LIM
|
||||
LinkIntro,
|
||||
/// handshake done and LIM has been obtained
|
||||
Ready,
|
||||
/// we are closed now
|
||||
Closed
|
||||
};
|
||||
static std::string
|
||||
StateToString(State state);
|
||||
State m_State;
|
||||
SessionStats m_Stats;
|
||||
|
||||
/// are we inbound session ?
|
||||
const bool m_Inbound;
|
||||
/// parent link layer
|
||||
LinkLayer* const m_Parent;
|
||||
const llarp_time_t m_CreatedAt;
|
||||
const SockAddr m_RemoteAddr;
|
||||
|
||||
AddressInfo m_ChosenAI;
|
||||
/// remote rc
|
||||
RouterContact m_RemoteRC;
|
||||
/// session key
|
||||
SharedSecret m_SessionKey;
|
||||
/// session token
|
||||
AlignedBuffer<24> token;
|
||||
|
||||
PubKey m_ExpectedIdent;
|
||||
PubKey m_RemoteOnionKey;
|
||||
|
||||
llarp_time_t m_LastTX = 0s;
|
||||
llarp_time_t m_LastRX = 0s;
|
||||
|
||||
// accumulate for periodic rate calculation
|
||||
uint64_t m_TXRate = 0;
|
||||
uint64_t m_RXRate = 0;
|
||||
|
||||
llarp_time_t m_ResetRatesAt = 0s;
|
||||
|
||||
uint64_t m_TXID = 0;
|
||||
|
||||
bool
|
||||
ShouldResetRates(llarp_time_t now) const;
|
||||
|
||||
void
|
||||
ResetRates();
|
||||
|
||||
std::map<uint64_t, InboundMessage> m_RXMsgs;
|
||||
std::map<uint64_t, OutboundMessage> m_TXMsgs;
|
||||
|
||||
/// maps rxid to time recieved
|
||||
std::unordered_map<uint64_t, llarp_time_t> m_ReplayFilter;
|
||||
/// rx messages to send in next round of multiacks
|
||||
util::ascending_priority_queue<uint64_t> m_SendMACKs;
|
||||
|
||||
using CryptoQueue_t = std::vector<Packet_t>;
|
||||
|
||||
CryptoQueue_t m_EncryptNext;
|
||||
CryptoQueue_t m_DecryptNext;
|
||||
|
||||
std::atomic_flag m_PlaintextEmpty;
|
||||
llarp::thread::Queue<CryptoQueue_t> m_PlaintextRecv;
|
||||
std::atomic_flag m_SentClosed;
|
||||
|
||||
void
|
||||
EncryptWorker(CryptoQueue_t msgs);
|
||||
|
||||
void
|
||||
DecryptWorker(CryptoQueue_t msgs);
|
||||
|
||||
void
|
||||
HandleGotIntro(Packet_t pkt);
|
||||
|
||||
void
|
||||
HandleGotIntroAck(Packet_t pkt);
|
||||
|
||||
void
|
||||
HandleCreateSessionRequest(Packet_t pkt);
|
||||
|
||||
void
|
||||
HandleAckSession(Packet_t pkt);
|
||||
|
||||
void
|
||||
HandleSessionData(Packet_t pkt);
|
||||
|
||||
bool
|
||||
DecryptMessageInPlace(Packet_t& pkt);
|
||||
|
||||
void
|
||||
SendMACK();
|
||||
|
||||
void
|
||||
HandleRecvMsgCompleted(const InboundMessage& msg);
|
||||
|
||||
void
|
||||
GenerateAndSendIntro();
|
||||
|
||||
bool
|
||||
GotInboundLIM(const LinkIntroMessage* msg);
|
||||
|
||||
bool
|
||||
GotOutboundLIM(const LinkIntroMessage* msg);
|
||||
|
||||
bool
|
||||
GotRenegLIM(const LinkIntroMessage* msg);
|
||||
|
||||
void
|
||||
SendOurLIM(AbstractLinkSession::CompletionHandler h = nullptr);
|
||||
|
||||
void
|
||||
HandleXMIT(Packet_t msg);
|
||||
|
||||
void
|
||||
HandleDATA(Packet_t msg);
|
||||
|
||||
void
|
||||
HandleACKS(Packet_t msg);
|
||||
|
||||
void
|
||||
HandleNACK(Packet_t msg);
|
||||
|
||||
void
|
||||
HandlePING(Packet_t msg);
|
||||
|
||||
void
|
||||
HandleCLOS(Packet_t msg);
|
||||
|
||||
void
|
||||
HandleMACK(Packet_t msg);
|
||||
};
|
||||
} // namespace llarp::iwp
|
@ -1,72 +0,0 @@
|
||||
#include "endpoint.hpp"
|
||||
#include "link_manager.hpp"
|
||||
|
||||
namespace llarp::link
|
||||
{
|
||||
std::shared_ptr<link::Connection>
|
||||
Endpoint::get_conn(const RouterContact& rc) const
|
||||
{
|
||||
for (const auto& [rid, conn] : conns)
|
||||
{
|
||||
if (conn->remote_rc == rc)
|
||||
return conn;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool
|
||||
Endpoint::have_conn(const RouterID& remote, bool client_only) const
|
||||
{
|
||||
if (auto itr = conns.find(remote); itr != conns.end())
|
||||
{
|
||||
if (not(itr->second->remote_is_relay and client_only))
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// TOFIX: use the new close methods after bumping libquic
|
||||
bool
|
||||
Endpoint::deregister_peer(RouterID remote)
|
||||
{
|
||||
if (auto itr = conns.find(remote); itr != conns.end())
|
||||
{
|
||||
endpoint->close_connection(*dynamic_cast<oxen::quic::Connection*>(itr->second->conn.get()));
|
||||
conns.erase(itr);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
Endpoint::establish_connection(const oxen::quic::opt::local_addr& remote)
|
||||
{
|
||||
try
|
||||
{
|
||||
oxen::quic::dgram_data_callback dgram_cb =
|
||||
[this](oxen::quic::dgram_interface& dgi, bstring dgram) {
|
||||
link_manager.recv_data_message(dgi, dgram);
|
||||
};
|
||||
|
||||
auto conn_interface = endpoint->connect(remote, link_manager.tls_creds, dgram_cb);
|
||||
auto control_stream = conn_interface->get_new_stream();
|
||||
|
||||
// TOFIX: get a real RouterID after refactoring it
|
||||
RouterID rid;
|
||||
auto [itr, b] = conns.emplace(rid);
|
||||
itr->second = std::make_shared<link::Connection>(conn_interface, control_stream);
|
||||
connid_map.emplace(conn_interface->scid(), rid);
|
||||
|
||||
return true;
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
log::error(quic_cat, "Error: failed to establish connection to {}", remote);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace llarp::link
|
@ -1,44 +1,12 @@
|
||||
#pragma once
|
||||
|
||||
#include "connection.hpp"
|
||||
#include "link_manager.hpp"
|
||||
|
||||
#include <llarp/router/abstractrouter.hpp>
|
||||
#include <llarp/router/router.hpp>
|
||||
#include <llarp/router_id.hpp>
|
||||
|
||||
#include <external/oxen-libquic/include/quic.hpp>
|
||||
|
||||
namespace llarp::link
|
||||
{
|
||||
struct Endpoint
|
||||
{
|
||||
Endpoint(std::shared_ptr<oxen::quic::Endpoint> ep, LinkManager& lm)
|
||||
: endpoint{std::move(ep)}, link_manager{lm}
|
||||
{}
|
||||
|
||||
std::shared_ptr<oxen::quic::Endpoint> endpoint;
|
||||
LinkManager& link_manager;
|
||||
|
||||
// for outgoing packets, we route via RouterID; map RouterID->Connection
|
||||
// for incoming packets, we get a ConnectionID; map ConnectionID->RouterID
|
||||
std::unordered_map<RouterID, std::shared_ptr<link::Connection>> conns;
|
||||
std::unordered_map<oxen::quic::ConnectionID, RouterID> connid_map;
|
||||
|
||||
std::shared_ptr<link::Connection>
|
||||
get_conn(const RouterContact&) const;
|
||||
|
||||
bool
|
||||
have_conn(const RouterID& remote, bool client_only) const;
|
||||
|
||||
bool
|
||||
deregister_peer(RouterID remote);
|
||||
|
||||
bool
|
||||
establish_connection(const oxen::quic::opt::local_addr& remote);
|
||||
};
|
||||
|
||||
} // namespace llarp::link
|
||||
|
||||
/*
|
||||
- Refactor RouterID to use gnutls info and maybe ConnectionID
|
||||
|
||||
*/
|
||||
{} // namespace llarp::link
|
||||
|
@ -1,43 +0,0 @@
|
||||
#include "factory.hpp"
|
||||
#include <llarp/iwp/iwp.hpp>
|
||||
|
||||
namespace llarp
|
||||
{
|
||||
LinkFactory::LinkType
|
||||
LinkFactory::TypeFromName(std::string_view str)
|
||||
{
|
||||
if (str == "iwp")
|
||||
return LinkType::eLinkIWP;
|
||||
if (str == "mempipe")
|
||||
return LinkType::eLinkMempipe;
|
||||
return LinkType::eLinkUnknown;
|
||||
}
|
||||
|
||||
std::string
|
||||
LinkFactory::NameFromType(LinkFactory::LinkType tp)
|
||||
{
|
||||
switch (tp)
|
||||
{
|
||||
case LinkType::eLinkIWP:
|
||||
return "iwp";
|
||||
case LinkType::eLinkMempipe:
|
||||
return "mempipe";
|
||||
default:
|
||||
return "unspec";
|
||||
}
|
||||
}
|
||||
|
||||
LinkFactory::Factory
|
||||
LinkFactory::Obtain(LinkFactory::LinkType tp, bool permitInbound)
|
||||
{
|
||||
switch (tp)
|
||||
{
|
||||
case LinkType::eLinkIWP:
|
||||
if (permitInbound)
|
||||
return llarp::iwp::NewInboundLink;
|
||||
return llarp::iwp::NewOutboundLink;
|
||||
default:
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
} // namespace llarp
|
@ -1,48 +0,0 @@
|
||||
#pragma once
|
||||
#include <llarp/config/key_manager.hpp>
|
||||
#include <string_view>
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
|
||||
#include "server.hpp"
|
||||
|
||||
namespace llarp
|
||||
{
|
||||
/// LinkFactory is responsible for returning std::functions that create the
|
||||
/// link layer types
|
||||
struct LinkFactory
|
||||
{
|
||||
enum class LinkType
|
||||
{
|
||||
eLinkUTP,
|
||||
eLinkIWP,
|
||||
eLinkMempipe,
|
||||
eLinkUnknown
|
||||
};
|
||||
|
||||
using Factory = std::function<LinkLayer_ptr(
|
||||
std::shared_ptr<KeyManager>,
|
||||
GetRCFunc,
|
||||
LinkMessageHandler,
|
||||
SignBufferFunc,
|
||||
SessionEstablishedHandler,
|
||||
SessionRenegotiateHandler,
|
||||
TimeoutHandler,
|
||||
SessionClosedHandler,
|
||||
PumpDoneHandler)>;
|
||||
|
||||
/// get link type by name string
|
||||
/// if invalid returns eLinkUnspec
|
||||
static LinkType
|
||||
TypeFromName(std::string_view name);
|
||||
|
||||
/// turns a link type into a string representation
|
||||
static std::string
|
||||
NameFromType(LinkType t);
|
||||
|
||||
/// obtain a link factory of a certain type
|
||||
static Factory
|
||||
Obtain(LinkType t, bool permitInbound);
|
||||
};
|
||||
|
||||
} // namespace llarp
|
@ -1,278 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <llarp/crypto/types.hpp>
|
||||
#include <llarp/ev/ev.hpp>
|
||||
#include "session.hpp"
|
||||
#include <llarp/net/sock_addr.hpp>
|
||||
#include <llarp/router_contact.hpp>
|
||||
#include <llarp/util/status.hpp>
|
||||
#include <llarp/util/thread/threading.hpp>
|
||||
#include <llarp/config/key_manager.hpp>
|
||||
|
||||
#include <list>
|
||||
#include <memory>
|
||||
#include <unordered_map>
|
||||
|
||||
namespace llarp
|
||||
{
|
||||
/// handle a link layer message. this allows for the message to be handled by "upper layers"
|
||||
///
|
||||
/// currently called from iwp::Session when messages are sent or received.
|
||||
using LinkMessageHandler = std::function<bool(AbstractLinkSession*, const llarp_buffer_t&)>;
|
||||
|
||||
/// sign a buffer with identity key. this function should take the given `llarp_buffer_t` and
|
||||
/// sign it, prividing the signature in the out variable `Signature&`.
|
||||
///
|
||||
/// currently called from iwp::Session for signing LIMs (link introduction messages)
|
||||
using SignBufferFunc = std::function<bool(Signature&, const llarp_buffer_t&)>;
|
||||
|
||||
/// handle connection timeout
|
||||
///
|
||||
/// currently called from ILinkLayer::Pump() when an unestablished session times out
|
||||
using TimeoutHandler = std::function<void(AbstractLinkSession*)>;
|
||||
|
||||
/// get our RC
|
||||
///
|
||||
/// currently called by iwp::Session to include as part of a LIM (link introduction message)
|
||||
using GetRCFunc = std::function<const llarp::RouterContact&(void)>;
|
||||
|
||||
/// handler of session established
|
||||
/// return false to reject
|
||||
/// return true to accept
|
||||
///
|
||||
/// currently called in iwp::Session when a valid LIM is received.
|
||||
using SessionEstablishedHandler = std::function<bool(AbstractLinkSession*, bool)>;
|
||||
|
||||
/// f(new, old)
|
||||
/// handler of session renegotiation
|
||||
/// returns true if the new rc is valid
|
||||
/// returns false otherwise and the session is terminated
|
||||
///
|
||||
/// currently called from iwp::Session when we receive a renegotiation LIM
|
||||
using SessionRenegotiateHandler = std::function<bool(llarp::RouterContact, llarp::RouterContact)>;
|
||||
|
||||
/// handles close of all sessions with pubkey
|
||||
///
|
||||
/// Note that this handler is called while m_AuthedLinksMutex is held
|
||||
///
|
||||
/// currently called from iwp::ILinkSession when a previously established session times out
|
||||
using SessionClosedHandler = std::function<void(llarp::RouterID)>;
|
||||
|
||||
/// notifies router that a link session has ended its pump and we should flush
|
||||
/// messages to upper layers
|
||||
///
|
||||
/// currently called at the end of every iwp::Session::Pump() call
|
||||
using PumpDoneHandler = std::function<void(void)>;
|
||||
|
||||
using Work_t = std::function<void(void)>;
|
||||
/// queue work to worker thread
|
||||
using WorkerFunc_t = std::function<void(Work_t)>;
|
||||
|
||||
/// before connection hook, called before we try connecting via outbound link
|
||||
using BeforeConnectFunc_t = std::function<void(llarp::RouterContact)>;
|
||||
|
||||
struct ILinkLayer
|
||||
{
|
||||
ILinkLayer(
|
||||
std::shared_ptr<KeyManager> keyManager,
|
||||
GetRCFunc getrc,
|
||||
LinkMessageHandler handler,
|
||||
SignBufferFunc signFunc,
|
||||
BeforeConnectFunc_t before,
|
||||
SessionEstablishedHandler sessionEstablish,
|
||||
SessionRenegotiateHandler renegotiate,
|
||||
TimeoutHandler timeout,
|
||||
SessionClosedHandler closed,
|
||||
PumpDoneHandler pumpDone,
|
||||
WorkerFunc_t doWork);
|
||||
virtual ~ILinkLayer() = default;
|
||||
|
||||
/// get current time via event loop
|
||||
llarp_time_t
|
||||
Now() const;
|
||||
|
||||
bool
|
||||
HasSessionTo(const RouterID& pk);
|
||||
|
||||
void
|
||||
ForEachSession(std::function<void(const AbstractLinkSession*)> visit, bool randomize = false)
|
||||
const EXCLUDES(m_AuthedLinksMutex);
|
||||
|
||||
void
|
||||
ForEachSession(std::function<void(AbstractLinkSession*)> visit) EXCLUDES(m_AuthedLinksMutex);
|
||||
|
||||
void
|
||||
UnmapAddr(const SockAddr& addr);
|
||||
|
||||
void
|
||||
SendTo_LL(const SockAddr& to, const llarp_buffer_t& pkt);
|
||||
|
||||
void
|
||||
Bind(AbstractRouter* router, SockAddr addr);
|
||||
|
||||
virtual std::shared_ptr<AbstractLinkSession>
|
||||
NewOutboundSession(const RouterContact& rc, const AddressInfo& ai) = 0;
|
||||
|
||||
/// fetch a session by the identity pubkey it claims
|
||||
std::shared_ptr<AbstractLinkSession>
|
||||
FindSessionByPubkey(RouterID pk);
|
||||
|
||||
virtual void
|
||||
Pump();
|
||||
|
||||
virtual void
|
||||
RecvFrom(const SockAddr& from, AbstractLinkSession::Packet_t pkt) = 0;
|
||||
|
||||
bool
|
||||
PickAddress(const RouterContact& rc, AddressInfo& picked) const;
|
||||
|
||||
bool
|
||||
TryEstablishTo(RouterContact rc);
|
||||
|
||||
bool
|
||||
Start();
|
||||
|
||||
virtual void
|
||||
Stop();
|
||||
|
||||
virtual std::string_view
|
||||
Name() const = 0;
|
||||
|
||||
util::StatusObject
|
||||
ExtractStatus() const EXCLUDES(m_AuthedLinksMutex);
|
||||
|
||||
void
|
||||
CloseSessionTo(const RouterID& remote);
|
||||
|
||||
void
|
||||
KeepAliveSessionTo(const RouterID& remote);
|
||||
|
||||
virtual bool
|
||||
SendTo(
|
||||
const RouterID& remote,
|
||||
const llarp_buffer_t& buf,
|
||||
AbstractLinkSession::CompletionHandler completed,
|
||||
uint16_t priority);
|
||||
|
||||
virtual bool
|
||||
GetOurAddressInfo(AddressInfo& addr) const;
|
||||
|
||||
bool
|
||||
VisitSessionByPubkey(const RouterID& pk, std::function<bool(AbstractLinkSession*)> visit)
|
||||
EXCLUDES(m_AuthedLinksMutex);
|
||||
|
||||
virtual uint16_t
|
||||
Rank() const = 0;
|
||||
|
||||
const byte_t*
|
||||
TransportPubKey() const;
|
||||
|
||||
const SecretKey&
|
||||
RouterEncryptionSecret() const
|
||||
{
|
||||
return m_RouterEncSecret;
|
||||
}
|
||||
|
||||
const SecretKey&
|
||||
TransportSecretKey() const;
|
||||
|
||||
bool
|
||||
IsCompatable(const llarp::RouterContact& other) const
|
||||
{
|
||||
const auto us = Name();
|
||||
for (const auto& ai : other.addrs)
|
||||
if (ai.dialect == us)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
MapAddr(const RouterID& pk, AbstractLinkSession* s);
|
||||
|
||||
void
|
||||
Tick(llarp_time_t now);
|
||||
|
||||
LinkMessageHandler HandleMessage;
|
||||
TimeoutHandler HandleTimeout;
|
||||
SignBufferFunc Sign;
|
||||
GetRCFunc GetOurRC;
|
||||
BeforeConnectFunc_t BeforeConnect;
|
||||
SessionEstablishedHandler SessionEstablished;
|
||||
SessionClosedHandler SessionClosed;
|
||||
SessionRenegotiateHandler SessionRenegotiate;
|
||||
PumpDoneHandler PumpDone;
|
||||
std::shared_ptr<KeyManager> keyManager;
|
||||
WorkerFunc_t QueueWork;
|
||||
|
||||
bool
|
||||
operator<(const ILinkLayer& other) const
|
||||
{
|
||||
auto rankA = Rank(), rankB = other.Rank();
|
||||
auto nameA = Name(), nameB = other.Name();
|
||||
return std::tie(rankA, nameA, m_ourAddr) < std::tie(rankB, nameB, other.m_ourAddr);
|
||||
}
|
||||
|
||||
/// called by link session to remove a pending session who is timed out
|
||||
// void
|
||||
// RemovePending(ILinkSession* s) EXCLUDES(m_PendingMutex);
|
||||
|
||||
/// count the number of sessions that are yet to be fully connected
|
||||
size_t
|
||||
NumberOfPendingSessions() const
|
||||
{
|
||||
Lock_t lock(m_PendingMutex);
|
||||
return m_Pending.size();
|
||||
}
|
||||
|
||||
// Returns the file description of the UDP server, if available.
|
||||
std::optional<int>
|
||||
GetUDPFD() const;
|
||||
|
||||
// Gets a pointer to the router owning us.
|
||||
AbstractRouter*
|
||||
Router() const
|
||||
{
|
||||
return m_Router;
|
||||
}
|
||||
|
||||
/// Get the local sock addr we are bound on
|
||||
const SockAddr&
|
||||
LocalSocketAddr() const
|
||||
{
|
||||
return m_ourAddr;
|
||||
}
|
||||
|
||||
private:
|
||||
const SecretKey& m_RouterEncSecret;
|
||||
|
||||
protected:
|
||||
#ifdef TRACY_ENABLE
|
||||
using Lock_t = std::lock_guard<LockableBase(std::mutex)>;
|
||||
using Mutex_t = std::mutex;
|
||||
#else
|
||||
using Lock_t = util::NullLock;
|
||||
using Mutex_t = util::NullMutex;
|
||||
#endif
|
||||
bool
|
||||
PutSession(const std::shared_ptr<AbstractLinkSession>& s);
|
||||
|
||||
AbstractRouter* m_Router;
|
||||
SockAddr m_ourAddr;
|
||||
std::shared_ptr<llarp::UDPHandle> m_udp;
|
||||
SecretKey m_SecretKey;
|
||||
|
||||
using AuthedLinks = std::unordered_multimap<RouterID, std::shared_ptr<AbstractLinkSession>>;
|
||||
using Pending = std::unordered_map<SockAddr, std::shared_ptr<AbstractLinkSession>>;
|
||||
mutable DECLARE_LOCK(Mutex_t, m_AuthedLinksMutex, ACQUIRED_BEFORE(m_PendingMutex));
|
||||
AuthedLinks m_AuthedLinks GUARDED_BY(m_AuthedLinksMutex);
|
||||
mutable DECLARE_LOCK(Mutex_t, m_PendingMutex, ACQUIRED_AFTER(m_AuthedLinksMutex));
|
||||
Pending m_Pending GUARDED_BY(m_PendingMutex);
|
||||
std::unordered_map<SockAddr, RouterID> m_AuthedAddrs;
|
||||
std::unordered_map<SockAddr, llarp_time_t> m_RecentlyClosed;
|
||||
|
||||
private:
|
||||
std::shared_ptr<int> m_repeater_keepalive;
|
||||
};
|
||||
|
||||
using LinkLayer_ptr = std::shared_ptr<ILinkLayer>;
|
||||
} // namespace llarp
|
@ -1,11 +0,0 @@
|
||||
#include "session.hpp"
|
||||
|
||||
namespace llarp
|
||||
{
|
||||
bool
|
||||
AbstractLinkSession::IsRelay() const
|
||||
{
|
||||
return GetRemoteRC().IsPublicRouter();
|
||||
}
|
||||
|
||||
} // namespace llarp
|
@ -1,138 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <llarp/crypto/types.hpp>
|
||||
#include <llarp/net/net.hpp>
|
||||
#include <llarp/ev/ev.hpp>
|
||||
#include <llarp/router_contact.hpp>
|
||||
#include <llarp/util/types.hpp>
|
||||
|
||||
#include <functional>
|
||||
|
||||
namespace llarp
|
||||
{
|
||||
struct LinkIntroMessage;
|
||||
struct AbstractLinkMessage;
|
||||
struct ILinkLayer;
|
||||
|
||||
struct SessionStats
|
||||
{
|
||||
// rate
|
||||
uint64_t currentRateRX = 0;
|
||||
uint64_t currentRateTX = 0;
|
||||
|
||||
uint64_t totalPacketsRX = 0;
|
||||
|
||||
uint64_t totalAckedTX = 0;
|
||||
uint64_t totalDroppedTX = 0;
|
||||
uint64_t totalInFlightTX = 0;
|
||||
};
|
||||
|
||||
struct AbstractLinkSession
|
||||
{
|
||||
virtual ~AbstractLinkSession() = default;
|
||||
|
||||
/// delivery status of a message
|
||||
enum class DeliveryStatus
|
||||
{
|
||||
eDeliverySuccess = 0,
|
||||
eDeliveryDropped = 1
|
||||
};
|
||||
|
||||
/// hook for utp for when we have established a connection
|
||||
virtual void
|
||||
OnLinkEstablished(ILinkLayer*){};
|
||||
|
||||
/// called during pumping
|
||||
virtual void
|
||||
Pump() = 0;
|
||||
|
||||
/// called every timer tick
|
||||
virtual void Tick(llarp_time_t) = 0;
|
||||
|
||||
/// message delivery result hook function
|
||||
using CompletionHandler = std::function<void(DeliveryStatus)>;
|
||||
|
||||
using Packet_t = std::vector<byte_t>;
|
||||
using Message_t = std::vector<byte_t>;
|
||||
|
||||
/// send a message buffer to the remote endpoint
|
||||
virtual bool
|
||||
SendMessageBuffer(Message_t, CompletionHandler handler, uint16_t priority) = 0;
|
||||
|
||||
/// start the connection
|
||||
virtual void
|
||||
Start() = 0;
|
||||
|
||||
virtual void
|
||||
Close() = 0;
|
||||
|
||||
/// recv packet on low layer
|
||||
/// not used by utp
|
||||
virtual bool
|
||||
Recv_LL(Packet_t)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/// send a keepalive to the remote endpoint
|
||||
virtual bool
|
||||
SendKeepAlive() = 0;
|
||||
|
||||
/// return true if we are established
|
||||
virtual bool
|
||||
IsEstablished() const = 0;
|
||||
|
||||
/// return true if this session has timed out
|
||||
virtual bool
|
||||
TimedOut(llarp_time_t now) const = 0;
|
||||
|
||||
/// get remote public identity key
|
||||
virtual PubKey
|
||||
GetPubKey() const = 0;
|
||||
|
||||
/// is an inbound session or not
|
||||
virtual bool
|
||||
IsInbound() const = 0;
|
||||
|
||||
/// get remote address
|
||||
virtual const SockAddr&
|
||||
GetRemoteEndpoint() const = 0;
|
||||
|
||||
// get remote rc
|
||||
virtual RouterContact
|
||||
GetRemoteRC() const = 0;
|
||||
|
||||
/// is this session a session to a relay?
|
||||
bool
|
||||
IsRelay() const;
|
||||
|
||||
/// handle a valid LIM
|
||||
std::function<bool(const LinkIntroMessage* msg)> GotLIM;
|
||||
|
||||
/// send queue current blacklog
|
||||
virtual size_t
|
||||
SendQueueBacklog() const = 0;
|
||||
|
||||
/// get parent link layer
|
||||
virtual ILinkLayer*
|
||||
GetLinkLayer() const = 0;
|
||||
|
||||
/// renegotiate session when we have a new RC locally
|
||||
virtual bool
|
||||
RenegotiateSession() = 0;
|
||||
|
||||
/// return true if we should send an explicit keepalive message
|
||||
virtual bool
|
||||
ShouldPing() const = 0;
|
||||
|
||||
/// return the current stats for this session
|
||||
virtual SessionStats
|
||||
GetSessionStats() const = 0;
|
||||
|
||||
virtual util::StatusObject
|
||||
ExtractStatus() const = 0;
|
||||
|
||||
virtual void
|
||||
HandlePlaintext() = 0;
|
||||
};
|
||||
} // namespace llarp
|
@ -1,185 +0,0 @@
|
||||
#include "address_info.hpp"
|
||||
#include <stdexcept>
|
||||
|
||||
#ifndef _WIN32
|
||||
#include <arpa/inet.h>
|
||||
#endif
|
||||
#include "net.hpp"
|
||||
#include <llarp/util/bencode.h>
|
||||
#include <llarp/util/mem.h>
|
||||
|
||||
#include <cstring>
|
||||
|
||||
namespace llarp
|
||||
{
|
||||
bool
|
||||
operator==(const AddressInfo& lhs, const AddressInfo& rhs)
|
||||
{
|
||||
// we don't care about rank
|
||||
return lhs.pubkey == rhs.pubkey && lhs.port == rhs.port && lhs.dialect == rhs.dialect
|
||||
&& lhs.ip == rhs.ip;
|
||||
}
|
||||
|
||||
bool
|
||||
operator<(const AddressInfo& lhs, const AddressInfo& rhs)
|
||||
{
|
||||
return std::tie(lhs.rank, lhs.ip, lhs.port) < std::tie(rhs.rank, rhs.ip, rhs.port);
|
||||
}
|
||||
|
||||
std::variant<nuint32_t, nuint128_t>
|
||||
AddressInfo::IP() const
|
||||
{
|
||||
return SockAddr{ip}.getIP();
|
||||
}
|
||||
|
||||
bool
|
||||
AddressInfo::decode_key(const llarp_buffer_t& key, llarp_buffer_t* buf)
|
||||
{
|
||||
uint64_t i;
|
||||
char tmp[128] = {0};
|
||||
|
||||
llarp_buffer_t strbuf;
|
||||
|
||||
// rank
|
||||
if (key.startswith("c"))
|
||||
{
|
||||
if (!bencode_read_integer(buf, &i))
|
||||
return false;
|
||||
|
||||
if (i > 65536 || i <= 0)
|
||||
return false;
|
||||
|
||||
rank = i;
|
||||
return true;
|
||||
}
|
||||
|
||||
// dialect
|
||||
if (key.startswith("d"))
|
||||
{
|
||||
if (!bencode_read_string(buf, &strbuf))
|
||||
return false;
|
||||
if (strbuf.sz > sizeof(tmp))
|
||||
return false;
|
||||
memcpy(tmp, strbuf.base, strbuf.sz);
|
||||
tmp[strbuf.sz] = 0;
|
||||
dialect = std::string(tmp);
|
||||
return true;
|
||||
}
|
||||
|
||||
// encryption public key
|
||||
if (key.startswith("e"))
|
||||
{
|
||||
return pubkey.BDecode(buf);
|
||||
}
|
||||
|
||||
// ip address
|
||||
if (key.startswith("i"))
|
||||
{
|
||||
if (!bencode_read_string(buf, &strbuf))
|
||||
return false;
|
||||
|
||||
if (strbuf.sz >= sizeof(tmp))
|
||||
return false;
|
||||
|
||||
memcpy(tmp, strbuf.base, strbuf.sz);
|
||||
tmp[strbuf.sz] = 0;
|
||||
return inet_pton(AF_INET6, tmp, &ip.s6_addr[0]) == 1;
|
||||
}
|
||||
|
||||
// port
|
||||
if (key.startswith("p"))
|
||||
{
|
||||
if (!bencode_read_integer(buf, &i))
|
||||
return false;
|
||||
|
||||
if (i > 65536 || i <= 0)
|
||||
return false;
|
||||
|
||||
port = i;
|
||||
return true;
|
||||
}
|
||||
|
||||
// version
|
||||
if (key.startswith("v"))
|
||||
{
|
||||
if (!bencode_read_integer(buf, &i))
|
||||
return false;
|
||||
return i == llarp::constants::proto_version;
|
||||
}
|
||||
|
||||
// bad key
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string
|
||||
AddressInfo::bt_encode() const
|
||||
{
|
||||
char ipbuff[128] = {0};
|
||||
oxenc::bt_dict_producer btdp;
|
||||
|
||||
try
|
||||
{
|
||||
btdp.append("c", rank);
|
||||
btdp.append("d", dialect);
|
||||
btdp.append("e", pubkey.ToView());
|
||||
|
||||
const char* ipstr = inet_ntop(AF_INET6, (void*)&ip, ipbuff, sizeof(ipbuff));
|
||||
|
||||
btdp.append("i", std::string_view{ipstr, strnlen(ipstr, sizeof(ipbuff))});
|
||||
btdp.append("p", port);
|
||||
btdp.append("v", version);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
log::critical(net_cat, "Error: AddressInfo failed to bt encode contents!");
|
||||
}
|
||||
|
||||
return std::move(btdp).str();
|
||||
}
|
||||
|
||||
IpAddress
|
||||
AddressInfo::toIpAddress() const
|
||||
{
|
||||
SockAddr addr(ip);
|
||||
addr.setPort(port);
|
||||
return {addr};
|
||||
}
|
||||
|
||||
void
|
||||
AddressInfo::fromSockAddr(const SockAddr& addr)
|
||||
{
|
||||
const auto* addr6 = static_cast<const sockaddr_in6*>(addr);
|
||||
memcpy(ip.s6_addr, addr6->sin6_addr.s6_addr, sizeof(ip.s6_addr));
|
||||
port = addr.getPort();
|
||||
}
|
||||
|
||||
std::string
|
||||
AddressInfo::ToString() const
|
||||
{
|
||||
char tmp[INET6_ADDRSTRLEN] = {0};
|
||||
inet_ntop(AF_INET6, (void*)&ip, tmp, sizeof(tmp));
|
||||
return fmt::format("[{}]:{}", tmp, port);
|
||||
}
|
||||
|
||||
std::string
|
||||
AddressInfo::IPString() const
|
||||
{
|
||||
char tmp[INET6_ADDRSTRLEN] = {0};
|
||||
inet_ntop(AF_INET6, (void*)&ip, tmp, sizeof(tmp));
|
||||
return std::string{tmp};
|
||||
}
|
||||
|
||||
void
|
||||
to_json(nlohmann::json& j, const AddressInfo& a)
|
||||
{
|
||||
char tmp[128] = {0};
|
||||
inet_ntop(AF_INET6, (void*)&a.ip, tmp, sizeof(tmp));
|
||||
|
||||
j = nlohmann::json{
|
||||
{"rank", a.rank},
|
||||
{"dialect", a.dialect},
|
||||
{"pubkey", a.pubkey.ToString()},
|
||||
{"in6_addr", tmp},
|
||||
{"port", a.port}};
|
||||
}
|
||||
} // namespace llarp
|
@ -1,98 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <llarp/crypto/types.hpp>
|
||||
#include "ip_address.hpp"
|
||||
#include "net.h"
|
||||
#include <llarp/util/bencode.hpp>
|
||||
#include <llarp/util/mem.h>
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include <oxenc/variant.h>
|
||||
|
||||
/**
|
||||
* address_info.hpp
|
||||
*
|
||||
* utilities for handling addresses on the llarp network
|
||||
*/
|
||||
|
||||
/// address information model
|
||||
namespace llarp
|
||||
{
|
||||
struct AddressInfo
|
||||
{
|
||||
uint16_t rank;
|
||||
std::string dialect;
|
||||
llarp::PubKey pubkey;
|
||||
in6_addr ip = {};
|
||||
uint16_t port;
|
||||
uint64_t version = llarp::constants::proto_version;
|
||||
|
||||
bool
|
||||
BDecode(llarp_buffer_t* buf)
|
||||
{
|
||||
return bencode_decode_dict(*this, buf);
|
||||
}
|
||||
|
||||
std::string
|
||||
bt_encode() const;
|
||||
|
||||
bool
|
||||
decode_key(const llarp_buffer_t& k, llarp_buffer_t* buf);
|
||||
|
||||
/// Return an IpAddress representing the address portion of this AddressInfo
|
||||
IpAddress
|
||||
toIpAddress() const;
|
||||
|
||||
/// Updates our ip and port to reflect that of the given SockAddr
|
||||
void
|
||||
fromSockAddr(const SockAddr& address);
|
||||
|
||||
/// get this as an explicit v4 or explicit v6
|
||||
net::ipaddr_t
|
||||
IP() const;
|
||||
|
||||
/// get this as an v4 or throw if it is not one
|
||||
inline net::ipv4addr_t
|
||||
IPv4() const
|
||||
{
|
||||
auto ip = IP();
|
||||
if (auto* ptr = std::get_if<net::ipv4addr_t>(&ip))
|
||||
return *ptr;
|
||||
throw std::runtime_error{"no ipv4 address found in address info"};
|
||||
}
|
||||
|
||||
std::string
|
||||
ToString() const;
|
||||
|
||||
std::string
|
||||
IPString() const;
|
||||
};
|
||||
|
||||
void
|
||||
to_json(nlohmann::json& j, const AddressInfo& a);
|
||||
|
||||
bool
|
||||
operator==(const AddressInfo& lhs, const AddressInfo& rhs);
|
||||
|
||||
bool
|
||||
operator<(const AddressInfo& lhs, const AddressInfo& rhs);
|
||||
|
||||
template <>
|
||||
constexpr inline bool IsToStringFormattable<AddressInfo> = true;
|
||||
|
||||
} // namespace llarp
|
||||
|
||||
namespace std
|
||||
{
|
||||
template <>
|
||||
struct hash<llarp::AddressInfo>
|
||||
{
|
||||
size_t
|
||||
operator()(const llarp::AddressInfo& addr) const
|
||||
{
|
||||
return std::hash<llarp::PubKey>{}(addr.pubkey);
|
||||
}
|
||||
};
|
||||
} // namespace std
|
@ -1,397 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <llarp/config/config.hpp>
|
||||
#include <llarp/config/key_manager.hpp>
|
||||
#include <memory>
|
||||
#include <llarp/util/types.hpp>
|
||||
#include <llarp/util/status.hpp>
|
||||
#include "outbound_message_handler.hpp"
|
||||
#include <vector>
|
||||
#include <llarp/ev/ev.hpp>
|
||||
#include <functional>
|
||||
#include <llarp/router_contact.hpp>
|
||||
#include <llarp/tooling/router_event.hpp>
|
||||
#include <llarp/peerstats/peer_db.hpp>
|
||||
#include <llarp/consensus/reachability_testing.hpp>
|
||||
|
||||
#include <optional>
|
||||
|
||||
#ifdef LOKINET_HIVE
|
||||
#include <llarp/tooling/router_event.hpp>
|
||||
#endif
|
||||
|
||||
struct llarp_buffer_t;
|
||||
struct llarp_dht_context;
|
||||
|
||||
namespace oxenmq
|
||||
{
|
||||
class OxenMQ;
|
||||
}
|
||||
|
||||
namespace llarp
|
||||
{
|
||||
class NodeDB;
|
||||
struct Config;
|
||||
struct RouterID;
|
||||
struct AbstractLinkMessage;
|
||||
struct AbstractLinkSession;
|
||||
struct PathID_t;
|
||||
struct Profiling;
|
||||
struct SecretKey;
|
||||
struct Signature;
|
||||
struct OutboundMessageHandler;
|
||||
struct LinkManager;
|
||||
struct RCLookupHandler;
|
||||
struct RoutePoker;
|
||||
|
||||
namespace dht
|
||||
{
|
||||
struct AbstractDHTMessageHandler;
|
||||
}
|
||||
|
||||
namespace dns
|
||||
{
|
||||
class I_SystemSettings;
|
||||
}
|
||||
|
||||
namespace net
|
||||
{
|
||||
class Platform;
|
||||
}
|
||||
|
||||
namespace exit
|
||||
{
|
||||
struct Context;
|
||||
}
|
||||
|
||||
namespace rpc
|
||||
{
|
||||
struct LokidRpcClient;
|
||||
}
|
||||
|
||||
namespace path
|
||||
{
|
||||
struct PathContext;
|
||||
}
|
||||
|
||||
namespace routing
|
||||
{
|
||||
struct AbstractRoutingMessageHandler;
|
||||
}
|
||||
|
||||
namespace service
|
||||
{
|
||||
struct Context;
|
||||
}
|
||||
|
||||
namespace thread
|
||||
{
|
||||
class ThreadPool;
|
||||
}
|
||||
|
||||
namespace vpn
|
||||
{
|
||||
class Platform;
|
||||
}
|
||||
|
||||
using LMQ_ptr = std::shared_ptr<oxenmq::OxenMQ>;
|
||||
|
||||
struct AbstractRouter : public std::enable_shared_from_this<AbstractRouter>
|
||||
{
|
||||
#ifdef LOKINET_HIVE
|
||||
tooling::RouterHive* hive = nullptr;
|
||||
#endif
|
||||
|
||||
virtual ~AbstractRouter() = default;
|
||||
|
||||
virtual bool
|
||||
HandleRecvLinkMessageBuffer(AbstractLinkSession* from, const llarp_buffer_t& msg) = 0;
|
||||
|
||||
virtual const net::Platform&
|
||||
Net() const = 0;
|
||||
|
||||
virtual const LMQ_ptr&
|
||||
lmq() const = 0;
|
||||
|
||||
virtual vpn::Platform*
|
||||
GetVPNPlatform() const = 0;
|
||||
|
||||
virtual const std::shared_ptr<rpc::LokidRpcClient>&
|
||||
RpcClient() const = 0;
|
||||
|
||||
virtual std::shared_ptr<dht::AbstractDHTMessageHandler>
|
||||
dht() const = 0;
|
||||
|
||||
virtual const std::shared_ptr<NodeDB>&
|
||||
nodedb() const = 0;
|
||||
|
||||
virtual const path::PathContext&
|
||||
pathContext() const = 0;
|
||||
|
||||
virtual path::PathContext&
|
||||
pathContext() = 0;
|
||||
|
||||
virtual const RouterContact&
|
||||
rc() const = 0;
|
||||
|
||||
/// modify our rc
|
||||
/// modify returns nullopt if unmodified otherwise it returns the new rc to be sigend and
|
||||
/// published out
|
||||
virtual void
|
||||
ModifyOurRC(std::function<std::optional<RouterContact>(RouterContact)> modify) = 0;
|
||||
|
||||
virtual exit::Context&
|
||||
exitContext() = 0;
|
||||
|
||||
virtual const std::shared_ptr<KeyManager>&
|
||||
keyManager() const = 0;
|
||||
|
||||
virtual const SecretKey&
|
||||
identity() const = 0;
|
||||
|
||||
virtual const SecretKey&
|
||||
encryption() const = 0;
|
||||
|
||||
virtual Profiling&
|
||||
routerProfiling() = 0;
|
||||
|
||||
virtual const EventLoop_ptr&
|
||||
loop() const = 0;
|
||||
|
||||
/// call function in crypto worker
|
||||
virtual void QueueWork(std::function<void(void)>) = 0;
|
||||
|
||||
/// call function in disk io thread
|
||||
virtual void QueueDiskIO(std::function<void(void)>) = 0;
|
||||
|
||||
virtual std::shared_ptr<Config>
|
||||
GetConfig() const
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
virtual service::Context&
|
||||
hiddenServiceContext() = 0;
|
||||
|
||||
virtual const service::Context&
|
||||
hiddenServiceContext() const = 0;
|
||||
|
||||
virtual OutboundMessageHandler&
|
||||
outboundMessageHandler() = 0;
|
||||
|
||||
virtual LinkManager&
|
||||
linkManager() = 0;
|
||||
|
||||
virtual const std::shared_ptr<RoutePoker>&
|
||||
routePoker() const = 0;
|
||||
|
||||
virtual RCLookupHandler&
|
||||
rcLookupHandler() = 0;
|
||||
|
||||
virtual std::shared_ptr<PeerDb>
|
||||
peerDb() = 0;
|
||||
|
||||
virtual bool
|
||||
Sign(Signature& sig, const llarp_buffer_t& buf) const = 0;
|
||||
|
||||
virtual bool
|
||||
Configure(std::shared_ptr<Config> conf, bool isSNode, std::shared_ptr<NodeDB> nodedb) = 0;
|
||||
|
||||
virtual bool
|
||||
IsServiceNode() const = 0;
|
||||
|
||||
/// Called to determine if we're in a bad state (which gets reported to our oxend) that should
|
||||
/// prevent uptime proofs from going out to the network (so that the error state gets noticed).
|
||||
/// Currently this means we require a decent number of peers whenever we are fully staked
|
||||
/// (active or decommed).
|
||||
virtual std::optional<std::string>
|
||||
OxendErrorState() const = 0;
|
||||
|
||||
virtual bool
|
||||
StartRpcServer() = 0;
|
||||
|
||||
virtual bool
|
||||
Run() = 0;
|
||||
|
||||
virtual bool
|
||||
IsRunning() const = 0;
|
||||
|
||||
virtual bool
|
||||
LooksAlive() const = 0;
|
||||
|
||||
/// stop running the router logic gracefully
|
||||
virtual void
|
||||
Stop() = 0;
|
||||
|
||||
/// indicate we are about to sleep for a while
|
||||
virtual void
|
||||
Freeze() = 0;
|
||||
|
||||
/// thaw from long sleep or network changed event
|
||||
virtual void
|
||||
Thaw() = 0;
|
||||
|
||||
/// non gracefully stop the router
|
||||
virtual void
|
||||
Die() = 0;
|
||||
|
||||
/// Trigger a pump of low level links. Idempotent.
|
||||
virtual void
|
||||
TriggerPump() = 0;
|
||||
|
||||
virtual bool
|
||||
IsBootstrapNode(RouterID r) const = 0;
|
||||
|
||||
virtual const byte_t*
|
||||
pubkey() const = 0;
|
||||
|
||||
/// get what our real public ip is if we can know it
|
||||
virtual std::optional<std::variant<nuint32_t, nuint128_t>>
|
||||
OurPublicIP() const = 0;
|
||||
|
||||
/// connect to N random routers
|
||||
virtual void
|
||||
ConnectToRandomRouters(int N) = 0;
|
||||
|
||||
virtual bool
|
||||
TryConnectAsync(RouterContact rc, uint16_t tries) = 0;
|
||||
|
||||
/// called by link when a remote session has no more sessions open
|
||||
virtual void
|
||||
SessionClosed(RouterID remote) = 0;
|
||||
|
||||
/// returns system clock milliseconds since epoch
|
||||
virtual llarp_time_t
|
||||
Now() const = 0;
|
||||
|
||||
/// returns milliseconds since started
|
||||
virtual llarp_time_t
|
||||
Uptime() const = 0;
|
||||
|
||||
virtual bool
|
||||
GetRandomGoodRouter(RouterID& r) = 0;
|
||||
|
||||
virtual bool
|
||||
SendToOrQueue(
|
||||
const RouterID& remote,
|
||||
const AbstractLinkMessage& msg,
|
||||
SendStatusHandler handler = nullptr) = 0;
|
||||
|
||||
virtual void
|
||||
PersistSessionUntil(const RouterID& remote, llarp_time_t until) = 0;
|
||||
|
||||
virtual bool
|
||||
ParseRoutingMessageBuffer(
|
||||
const llarp_buffer_t& buf,
|
||||
routing::AbstractRoutingMessageHandler* h,
|
||||
const PathID_t& rxid) = 0;
|
||||
|
||||
/// count the number of service nodes we are connected to
|
||||
virtual size_t
|
||||
NumberOfConnectedRouters() const = 0;
|
||||
|
||||
/// count the number of clients that are connected to us
|
||||
virtual size_t
|
||||
NumberOfConnectedClients() const = 0;
|
||||
|
||||
virtual bool
|
||||
GetRandomConnectedRouter(RouterContact& result) const = 0;
|
||||
|
||||
virtual void
|
||||
HandleDHTLookupForExplore(RouterID remote, const std::vector<RouterContact>& results) = 0;
|
||||
|
||||
virtual void SetDownHook(std::function<void(void)>){};
|
||||
|
||||
/// lookup router by pubkey
|
||||
/// if we are a service node this is done direct otherwise it's done via
|
||||
/// path
|
||||
virtual void
|
||||
LookupRouter(RouterID remote, RouterLookupHandler resultHandler) = 0;
|
||||
|
||||
/// check if newRc matches oldRC and update local rc for this remote contact
|
||||
/// if valid
|
||||
/// returns true on valid and updated
|
||||
/// returns false otherwise
|
||||
virtual bool
|
||||
CheckRenegotiateValid(RouterContact newRc, RouterContact oldRC) = 0;
|
||||
|
||||
/// set router's service node whitelist
|
||||
virtual void
|
||||
SetRouterWhitelist(
|
||||
const std::vector<RouterID>& whitelist,
|
||||
const std::vector<RouterID>& greylist,
|
||||
const std::vector<RouterID>& unfundedlist) = 0;
|
||||
|
||||
virtual std::unordered_set<RouterID>
|
||||
GetRouterWhitelist() const = 0;
|
||||
|
||||
/// visit each connected link session
|
||||
virtual void
|
||||
ForEachPeer(
|
||||
std::function<void(const AbstractLinkSession*, bool)> visit, bool randomize) const = 0;
|
||||
|
||||
virtual bool
|
||||
SessionToRouterAllowed(const RouterID& router) const = 0;
|
||||
|
||||
virtual bool
|
||||
PathToRouterAllowed(const RouterID& router) const = 0;
|
||||
|
||||
/// return true if we have an exit as a client
|
||||
virtual bool
|
||||
HasClientExit() const
|
||||
{
|
||||
return false;
|
||||
};
|
||||
|
||||
virtual path::BuildLimiter&
|
||||
pathBuildLimiter() = 0;
|
||||
|
||||
/// return true if we have at least 1 session to this router in either
|
||||
/// direction
|
||||
virtual bool
|
||||
HasSessionTo(const RouterID& router) const = 0;
|
||||
|
||||
virtual uint32_t
|
||||
NextPathBuildNumber() = 0;
|
||||
|
||||
virtual std::string
|
||||
ShortName() const = 0;
|
||||
|
||||
virtual util::StatusObject
|
||||
ExtractStatus() const = 0;
|
||||
|
||||
virtual util::StatusObject
|
||||
ExtractSummaryStatus() const = 0;
|
||||
|
||||
/// gossip an rc if required
|
||||
virtual void
|
||||
GossipRCIfNeeded(const RouterContact rc) = 0;
|
||||
|
||||
virtual std::string
|
||||
status_line() = 0;
|
||||
|
||||
/// Templated convenience function to generate a RouterHive event and
|
||||
/// delegate to non-templated (and overridable) function for handling.
|
||||
template <class EventType, class... Params>
|
||||
void
|
||||
NotifyRouterEvent([[maybe_unused]] Params&&... args) const
|
||||
{
|
||||
// TODO: no-op when appropriate
|
||||
auto event = std::make_unique<EventType>(args...);
|
||||
HandleRouterEvent(std::move(event));
|
||||
}
|
||||
|
||||
virtual int
|
||||
OutboundUDPSocket() const
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
protected:
|
||||
/// Virtual function to handle RouterEvent. HiveRouter overrides this in
|
||||
/// order to inject the event. The default implementation in Router simply
|
||||
/// logs it.
|
||||
virtual void
|
||||
HandleRouterEvent(tooling::RouterEventPtr event) const = 0;
|
||||
};
|
||||
} // namespace llarp
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue