lokinet/llarp/iwp/session.hpp

267 lines
6.1 KiB
C++
Raw Normal View History

2019-08-22 20:53:27 +00:00
#ifndef LLARP_IWP_SESSION_HPP
#define LLARP_IWP_SESSION_HPP
#include <link/session.hpp>
#include <iwp/linklayer.hpp>
#include <iwp/message_buffer.hpp>
#include <unordered_set>
2019-10-02 13:06:14 +00:00
#include <deque>
2019-08-22 20:53:27 +00:00
namespace llarp
{
namespace iwp
{
/// 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
CreatePacket(Command cmd, size_t plainsize, size_t min_pad = 16,
size_t pad_variance = 16);
2019-08-22 20:53:27 +00:00
struct Session : public ILinkSession,
public std::enable_shared_from_this< Session >
{
/// Time how long we try delivery for
2019-12-14 18:50:36 +00:00
static constexpr llarp_time_t DeliveryTimeout = 500;
/// Time how long we wait to recieve a message
2019-12-14 18:50:36 +00:00
static constexpr llarp_time_t ReceivalTimeout = (DeliveryTimeout * 8) / 5;
/// How long to keep a replay window for
2019-12-14 18:50:36 +00:00
static constexpr llarp_time_t ReplayWindow = (ReceivalTimeout * 3) / 2;
/// How often to acks RX messages
2019-12-14 18:50:36 +00:00
static constexpr llarp_time_t ACKResendInterval = DeliveryTimeout / 2;
/// How often to retransmit TX fragments
static constexpr llarp_time_t TXFlushInterval = (DeliveryTimeout / 5) * 4;
/// How often we send a keepalive
static constexpr llarp_time_t PingInterval = 5000;
/// How long we wait for a session to die with no tx from them
static constexpr llarp_time_t SessionAliveTimeout = PingInterval * 5;
/// 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-22 20:53:27 +00:00
/// outbound session
2019-11-20 16:10:52 +00:00
Session(LinkLayer* parent, const RouterContact& rc,
const AddressInfo& ai);
2019-08-22 20:53:27 +00:00
/// inbound session
2019-11-20 16:10:52 +00:00
Session(LinkLayer* parent, const Addr& from);
2019-08-22 20:53:27 +00:00
~Session() = default;
2019-08-22 20:53:27 +00:00
2019-08-29 12:05:29 +00:00
std::shared_ptr< ILinkSession >
2019-08-29 12:04:46 +00:00
BorrowSelf() override
{
return shared_from_this();
}
2019-08-22 20:53:27 +00:00
void
Pump() override;
void
Tick(llarp_time_t now) override;
bool
2019-09-12 14:34:27 +00:00
SendMessageBuffer(ILinkSession::Message_t msg,
2019-08-22 20:53:27 +00:00
CompletionHandler resultHandler) override;
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;
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;
}
Addr
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;
util::StatusObject
ExtractStatus() const override;
2020-01-21 17:31:48 +00:00
bool
IsInbound() const override
{
return m_Inbound;
}
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
};
State m_State;
/// are we inbound session ?
const bool m_Inbound;
/// parent link layer
LinkLayer* const m_Parent;
const llarp_time_t m_CreatedAt;
const Addr m_RemoteAddr;
AddressInfo m_ChosenAI;
/// remote rc
RouterContact m_RemoteRC;
/// session key
SharedSecret m_SessionKey;
/// session token
2019-08-23 11:32:52 +00:00
AlignedBuffer< 24 > token;
2019-08-22 20:53:27 +00:00
PubKey m_ExpectedIdent;
2019-08-22 20:53:27 +00:00
PubKey m_RemoteOnionKey;
llarp_time_t m_LastTX = 0;
llarp_time_t m_LastRX = 0;
2019-12-17 14:36:56 +00:00
uint64_t m_TXRate = 0;
uint64_t m_RXRate = 0;
uint64_t m_CurrentTX = 0;
uint64_t m_CurrentRX = 0;
llarp_time_t m_ResetRatesAt = 0;
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();
2019-08-22 20:53:27 +00:00
std::unordered_map< uint64_t, InboundMessage > m_RXMsgs;
std::unordered_map< uint64_t, OutboundMessage > m_TXMsgs;
/// maps rxid to time recieved
std::unordered_map< uint64_t, llarp_time_t > m_ReplayFilter;
/// set of rx messages to send in next round of multiacks
std::unordered_set< uint64_t > m_SendMACKs;
2019-10-02 13:06:14 +00:00
using CryptoQueue_t = std::vector< Packet_t >;
using CryptoQueue_ptr = std::shared_ptr< CryptoQueue_t >;
CryptoQueue_ptr m_EncryptNext;
CryptoQueue_ptr m_DecryptNext;
2019-09-05 14:57:01 +00:00
void
EncryptWorker(CryptoQueue_ptr msgs);
2019-09-05 14:57:01 +00:00
void
DecryptWorker(CryptoQueue_ptr msgs);
2019-09-05 14:57:01 +00:00
void
2019-10-02 13:06:14 +00:00
HandlePlaintext(CryptoQueue_ptr 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
void
SendMACK();
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);
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
2019-12-14 18:50:36 +00:00
#endif