2018-06-05 19:53:13 +03:00
# ifndef NTCP2_H__
# define NTCP2_H__
# include <inttypes.h>
# include <memory>
2018-06-11 21:05:30 +03:00
# include <thread>
2018-06-06 22:38:18 +03:00
# include <boost/asio.hpp>
2018-06-05 19:53:13 +03:00
# include "RouterInfo.h"
# include "TransportSession.h"
namespace i2p
{
namespace transport
{
2018-06-06 22:38:18 +03:00
class NTCP2Server ;
2018-06-05 19:53:13 +03:00
class NTCP2Session : public TransportSession , public std : : enable_shared_from_this < NTCP2Session >
{
public :
2018-06-11 21:05:30 +03:00
NTCP2Session ( NTCP2Server & server , std : : shared_ptr < const i2p : : data : : RouterInfo > in_RemoteRouter = nullptr ) ;
2018-06-05 19:53:13 +03:00
~ NTCP2Session ( ) ;
2018-06-11 19:29:30 +03:00
void Terminate ( ) ;
2018-06-11 21:05:30 +03:00
void Done ( ) ;
2018-06-05 19:53:13 +03:00
2018-06-06 22:38:18 +03:00
boost : : asio : : ip : : tcp : : socket & GetSocket ( ) { return m_Socket ; } ;
void ClientLogin ( ) ; // Alice
2018-06-19 22:43:47 +03:00
void ServerLogin ( ) ; // Bob
2018-06-11 21:05:30 +03:00
void SendI2NPMessages ( const std : : vector < std : : shared_ptr < I2NPMessage > > & msgs ) { } ; // TODO
2018-06-06 22:38:18 +03:00
2018-06-05 19:53:13 +03:00
private :
2018-06-14 22:29:36 +03:00
void MixKey ( const uint8_t * inputKeyMaterial , uint8_t * derived ) ;
2018-06-25 19:28:07 +03:00
void CreateNonce ( uint64_t seqn , uint8_t * nonce ) ;
2018-06-19 22:43:47 +03:00
void KeyDerivationFunction1 ( const uint8_t * rs , const uint8_t * priv , const uint8_t * pub , uint8_t * derived ) ; // for SessionRequest
void KeyDerivationFunction2 ( const uint8_t * priv , const uint8_t * pub , const uint8_t * sessionRequest , size_t sessionRequestLen , uint8_t * derived ) ; // for SessionCreate
2018-06-14 22:29:36 +03:00
void KeyDerivationFunction3 ( const uint8_t * staticPrivKey , uint8_t * derived ) ; // for SessionConfirmed part 2
2018-06-21 19:39:24 +03:00
void KeyDerivationFunctionDataPhase ( ) ;
2018-06-13 23:16:23 +03:00
2018-06-21 23:24:19 +03:00
// establish
2018-06-05 19:53:13 +03:00
void CreateEphemeralKey ( uint8_t * pub ) ;
2018-06-06 22:38:18 +03:00
void SendSessionRequest ( ) ;
2018-06-19 22:43:47 +03:00
void SendSessionCreated ( ) ;
2018-06-14 22:29:36 +03:00
void SendSessionConfirmed ( ) ;
2018-06-06 22:38:18 +03:00
void HandleSessionRequestSent ( const boost : : system : : error_code & ecode , std : : size_t bytes_transferred ) ;
2018-06-19 22:43:47 +03:00
void HandleSessionRequestReceived ( const boost : : system : : error_code & ecode , std : : size_t bytes_transferred ) ;
void HandleSessionRequestPaddingReceived ( const boost : : system : : error_code & ecode , std : : size_t bytes_transferred ) ;
void HandleSessionCreatedSent ( const boost : : system : : error_code & ecode , std : : size_t bytes_transferred ) ;
2018-06-11 19:29:30 +03:00
void HandleSessionCreatedReceived ( const boost : : system : : error_code & ecode , std : : size_t bytes_transferred ) ;
2018-06-14 22:29:36 +03:00
void HandleSessionCreatedPaddingReceived ( const boost : : system : : error_code & ecode , std : : size_t bytes_transferred ) ;
void HandleSessionConfirmedSent ( const boost : : system : : error_code & ecode , std : : size_t bytes_transferred ) ;
2018-06-05 19:53:13 +03:00
2018-06-21 23:24:19 +03:00
// data
void ReceiveLength ( ) ;
void HandleReceivedLength ( const boost : : system : : error_code & ecode , std : : size_t bytes_transferred ) ;
void Receive ( ) ;
void HandleReceived ( const boost : : system : : error_code & ecode , std : : size_t bytes_transferred ) ;
2018-06-22 22:02:49 +03:00
void ProcessNextFrame ( const uint8_t * frame , size_t len ) ;
2018-06-21 23:24:19 +03:00
2018-06-25 19:28:07 +03:00
void SendNextFrame ( const uint8_t * payload , size_t len ) ;
void HandleNextFrameSent ( const boost : : system : : error_code & ecode , std : : size_t bytes_transferred ) ;
2018-06-05 19:53:13 +03:00
private :
2018-06-06 22:38:18 +03:00
NTCP2Server & m_Server ;
boost : : asio : : ip : : tcp : : socket m_Socket ;
2018-06-11 19:29:30 +03:00
bool m_IsEstablished , m_IsTerminated ;
2018-06-19 22:43:47 +03:00
uint8_t m_EphemeralPrivateKey [ 32 ] ; // x25519
uint8_t m_RemoteStaticKey [ 32 ] , m_IV [ 16 ] , m_H [ 32 ] /*h*/ , m_CK [ 33 ] /*ck*/ , m_K [ 32 ] /* derived after SessionCreated */ , m_Y [ 32 ] /* or X for Bob */ ;
2018-06-14 22:29:36 +03:00
uint8_t * m_SessionRequestBuffer , * m_SessionCreatedBuffer , * m_SessionConfirmedBuffer ;
size_t m_SessionRequestBufferLen , m_SessionCreatedBufferLen ;
2018-06-21 19:39:24 +03:00
// data phase
2018-06-21 23:24:19 +03:00
uint8_t m_Kab [ 33 ] , m_Kba [ 32 ] , m_Sipkeysab [ 33 ] , m_Sipkeysba [ 32 ] ;
uint16_t m_NextReceivedLen ;
2018-06-25 19:28:07 +03:00
uint8_t * m_NextReceivedBuffer , * m_NextSendBuffer ;
uint8_t m_ReceiveIV [ 8 ] , m_SendIV [ 8 ] ;
uint64_t m_ReceiveSequenceNumber , m_SendSequenceNumber ;
2018-06-06 22:38:18 +03:00
} ;
class NTCP2Server
{
public :
2018-06-11 19:29:30 +03:00
NTCP2Server ( ) ;
~ NTCP2Server ( ) ;
void Start ( ) ;
void Stop ( ) ;
2018-06-06 22:38:18 +03:00
boost : : asio : : io_service & GetService ( ) { return m_Service ; } ;
2018-06-11 19:29:30 +03:00
void Connect ( const boost : : asio : : ip : : address & address , uint16_t port , std : : shared_ptr < NTCP2Session > conn ) ;
private :
void Run ( ) ;
void HandleConnect ( const boost : : system : : error_code & ecode , std : : shared_ptr < NTCP2Session > conn ) ;
2018-06-06 22:38:18 +03:00
private :
2018-06-11 19:29:30 +03:00
bool m_IsRunning ;
std : : thread * m_Thread ;
2018-06-06 22:38:18 +03:00
boost : : asio : : io_service m_Service ;
2018-06-11 19:29:30 +03:00
boost : : asio : : io_service : : work m_Work ;
2018-06-05 19:53:13 +03:00
} ;
}
}
# endif