2022-02-04 23:01:18 +03:00
/*
2022-02-18 09:20:06 +03:00
* Copyright ( c ) 2022 , The PurpleI2P Project
2022-02-04 23:01:18 +03:00
*
* This file is part of Purple i2pd project and licensed under BSD3
*
* See full license text in LICENSE file at top of project tree
*/
# ifndef SSU2_H__
# define SSU2_H__
# include <memory>
2022-05-01 17:33:25 +03:00
# include <functional>
2022-03-01 05:46:00 +03:00
# include <map>
2022-03-30 19:31:24 +03:00
# include <set>
2022-02-28 04:15:14 +03:00
# include <unordered_map>
2022-03-01 05:46:00 +03:00
# include <boost/asio.hpp>
2022-02-04 23:01:18 +03:00
# include "Crypto.h"
# include "RouterInfo.h"
# include "TransportSession.h"
namespace i2p
{
namespace transport
{
2022-03-19 03:21:31 +03:00
const int SSU2_CONNECT_TIMEOUT = 5 ; // 5 seconds
2022-02-04 23:01:18 +03:00
const int SSU2_TERMINATION_TIMEOUT = 330 ; // 5.5 minutes
2022-03-19 03:21:31 +03:00
const int SSU2_TERMINATION_CHECK_TIMEOUT = 30 ; // 30 seconds
2022-04-26 20:59:59 +03:00
const int SSU2_TOKEN_EXPIRATION_TIMEOUT = 9 ; // in seconds
const int SSU2_RELAY_NONCE_EXPIRATION_TIMEOUT = 10 ; // in seconds
2022-05-14 03:38:18 +03:00
const int SSU2_PEER_TEST_EXPIRATION_TIMEOUT = 60 ; // 60 seconds
2022-03-01 05:46:00 +03:00
const size_t SSU2_SOCKET_RECEIVE_BUFFER_SIZE = 0x1FFFF ; // 128K
const size_t SSU2_SOCKET_SEND_BUFFER_SIZE = 0x1FFFF ; // 128K
2022-03-15 02:25:59 +03:00
const size_t SSU2_MTU = 1488 ;
2022-03-31 01:04:12 +03:00
const size_t SSU2_MAX_PAYLOAD_SIZE = SSU2_MTU - 32 ;
const int SSU2_RESEND_INTERVAL = 3 ; // in seconds
const int SSU2_MAX_NUM_RESENDS = 5 ;
2022-04-02 20:05:11 +03:00
const int SSU2_INCOMPLETE_MESSAGES_CLEANUP_TIMEOUT = 30 ; // in seconds
2022-04-18 20:14:09 +03:00
const size_t SSU2_MAX_WINDOW_SIZE = 128 ; // in packets
2022-03-01 05:46:00 +03:00
2022-02-12 03:21:04 +03:00
enum SSU2MessageType
{
2022-03-05 05:51:40 +03:00
eSSU2SessionRequest = 0 ,
2022-03-20 22:10:18 +03:00
eSSU2SessionCreated = 1 ,
2022-03-22 04:06:14 +03:00
eSSU2SessionConfirmed = 2 ,
2022-03-25 22:34:43 +03:00
eSSU2Data = 6 ,
2022-05-12 00:48:25 +03:00
eSSU2PeerTest = 7 ,
2022-03-24 02:13:44 +03:00
eSSU2Retry = 9 ,
2022-05-04 20:58:06 +03:00
eSSU2TokenRequest = 10 ,
eSSU2HolePunch = 11
2022-02-12 03:21:04 +03:00
} ;
2022-02-28 04:15:14 +03:00
2022-03-16 03:49:41 +03:00
enum SSU2BlockType
{
eSSU2BlkDateTime = 0 ,
eSSU2BlkOptions , // 1
eSSU2BlkRouterInfo , // 2
eSSU2BlkI2NPMessage , // 3
eSSU2BlkFirstFragment , // 4
eSSU2BlkFollowOnFragment , // 5
eSSU2BlkTermination , // 6
eSSU2BlkRelayRequest , // 7
eSSU2BlkRelayResponse , // 8
eSSU2BlkRelayIntro , // 9
eSSU2BlkPeerTest , // 10
eSSU2BlkNextNonce , // 11
eSSU2BlkAck , // 12
eSSU2BlkAddress , // 13
eSSU2BlkIntroKey , // 14
eSSU2BlkRelayTagRequest , // 15
eSSU2BlkRelayTag , // 16
eSSU2BlkNewToken , // 17
eSSU2BlkPathChallenge , // 18
eSSU2BlkPathResponse , // 19
eSSU2BlkFirstPacketNumber , // 20
eSSU2BlkPadding = 254
} ;
2022-03-22 04:06:14 +03:00
2022-03-25 22:34:43 +03:00
enum SSU2SessionState
{
eSSU2SessionStateUnknown ,
2022-04-26 20:59:59 +03:00
eSSU2SessionStateIntroduced ,
2022-05-12 00:48:25 +03:00
eSSU2SessionStatePeerTest ,
2022-03-25 22:34:43 +03:00
eSSU2SessionStateEstablished ,
2022-03-27 23:39:58 +03:00
eSSU2SessionStateTerminated ,
2022-03-25 22:34:43 +03:00
eSSU2SessionStateFailed
} ;
2022-04-02 20:05:11 +03:00
struct SSU2IncompleteMessage
{
struct Fragment
{
uint8_t buf [ SSU2_MTU ] ;
size_t len ;
bool isLast ;
} ;
std : : shared_ptr < I2NPMessage > msg ;
int nextFragmentNum ;
uint32_t lastFragmentInsertTime ; // in seconds
std : : map < int , std : : shared_ptr < Fragment > > outOfSequenceFragments ;
} ;
2022-03-25 22:34:43 +03:00
2022-03-22 04:06:14 +03:00
// RouterInfo flags
const uint8_t SSU2_ROUTER_INFO_FLAG_REQUEST_FLOOD = 0x01 ;
const uint8_t SSU2_ROUTER_INFO_FLAG_GZIP = 0x02 ;
2022-03-16 03:49:41 +03:00
2022-02-28 04:15:14 +03:00
class SSU2Server ;
2022-02-04 23:01:18 +03:00
class SSU2Session : public TransportSession , public std : : enable_shared_from_this < SSU2Session >
{
2022-02-12 03:21:04 +03:00
union Header
{
uint64_t ll [ 2 ] ;
uint8_t buf [ 16 ] ;
struct
{
2022-03-01 05:46:00 +03:00
uint64_t connID ;
2022-03-22 04:06:14 +03:00
uint32_t packetNum ;
2022-03-09 05:33:21 +03:00
uint8_t type ;
uint8_t flags [ 3 ] ;
2022-02-12 03:21:04 +03:00
} h ;
} ;
2022-03-30 22:03:45 +03:00
struct SentPacket
{
2022-04-16 22:42:11 +03:00
uint8_t payload [ SSU2_MAX_PAYLOAD_SIZE ] ;
size_t payloadSize = 0 ;
2022-03-30 22:03:45 +03:00
uint32_t nextResendTime ; // in seconds
2022-04-16 22:42:11 +03:00
int numResends = 0 ;
} ;
struct SessionConfirmedFragment
{
Header header ;
uint8_t payload [ SSU2_MAX_PAYLOAD_SIZE ] ;
size_t payloadSize ;
2022-03-30 22:03:45 +03:00
} ;
2022-05-14 03:38:18 +03:00
2022-05-01 17:33:25 +03:00
typedef std : : function < void ( ) > OnEstablished ;
2022-03-30 22:03:45 +03:00
2022-02-04 23:01:18 +03:00
public :
2022-02-28 04:15:14 +03:00
SSU2Session ( SSU2Server & server , std : : shared_ptr < const i2p : : data : : RouterInfo > in_RemoteRouter = nullptr ,
2022-05-01 17:33:25 +03:00
std : : shared_ptr < const i2p : : data : : RouterInfo : : Address > addr = nullptr ) ;
2022-02-04 23:01:18 +03:00
~ SSU2Session ( ) ;
2022-02-05 23:58:39 +03:00
2022-03-09 05:33:21 +03:00
void SetRemoteEndpoint ( const boost : : asio : : ip : : udp : : endpoint & ep ) { m_RemoteEndpoint = ep ; } ;
2022-03-27 23:39:58 +03:00
const boost : : asio : : ip : : udp : : endpoint & GetRemoteEndpoint ( ) const { return m_RemoteEndpoint ; } ;
2022-05-01 17:33:25 +03:00
void SetOnEstablished ( OnEstablished e ) { m_OnEstablished = e ; } ;
2022-03-27 23:39:58 +03:00
2022-03-17 04:11:48 +03:00
void Connect ( ) ;
2022-04-28 01:52:44 +03:00
bool Introduce ( std : : shared_ptr < SSU2Session > session , uint32_t relayTag ) ;
2022-03-27 23:39:58 +03:00
void Terminate ( ) ;
void TerminateByTimeout ( ) ;
2022-04-02 20:05:11 +03:00
void CleanUp ( uint64_t ts ) ;
2022-04-12 18:42:51 +03:00
void FlushData ( ) ;
2022-03-31 01:04:12 +03:00
void Done ( ) override ;
void SendI2NPMessages ( const std : : vector < std : : shared_ptr < I2NPMessage > > & msgs ) override ;
2022-03-31 22:35:55 +03:00
void Resend ( uint64_t ts ) ;
2022-03-25 22:34:43 +03:00
bool IsEstablished ( ) const { return m_State = = eSSU2SessionStateEstablished ; } ;
2022-03-27 23:39:58 +03:00
uint64_t GetConnID ( ) const { return m_SourceConnID ; } ;
2022-05-01 17:33:25 +03:00
SSU2SessionState GetState ( ) const { return m_State ; } ;
void SetState ( SSU2SessionState state ) { m_State = state ; } ;
2022-03-25 22:34:43 +03:00
2022-05-02 22:05:44 +03:00
bool ProcessFirstIncomingMessage ( uint64_t connID , uint8_t * buf , size_t len ) ;
2022-03-05 05:51:40 +03:00
bool ProcessSessionCreated ( uint8_t * buf , size_t len ) ;
2022-03-23 21:06:55 +03:00
bool ProcessSessionConfirmed ( uint8_t * buf , size_t len ) ;
2022-03-20 22:10:18 +03:00
bool ProcessRetry ( uint8_t * buf , size_t len ) ;
2022-05-04 20:58:06 +03:00
bool ProcessHolePunch ( uint8_t * buf , size_t len ) ;
2022-05-12 00:48:25 +03:00
bool ProcessPeerTest ( uint8_t * buf , size_t len ) ;
2022-03-25 22:34:43 +03:00
void ProcessData ( uint8_t * buf , size_t len ) ;
2022-03-05 05:51:40 +03:00
2022-02-10 22:03:09 +03:00
private :
2022-03-27 23:39:58 +03:00
void Established ( ) ;
2022-03-31 01:04:12 +03:00
void PostI2NPMessages ( std : : vector < std : : shared_ptr < I2NPMessage > > msgs ) ;
2022-04-18 22:47:35 +03:00
bool SendQueue ( ) ;
2022-04-09 18:42:34 +03:00
void SendFragmentedMessage ( std : : shared_ptr < I2NPMessage > msg ) ;
2022-03-27 23:39:58 +03:00
2022-03-24 04:48:41 +03:00
void ProcessSessionRequest ( Header & header , uint8_t * buf , size_t len ) ;
void ProcessTokenRequest ( Header & header , uint8_t * buf , size_t len ) ;
2022-03-20 22:10:18 +03:00
void SendSessionRequest ( uint64_t token = 0 ) ;
2022-03-09 05:33:21 +03:00
void SendSessionCreated ( const uint8_t * X ) ;
2022-03-22 04:06:14 +03:00
void SendSessionConfirmed ( const uint8_t * Y ) ;
2022-03-25 22:34:43 +03:00
void KDFDataPhase ( uint8_t * keydata_ab , uint8_t * keydata_ba ) ;
2022-03-24 02:13:44 +03:00
void SendTokenRequest ( ) ;
2022-03-24 04:48:41 +03:00
void SendRetry ( ) ;
2022-04-16 22:42:11 +03:00
uint32_t SendData ( const uint8_t * buf , size_t len ) ; // returns packet num
2022-03-26 23:35:07 +03:00
void SendQuickAck ( ) ;
2022-03-27 23:39:58 +03:00
void SendTermination ( ) ;
2022-05-04 20:58:06 +03:00
void SendHolePunch ( uint32_t nonce , const boost : : asio : : ip : : udp : : endpoint & ep , const uint8_t * introKey ) ;
2022-03-25 22:34:43 +03:00
2022-04-12 18:42:51 +03:00
void HandlePayload ( const uint8_t * buf , size_t len ) ;
2022-03-30 22:03:45 +03:00
void HandleAck ( const uint8_t * buf , size_t len ) ;
2022-04-01 22:09:35 +03:00
void HandleAckRange ( uint32_t firstPacketNum , uint32_t lastPacketNum ) ;
2022-03-16 20:13:31 +03:00
bool ExtractEndpoint ( const uint8_t * buf , size_t size , boost : : asio : : ip : : udp : : endpoint & ep ) ;
2022-04-23 03:34:19 +03:00
size_t CreateEndpoint ( uint8_t * buf , size_t len , const boost : : asio : : ip : : udp : : endpoint & ep ) ;
2022-03-23 21:06:55 +03:00
std : : shared_ptr < const i2p : : data : : RouterInfo > ExtractRouterInfo ( const uint8_t * buf , size_t size ) ;
2022-03-22 04:06:14 +03:00
void CreateNonce ( uint64_t seqn , uint8_t * nonce ) ;
2022-03-30 22:03:45 +03:00
bool UpdateReceivePacketNum ( uint32_t packetNum ) ; // for Ack, returns false if duplicate
2022-04-02 20:05:11 +03:00
void HandleFirstFragment ( const uint8_t * buf , size_t len ) ;
void HandleFollowOnFragment ( const uint8_t * buf , size_t len ) ;
bool ConcatOutOfSequenceFragments ( std : : shared_ptr < SSU2IncompleteMessage > m ) ; // true if message complete
2022-04-21 22:47:36 +03:00
void HandleRelayRequest ( const uint8_t * buf , size_t len ) ;
2022-04-22 22:03:49 +03:00
void HandleRelayIntro ( const uint8_t * buf , size_t len ) ;
2022-04-26 20:59:59 +03:00
void HandleRelayResponse ( const uint8_t * buf , size_t len ) ;
2022-05-14 03:38:18 +03:00
void HandlePeerTest ( const uint8_t * buf , size_t len ) ;
2022-04-02 20:05:11 +03:00
2022-05-04 20:58:06 +03:00
size_t CreateAddressBlock ( uint8_t * buf , size_t len , const boost : : asio : : ip : : udp : : endpoint & ep ) ;
2022-05-06 22:02:09 +03:00
size_t CreateRouterInfoBlock ( uint8_t * buf , size_t len , std : : shared_ptr < const i2p : : data : : RouterInfo > r ) ;
2022-03-26 23:35:07 +03:00
size_t CreateAckBlock ( uint8_t * buf , size_t len ) ;
2022-03-27 16:26:45 +03:00
size_t CreatePaddingBlock ( uint8_t * buf , size_t len , size_t minSize = 0 ) ;
2022-03-31 01:04:12 +03:00
size_t CreateI2NPBlock ( uint8_t * buf , size_t len , std : : shared_ptr < I2NPMessage > & & msg ) ;
2022-04-09 18:42:34 +03:00
size_t CreateFirstFragmentBlock ( uint8_t * buf , size_t len , std : : shared_ptr < I2NPMessage > msg ) ;
size_t CreateFollowOnFragmentBlock ( uint8_t * buf , size_t len , std : : shared_ptr < I2NPMessage > msg , uint8_t & fragmentNum , uint32_t msgID ) ;
2022-04-21 22:47:36 +03:00
size_t CreateRelayIntroBlock ( uint8_t * buf , size_t len , const uint8_t * introData , size_t introDataLen ) ;
2022-04-26 20:59:59 +03:00
size_t CreateRelayResponseBlock ( uint8_t * buf , size_t len , uint32_t nonce ) ; // Charlie
2022-05-15 02:18:58 +03:00
size_t CreatePeerTestBlock ( uint8_t * buf , size_t len , uint8_t msg , const uint8_t * routerHash , const uint8_t * signedData , size_t signedDataLen ) ;
2022-04-28 01:52:44 +03:00
2022-02-05 23:58:39 +03:00
private :
2022-02-28 04:15:14 +03:00
SSU2Server & m_Server ;
2022-02-05 23:58:39 +03:00
std : : shared_ptr < i2p : : crypto : : X25519Keys > m_EphemeralKeys ;
std : : unique_ptr < i2p : : crypto : : NoiseSymmetricState > m_NoiseState ;
2022-04-16 22:42:11 +03:00
std : : unique_ptr < SessionConfirmedFragment > m_SessionConfirmedFragment1 ; // for Bob if applicable
2022-02-10 22:03:09 +03:00
std : : shared_ptr < const i2p : : data : : RouterInfo : : Address > m_Address ;
2022-03-09 05:33:21 +03:00
boost : : asio : : ip : : udp : : endpoint m_RemoteEndpoint ;
2022-03-01 05:46:00 +03:00
uint64_t m_DestConnID , m_SourceConnID ;
2022-03-25 22:34:43 +03:00
SSU2SessionState m_State ;
uint8_t m_KeyDataSend [ 64 ] , m_KeyDataReceive [ 64 ] ;
2022-03-26 23:35:07 +03:00
uint32_t m_SendPacketNum , m_ReceivePacketNum ;
2022-03-30 19:31:24 +03:00
std : : set < uint32_t > m_OutOfSequencePackets ; // packet nums > receive packet num
2022-03-30 22:03:45 +03:00
std : : map < uint32_t , std : : shared_ptr < SentPacket > > m_SentPackets ; // packetNum -> packet
2022-04-02 20:05:11 +03:00
std : : map < uint32_t , std : : shared_ptr < SSU2IncompleteMessage > > m_IncompleteMessages ; // I2NP
2022-04-26 20:59:59 +03:00
std : : map < uint32_t , std : : pair < std : : shared_ptr < SSU2Session > , uint64_t > > m_RelaySessions ; // nonce->(Alice, timestamp) for Bob or nonce->(Charlie, timestamp) for Alice
2022-05-14 03:38:18 +03:00
std : : map < uint32_t , std : : pair < std : : shared_ptr < SSU2Session > , uint64_t > > m_PeerTests ; // same as for relay sessions
2022-03-31 01:04:12 +03:00
std : : list < std : : shared_ptr < I2NPMessage > > m_SendQueue ;
2022-03-27 04:59:21 +03:00
i2p : : I2NPMessagesHandler m_Handler ;
2022-04-12 18:42:51 +03:00
bool m_IsDataReceived ;
2022-04-18 20:14:09 +03:00
size_t m_WindowSize ;
2022-05-01 17:33:25 +03:00
uint32_t m_RelayTag ; // between Bob and Charlie
OnEstablished m_OnEstablished ; // callback from Established
2022-02-04 23:01:18 +03:00
} ;
2022-02-28 04:15:14 +03:00
2022-03-12 00:17:44 +03:00
class SSU2Server : private i2p : : util : : RunnableServiceWithWork
2022-02-28 04:15:14 +03:00
{
2022-03-15 02:25:59 +03:00
struct Packet
{
uint8_t buf [ SSU2_MTU ] ;
size_t len ;
boost : : asio : : ip : : udp : : endpoint from ;
} ;
2022-04-05 23:14:13 +03:00
class ReceiveService : public i2p : : util : : RunnableService
{
public :
ReceiveService ( const std : : string & name ) : RunnableService ( name ) { } ;
boost : : asio : : io_service & GetService ( ) { return GetIOService ( ) ; } ;
void Start ( ) { StartIOService ( ) ; } ;
void Stop ( ) { StopIOService ( ) ; } ;
} ;
2022-03-15 02:25:59 +03:00
2022-02-28 04:15:14 +03:00
public :
2022-03-12 00:17:44 +03:00
SSU2Server ( ) ;
2022-02-28 04:15:14 +03:00
~ SSU2Server ( ) { } ;
2022-03-12 00:17:44 +03:00
void Start ( ) ;
void Stop ( ) ;
boost : : asio : : io_service & GetService ( ) { return GetIOService ( ) ; } ;
2022-03-27 23:39:58 +03:00
void AddSession ( std : : shared_ptr < SSU2Session > session ) ;
void RemoveSession ( uint64_t connID ) ;
2022-04-28 20:11:51 +03:00
void AddSessionByRouterHash ( std : : shared_ptr < SSU2Session > session ) ;
2022-03-27 23:39:58 +03:00
void AddPendingOutgoingSession ( std : : shared_ptr < SSU2Session > session ) ;
2022-02-28 04:15:14 +03:00
2022-04-21 22:47:36 +03:00
void AddRelay ( uint32_t tag , std : : shared_ptr < SSU2Session > relay ) ;
void RemoveRelay ( uint32_t tag ) ;
std : : shared_ptr < SSU2Session > FindRelaySession ( uint32_t tag ) ;
2022-03-26 23:35:07 +03:00
void Send ( const uint8_t * header , size_t headerLen , const uint8_t * payload , size_t payloadLen ,
const boost : : asio : : ip : : udp : : endpoint & to ) ;
2022-03-01 05:46:00 +03:00
void Send ( const uint8_t * header , size_t headerLen , const uint8_t * headerX , size_t headerXLen ,
const uint8_t * payload , size_t payloadLen , const boost : : asio : : ip : : udp : : endpoint & to ) ;
2022-04-22 22:03:49 +03:00
2022-03-17 04:11:48 +03:00
bool CreateSession ( std : : shared_ptr < const i2p : : data : : RouterInfo > router ,
std : : shared_ptr < const i2p : : data : : RouterInfo : : Address > address ) ;
2022-03-24 02:13:44 +03:00
void UpdateOutgoingToken ( const boost : : asio : : ip : : udp : : endpoint & ep , uint64_t token , uint32_t exp ) ;
2022-03-24 04:48:41 +03:00
uint64_t FindOutgoingToken ( const boost : : asio : : ip : : udp : : endpoint & ep ) const ;
uint64_t GetIncomingToken ( const boost : : asio : : ip : : udp : : endpoint & ep ) ;
2022-03-01 05:46:00 +03:00
2022-02-28 04:15:14 +03:00
private :
2022-03-18 01:45:14 +03:00
boost : : asio : : ip : : udp : : socket & OpenSocket ( const boost : : asio : : ip : : udp : : endpoint & localEndpoint ) ;
void Receive ( boost : : asio : : ip : : udp : : socket & socket ) ;
void HandleReceivedFrom ( const boost : : system : : error_code & ecode , size_t bytes_transferred ,
Packet * packet , boost : : asio : : ip : : udp : : socket & socket ) ;
2022-04-13 19:33:59 +03:00
void HandleReceivedPacket ( Packet * packet ) ;
void HandleReceivedPackets ( std : : vector < Packet * > packets ) ;
2022-03-01 05:46:00 +03:00
void ProcessNextPacket ( uint8_t * buf , size_t len , const boost : : asio : : ip : : udp : : endpoint & senderEndpoint ) ;
2022-03-19 03:21:31 +03:00
void ScheduleTermination ( ) ;
void HandleTerminationTimer ( const boost : : system : : error_code & ecode ) ;
2022-03-31 22:35:55 +03:00
void ScheduleResend ( ) ;
void HandleResendTimer ( const boost : : system : : error_code & ecode ) ;
2022-05-01 17:33:25 +03:00
void ConnectThroughIntroducer ( std : : shared_ptr < const i2p : : data : : RouterInfo > router ,
std : : shared_ptr < const i2p : : data : : RouterInfo : : Address > address ) ;
2022-02-28 04:15:14 +03:00
private :
2022-04-05 23:27:52 +03:00
ReceiveService m_ReceiveService ;
2022-04-05 23:14:13 +03:00
boost : : asio : : ip : : udp : : socket m_SocketV4 , m_SocketV6 ;
2022-02-28 04:15:14 +03:00
std : : unordered_map < uint64_t , std : : shared_ptr < SSU2Session > > m_Sessions ;
2022-04-28 20:11:51 +03:00
std : : map < i2p : : data : : IdentHash , std : : shared_ptr < SSU2Session > > m_SessionsByRouterHash ;
2022-03-01 05:46:00 +03:00
std : : map < boost : : asio : : ip : : udp : : endpoint , std : : shared_ptr < SSU2Session > > m_PendingOutgoingSessions ;
2022-03-24 02:13:44 +03:00
std : : map < boost : : asio : : ip : : udp : : endpoint , std : : pair < uint64_t , uint32_t > > m_IncomingTokens , m_OutgoingTokens ; // remote endpoint -> (token, expires in seconds)
2022-04-21 22:47:36 +03:00
std : : map < uint32_t , std : : shared_ptr < SSU2Session > > m_Relays ; // we are introducer, relay tag -> session
2022-03-15 02:25:59 +03:00
i2p : : util : : MemoryPoolMt < Packet > m_PacketsPool ;
2022-03-31 22:35:55 +03:00
boost : : asio : : deadline_timer m_TerminationTimer , m_ResendTimer ;
2022-04-07 17:57:57 +03:00
std : : shared_ptr < SSU2Session > m_LastSession ;
2022-03-28 02:29:50 +03:00
public :
// for HTTP/I2PControl
const decltype ( m_Sessions ) & GetSSU2Sessions ( ) const { return m_Sessions ; } ;
2022-02-28 04:15:14 +03:00
} ;
2022-02-04 23:01:18 +03:00
}
}
# endif