2023-10-06 17:24:48 -06:00
# include "Packet.h"
2023-11-19 13:17:42 -07:00
# include "Transport.h"
2023-10-06 17:24:48 -06:00
# include "Identity.h"
# include "Log.h"
# include <string.h>
# include <stdexcept>
using namespace RNS ;
2023-11-19 11:36:09 -07:00
using namespace RNS : : Type : : PacketReceipt ;
using namespace RNS : : Type : : Packet ;
2023-10-06 17:24:48 -06:00
2023-11-20 10:51:56 -07:00
Packet : : Packet ( const Destination & destination , const Interface & attached_interface , const Bytes & data , types packet_type /*= DATA*/ , context_types context /*= CONTEXT_NONE*/ , Type : : Transport : : types transport_type /*= Type::Transport::BROADCAST*/ , header_types header_type /*= HEADER_1*/ , const Bytes & transport_id /*= {Bytes::NONE}*/ , bool create_receipt /*= true*/ ) : _object ( new Object ( destination , attached_interface ) ) {
2023-10-06 17:24:48 -06:00
if ( _object - > _destination ) {
2023-11-19 08:51:10 -07:00
extreme ( " Creating packet with destination... " ) ;
2023-11-20 10:26:14 -07:00
// CBA Should never see empty transport_type
//if (transport_type == NONE) {
// transport_type = Type::Transport::BROADCAST;
//}
2023-10-06 17:24:48 -06:00
// following moved to object constructor to avoid extra NONE object
//_destination = destination;
2023-10-09 09:39:11 -06:00
_object - > _header_type = header_type ;
_object - > _packet_type = packet_type ;
_object - > _transport_type = transport_type ;
_object - > _context = context ;
_object - > _transport_id = transport_id ;
_object - > _data = data ;
if ( _object - > _data . size ( ) > MDU ) {
_object - > _truncated = true ;
_object - > _data . resize ( MDU ) ;
2023-10-08 23:59:43 -06:00
}
2023-10-09 09:39:11 -06:00
_object - > _flags = get_packed_flags ( ) ;
_object - > _create_receipt = create_receipt ;
2023-10-06 17:24:48 -06:00
}
else {
2023-11-19 08:51:10 -07:00
extreme ( " Creating packet without destination... " ) ;
2023-10-09 09:39:11 -06:00
_object - > _raw = data ;
_object - > _packed = true ;
_object - > _fromPacked = true ;
_object - > _create_receipt = false ;
2023-10-06 17:24:48 -06:00
}
extreme ( " Packet object created " ) ;
}
Packet : : ~ Packet ( ) {
extreme ( " Packet object destroyed " ) ;
}
uint8_t Packet : : get_packed_flags ( ) {
2023-10-09 09:39:11 -06:00
assert ( _object ) ;
2023-10-06 17:24:48 -06:00
uint8_t packed_flags = 0 ;
2023-10-09 09:39:11 -06:00
if ( _object - > _context = = LRPROOF ) {
2023-11-19 11:36:09 -07:00
packed_flags = ( _object - > _header_type < < 6 ) | ( _object - > _transport_type < < 4 ) | ( Type : : Destination : : LINK < < 2 ) | _object - > _packet_type ;
2023-10-06 17:24:48 -06:00
}
else {
2023-10-09 09:39:11 -06:00
packed_flags = ( _object - > _header_type < < 6 ) | ( _object - > _transport_type < < 4 ) | ( _object - > _destination . type ( ) < < 2 ) | _object - > _packet_type ;
2023-10-06 17:24:48 -06:00
}
return packed_flags ;
}
2023-10-08 23:59:43 -06:00
void Packet : : unpack_flags ( uint8_t flags ) {
2023-10-09 09:39:11 -06:00
assert ( _object ) ;
_object - > _header_type = static_cast < header_types > ( ( flags & 0b01000000 ) > > 6 ) ;
2023-11-19 11:36:09 -07:00
_object - > _transport_type = static_cast < Type : : Transport : : types > ( ( flags & 0b00110000 ) > > 4 ) ;
_object - > _destination_type = static_cast < Type : : Destination : : types > ( ( flags & 0b00001100 ) > > 2 ) ;
2023-10-09 09:39:11 -06:00
_object - > _packet_type = static_cast < types > ( flags & 0b00000011 ) ;
2023-10-08 23:59:43 -06:00
}
2023-10-06 17:24:48 -06:00
/*
= = Reticulum Wire Format = = = = = =
A Reticulum packet is composed of the following fields :
[ HEADER 2 bytes ] [ ADDRESSES 16 / 32 bytes ] [ CONTEXT 1 byte ] [ DATA 0 - 465 bytes ]
* The HEADER field is 2 bytes long .
* Byte 1 : [ IFAC Flag ] , [ Header Type ] , [ Propagation Type ] , [ Destination Type ] and [ Packet Type ]
* Byte 2 : Number of hops
* Interface Access Code field if the IFAC flag was set .
* The length of the Interface Access Code can vary from
1 to 64 bytes according to physical interface
capabilities and configuration .
* The ADDRESSES field contains either 1 or 2 addresses .
* Each address is 16 bytes long .
* The Header Type flag in the HEADER field determines
whether the ADDRESSES field contains 1 or 2 addresses .
* Addresses are SHA - 256 hashes truncated to 16 bytes .
* The CONTEXT field is 1 byte .
* It is used by Reticulum to determine packet context .
* The DATA field is between 0 and 465 bytes .
* It contains the packets data payload .
IFAC Flag
- - - - - - - - - - - - - - - - -
open 0 Packet for publically accessible interface
authenticated 1 Interface authentication is included in packet
Header Types
- - - - - - - - - - - - - - - - -
type 1 0 Two byte header , one 16 byte address field
type 2 1 Two byte header , two 16 byte address fields
Propagation Types
- - - - - - - - - - - - - - - - -
broadcast 00
transport 01
reserved 10
reserved 11
Destination Types
- - - - - - - - - - - - - - - - -
single 00
group 01
plain 10
link 11
Packet Types
- - - - - - - - - - - - - - - - -
data 00
announce 01
link request 10
proof 11
+ - Packet Example - +
HEADER FIELD DESTINATION FIELDS CONTEXT FIELD DATA FIELD
_______ | _______ ________________ | ________________ ________ | ______ __ | _
| | | | | | | |
01010000 00000100 [ HASH1 , 16 bytes ] [ HASH2 , 16 bytes ] [ CONTEXT , 1 byte ] [ DATA ]
| | | | | |
| | | | | + - - Hops = 4
| | | | + - - - - - - - Packet Type = DATA
| | | + - - - - - - - - - Destination Type = SINGLE
| | + - - - - - - - - - - - Propagation Type = TRANSPORT
| + - - - - - - - - - - - - - Header Type = HEADER_2 ( two byte header , two address fields )
+ - - - - - - - - - - - - - - Access Codes = DISABLED
+ - Packet Example - +
HEADER FIELD DESTINATION FIELD CONTEXT FIELD DATA FIELD
_______ | _______ _______ | _______ ________ | ______ __ | _
| | | | | | | |
00000000 00000111 [ HASH1 , 16 bytes ] [ CONTEXT , 1 byte ] [ DATA ]
| | | | | |
| | | | | + - - Hops = 7
| | | | + - - - - - - - Packet Type = DATA
| | | + - - - - - - - - - Destination Type = SINGLE
| | + - - - - - - - - - - - Propagation Type = BROADCAST
| + - - - - - - - - - - - - - Header Type = HEADER_1 ( two byte header , one address field )
+ - - - - - - - - - - - - - - Access Codes = DISABLED
+ - Packet Example - +
HEADER FIELD IFAC FIELD DESTINATION FIELD CONTEXT FIELD DATA FIELD
_______ | _______ ______ | ______ _______ | _______ ________ | ______ __ | _
| | | | | | | | | |
10000000 00000111 [ IFAC , N bytes ] [ HASH1 , 16 bytes ] [ CONTEXT , 1 byte ] [ DATA ]
| | | | | |
| | | | | + - - Hops = 7
| | | | + - - - - - - - Packet Type = DATA
| | | + - - - - - - - - - Destination Type = SINGLE
| | + - - - - - - - - - - - Propagation Type = BROADCAST
| + - - - - - - - - - - - - - Header Type = HEADER_1 ( two byte header , one address field )
+ - - - - - - - - - - - - - - Access Codes = ENABLED
Size examples of different packet types
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
The following table lists example sizes of various
packet types . The size listed are the complete on -
wire size counting all fields including headers ,
but excluding any interface access codes .
- Path Request : 51 bytes
- Announce : 167 bytes
- Link Request : 83 bytes
- Link Proof : 115 bytes
- Link RTT packet : 99 bytes
- Link keepalive : 20 bytes
*/
// Reticulum Packet Structure
//
// 0 1 2 3
// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// |I|H|PRT|DT |PT | hops | destination... |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// | ...destination... |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// | ...destination... |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// | ...destination... |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// | ...destination | context | data ... |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
//
// 0 1 2 3
// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// |I|H|PRT|DT |PT | hops | destination_1... |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// | ...destination_1... |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// | ...destination_1... |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// | ...destination_1... |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// | ...destination_1 | destination_2... |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// | ...destination_2... |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// | ...destination_2... |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// | ...destination_2... |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// | ...destination_2 | context | data ... |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
void Packet : : pack ( ) {
assert ( _object ) ;
debug ( " Packet::pack: packing packet... " ) ;
2023-10-08 23:59:43 -06:00
2023-10-09 09:39:11 -06:00
_object - > _destination_hash = _object - > _destination . hash ( ) ;
2023-10-08 23:59:43 -06:00
2023-10-09 09:39:11 -06:00
_object - > _raw . clear ( ) ;
_object - > _encrypted = false ;
2023-10-08 23:59:43 -06:00
2023-10-09 09:39:11 -06:00
_object - > _raw < < _object - > _flags ;
_object - > _raw < < _object - > _hops ;
2023-10-08 23:59:43 -06:00
2023-10-09 09:39:11 -06:00
if ( _object - > _context = = LRPROOF ) {
2023-10-08 23:59:43 -06:00
debug ( " Packet::pack: destination link id: " + _object - > _destination . link_id ( ) . toHex ( ) ) ;
2023-10-09 09:39:11 -06:00
_object - > _raw < < _object - > _destination . link_id ( ) ;
_object - > _raw < < ( uint8_t ) _object - > _context ;
_object - > _raw < < _object - > _data ;
2023-10-08 23:59:43 -06:00
}
else {
2023-10-09 09:39:11 -06:00
if ( _object - > _header_type = = HEADER_1 ) {
2023-10-08 23:59:43 -06:00
debug ( " Packet::pack: destination hash: " + _object - > _destination . hash ( ) . toHex ( ) ) ;
2023-10-09 09:39:11 -06:00
_object - > _raw < < _object - > _destination . hash ( ) ;
_object - > _raw < < ( uint8_t ) _object - > _context ;
2023-10-08 23:59:43 -06:00
2023-10-09 09:39:11 -06:00
if ( _object - > _packet_type = = ANNOUNCE ) {
2023-10-08 23:59:43 -06:00
// Announce packets are not encrypted
2023-10-09 09:39:11 -06:00
_object - > _raw < < _object - > _data ;
2023-10-08 23:59:43 -06:00
}
2023-10-09 09:39:11 -06:00
else if ( _object - > _packet_type = = LINKREQUEST ) {
2023-10-08 23:59:43 -06:00
// Link request packets are not encrypted
2023-10-09 09:39:11 -06:00
_object - > _raw < < _object - > _data ;
2023-10-08 23:59:43 -06:00
}
2023-10-09 09:39:11 -06:00
else if ( _object - > _packet_type = = PROOF & & _object - > _context = = RESOURCE_PRF ) {
2023-10-08 23:59:43 -06:00
// Resource proofs are not encrypted
2023-10-09 09:39:11 -06:00
_object - > _raw < < _object - > _data ;
2023-10-08 23:59:43 -06:00
}
2023-11-19 11:36:09 -07:00
else if ( _object - > _packet_type = = PROOF & & _object - > _destination . type ( ) = = Type : : Destination : : LINK ) {
2023-10-08 23:59:43 -06:00
// Packet proofs over links are not encrypted
2023-10-09 09:39:11 -06:00
_object - > _raw < < _object - > _data ;
2023-10-08 23:59:43 -06:00
}
2023-10-09 09:39:11 -06:00
else if ( _object - > _context = = RESOURCE ) {
2023-10-08 23:59:43 -06:00
// A resource takes care of encryption
// by itself
2023-10-09 09:39:11 -06:00
_object - > _raw < < _object - > _data ;
2023-10-08 23:59:43 -06:00
}
2023-10-09 09:39:11 -06:00
else if ( _object - > _context = = KEEPALIVE ) {
2023-10-08 23:59:43 -06:00
// Keepalive packets contain no actual
// data
2023-10-09 09:39:11 -06:00
_object - > _raw < < _object - > _data ;
2023-10-08 23:59:43 -06:00
}
2023-10-09 09:39:11 -06:00
else if ( _object - > _context = = CACHE_REQUEST ) {
2023-10-08 23:59:43 -06:00
// Cache-requests are not encrypted
2023-10-09 09:39:11 -06:00
_object - > _raw < < _object - > _data ;
2023-10-08 23:59:43 -06:00
}
else {
// In all other cases, we encrypt the packet
// with the destination's encryption method
2023-10-09 09:39:11 -06:00
_object - > _raw < < _object - > _destination . encrypt ( _object - > _data ) ;
_object - > _encrypted = true ;
2023-10-08 23:59:43 -06:00
}
}
2023-10-09 09:39:11 -06:00
else if ( _object - > _header_type = = HEADER_2 ) {
if ( ! _object - > _transport_id ) {
2023-10-08 23:59:43 -06:00
throw std : : invalid_argument ( " Packet with header type 2 must have a transport ID " ) ;
}
2023-10-09 09:39:11 -06:00
debug ( " Packet::pack: transport id: " + _object - > _transport_id . toHex ( ) ) ;
2023-10-08 23:59:43 -06:00
debug ( " Packet::pack: destination hash: " + _object - > _destination . hash ( ) . toHex ( ) ) ;
2023-10-09 09:39:11 -06:00
_object - > _raw < < _object - > _transport_id ;
_object - > _raw < < _object - > _destination . hash ( ) ;
_object - > _raw < < ( uint8_t ) _object - > _context ;
2023-10-08 23:59:43 -06:00
2023-10-09 09:39:11 -06:00
if ( _object - > _packet_type = = ANNOUNCE ) {
2023-10-08 23:59:43 -06:00
// Announce packets are not encrypted
2023-10-09 09:39:11 -06:00
_object - > _raw < < _object - > _data ;
2023-10-08 23:59:43 -06:00
}
}
}
2023-10-09 09:39:11 -06:00
if ( _object - > _raw . size ( ) > _object - > _mtu ) {
throw std : : length_error ( " Packet size of " + std : : to_string ( _object - > _raw . size ( ) ) + " exceeds MTU of " + std : : to_string ( _object - > _mtu ) + " bytes " ) ;
2023-10-08 23:59:43 -06:00
}
2023-10-09 09:39:11 -06:00
_object - > _packed = true ;
2023-10-08 23:59:43 -06:00
update_hash ( ) ;
2023-10-06 17:24:48 -06:00
}
2023-10-08 23:59:43 -06:00
bool Packet : : unpack ( ) {
assert ( _object ) ;
debug ( " Packet::unpack: unpacking packet... " ) ;
try {
2023-11-19 11:36:09 -07:00
if ( _object - > _raw . size ( ) < Type : : Reticulum : : HEADER_MINSIZE ) {
throw std : : length_error ( " Packet size of " + std : : to_string ( _object - > _raw . size ( ) ) + " does not meet minimum header size of " + std : : to_string ( Type : : Reticulum : : HEADER_MINSIZE ) + " bytes " ) ;
2023-10-08 23:59:43 -06:00
}
2023-10-09 09:39:11 -06:00
const uint8_t * raw = _object - > _raw . data ( ) ;
2023-10-08 23:59:43 -06:00
// read header
2023-10-09 09:39:11 -06:00
_object - > _flags = raw [ 0 ] ;
_object - > _hops = raw [ 1 ] ;
2023-10-08 23:59:43 -06:00
2023-10-09 09:39:11 -06:00
unpack_flags ( _object - > _flags ) ;
2023-10-08 23:59:43 -06:00
// CBA TODO detect invalid flags and throw error
if ( false ) {
log ( " Received malformed packet, dropping it. " ) ;
return false ;
}
2023-10-09 09:39:11 -06:00
if ( _object - > _header_type = = HEADER_2 ) {
2023-11-19 11:36:09 -07:00
if ( _object - > _raw . size ( ) < Type : : Reticulum : : HEADER_MAXSIZE ) {
throw std : : length_error ( " Packet size of " + std : : to_string ( _object - > _raw . size ( ) ) + " does not meet minimum header size of " + std : : to_string ( Type : : Reticulum : : HEADER_MAXSIZE ) + " bytes " ) ;
2023-10-08 23:59:43 -06:00
}
2023-11-19 11:36:09 -07:00
_object - > _transport_id . assign ( raw + 2 , Type : : Reticulum : : DESTINATION_LENGTH ) ;
_object - > _destination_hash . assign ( raw + Type : : Reticulum : : DESTINATION_LENGTH + 2 , Type : : Reticulum : : DESTINATION_LENGTH ) ;
_object - > _context = static_cast < context_types > ( raw [ 2 * Type : : Reticulum : : DESTINATION_LENGTH + 2 ] ) ;
_object - > _data . assign ( raw + 2 * Type : : Reticulum : : DESTINATION_LENGTH + 3 , _object - > _raw . size ( ) - ( 2 * Type : : Reticulum : : DESTINATION_LENGTH + 3 ) ) ;
2023-10-09 08:58:38 -06:00
// uknown at this point whether data is encrypted or not
2023-10-09 09:39:11 -06:00
_object - > _encrypted = true ;
2023-10-08 23:59:43 -06:00
}
else {
2023-10-09 09:39:11 -06:00
_object - > _transport_id . clear ( ) ;
2023-11-19 11:36:09 -07:00
_object - > _destination_hash . assign ( raw + 2 , Type : : Reticulum : : DESTINATION_LENGTH ) ;
_object - > _context = static_cast < context_types > ( raw [ Type : : Reticulum : : DESTINATION_LENGTH + 2 ] ) ;
_object - > _data . assign ( raw + Type : : Reticulum : : DESTINATION_LENGTH + 3 , _object - > _raw . size ( ) - ( Type : : Reticulum : : DESTINATION_LENGTH + 3 ) ) ;
2023-10-09 08:58:38 -06:00
// uknown at this point whether data is encrypted or not
2023-10-09 09:39:11 -06:00
_object - > _encrypted = true ;
2023-10-08 23:59:43 -06:00
}
2023-10-09 09:39:11 -06:00
_object - > _packed = false ;
2023-10-08 23:59:43 -06:00
update_hash ( ) ;
}
catch ( std : : exception & e ) {
error ( std : : string ( " Received malformed packet, dropping it. The contained exception was: " ) + e . what ( ) ) ;
return false ;
}
2023-10-06 17:24:48 -06:00
return true ;
}
/*
Sends the packet .
: returns : A : ref : ` RNS . PacketReceipt < api - packetreceipt > ` instance if * create_receipt * was set to * True * when the packet was instantiated , if not returns * None * . If the packet could not be sent * False * is returned .
*/
bool Packet : : send ( ) {
assert ( _object ) ;
debug ( " Packet::send: sending packet... " ) ;
2023-10-09 09:39:11 -06:00
if ( _object - > _sent ) {
2023-10-06 17:24:48 -06:00
throw std : : logic_error ( " Packet was already sent " ) ;
}
/*
if ( _destination - > type = = RNS : : Destination : : LINK ) {
2023-11-19 11:36:09 -07:00
if ( _destination - > status = = Type : : Link : : CLOSED ) {
2023-10-06 17:24:48 -06:00
throw std : : runtime_error ( " Attempt to transmit over a closed link " ) ;
}
else {
_destination - > last_outbound = time ( ) ;
_destination - > tx + = 1 ;
_destination - > txbytes + = _data_len ;
}
}
*/
2023-10-09 09:39:11 -06:00
if ( ! _object - > _packed ) {
2023-10-06 17:24:48 -06:00
pack ( ) ;
}
2023-11-19 11:36:09 -07:00
if ( Transport : : outbound ( * this ) ) {
2023-10-06 17:24:48 -06:00
debug ( " Packet::send: successfully sent packet!!! " ) ;
2023-11-19 08:51:10 -07:00
//zreturn self.receipt
2023-10-06 17:24:48 -06:00
// MOCK
return true ;
}
else {
error ( " No interfaces could process the outbound packet " ) ;
2023-10-09 09:39:11 -06:00
_object - > _sent = false ;
2023-10-06 17:24:48 -06:00
//z_receipt = None;
return false ;
}
}
/*
Re - sends the packet .
: returns : A : ref : ` RNS . PacketReceipt < api - packetreceipt > ` instance if * create_receipt * was set to * True * when the packet was instantiated , if not returns * None * . If the packet could not be sent * False * is returned .
*/
bool Packet : : resend ( ) {
assert ( _object ) ;
debug ( " Packet::resend: re-sending packet... " ) ;
2023-10-09 09:39:11 -06:00
if ( ! _object - > _sent ) {
2023-10-06 17:24:48 -06:00
throw std : : logic_error ( " Packet was not sent yet " ) ;
}
// Re-pack the packet to obtain new ciphertext for
// encrypted destinations
pack ( ) ;
2023-11-19 11:36:09 -07:00
if ( Transport : : outbound ( * this ) ) {
2023-10-06 17:24:48 -06:00
debug ( " Packet::resend: successfully sent packet!!! " ) ;
2023-11-19 08:51:10 -07:00
//zreturn self.receipt
2023-10-06 17:24:48 -06:00
// MOCK
return true ;
}
else {
error ( " No interfaces could process the outbound packet " ) ;
2023-10-09 09:39:11 -06:00
_object - > _sent = false ;
2023-10-06 17:24:48 -06:00
//zself.receipt = None;
return false ;
}
}
2023-11-20 10:51:56 -07:00
void Packet : : prove ( const Destination & destination /*= {Type::NONE}*/ ) {
2023-11-19 08:51:10 -07:00
/*
assert ( _object ) ;
if ( _object - > _fromPacked & & _object - > _destination ) {
if ( _object - > _destination . identity ( ) & & _object - > _destination . identity ( ) . prv ( ) ) {
_object - > _destination . identity ( ) . prove ( * this , _object - > _destination ) ;
}
}
else if ( _object - > _fromPacked & & _object - > _link ) {
_object - > _link . prove_packet ( * this ) ;
}
else {
error ( " Could not prove packet associated with neither a destination nor a link " ) ;
}
*/
}
2023-10-06 17:24:48 -06:00
void Packet : : update_hash ( ) {
assert ( _object ) ;
2023-10-09 09:39:11 -06:00
_object - > _packet_hash = get_hash ( ) ;
2023-10-06 17:24:48 -06:00
}
2023-11-19 08:51:10 -07:00
const Bytes Packet : : get_hash ( ) const {
2023-10-06 17:24:48 -06:00
assert ( _object ) ;
Bytes hashable_part = get_hashable_part ( ) ;
return Identity : : full_hash ( hashable_part ) ;
}
2023-11-19 08:51:10 -07:00
const Bytes Packet : : getTruncatedHash ( ) const {
2023-10-06 17:24:48 -06:00
assert ( _object ) ;
Bytes hashable_part = get_hashable_part ( ) ;
return Identity : : truncated_hash ( hashable_part ) ;
}
2023-11-19 08:51:10 -07:00
const Bytes Packet : : get_hashable_part ( ) const {
2023-10-06 17:24:48 -06:00
assert ( _object ) ;
Bytes hashable_part ;
2023-10-09 09:39:11 -06:00
hashable_part < < ( uint8_t ) ( _object - > _raw . data ( ) [ 0 ] & 0b00001111 ) ;
2023-11-19 11:36:09 -07:00
if ( _object - > _header_type = = HEADER_2 ) {
2023-10-08 23:59:43 -06:00
//hashable_part += self.raw[(RNS.Identity.TRUNCATED_HASHLENGTH//8)+2:]
2023-11-19 11:36:09 -07:00
hashable_part < < _object - > _raw . mid ( ( Type : : Identity : : TRUNCATED_HASHLENGTH / 8 ) + 2 ) ;
2023-10-08 23:59:43 -06:00
}
else {
//hashable_part += self.raw[2:];
2023-10-09 09:39:11 -06:00
hashable_part < < _object - > _raw . mid ( 2 ) ;
2023-10-08 23:59:43 -06:00
}
2023-10-06 17:24:48 -06:00
return hashable_part ;
}
2023-10-07 15:03:21 -06:00
// Generates a special destination that allows Reticulum
// to direct the proof back to the proved packet's sender
2023-11-20 10:51:56 -07:00
//ProofDestination& Packet::generate_proof_destination() {
2023-10-07 15:03:21 -06:00
// return ProofDestination();
//}
2023-10-08 23:59:43 -06:00
2023-11-19 08:51:10 -07:00
std : : string Packet : : debugString ( ) const {
2023-10-09 09:39:11 -06:00
if ( _object - > _packed ) {
2023-10-08 23:59:43 -06:00
//unpack();
}
std : : string dump ;
dump = " \n -------------------- \n " ;
2023-10-09 09:39:11 -06:00
dump + = " flags: " + hexFromByte ( _object - > _flags ) + " \n " ;
dump + = " header_type: " + std : : to_string ( _object - > _header_type ) + " \n " ;
dump + = " transport_type: " + std : : to_string ( _object - > _transport_type ) + " \n " ;
dump + = " destination_type: " + std : : to_string ( _object - > _destination_type ) + " \n " ;
dump + = " packet_type: " + std : : to_string ( _object - > _packet_type ) + " \n " ;
dump + = " hops: " + std : : to_string ( _object - > _hops ) + " \n " ;
dump + = " transport: " + _object - > _transport_id . toHex ( ) + " \n " ;
dump + = " destination: " + _object - > _destination_hash . toHex ( ) + " \n " ;
dump + = " context_type: " + std : : to_string ( _object - > _header_type ) + " \n " ;
dump + = " raw: " + _object - > _raw . toHex ( ) + " \n " ;
dump + = " length: " + std : : to_string ( _object - > _raw . size ( ) ) + " \n " ;
2023-11-19 08:51:10 -07:00
dump + = " data: " + _object - > _data . toHex ( ) + " \n " ;
dump + = " length: " + std : : to_string ( _object - > _data . size ( ) ) + " \n " ;
2023-10-09 09:39:11 -06:00
if ( _object - > _encrypted & & _object - > _raw . size ( ) > 0 ) {
2023-11-19 11:36:09 -07:00
size_t header_len = Type : : Reticulum : : HEADER_MINSIZE ;
2023-10-09 09:39:11 -06:00
if ( _object - > _header_type = = HEADER_2 ) {
2023-11-19 11:36:09 -07:00
header_len = Type : : Reticulum : : HEADER_MAXSIZE ;
2023-10-08 23:59:43 -06:00
}
2023-11-19 08:51:10 -07:00
dump + = " encrypted: \n " ;
2023-10-09 09:39:11 -06:00
dump + = " header: " + _object - > _raw . left ( header_len ) . toHex ( ) + " \n " ;
2023-11-19 11:36:09 -07:00
dump + = " key: " + _object - > _raw . mid ( header_len , Type : : Identity : : KEYSIZE / 8 / 2 ) . toHex ( ) + " \n " ;
Bytes ciphertext ( _object - > _raw . mid ( header_len + Type : : Identity : : KEYSIZE / 8 / 2 ) ) ;
2023-10-08 23:59:43 -06:00
dump + = " ciphertext: " + ciphertext . toHex ( ) + " \n " ;
dump + = " length: " + std : : to_string ( ciphertext . size ( ) ) + " \n " ;
dump + = " iv: " + ciphertext . left ( 16 ) . toHex ( ) + " \n " ;
dump + = " sig: " + ciphertext . right ( 32 ) . toHex ( ) + " \n " ;
dump + = " aes ciphertext: " + ciphertext . mid ( 16 , ciphertext . size ( ) - 48 ) . toHex ( ) + " \n " ;
dump + = " length: " + std : : to_string ( ciphertext . size ( ) - 48 ) + " \n " ;
}
dump + = " -------------------- \n " ;
return dump ;
}
2023-11-19 08:51:10 -07:00
void PacketReceipt : : check_timeout ( ) {
assert ( _object ) ;
if ( _object - > _status = = SENT & & is_timed_out ( ) ) {
if ( _object - > _timeout = = - 1 ) {
_object - > _status = CULLED ;
}
else {
_object - > _status = FAILED ;
}
_object - > _concluded_at = Utilities : : OS : : time ( ) ;
if ( _object - > _callbacks . _timeout ) {
//zthread = threading.Thread(target=self.callbacks.timeout, args=(self,))
//zthread.daemon = True
//zthread.start();
}
}
}