lokinet/llarp/utp/session.hpp

238 lines
5.4 KiB
C++
Raw Normal View History

2019-03-29 14:23:19 +00:00
#ifndef LLARP_UTP_SESSION_HPP
#define LLARP_UTP_SESSION_HPP
2019-03-29 14:03:07 +00:00
#include <crypto/crypto.hpp>
#include <link/session.hpp>
2019-03-29 14:23:19 +00:00
#include <utp/inbound_message.hpp>
2019-04-01 21:26:31 +00:00
#include <deque>
2019-03-29 14:03:07 +00:00
#include <utp.h>
namespace llarp
{
namespace utp
{
struct LinkLayer;
2019-04-02 09:03:53 +00:00
struct Session : public ILinkSession
{
/// remote router's rc
RouterContact remoteRC;
/// underlying socket
utp_socket* sock;
/// link layer parent
2019-04-02 09:03:53 +00:00
ILinkLayer* parent;
/// did we get a LIM from the remote yet?
bool gotLIM;
/// remote router's transport pubkey
PubKey remoteTransportPubKey;
/// remote router's transport ip
Addr remoteAddr;
/// rx session key
SharedSecret rxKey;
/// tx session key
SharedSecret txKey;
/// timestamp last active
llarp_time_t lastActive;
2019-03-29 15:26:44 +00:00
/// timestamp last send success
llarp_time_t lastSend;
2019-03-07 22:53:36 +00:00
/// session timeout (60s)
const static llarp_time_t sessionTimeout = DefaultLinkSessionLifetime;
/// send queue for utp
std::deque< utp_iovec > vecq;
/// tx fragment queue
std::deque< FragmentBuffer > sendq;
/// current rx fragment buffer
FragmentBuffer recvBuf;
/// current offset in current rx fragment buffer
size_t recvBufOffset;
/// rx fragment message body
AlignedBuffer< FragmentBodySize > rxFragBody;
/// the next message id for tx
uint32_t m_NextTXMsgID;
/// the next message id for rx
uint32_t m_NextRXMsgID;
/// messages we are recving right now
std::unordered_map< uint32_t, InboundMessage > m_RecvMsgs;
/// are we stalled or nah?
bool stalled = false;
uint64_t m_RXRate = 0;
uint64_t m_TXRate = 0;
/// mark session as alive
void
Alive();
2019-02-18 23:58:12 +00:00
util::StatusObject
ExtractStatus() const override;
2019-04-02 09:03:53 +00:00
virtual ~Session() = 0;
2019-04-02 09:03:53 +00:00
/// base
explicit Session(LinkLayer* p);
enum State
{
eInitial, // initial state
eConnecting, // we are connecting
eLinkEstablished, // when utp connection is established
eCryptoHandshake, // crypto handshake initiated
eSessionReady, // session is ready
eClose // utp connection is closed
};
/// session state, call EnterState(State) to set
State state;
/// hook for utp for when we have established a connection
void
2019-04-02 09:03:53 +00:00
OnLinkEstablished(ILinkLayer* p) override;
Crypto*
OurCrypto();
/// switch states
void
EnterState(State st);
/// handle LIM after handshake
bool
GotSessionRenegotiate(const LinkIntroMessage* msg);
/// re negotiate session with our new local RC
bool
2019-04-02 09:03:53 +00:00
RenegotiateSession() override;
bool
ShouldPing() const override;
/// pump tx queue
void
PumpWrite();
2019-01-04 12:43:41 +00:00
void
2019-04-02 09:03:53 +00:00
Pump() override;
bool
SendKeepAlive() override;
bool
IsEstablished() override
{
return state == eSessionReady || state == eLinkEstablished;
}
bool
TimedOut(llarp_time_t now) const override;
2019-01-04 12:43:41 +00:00
/// verify a fragment buffer and the decrypt it
/// buf is assumed to be FragmentBufferSize bytes long
bool
VerifyThenDecrypt(const byte_t* buf);
/// encrypt a fragment then hash the ciphertext
bool
EncryptThenHash(const byte_t* ptr, uint32_t msgid, uint16_t sz,
uint16_t remain);
/// queue a fully formed message
bool
2019-04-02 09:03:53 +00:00
SendMessageBuffer(const llarp_buffer_t& buf) override;
/// prune expired inbound messages
void
PruneInboundMessages(llarp_time_t now);
/// do low level connect
void
Connect();
/// handle outbound connection made
void
OutboundLinkEstablished(LinkLayer* p);
// send first message
void
OutboundHandshake();
// do key exchange for handshake
bool
DoKeyExchange(transport_dh_func dh, SharedSecret& K,
const KeyExchangeNonce& n, const PubKey& other,
const SecretKey& secret);
/// does K = HS(K + A)
bool
MutateKey(SharedSecret& K, const AlignedBuffer< 24 >& A);
void
2019-04-02 09:03:53 +00:00
Tick(llarp_time_t now) override;
/// close session
void
2019-04-02 09:03:53 +00:00
Close() override;
/// low level read
bool
Recv(const byte_t* buf, size_t sz);
/// get remote identity pubkey
2019-04-02 09:03:53 +00:00
PubKey
GetPubKey() const override;
/// get remote address
Addr
2019-04-02 09:03:53 +00:00
GetRemoteEndpoint() const override;
RouterContact
GetRemoteRC() const override
{
return remoteRC;
}
/// get parent link
ILinkLayer*
2019-04-02 09:03:53 +00:00
GetLinkLayer() const override;
void
MarkEstablished();
2019-04-02 09:03:53 +00:00
size_t
SendQueueBacklog() const override
{
return sendq.size();
}
};
struct InboundSession final : public Session
{
InboundSession(LinkLayer* p, utp_socket* s, const Addr& addr);
bool
InboundLIM(const LinkIntroMessage* msg);
void
Start() override
{
}
};
struct OutboundSession final : public Session
{
OutboundSession(LinkLayer* p, utp_socket* s, const RouterContact& rc,
const AddressInfo& addr);
bool
OutboundLIM(const LinkIntroMessage* msg);
void
Start() override;
};
} // namespace utp
} // namespace llarp
#endif