2021-03-09 22:24:35 +00:00
|
|
|
#pragma once
|
2019-08-22 20:53:27 +00:00
|
|
|
|
2021-03-09 22:24:35 +00:00
|
|
|
#include <llarp/link/session.hpp>
|
|
|
|
#include "linklayer.hpp"
|
|
|
|
#include "message_buffer.hpp"
|
|
|
|
#include <llarp/net/ip_address.hpp>
|
2020-05-06 20:38:44 +00:00
|
|
|
|
2021-02-14 12:57:47 +00:00
|
|
|
#include <map>
|
2019-09-16 16:12:05 +00:00
|
|
|
#include <unordered_set>
|
2019-10-02 13:06:14 +00:00
|
|
|
#include <deque>
|
2020-06-11 11:44:02 +00:00
|
|
|
#include <queue>
|
2019-08-22 20:53:27 +00:00
|
|
|
|
2021-03-09 22:24:35 +00:00
|
|
|
#include <llarp/util/thread/queue.hpp>
|
2021-02-23 10:53:48 +00:00
|
|
|
|
2019-08-22 20:53:27 +00:00
|
|
|
namespace llarp
|
|
|
|
{
|
|
|
|
namespace iwp
|
|
|
|
{
|
2019-09-16 16:12:05 +00:00
|
|
|
/// packet crypto overhead size
|
2019-09-12 14:34:27 +00:00
|
|
|
static constexpr size_t PacketOverhead = HMACSIZE + TUNNONCESIZE;
|
|
|
|
/// creates a packet with plaintext size + wire overhead + random pad
|
|
|
|
ILinkSession::Packet_t
|
2020-04-07 18:38:56 +00:00
|
|
|
CreatePacket(Command cmd, size_t plainsize, size_t min_pad = 16, size_t pad_variance = 16);
|
2020-02-24 19:40:45 +00:00
|
|
|
/// Time how long we try delivery for
|
2020-02-25 17:05:13 +00:00
|
|
|
static constexpr std::chrono::milliseconds DeliveryTimeout = 500ms;
|
2020-02-24 19:40:45 +00:00
|
|
|
/// Time how long we wait to recieve a message
|
2020-02-25 16:05:54 +00:00
|
|
|
static constexpr auto ReceivalTimeout = (DeliveryTimeout * 8) / 5;
|
2020-02-24 19:40:45 +00:00
|
|
|
/// How long to keep a replay window for
|
2020-02-25 16:05:54 +00:00
|
|
|
static constexpr auto ReplayWindow = (ReceivalTimeout * 3) / 2;
|
2020-02-24 19:40:45 +00:00
|
|
|
/// How often to acks RX messages
|
2020-07-01 14:14:45 +00:00
|
|
|
static constexpr auto ACKResendInterval = DeliveryTimeout / 2;
|
2020-02-24 19:40:45 +00:00
|
|
|
/// How often to retransmit TX fragments
|
2020-02-25 16:05:54 +00:00
|
|
|
static constexpr auto TXFlushInterval = (DeliveryTimeout / 5) * 4;
|
2020-02-24 19:40:45 +00:00
|
|
|
/// How often we send a keepalive
|
2020-02-25 17:05:13 +00:00
|
|
|
static constexpr std::chrono::milliseconds PingInterval = 5s;
|
2020-02-24 19:40:45 +00:00
|
|
|
/// How long we wait for a session to die with no tx from them
|
2020-02-25 16:05:54 +00:00
|
|
|
static constexpr auto SessionAliveTimeout = PingInterval * 5;
|
2019-08-28 11:02:00 +00:00
|
|
|
|
2020-04-07 18:38:56 +00:00
|
|
|
struct Session : public ILinkSession, public std::enable_shared_from_this<Session>
|
2019-08-22 20:53:27 +00:00
|
|
|
{
|
2020-02-25 17:05:13 +00:00
|
|
|
using Time_t = std::chrono::milliseconds;
|
|
|
|
|
2019-09-05 13:21:35 +00:00
|
|
|
/// maximum number of messages we can ack in a multiack
|
2019-09-05 13:34:59 +00:00
|
|
|
static constexpr std::size_t MaxACKSInMACK = 1024 / sizeof(uint64_t);
|
2019-08-28 11:02:00 +00:00
|
|
|
|
2019-08-22 20:53:27 +00:00
|
|
|
/// outbound session
|
2020-04-07 18:38:56 +00:00
|
|
|
Session(LinkLayer* parent, const RouterContact& rc, const AddressInfo& ai);
|
2019-08-22 20:53:27 +00:00
|
|
|
/// inbound session
|
2021-02-22 15:01:05 +00:00
|
|
|
Session(LinkLayer* parent, const SockAddr& from);
|
2019-08-22 20:53:27 +00:00
|
|
|
|
2021-11-11 14:17:48 +00:00
|
|
|
// Signal the event loop that a pump is needed (idempotent)
|
|
|
|
void
|
|
|
|
TriggerPump();
|
2019-08-22 20:53:27 +00:00
|
|
|
|
2021-11-11 14:17:48 +00:00
|
|
|
// Does the actual pump
|
2019-08-22 20:53:27 +00:00
|
|
|
void
|
|
|
|
Pump() override;
|
|
|
|
|
|
|
|
void
|
|
|
|
Tick(llarp_time_t now) override;
|
|
|
|
|
|
|
|
bool
|
2020-04-07 18:38:56 +00:00
|
|
|
SendMessageBuffer(ILinkSession::Message_t msg, CompletionHandler resultHandler) override;
|
2019-08-22 20:53:27 +00:00
|
|
|
|
|
|
|
void
|
2019-11-19 20:30:51 +00:00
|
|
|
Send_LL(const byte_t* buf, size_t sz);
|
2019-08-22 20:53:27 +00:00
|
|
|
|
2019-09-12 14:34:27 +00:00
|
|
|
void EncryptAndSend(ILinkSession::Packet_t);
|
2019-08-22 20:53:27 +00:00
|
|
|
|
|
|
|
void
|
|
|
|
Start() override;
|
|
|
|
|
|
|
|
void
|
|
|
|
Close() override;
|
|
|
|
|
2019-11-19 16:24:29 +00:00
|
|
|
bool Recv_LL(ILinkSession::Packet_t) override;
|
2019-08-22 20:53:27 +00:00
|
|
|
|
|
|
|
bool
|
|
|
|
SendKeepAlive() override;
|
|
|
|
|
|
|
|
bool
|
|
|
|
IsEstablished() const override;
|
|
|
|
|
|
|
|
bool
|
|
|
|
TimedOut(llarp_time_t now) const override;
|
|
|
|
|
|
|
|
PubKey
|
|
|
|
GetPubKey() const override
|
|
|
|
{
|
|
|
|
return m_RemoteRC.pubkey;
|
|
|
|
}
|
|
|
|
|
2021-02-22 15:01:05 +00:00
|
|
|
const SockAddr&
|
2019-08-22 20:53:27 +00:00
|
|
|
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;
|
|
|
|
|
2020-06-04 16:00:30 +00:00
|
|
|
SessionStats
|
|
|
|
GetSessionStats() const override;
|
|
|
|
|
2019-08-22 20:53:27 +00:00
|
|
|
util::StatusObject
|
|
|
|
ExtractStatus() const override;
|
|
|
|
|
2020-01-21 17:31:48 +00:00
|
|
|
bool
|
|
|
|
IsInbound() const override
|
|
|
|
{
|
|
|
|
return m_Inbound;
|
|
|
|
}
|
2021-02-22 13:26:32 +00:00
|
|
|
void
|
2021-11-11 21:46:53 +00:00
|
|
|
HandlePlaintext() override;
|
2020-01-21 17:31:48 +00:00
|
|
|
|
2019-08-22 20:53:27 +00:00
|
|
|
private:
|
|
|
|
enum class State
|
|
|
|
{
|
|
|
|
/// we have no data recv'd
|
|
|
|
Initial,
|
2019-08-23 11:32:52 +00:00
|
|
|
/// we are in introduction phase
|
2019-08-22 20:53:27 +00:00
|
|
|
Introduction,
|
|
|
|
/// we sent our LIM
|
|
|
|
LinkIntro,
|
|
|
|
/// handshake done and LIM has been obtained
|
|
|
|
Ready,
|
|
|
|
/// we are closed now
|
|
|
|
Closed
|
|
|
|
};
|
2020-02-10 19:51:54 +00:00
|
|
|
static std::string
|
|
|
|
StateToString(State state);
|
2019-08-22 20:53:27 +00:00
|
|
|
State m_State;
|
2020-06-04 16:00:30 +00:00
|
|
|
SessionStats m_Stats;
|
2020-02-07 18:43:40 +00:00
|
|
|
|
2019-08-22 20:53:27 +00:00
|
|
|
/// are we inbound session ?
|
|
|
|
const bool m_Inbound;
|
|
|
|
/// parent link layer
|
|
|
|
LinkLayer* const m_Parent;
|
|
|
|
const llarp_time_t m_CreatedAt;
|
2021-02-22 15:01:05 +00:00
|
|
|
const SockAddr m_RemoteAddr;
|
2019-08-22 20:53:27 +00:00
|
|
|
|
|
|
|
AddressInfo m_ChosenAI;
|
|
|
|
/// remote rc
|
|
|
|
RouterContact m_RemoteRC;
|
|
|
|
/// session key
|
|
|
|
SharedSecret m_SessionKey;
|
|
|
|
/// session token
|
2020-04-07 18:38:56 +00:00
|
|
|
AlignedBuffer<24> token;
|
2019-08-22 20:53:27 +00:00
|
|
|
|
2019-09-05 13:21:35 +00:00
|
|
|
PubKey m_ExpectedIdent;
|
2019-08-22 20:53:27 +00:00
|
|
|
PubKey m_RemoteOnionKey;
|
|
|
|
|
2020-02-24 19:40:45 +00:00
|
|
|
llarp_time_t m_LastTX = 0s;
|
|
|
|
llarp_time_t m_LastRX = 0s;
|
2019-08-22 20:53:27 +00:00
|
|
|
|
2020-02-07 18:43:40 +00:00
|
|
|
// accumulate for periodic rate calculation
|
2019-12-17 14:36:56 +00:00
|
|
|
uint64_t m_TXRate = 0;
|
|
|
|
uint64_t m_RXRate = 0;
|
|
|
|
|
2020-02-24 19:40:45 +00:00
|
|
|
llarp_time_t m_ResetRatesAt = 0s;
|
2019-12-17 14:36:56 +00:00
|
|
|
|
2019-08-22 20:53:27 +00:00
|
|
|
uint64_t m_TXID = 0;
|
|
|
|
|
2019-12-17 14:36:56 +00:00
|
|
|
bool
|
|
|
|
ShouldResetRates(llarp_time_t now) const;
|
|
|
|
|
|
|
|
void
|
|
|
|
ResetRates();
|
|
|
|
|
2021-02-14 12:57:47 +00:00
|
|
|
std::map<uint64_t, InboundMessage> m_RXMsgs;
|
|
|
|
std::map<uint64_t, OutboundMessage> m_TXMsgs;
|
2019-08-22 20:53:27 +00:00
|
|
|
|
2019-08-28 11:02:00 +00:00
|
|
|
/// maps rxid to time recieved
|
2020-04-07 18:38:56 +00:00
|
|
|
std::unordered_map<uint64_t, llarp_time_t> m_ReplayFilter;
|
2020-06-11 11:44:02 +00:00
|
|
|
/// rx messages to send in next round of multiacks
|
2021-11-11 14:17:48 +00:00
|
|
|
std::priority_queue<uint64_t, std::vector<uint64_t>, std::greater<>> m_SendMACKs;
|
2019-08-28 11:02:00 +00:00
|
|
|
|
2021-02-22 13:26:32 +00:00
|
|
|
using CryptoQueue_t = std::vector<Packet_t>;
|
2019-09-05 14:57:01 +00:00
|
|
|
|
2021-02-22 13:26:32 +00:00
|
|
|
CryptoQueue_t m_EncryptNext;
|
|
|
|
CryptoQueue_t m_DecryptNext;
|
|
|
|
|
2021-11-11 21:46:53 +00:00
|
|
|
std::atomic_flag m_PlaintextEmpty;
|
2021-02-22 13:26:32 +00:00
|
|
|
llarp::thread::Queue<CryptoQueue_t> m_PlaintextRecv;
|
2019-09-05 14:57:01 +00:00
|
|
|
|
|
|
|
void
|
2021-02-22 13:26:32 +00:00
|
|
|
EncryptWorker(CryptoQueue_t msgs);
|
2019-09-05 14:57:01 +00:00
|
|
|
|
|
|
|
void
|
2021-02-22 13:26:32 +00:00
|
|
|
DecryptWorker(CryptoQueue_t msgs);
|
2019-09-05 14:57:01 +00:00
|
|
|
|
2019-08-22 20:53:27 +00:00
|
|
|
void
|
2019-09-12 14:34:27 +00:00
|
|
|
HandleGotIntro(Packet_t pkt);
|
2019-08-22 20:53:27 +00:00
|
|
|
|
|
|
|
void
|
2019-09-12 14:34:27 +00:00
|
|
|
HandleGotIntroAck(Packet_t pkt);
|
2019-08-22 20:53:27 +00:00
|
|
|
|
|
|
|
void
|
2019-09-12 14:34:27 +00:00
|
|
|
HandleCreateSessionRequest(Packet_t pkt);
|
2019-08-22 20:53:27 +00:00
|
|
|
|
|
|
|
void
|
2019-09-12 14:34:27 +00:00
|
|
|
HandleAckSession(Packet_t pkt);
|
2019-08-22 20:53:27 +00:00
|
|
|
|
|
|
|
void
|
2019-09-12 14:34:27 +00:00
|
|
|
HandleSessionData(Packet_t pkt);
|
2019-08-22 20:53:27 +00:00
|
|
|
|
2019-08-23 11:32:52 +00:00
|
|
|
bool
|
2019-09-12 14:34:27 +00:00
|
|
|
DecryptMessageInPlace(Packet_t& pkt);
|
2019-08-22 20:53:27 +00:00
|
|
|
|
2019-09-05 13:21:35 +00:00
|
|
|
void
|
|
|
|
SendMACK();
|
|
|
|
|
2021-02-14 13:24:13 +00:00
|
|
|
void
|
|
|
|
HandleRecvMsgCompleted(const InboundMessage& msg);
|
|
|
|
|
2019-08-23 11:32:52 +00:00
|
|
|
void
|
2019-08-22 20:53:27 +00:00
|
|
|
GenerateAndSendIntro();
|
|
|
|
|
|
|
|
bool
|
2019-08-23 11:32:52 +00:00
|
|
|
GotInboundLIM(const LinkIntroMessage* msg);
|
|
|
|
|
2019-08-22 20:53:27 +00:00
|
|
|
bool
|
2019-08-23 11:32:52 +00:00
|
|
|
GotOutboundLIM(const LinkIntroMessage* msg);
|
2019-08-22 20:53:27 +00:00
|
|
|
|
|
|
|
bool
|
2019-08-23 11:32:52 +00:00
|
|
|
GotRenegLIM(const LinkIntroMessage* msg);
|
|
|
|
|
|
|
|
void
|
|
|
|
SendOurLIM(ILinkSession::CompletionHandler h = nullptr);
|
|
|
|
|
2019-08-22 20:53:27 +00:00
|
|
|
void
|
2019-10-02 13:06:14 +00:00
|
|
|
HandleXMIT(Packet_t msg);
|
2019-08-22 20:53:27 +00:00
|
|
|
|
2019-08-23 11:32:52 +00:00
|
|
|
void
|
2019-10-02 13:06:14 +00:00
|
|
|
HandleDATA(Packet_t msg);
|
2019-08-22 20:53:27 +00:00
|
|
|
|
2019-08-23 11:32:52 +00:00
|
|
|
void
|
2019-10-02 13:06:14 +00:00
|
|
|
HandleACKS(Packet_t msg);
|
2019-08-22 20:53:27 +00:00
|
|
|
|
2019-08-23 11:32:52 +00:00
|
|
|
void
|
2019-10-02 13:06:14 +00:00
|
|
|
HandleNACK(Packet_t msg);
|
2019-08-22 20:53:27 +00:00
|
|
|
|
2019-08-23 11:32:52 +00:00
|
|
|
void
|
2019-10-02 13:06:14 +00:00
|
|
|
HandlePING(Packet_t msg);
|
2019-08-23 11:32:52 +00:00
|
|
|
|
|
|
|
void
|
2019-10-02 13:06:14 +00:00
|
|
|
HandleCLOS(Packet_t msg);
|
2019-09-05 13:21:35 +00:00
|
|
|
|
|
|
|
void
|
2019-10-02 13:06:14 +00:00
|
|
|
HandleMACK(Packet_t msg);
|
2019-08-22 20:53:27 +00:00
|
|
|
};
|
|
|
|
} // namespace iwp
|
|
|
|
} // namespace llarp
|