2020-05-22 16:18:41 +03:00
/*
2024-01-22 02:59:04 +03:00
* Copyright ( c ) 2013 - 2024 , The PurpleI2P Project
2020-05-22 16:18:41 +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
*/
2013-10-27 19:20:29 +04:00
# ifndef I2NP_PROTOCOL_H__
# define I2NP_PROTOCOL_H__
# include <inttypes.h>
2015-02-06 02:53:43 +03:00
# include <string.h>
2014-01-05 18:53:44 +04:00
# include <set>
2015-02-06 02:53:43 +03:00
# include <memory>
2024-01-30 03:54:43 +03:00
# include <functional>
2016-05-11 22:12:38 +03:00
# include "Crypto.h"
2014-02-07 20:26:00 +04:00
# include "I2PEndian.h"
2014-12-30 20:25:08 +03:00
# include "Identity.h"
2013-10-27 19:20:29 +04:00
# include "RouterInfo.h"
2014-07-29 22:31:55 +04:00
# include "LeaseSet.h"
2013-10-27 19:20:29 +04:00
namespace i2p
2018-01-06 06:48:51 +03:00
{
2015-01-02 00:51:15 +03:00
// I2NP header
const size_t I2NP_HEADER_TYPEID_OFFSET = 0 ;
const size_t I2NP_HEADER_MSGID_OFFSET = I2NP_HEADER_TYPEID_OFFSET + 1 ;
const size_t I2NP_HEADER_EXPIRATION_OFFSET = I2NP_HEADER_MSGID_OFFSET + 4 ;
const size_t I2NP_HEADER_SIZE_OFFSET = I2NP_HEADER_EXPIRATION_OFFSET + 8 ;
const size_t I2NP_HEADER_CHKS_OFFSET = I2NP_HEADER_SIZE_OFFSET + 2 ;
2015-01-02 02:53:44 +03:00
const size_t I2NP_HEADER_SIZE = I2NP_HEADER_CHKS_OFFSET + 1 ;
2015-01-02 07:00:33 +03:00
// I2NP short header
const size_t I2NP_SHORT_HEADER_TYPEID_OFFSET = 0 ;
const size_t I2NP_SHORT_HEADER_EXPIRATION_OFFSET = I2NP_SHORT_HEADER_TYPEID_OFFSET + 1 ;
const size_t I2NP_SHORT_HEADER_SIZE = I2NP_SHORT_HEADER_EXPIRATION_OFFSET + 4 ;
2018-01-06 06:48:51 +03:00
2018-07-17 22:17:05 +03:00
// I2NP NTCP2 header
2020-03-01 13:25:50 +03:00
const size_t I2NP_NTCP2_HEADER_SIZE = I2NP_HEADER_EXPIRATION_OFFSET + 4 ;
2018-07-17 22:17:05 +03:00
2015-01-02 02:53:44 +03:00
// Tunnel Gateway header
const size_t TUNNEL_GATEWAY_HEADER_TUNNELID_OFFSET = 0 ;
const size_t TUNNEL_GATEWAY_HEADER_LENGTH_OFFSET = TUNNEL_GATEWAY_HEADER_TUNNELID_OFFSET + 4 ;
const size_t TUNNEL_GATEWAY_HEADER_SIZE = TUNNEL_GATEWAY_HEADER_LENGTH_OFFSET + 2 ;
2015-01-03 01:39:35 +03:00
2018-01-06 06:48:51 +03:00
// DeliveryStatus
2015-01-03 01:39:35 +03:00
const size_t DELIVERY_STATUS_MSGID_OFFSET = 0 ;
const size_t DELIVERY_STATUS_TIMESTAMP_OFFSET = DELIVERY_STATUS_MSGID_OFFSET + 4 ;
const size_t DELIVERY_STATUS_SIZE = DELIVERY_STATUS_TIMESTAMP_OFFSET + 8 ;
2015-01-03 05:11:40 +03:00
2024-02-27 11:15:15 +03:00
// TunnelTest
const size_t TUNNEL_TEST_MSGID_OFFSET = 0 ;
const size_t TUNNEL_TEST_TIMESTAMP_OFFSET = TUNNEL_TEST_MSGID_OFFSET + 4 ;
const size_t TUNNEL_TEST_SIZE = TUNNEL_TEST_TIMESTAMP_OFFSET + 8 ;
2015-01-03 05:11:40 +03:00
// DatabaseStore
const size_t DATABASE_STORE_KEY_OFFSET = 0 ;
const size_t DATABASE_STORE_TYPE_OFFSET = DATABASE_STORE_KEY_OFFSET + 32 ;
const size_t DATABASE_STORE_REPLY_TOKEN_OFFSET = DATABASE_STORE_TYPE_OFFSET + 1 ;
const size_t DATABASE_STORE_HEADER_SIZE = DATABASE_STORE_REPLY_TOKEN_OFFSET + 4 ;
2015-01-03 17:47:24 +03:00
2018-01-06 06:48:51 +03:00
// TunnelBuild
2015-01-03 17:47:24 +03:00
const size_t TUNNEL_BUILD_RECORD_SIZE = 528 ;
2021-06-22 20:11:02 +03:00
const size_t SHORT_TUNNEL_BUILD_RECORD_SIZE = 218 ;
2021-11-27 23:30:35 +03:00
2018-01-06 06:48:51 +03:00
// BuildRequestRecordEncrypted
2015-01-04 00:31:44 +03:00
const size_t BUILD_REQUEST_RECORD_TO_PEER_OFFSET = 0 ;
const size_t BUILD_REQUEST_RECORD_ENCRYPTED_OFFSET = BUILD_REQUEST_RECORD_TO_PEER_OFFSET + 16 ;
2018-01-06 06:48:51 +03:00
2020-10-23 22:53:22 +03:00
// ECIES BuildRequestRecordClearText
const size_t ECIES_BUILD_REQUEST_RECORD_RECEIVE_TUNNEL_OFFSET = 0 ;
const size_t ECIES_BUILD_REQUEST_RECORD_NEXT_TUNNEL_OFFSET = ECIES_BUILD_REQUEST_RECORD_RECEIVE_TUNNEL_OFFSET + 4 ;
const size_t ECIES_BUILD_REQUEST_RECORD_NEXT_IDENT_OFFSET = ECIES_BUILD_REQUEST_RECORD_NEXT_TUNNEL_OFFSET + 4 ;
const size_t ECIES_BUILD_REQUEST_RECORD_LAYER_KEY_OFFSET = ECIES_BUILD_REQUEST_RECORD_NEXT_IDENT_OFFSET + 32 ;
const size_t ECIES_BUILD_REQUEST_RECORD_IV_KEY_OFFSET = ECIES_BUILD_REQUEST_RECORD_LAYER_KEY_OFFSET + 32 ;
const size_t ECIES_BUILD_REQUEST_RECORD_REPLY_KEY_OFFSET = ECIES_BUILD_REQUEST_RECORD_IV_KEY_OFFSET + 32 ;
const size_t ECIES_BUILD_REQUEST_RECORD_REPLY_IV_OFFSET = ECIES_BUILD_REQUEST_RECORD_REPLY_KEY_OFFSET + 32 ;
const size_t ECIES_BUILD_REQUEST_RECORD_FLAG_OFFSET = ECIES_BUILD_REQUEST_RECORD_REPLY_IV_OFFSET + 16 ;
const size_t ECIES_BUILD_REQUEST_RECORD_MORE_FLAGS_OFFSET = ECIES_BUILD_REQUEST_RECORD_FLAG_OFFSET + 1 ;
const size_t ECIES_BUILD_REQUEST_RECORD_REQUEST_TIME_OFFSET = ECIES_BUILD_REQUEST_RECORD_MORE_FLAGS_OFFSET + 3 ;
const size_t ECIES_BUILD_REQUEST_RECORD_REQUEST_EXPIRATION_OFFSET = ECIES_BUILD_REQUEST_RECORD_REQUEST_TIME_OFFSET + 4 ;
const size_t ECIES_BUILD_REQUEST_RECORD_SEND_MSG_ID_OFFSET = ECIES_BUILD_REQUEST_RECORD_REQUEST_EXPIRATION_OFFSET + 4 ;
const size_t ECIES_BUILD_REQUEST_RECORD_PADDING_OFFSET = ECIES_BUILD_REQUEST_RECORD_SEND_MSG_ID_OFFSET + 4 ;
const size_t ECIES_BUILD_REQUEST_RECORD_CLEAR_TEXT_SIZE = 464 ;
// ECIES BuildResponseRecord
2020-11-03 02:49:07 +03:00
const size_t ECIES_BUILD_RESPONSE_RECORD_OPTIONS_OFFSET = 0 ;
2020-10-23 22:53:22 +03:00
const size_t ECIES_BUILD_RESPONSE_RECORD_RET_OFFSET = 511 ;
2021-06-03 02:50:29 +03:00
// ShortRequestRecordClearText
2021-06-06 20:55:38 +03:00
const size_t SHORT_REQUEST_RECORD_ENCRYPTED_OFFSET = 16 ;
2021-06-08 01:28:36 +03:00
const size_t SHORT_REQUEST_RECORD_RECEIVE_TUNNEL_OFFSET = 0 ;
const size_t SHORT_REQUEST_RECORD_NEXT_TUNNEL_OFFSET = SHORT_REQUEST_RECORD_RECEIVE_TUNNEL_OFFSET + 4 ;
const size_t SHORT_REQUEST_RECORD_NEXT_IDENT_OFFSET = SHORT_REQUEST_RECORD_NEXT_TUNNEL_OFFSET + 4 ;
const size_t SHORT_REQUEST_RECORD_FLAG_OFFSET = SHORT_REQUEST_RECORD_NEXT_IDENT_OFFSET + 32 ;
const size_t SHORT_REQUEST_RECORD_MORE_FLAGS_OFFSET = SHORT_REQUEST_RECORD_FLAG_OFFSET + 1 ;
const size_t SHORT_REQUEST_RECORD_LAYER_ENCRYPTION_TYPE = SHORT_REQUEST_RECORD_MORE_FLAGS_OFFSET + 2 ;
const size_t SHORT_REQUEST_RECORD_REQUEST_TIME_OFFSET = SHORT_REQUEST_RECORD_LAYER_ENCRYPTION_TYPE + 1 ;
const size_t SHORT_REQUEST_RECORD_REQUEST_EXPIRATION_OFFSET = SHORT_REQUEST_RECORD_REQUEST_TIME_OFFSET + 4 ;
const size_t SHORT_REQUEST_RECORD_SEND_MSG_ID_OFFSET = SHORT_REQUEST_RECORD_REQUEST_EXPIRATION_OFFSET + 4 ;
2021-07-03 05:06:24 +03:00
const size_t SHORT_REQUEST_RECORD_PADDING_OFFSET = SHORT_REQUEST_RECORD_SEND_MSG_ID_OFFSET + 4 ;
2021-06-22 20:11:02 +03:00
const size_t SHORT_REQUEST_RECORD_CLEAR_TEXT_SIZE = 154 ;
2021-07-12 02:29:16 +03:00
// ShortResponseRecord
const size_t SHORT_RESPONSE_RECORD_OPTIONS_OFFSET = 0 ;
const size_t SHORT_RESPONSE_RECORD_RET_OFFSET = 201 ;
2021-11-27 23:30:35 +03:00
2013-10-27 19:20:29 +04:00
enum I2NPMessageType
{
2020-03-01 13:25:50 +03:00
eI2NPDummyMsg = 0 ,
2013-10-27 19:20:29 +04:00
eI2NPDatabaseStore = 1 ,
eI2NPDatabaseLookup = 2 ,
eI2NPDatabaseSearchReply = 3 ,
eI2NPDeliveryStatus = 10 ,
eI2NPGarlic = 11 ,
eI2NPTunnelData = 18 ,
eI2NPTunnelGateway = 19 ,
eI2NPData = 20 ,
2014-04-30 22:08:57 +04:00
eI2NPTunnelBuild = 21 ,
eI2NPTunnelBuildReply = 22 ,
2013-10-27 19:20:29 +04:00
eI2NPVariableTunnelBuild = 23 ,
2021-06-06 20:55:38 +03:00
eI2NPVariableTunnelBuildReply = 24 ,
2021-06-08 22:36:27 +03:00
eI2NPShortTunnelBuild = 25 ,
2024-02-27 11:15:15 +03:00
eI2NPShortTunnelBuildReply = 26 ,
eI2NPTunnelTest = 231
2018-01-06 06:48:51 +03:00
} ;
2013-10-27 19:20:29 +04:00
2021-06-08 22:36:27 +03:00
const uint8_t TUNNEL_BUILD_RECORD_GATEWAY_FLAG = 0x80 ;
const uint8_t TUNNEL_BUILD_RECORD_ENDPOINT_FLAG = 0x40 ;
2018-01-06 06:48:51 +03:00
const int NUM_TUNNEL_BUILD_RECORDS = 8 ;
2014-04-30 22:08:57 +04:00
2015-02-02 19:06:36 +03:00
// DatabaseLookup flags
const uint8_t DATABASE_LOOKUP_DELIVERY_FLAG = 0x01 ;
2018-01-06 06:48:51 +03:00
const uint8_t DATABASE_LOOKUP_ENCRYPTION_FLAG = 0x02 ;
2020-04-07 18:40:18 +03:00
const uint8_t DATABASE_LOOKUP_ECIES_FLAG = 0x10 ;
2015-02-02 19:06:36 +03:00
const uint8_t DATABASE_LOOKUP_TYPE_FLAGS_MASK = 0x0C ;
const uint8_t DATABASE_LOOKUP_TYPE_NORMAL_LOOKUP = 0 ;
const uint8_t DATABASE_LOOKUP_TYPE_LEASESET_LOOKUP = 0x04 ; // 0100
2018-01-06 06:48:51 +03:00
const uint8_t DATABASE_LOOKUP_TYPE_ROUTERINFO_LOOKUP = 0x08 ; // 1000
2015-02-02 19:06:36 +03:00
const uint8_t DATABASE_LOOKUP_TYPE_EXPLORATORY_LOOKUP = 0x0C ; // 1100
2014-03-13 04:13:49 +04:00
namespace tunnel
2018-01-06 06:48:51 +03:00
{
2014-03-13 04:13:49 +04:00
class InboundTunnel ;
2014-10-07 04:18:18 +04:00
class TunnelPool ;
2014-03-13 04:13:49 +04:00
}
2024-02-20 11:30:05 +03:00
const int CONGESTION_LEVEL_MEDIUM = 70 ;
const int CONGESTION_LEVEL_HIGH = 90 ;
const int CONGESTION_LEVEL_FULL = 100 ;
2018-10-10 18:31:55 +03:00
const size_t I2NP_MAX_MESSAGE_SIZE = 62708 ;
2018-01-06 06:48:51 +03:00
const size_t I2NP_MAX_SHORT_MESSAGE_SIZE = 4096 ;
2023-03-18 22:32:05 +03:00
const size_t I2NP_MAX_MEDIUM_MESSAGE_SIZE = 16384 ;
2024-03-09 20:05:02 +03:00
const unsigned int I2NP_MESSAGE_LOCAL_EXPIRATION_TIMEOUT = 2000000 ; // in microseconds
2016-01-19 19:16:50 +03:00
const unsigned int I2NP_MESSAGE_EXPIRATION_TIMEOUT = 8000 ; // in milliseconds (as initial RTT)
2018-01-06 06:48:51 +03:00
const unsigned int I2NP_MESSAGE_CLOCK_SKEW = 60 * 1000 ; // 1 minute in milliseconds
2016-01-19 19:16:50 +03:00
2013-10-27 19:20:29 +04:00
struct I2NPMessage
2018-01-06 06:48:51 +03:00
{
uint8_t * buf ;
2014-07-31 02:20:42 +04:00
size_t len , offset , maxLen ;
2015-02-06 02:53:43 +03:00
std : : shared_ptr < i2p : : tunnel : : InboundTunnel > from ;
2024-01-30 03:54:43 +03:00
std : : function < void ( ) > onDrop ;
2024-03-09 20:05:02 +03:00
uint64_t localExpiration ; // monotonic microseconds
I2NPMessage ( ) : buf ( nullptr ) , len ( I2NP_HEADER_SIZE + 2 ) ,
offset ( 2 ) , maxLen ( 0 ) , from ( nullptr ) , localExpiration ( 0 ) { } ; // reserve 2 bytes for NTCP header
2018-01-06 06:48:51 +03:00
2015-01-02 00:51:15 +03:00
// header accessors
2015-01-03 01:39:35 +03:00
uint8_t * GetHeader ( ) { return GetBuffer ( ) ; } ;
const uint8_t * GetHeader ( ) const { return GetBuffer ( ) ; } ;
void SetTypeID ( uint8_t typeID ) { GetHeader ( ) [ I2NP_HEADER_TYPEID_OFFSET ] = typeID ; } ;
uint8_t GetTypeID ( ) const { return GetHeader ( ) [ I2NP_HEADER_TYPEID_OFFSET ] ; } ;
void SetMsgID ( uint32_t msgID ) { htobe32buf ( GetHeader ( ) + I2NP_HEADER_MSGID_OFFSET , msgID ) ; } ;
uint32_t GetMsgID ( ) const { return bufbe32toh ( GetHeader ( ) + I2NP_HEADER_MSGID_OFFSET ) ; } ;
void SetExpiration ( uint64_t expiration ) { htobe64buf ( GetHeader ( ) + I2NP_HEADER_EXPIRATION_OFFSET , expiration ) ; } ;
2024-03-09 20:05:02 +03:00
void SetLocalExpiration ( uint64_t expiration ) { localExpiration = expiration ; } ;
2015-01-03 01:39:35 +03:00
uint64_t GetExpiration ( ) const { return bufbe64toh ( GetHeader ( ) + I2NP_HEADER_EXPIRATION_OFFSET ) ; } ;
void SetSize ( uint16_t size ) { htobe16buf ( GetHeader ( ) + I2NP_HEADER_SIZE_OFFSET , size ) ; } ;
uint16_t GetSize ( ) const { return bufbe16toh ( GetHeader ( ) + I2NP_HEADER_SIZE_OFFSET ) ; } ;
2018-01-06 06:48:51 +03:00
void UpdateSize ( ) { SetSize ( GetPayloadLength ( ) ) ; } ;
2015-01-03 01:39:35 +03:00
void SetChks ( uint8_t chks ) { GetHeader ( ) [ I2NP_HEADER_CHKS_OFFSET ] = chks ; } ;
2018-01-06 06:48:51 +03:00
void UpdateChks ( )
2015-01-02 00:51:15 +03:00
{
uint8_t hash [ 32 ] ;
2015-11-03 17:15:49 +03:00
SHA256 ( GetPayload ( ) , GetPayloadLength ( ) , hash ) ;
2015-01-03 01:39:35 +03:00
GetHeader ( ) [ I2NP_HEADER_CHKS_OFFSET ] = hash [ 0 ] ;
2018-01-06 06:48:51 +03:00
}
2015-01-02 00:51:15 +03:00
// payload
2015-01-02 07:00:33 +03:00
uint8_t * GetPayload ( ) { return GetBuffer ( ) + I2NP_HEADER_SIZE ; } ;
2015-06-25 05:19:56 +03:00
const uint8_t * GetPayload ( ) const { return GetBuffer ( ) + I2NP_HEADER_SIZE ; } ;
2013-10-27 19:20:29 +04:00
uint8_t * GetBuffer ( ) { return buf + offset ; } ;
2014-03-20 17:47:02 +04:00
const uint8_t * GetBuffer ( ) const { return buf + offset ; } ;
2018-01-06 06:48:51 +03:00
size_t GetLength ( ) const { return len - offset ; } ;
size_t GetPayloadLength ( ) const { return GetLength ( ) - I2NP_HEADER_SIZE ; } ;
void Align ( size_t alignment )
2014-11-26 19:04:49 +03:00
{
2015-03-11 19:17:38 +03:00
if ( len + alignment > maxLen ) return ;
2014-11-26 19:04:49 +03:00
size_t rem = ( ( size_t ) GetBuffer ( ) ) % alignment ;
if ( rem )
2014-11-26 19:54:35 +03:00
{
2014-11-26 19:04:49 +03:00
offset + = ( alignment - rem ) ;
2014-11-26 19:54:35 +03:00
len + = ( alignment - rem ) ;
2018-01-06 06:48:51 +03:00
}
2014-11-26 19:04:49 +03:00
}
2013-11-11 03:23:26 +04:00
2016-01-05 22:29:18 +03:00
size_t Concat ( const uint8_t * buf1 , size_t len1 )
{
// make sure with don't write beyond maxLen
if ( len + len1 > maxLen ) len1 = maxLen - len ;
memcpy ( buf + len , buf1 , len1 ) ;
len + = len1 ;
return len1 ;
}
2013-11-11 03:23:26 +04:00
I2NPMessage & operator = ( const I2NPMessage & other )
{
memcpy ( buf + offset , other . buf + other . offset , other . GetLength ( ) ) ;
len = offset + other . GetLength ( ) ;
2014-03-13 04:13:49 +04:00
from = other . from ;
2013-11-11 03:23:26 +04:00
return * this ;
2018-01-06 06:48:51 +03:00
}
2014-02-07 20:26:00 +04:00
// for SSU only
2018-01-06 06:48:51 +03:00
uint8_t * GetSSUHeader ( ) { return buf + offset + I2NP_HEADER_SIZE - I2NP_SHORT_HEADER_SIZE ; } ;
2014-02-07 20:26:00 +04:00
void FromSSU ( uint32_t msgID ) // we have received SSU message and convert it to regular
{
2015-01-02 07:00:33 +03:00
const uint8_t * ssu = GetSSUHeader ( ) ;
2015-01-03 01:39:35 +03:00
GetHeader ( ) [ I2NP_HEADER_TYPEID_OFFSET ] = ssu [ I2NP_SHORT_HEADER_TYPEID_OFFSET ] ; // typeid
2015-01-02 07:00:33 +03:00
SetMsgID ( msgID ) ;
SetExpiration ( bufbe32toh ( ssu + I2NP_SHORT_HEADER_EXPIRATION_OFFSET ) * 1000LL ) ;
SetSize ( len - offset - I2NP_HEADER_SIZE ) ;
SetChks ( 0 ) ;
2014-02-07 20:26:00 +04:00
}
2014-02-10 03:28:34 +04:00
uint32_t ToSSU ( ) // return msgID
{
2015-01-02 07:00:33 +03:00
uint8_t header [ I2NP_HEADER_SIZE ] ;
2015-01-03 01:39:35 +03:00
memcpy ( header , GetHeader ( ) , I2NP_HEADER_SIZE ) ;
2015-01-02 07:00:33 +03:00
uint8_t * ssu = GetSSUHeader ( ) ;
ssu [ I2NP_SHORT_HEADER_TYPEID_OFFSET ] = header [ I2NP_HEADER_TYPEID_OFFSET ] ; // typeid
htobe32buf ( ssu + I2NP_SHORT_HEADER_EXPIRATION_OFFSET , bufbe64toh ( header + I2NP_HEADER_EXPIRATION_OFFSET ) / 1000LL ) ;
len = offset + I2NP_SHORT_HEADER_SIZE + bufbe16toh ( header + I2NP_HEADER_SIZE_OFFSET ) ;
return bufbe32toh ( header + I2NP_HEADER_MSGID_OFFSET ) ;
2018-01-06 06:48:51 +03:00
}
2018-07-17 22:17:05 +03:00
// for NTCP2 only
uint8_t * GetNTCP2Header ( ) { return GetPayload ( ) - I2NP_NTCP2_HEADER_SIZE ; } ;
2018-07-18 18:16:40 +03:00
size_t GetNTCP2Length ( ) const { return GetPayloadLength ( ) + I2NP_NTCP2_HEADER_SIZE ; } ;
2018-07-17 22:17:05 +03:00
void FromNTCP2 ( )
{
const uint8_t * ntcp2 = GetNTCP2Header ( ) ;
memcpy ( GetHeader ( ) + I2NP_HEADER_TYPEID_OFFSET , ntcp2 + I2NP_HEADER_TYPEID_OFFSET , 5 ) ; // typeid + msgid
SetExpiration ( bufbe32toh ( ntcp2 + I2NP_HEADER_EXPIRATION_OFFSET ) * 1000LL ) ;
SetSize ( len - offset - I2NP_HEADER_SIZE ) ;
SetChks ( 0 ) ;
2020-03-01 13:25:50 +03:00
}
2018-07-17 22:17:05 +03:00
void ToNTCP2 ( )
{
uint8_t * ntcp2 = GetNTCP2Header ( ) ;
htobe32buf ( ntcp2 + I2NP_HEADER_EXPIRATION_OFFSET , bufbe64toh ( GetHeader ( ) + I2NP_HEADER_EXPIRATION_OFFSET ) / 1000LL ) ;
memcpy ( ntcp2 + I2NP_HEADER_TYPEID_OFFSET , GetHeader ( ) + I2NP_HEADER_TYPEID_OFFSET , 5 ) ; // typeid + msgid
}
2015-07-03 18:11:07 +03:00
2020-05-02 18:13:40 +03:00
void FillI2NPMessageHeader ( I2NPMessageType msgType , uint32_t replyMsgID = 0 , bool checksum = true ) ;
2015-07-03 18:11:07 +03:00
void RenewI2NPMessageHeader ( ) ;
2016-01-19 05:13:43 +03:00
bool IsExpired ( ) const ;
2024-01-22 02:59:04 +03:00
bool IsExpired ( uint64_t ts ) const ; // in milliseconds
2024-03-09 20:05:02 +03:00
bool IsLocalExpired ( uint64_t mts ) const { return mts > localExpiration ; } ; // monotonic microseconds
2024-03-13 17:41:01 +03:00
bool IsLocalSemiExpired ( uint64_t mts ) const { return mts > localExpiration - I2NP_MESSAGE_LOCAL_EXPIRATION_TIMEOUT / 2 ; } ; // monotonic microseconds
2024-01-30 03:54:43 +03:00
void Drop ( ) { if ( onDrop ) { onDrop ( ) ; onDrop = nullptr ; } ; }
2018-01-06 06:48:51 +03:00
} ;
2014-07-31 00:52:35 +04:00
template < int sz >
struct I2NPMessageBuffer : public I2NPMessage
{
2014-07-31 02:20:42 +04:00
I2NPMessageBuffer ( ) { buf = m_Buffer ; maxLen = sz ; } ;
2016-01-02 01:39:12 +03:00
uint8_t m_Buffer [ sz + 32 ] ; // 16 alignment + 16 padding
2014-07-31 00:52:35 +04:00
} ;
2015-11-24 21:09:12 +03:00
std : : shared_ptr < I2NPMessage > NewI2NPMessage ( ) ;
std : : shared_ptr < I2NPMessage > NewI2NPShortMessage ( ) ;
2023-03-18 22:32:05 +03:00
std : : shared_ptr < I2NPMessage > NewI2NPMediumMessage ( ) ;
2021-06-27 22:49:57 +03:00
std : : shared_ptr < I2NPMessage > NewI2NPTunnelMessage ( bool endpoint ) ;
2015-11-24 21:09:12 +03:00
std : : shared_ptr < I2NPMessage > NewI2NPMessage ( size_t len ) ;
2018-01-06 06:48:51 +03:00
std : : shared_ptr < I2NPMessage > CreateI2NPMessage ( I2NPMessageType msgType , const uint8_t * buf , size_t len , uint32_t replyMsgID = 0 ) ;
2016-01-05 22:29:18 +03:00
std : : shared_ptr < I2NPMessage > CreateI2NPMessage ( const uint8_t * buf , size_t len , std : : shared_ptr < i2p : : tunnel : : InboundTunnel > from = nullptr ) ;
2016-02-01 02:27:47 +03:00
std : : shared_ptr < I2NPMessage > CopyI2NPMessage ( std : : shared_ptr < I2NPMessage > msg ) ;
2024-02-27 11:15:15 +03:00
std : : shared_ptr < I2NPMessage > CreateTunnelTestMsg ( uint32_t msgID ) ;
2015-06-24 17:45:58 +03:00
std : : shared_ptr < I2NPMessage > CreateDeliveryStatusMsg ( uint32_t msgID ) ;
2018-01-06 06:48:51 +03:00
std : : shared_ptr < I2NPMessage > CreateRouterInfoDatabaseLookupMsg ( const uint8_t * key , const uint8_t * from ,
2015-01-05 01:25:16 +03:00
uint32_t replyTunnelID , bool exploratory = false , std : : set < i2p : : data : : IdentHash > * excludedPeers = nullptr ) ;
2018-01-06 06:48:51 +03:00
std : : shared_ptr < I2NPMessage > CreateLeaseSetDatabaseLookupMsg ( const i2p : : data : : IdentHash & dest ,
2021-11-27 23:30:35 +03:00
const std : : set < i2p : : data : : IdentHash > & excludedFloodfills ,
2022-05-20 19:56:05 +03:00
std : : shared_ptr < const i2p : : tunnel : : InboundTunnel > replyTunnel ,
const uint8_t * replyKey , const uint8_t * replyTag , bool replyECIES = false ) ;
2015-11-03 17:15:49 +03:00
std : : shared_ptr < I2NPMessage > CreateDatabaseSearchReply ( const i2p : : data : : IdentHash & ident , std : : vector < i2p : : data : : IdentHash > routers ) ;
2018-01-06 06:48:51 +03:00
2021-02-06 22:49:42 +03:00
std : : shared_ptr < I2NPMessage > CreateDatabaseStoreMsg ( std : : shared_ptr < const i2p : : data : : RouterInfo > router = nullptr , uint32_t replyToken = 0 , std : : shared_ptr < const i2p : : tunnel : : InboundTunnel > replyTunnel = nullptr ) ;
2019-06-09 04:23:25 +03:00
std : : shared_ptr < I2NPMessage > CreateDatabaseStoreMsg ( const i2p : : data : : IdentHash & storeHash , std : : shared_ptr < const i2p : : data : : LeaseSet > leaseSet ) ; // for floodfill only
2018-01-06 06:48:51 +03:00
std : : shared_ptr < I2NPMessage > CreateDatabaseStoreMsg ( std : : shared_ptr < const i2p : : data : : LocalLeaseSet > leaseSet , uint32_t replyToken = 0 , std : : shared_ptr < const i2p : : tunnel : : InboundTunnel > replyTunnel = nullptr ) ;
bool IsRouterInfoMsg ( std : : shared_ptr < I2NPMessage > msg ) ;
2016-01-05 03:56:46 +03:00
2018-01-06 06:48:51 +03:00
std : : shared_ptr < I2NPMessage > CreateTunnelDataMsg ( const uint8_t * buf ) ;
std : : shared_ptr < I2NPMessage > CreateTunnelDataMsg ( uint32_t tunnelID , const uint8_t * payload ) ;
2021-06-27 22:49:57 +03:00
std : : shared_ptr < I2NPMessage > CreateEmptyTunnelDataMsg ( bool endpoint ) ;
2018-01-06 06:48:51 +03:00
2015-11-24 21:09:12 +03:00
std : : shared_ptr < I2NPMessage > CreateTunnelGatewayMsg ( uint32_t tunnelID , const uint8_t * buf , size_t len ) ;
2018-01-06 06:48:51 +03:00
std : : shared_ptr < I2NPMessage > CreateTunnelGatewayMsg ( uint32_t tunnelID , I2NPMessageType msgType ,
2013-11-11 03:23:26 +04:00
const uint8_t * buf , size_t len , uint32_t replyMsgID = 0 ) ;
2015-06-19 21:38:31 +03:00
std : : shared_ptr < I2NPMessage > CreateTunnelGatewayMsg ( uint32_t tunnelID , std : : shared_ptr < I2NPMessage > msg ) ;
2013-12-14 05:07:35 +04:00
2017-12-01 20:57:05 +03:00
size_t GetI2NPMessageLength ( const uint8_t * msg , size_t len ) ;
2023-05-08 18:33:40 +03:00
void HandleTunnelBuildI2NPMessage ( std : : shared_ptr < I2NPMessage > msg ) ;
2015-06-19 21:38:31 +03:00
void HandleI2NPMessage ( std : : shared_ptr < I2NPMessage > msg ) ;
2015-01-23 06:00:41 +03:00
class I2NPMessagesHandler
{
public :
~ I2NPMessagesHandler ( ) ;
2021-10-17 18:31:37 +03:00
void PutNextMessage ( std : : shared_ptr < I2NPMessage > & & msg ) ;
2015-01-23 06:00:41 +03:00
void Flush ( ) ;
2018-01-06 06:48:51 +03:00
2015-01-23 06:00:41 +03:00
private :
2015-06-19 21:38:31 +03:00
std : : vector < std : : shared_ptr < I2NPMessage > > m_TunnelMsgs , m_TunnelGatewayMsgs ;
2015-01-23 06:00:41 +03:00
} ;
2018-01-06 06:48:51 +03:00
}
2013-10-27 19:20:29 +04:00
# endif