llarp/iwp/session.hpp
Namespaces
| Name |
|---|
| llarp [crypto.hpp] |
| llarp::iwp |
Classes
| Name | |
|---|---|
| struct | llarp::iwp::Session |
Source code
#pragma once
#include <cstdint>
#include <llarp/link/session.hpp>
#include "linklayer.hpp"
#include "message_buffer.hpp"
#include <map>
#include <unordered_set>
#include <deque>
#include <llarp/util/priority_queue.hpp>
#include <llarp/util/thread/queue.hpp>
namespace llarp
{
namespace iwp
{
static constexpr size_t PacketOverhead = HMACSIZE + TUNNONCESIZE;
ILinkSession::Packet_t
CreatePacket(Command cmd, size_t plainsize, size_t min_pad = 16, size_t pad_variance = 16);
static constexpr std::chrono::milliseconds DeliveryTimeout = 500ms;
static constexpr auto ReceivalTimeout = (DeliveryTimeout * 8) / 5;
static constexpr auto ReplayWindow = (ReceivalTimeout * 3) / 2;
static constexpr auto ACKResendInterval = DeliveryTimeout / 2;
static constexpr auto TXFlushInterval = (DeliveryTimeout / 5) * 4;
static constexpr std::chrono::milliseconds PingInterval = 5s;
static constexpr auto SessionAliveTimeout = PingInterval * 5;
struct Session : public ILinkSession, public std::enable_shared_from_this<Session>
{
using Time_t = std::chrono::milliseconds;
static constexpr std::size_t MaxACKSInMACK = 1024 / sizeof(uint64_t);
Session(LinkLayer* parent, const RouterContact& rc, const AddressInfo& ai);
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(
ILinkSession::Message_t msg,
CompletionHandler resultHandler,
uint16_t priority = 0) override;
void
Send_LL(const byte_t* buf, size_t sz);
void EncryptAndSend(ILinkSession::Packet_t);
void
Start() override;
void
Close() override;
bool Recv_LL(ILinkSession::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;
bool
IsInbound() const override
{
return m_Inbound;
}
void
HandlePlaintext() override;
void
VerifiedMessage(uint64_t msgid);
void
DropMessage(uint64_t msgid);
void
TriggerHashGen();
void
SendMACK();
void
RecvHashed(std::vector<OutboundMessage> msgs);
private:
enum class State
{
Initial,
Introduction,
LinkIntro,
Ready,
Closed
};
static std::string
StateToString(State state);
State m_State;
SessionStats m_Stats;
const bool m_Inbound;
LinkLayer* const m_Parent;
const llarp_time_t m_CreatedAt;
const SockAddr m_RemoteAddr;
AddressInfo m_ChosenAI;
RouterContact m_RemoteRC;
SharedSecret m_SessionKey;
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;
std::unordered_map<uint64_t, llarp_time_t> m_ReplayFilter;
std::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::unordered_set<uint64_t> m_ToHash;
std::unordered_set<uint64_t> m_PendingHash;
std::atomic_flag m_SentClosed;
template <typename Iter_t>
void
maybe_queue_verify(Iter_t itr);
void
HandleGeneratedHash(const OutboundMessage&);
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
HandleRecvMsgCompleted(const InboundMessage& msg);
void
GenerateAndSendIntro();
bool
GotInboundLIM(const LinkIntroMessage* msg);
bool
GotOutboundLIM(const LinkIntroMessage* msg);
bool
GotRenegLIM(const LinkIntroMessage* msg);
void
SendOurLIM(ILinkSession::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 iwp
} // namespace llarp
Updated on 2026-01-10 at 22:49:45 +0000