2018-05-22 16:03:11 -04:00
/*******************************************************************************
* libretroshare / src / grouter : grouteritems . cc *
* *
* libretroshare : retroshare core library *
* *
* Copyright 2013 by Cyril Soler < csoler @ users . sourceforge . net > *
* *
* This program is free software : you can redistribute it and / or modify *
2018-05-28 16:03:39 -04:00
* it under the terms of the GNU Lesser General Public License as *
2018-05-22 16:03:11 -04:00
* published by the Free Software Foundation , either version 3 of the *
* License , or ( at your option ) any later version . *
* *
* This program is distributed in the hope that it will be useful , *
* but WITHOUT ANY WARRANTY ; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the *
2018-05-28 16:03:39 -04:00
* GNU Lesser General Public License for more details . *
2018-05-22 16:03:11 -04:00
* *
2018-05-28 16:03:39 -04:00
* You should have received a copy of the GNU Lesser General Public License *
2018-05-22 16:03:11 -04:00
* along with this program . If not , see < https : //www.gnu.org/licenses/>. *
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2017-04-25 15:21:46 -04:00
# include "util/rsprint.h"
2013-11-02 10:35:33 -04:00
# include "serialiser/rsbaseserial.h"
# include "serialiser/rstlvbase.h"
# include "grouteritems.h"
2017-04-30 10:05:37 -04:00
# include "serialiser/rstypeserializer.h"
2017-04-26 05:40:46 -04:00
2013-11-02 10:35:33 -04:00
/**********************************************************************************************/
2017-04-25 15:21:46 -04:00
/* SERIALISER STUFF */
2013-11-02 10:35:33 -04:00
/**********************************************************************************************/
2017-04-25 15:21:46 -04:00
RsItem * RsGRouterSerialiser : : create_item ( uint16_t service_id , uint8_t subtype ) const
2013-11-02 10:35:33 -04:00
{
2017-04-25 15:21:46 -04:00
if ( RS_SERVICE_TYPE_GROUTER ! = service_id )
return NULL ; /* wrong type */
2013-11-02 10:35:33 -04:00
2017-04-25 15:21:46 -04:00
switch ( subtype )
2013-11-02 10:35:33 -04:00
{
2017-04-25 15:21:46 -04:00
case RS_PKT_SUBTYPE_GROUTER_DATA : return new RsGRouterGenericDataItem ( ) ;
case RS_PKT_SUBTYPE_GROUTER_TRANSACTION_CHUNK : return new RsGRouterTransactionChunkItem ( ) ;
case RS_PKT_SUBTYPE_GROUTER_TRANSACTION_ACKN : return new RsGRouterTransactionAcknItem ( ) ;
case RS_PKT_SUBTYPE_GROUTER_SIGNED_RECEIPT : return new RsGRouterSignedReceiptItem ( ) ;
case RS_PKT_SUBTYPE_GROUTER_MATRIX_CLUES : return new RsGRouterMatrixCluesItem ( ) ;
case RS_PKT_SUBTYPE_GROUTER_MATRIX_TRACK : return new RsGRouterMatrixTrackItem ( ) ;
case RS_PKT_SUBTYPE_GROUTER_FRIENDS_LIST : return new RsGRouterMatrixFriendListItem ( ) ;
case RS_PKT_SUBTYPE_GROUTER_ROUTING_INFO : return new RsGRouterRoutingInfoItem ( ) ;
2013-11-02 10:35:33 -04:00
2017-04-25 15:21:46 -04:00
default :
return NULL ;
}
2013-11-02 10:35:33 -04:00
}
2017-04-26 05:40:46 -04:00
void RsGRouterTransactionChunkItem : : serial_process ( RsGenericSerializer : : SerializeJob j , RsGenericSerializer : : SerializeContext & ctx )
2013-11-02 10:35:33 -04:00
{
2017-04-25 15:21:46 -04:00
RsTypeSerializer : : serial_process < uint64_t > ( j , ctx , propagation_id , " propagation_id " ) ;
RsTypeSerializer : : serial_process < uint32_t > ( j , ctx , chunk_start , " chunk_start " ) ;
RsTypeSerializer : : serial_process < uint32_t > ( j , ctx , chunk_size , " chunk_size " ) ;
RsTypeSerializer : : serial_process < uint32_t > ( j , ctx , total_size , " total_size " ) ;
2013-11-02 10:35:33 -04:00
2017-04-25 15:21:46 -04:00
// Hack for backward compatibility (the chunk size is not directly next to the chunk data)
2013-11-02 10:35:33 -04:00
2017-04-26 05:40:46 -04:00
if ( j = = RsGenericSerializer : : DESERIALIZE )
2013-11-02 10:35:33 -04:00
{
2017-04-25 15:21:46 -04:00
if ( chunk_size > ctx . mSize | | ctx . mOffset > ctx . mSize - chunk_size ) // better than if(chunk_size + offset > size)
{
std : : cerr < < __PRETTY_FUNCTION__ < < " : Cannot read beyond item size. Serialisation error! " < < std : : endl ;
ctx . mOk = false ;
return ;
}
if ( NULL = = ( chunk_data = ( uint8_t * ) rs_malloc ( chunk_size ) ) )
{
ctx . mOk = false ;
return ;
}
2015-10-25 18:07:17 -04:00
2017-04-25 15:21:46 -04:00
memcpy ( chunk_data , & ( ( uint8_t * ) ctx . mData ) [ ctx . mOffset ] , chunk_size ) ;
ctx . mOffset + = chunk_size ;
2013-11-02 10:35:33 -04:00
}
2017-04-26 05:40:46 -04:00
else if ( j = = RsGenericSerializer : : SERIALIZE )
2017-04-25 15:21:46 -04:00
{
memcpy ( & ( ( uint8_t * ) ctx . mData ) [ ctx . mOffset ] , chunk_data , chunk_size ) ;
ctx . mOffset + = chunk_size ;
}
2017-04-26 05:40:46 -04:00
else if ( j = = RsGenericSerializer : : SIZE_ESTIMATE )
2017-04-25 15:21:46 -04:00
ctx . mOffset + = chunk_size ;
else
std : : cerr < < " [Binary data] " < < " , length= " < < chunk_size < < " data= " < < RsUtil : : BinToHex ( ( uint8_t * ) chunk_data , std : : min ( 50u , chunk_size ) ) < < ( ( chunk_size > 50 ) ? " ... " : " " ) < < std : : endl ;
2013-11-02 10:35:33 -04:00
}
2017-04-26 05:40:46 -04:00
void RsGRouterTransactionAcknItem : : serial_process ( RsGenericSerializer : : SerializeJob j , RsGenericSerializer : : SerializeContext & ctx )
2017-04-25 15:21:46 -04:00
{
RsTypeSerializer : : serial_process < uint64_t > ( j , ctx , propagation_id , " propagation_id " ) ;
}
2017-04-26 05:40:46 -04:00
void RsGRouterGenericDataItem : : serial_process ( RsGenericSerializer : : SerializeJob j , RsGenericSerializer : : SerializeContext & ctx )
2017-04-25 15:21:46 -04:00
{
RsTypeSerializer : : serial_process < uint64_t > ( j , ctx , routing_id , " routing_id " ) ;
RsTypeSerializer : : serial_process ( j , ctx , destination_key , " destination_key " ) ;
RsTypeSerializer : : serial_process < uint32_t > ( j , ctx , service_id , " service_id " ) ;
RsTypeSerializer : : TlvMemBlock_proxy prox ( data_bytes , data_size ) ;
RsTypeSerializer : : serial_process ( j , ctx , prox , " data " ) ;
if ( ctx . mFlags & RsGenericSerializer : : SERIALIZATION_FLAG_SIGNATURE )
return ;
RsTypeSerializer : : serial_process < RsTlvItem > ( j , ctx , signature , " signature " ) ;
RsTypeSerializer : : serial_process < uint32_t > ( j , ctx , duplication_factor , " duplication_factor " ) ;
RsTypeSerializer : : serial_process < uint32_t > ( j , ctx , flags , " flags " ) ;
2017-04-26 05:40:46 -04:00
if ( j = = RsGenericSerializer : : DESERIALIZE ) // make sure the duplication factor is not altered by friends. In the worst case, the item will duplicate a bit more.
2017-04-25 15:21:46 -04:00
{
if ( duplication_factor < 1 )
{
duplication_factor = 1 ;
std : : cerr < < " (II) correcting GRouter item duplication factor from 0 to 1, to ensure backward compat. " < < std : : endl ;
}
if ( duplication_factor > GROUTER_MAX_DUPLICATION_FACTOR )
{
std : : cerr < < " (WW) correcting GRouter item duplication factor of " < < duplication_factor < < " . This is very unexpected. " < < std : : endl ;
duplication_factor = GROUTER_MAX_DUPLICATION_FACTOR ;
}
}
}
2017-04-26 05:40:46 -04:00
void RsGRouterSignedReceiptItem : : serial_process ( RsGenericSerializer : : SerializeJob j , RsGenericSerializer : : SerializeContext & ctx )
2017-04-25 15:21:46 -04:00
{
RsTypeSerializer : : serial_process < uint64_t > ( j , ctx , routing_id , " routing_id " ) ;
RsTypeSerializer : : serial_process < uint32_t > ( j , ctx , flags , " flags " ) ;
RsTypeSerializer : : serial_process ( j , ctx , destination_key , " destination_key " ) ;
RsTypeSerializer : : serial_process < uint32_t > ( j , ctx , service_id , " service_id " ) ;
RsTypeSerializer : : serial_process ( j , ctx , data_hash , " data_hash " ) ;
2013-11-02 10:35:33 -04:00
2017-04-25 15:21:46 -04:00
if ( ctx . mFlags & RsGenericSerializer : : SERIALIZATION_FLAG_SIGNATURE )
return ;
RsTypeSerializer : : serial_process < RsTlvItem > ( j , ctx , signature , " signature " ) ;
}
2017-04-26 05:40:46 -04:00
void RsGRouterRoutingInfoItem : : serial_process ( RsGenericSerializer : : SerializeJob j , RsGenericSerializer : : SerializeContext & ctx )
2017-04-25 15:21:46 -04:00
{
RsTypeSerializer : : serial_process ( j , ctx , peerId , " peerId " ) ;
RsTypeSerializer : : serial_process < uint32_t > ( j , ctx , data_status , " data_status " ) ;
RsTypeSerializer : : serial_process < uint32_t > ( j , ctx , tunnel_status , " tunnel_status " ) ;
2018-10-06 19:34:05 -04:00
RsTypeSerializer : : serial_process < rstime_t > ( j , ctx , received_time_TS , " received_time_TS " ) ;
RsTypeSerializer : : serial_process < rstime_t > ( j , ctx , last_sent_TS , " last_sent_TS " ) ;
2017-04-25 15:21:46 -04:00
2018-10-06 19:34:05 -04:00
RsTypeSerializer : : serial_process < rstime_t > ( j , ctx , last_tunnel_request_TS , " last_tunnel_request_TS " ) ;
2017-04-25 15:21:46 -04:00
RsTypeSerializer : : serial_process < uint32_t > ( j , ctx , sending_attempts , " sending_attempts " ) ;
RsTypeSerializer : : serial_process < uint32_t > ( j , ctx , client_id , " client_id " ) ;
RsTypeSerializer : : serial_process ( j , ctx , item_hash , " item_hash " ) ;
RsTypeSerializer : : serial_process ( j , ctx , tunnel_hash , " tunnel_hash " ) ;
RsTypeSerializer : : serial_process < uint32_t > ( j , ctx , routing_flags , " routing_flags " ) ;
RsTypeSerializer : : serial_process < RsTlvItem > ( j , ctx , incoming_routes , " incoming_routes " ) ;
// Hack for backward compatibility. Normally we should need a single commandline to serialise/deserialise a single item here.
// But the full item is serialised, so we need the header.
2017-04-26 05:40:46 -04:00
if ( j = = RsGenericSerializer : : DESERIALIZE )
2017-04-25 15:21:46 -04:00
{
data_item = new RsGRouterGenericDataItem ( ) ;
ctx . mOffset + = 8 ;
data_item - > serial_process ( j , ctx ) ;
if ( ctx . mOffset < ctx . mSize )
{
receipt_item = new RsGRouterSignedReceiptItem ( ) ;
ctx . mOffset + = 8 ;
receipt_item - > serial_process ( j , ctx ) ;
}
else
receipt_item = NULL ;
}
2017-04-26 05:40:46 -04:00
else if ( j = = RsGenericSerializer : : SERIALIZE )
2017-04-25 15:21:46 -04:00
{
uint32_t remaining_size = ctx . mSize - ctx . mOffset ;
ctx . mOk = ctx . mOk & & RsGRouterSerialiser ( ) . serialise ( data_item , ctx . mData , & remaining_size ) ;
ctx . mOffset + = RsGRouterSerialiser ( ) . size ( data_item ) ;
if ( receipt_item ! = NULL )
{
remaining_size = ctx . mSize - ctx . mOffset ;
2017-04-26 05:40:46 -04:00
ctx . mOk = ctx . mOk & & RsGRouterSerialiser ( ) . serialise ( receipt_item , ctx . mData , & remaining_size ) ;
ctx . mOffset + = RsGRouterSerialiser ( ) . size ( receipt_item ) ;
2017-04-25 15:21:46 -04:00
}
}
2017-04-26 05:40:46 -04:00
else if ( j = = RsGenericSerializer : : PRINT )
2017-04-25 15:21:46 -04:00
{
std : : cerr < < " [Serialized data] " < < std : : endl ;
if ( receipt_item ! = NULL )
std : : cerr < < " [Receipt item ] " < < std : : endl ;
}
2017-04-26 05:40:46 -04:00
else if ( j = = RsGenericSerializer : : SIZE_ESTIMATE )
2017-04-25 15:21:46 -04:00
{
ctx . mOffset + = RsGRouterSerialiser ( ) . size ( data_item ) ;
if ( receipt_item ! = NULL )
ctx . mOffset + = RsGRouterSerialiser ( ) . size ( receipt_item ) ;
}
}
2013-11-02 10:35:33 -04:00
2017-04-26 05:40:46 -04:00
void RsGRouterMatrixFriendListItem : : serial_process ( RsGenericSerializer : : SerializeJob j , RsGenericSerializer : : SerializeContext & ctx )
2017-04-25 15:21:46 -04:00
{
RsTypeSerializer : : serial_process ( j , ctx , reverse_friend_indices , " reverse_friend_indices " ) ;
}
2017-04-26 05:40:46 -04:00
void RsGRouterMatrixTrackItem : : serial_process ( RsGenericSerializer : : SerializeJob j , RsGenericSerializer : : SerializeContext & ctx )
2017-04-25 15:21:46 -04:00
{
RsTypeSerializer : : serial_process ( j , ctx , provider_id , " provider_id " ) ;
RsTypeSerializer : : serial_process ( j , ctx , message_id , " message_id " ) ;
2018-10-06 19:34:05 -04:00
RsTypeSerializer : : serial_process < rstime_t > ( j , ctx , time_stamp , " time_stamp " ) ;
2017-04-25 15:21:46 -04:00
}
2015-10-25 18:07:17 -04:00
2017-04-26 05:40:46 -04:00
void RsGRouterMatrixCluesItem : : serial_process ( RsGenericSerializer : : SerializeJob j , RsGenericSerializer : : SerializeContext & ctx )
2017-04-25 15:21:46 -04:00
{
RsTypeSerializer : : serial_process ( j , ctx , destination_key , " destination_key " ) ;
RsTypeSerializer : : serial_process ( j , ctx , clues , " clues " ) ;
}
2017-04-26 05:40:46 -04:00
template < > void RsTypeSerializer : : serial_process ( RsGenericSerializer : : SerializeJob j , RsGenericSerializer : : SerializeContext & ctx , RoutingMatrixHitEntry & s , const std : : string & name )
2017-04-25 15:21:46 -04:00
{
RsTypeSerializer : : serial_process < uint32_t > ( j , ctx , s . friend_id , name + " :friend_id " ) ;
RsTypeSerializer : : serial_process < float > ( j , ctx , s . weight , name + " :weight " ) ;
2018-10-06 19:34:05 -04:00
RsTypeSerializer : : serial_process < rstime_t > ( j , ctx , s . time_stamp , name + " :time_stamp " ) ;
2017-04-25 15:21:46 -04:00
}
2013-12-22 12:04:13 -05:00
RsGRouterGenericDataItem * RsGRouterGenericDataItem : : duplicate ( ) const
{
2015-01-22 09:33:19 -05:00
RsGRouterGenericDataItem * item = new RsGRouterGenericDataItem ;
2013-12-27 15:06:47 -05:00
2015-01-22 09:33:19 -05:00
// copy all members
2013-12-22 12:04:13 -05:00
2015-01-22 09:33:19 -05:00
* item = * this ;
2013-12-22 12:04:13 -05:00
2015-01-22 09:33:19 -05:00
// then duplicate the memory chunk
2013-12-22 12:04:13 -05:00
2016-01-13 00:13:16 -05:00
if ( data_size > 0 )
{
item - > data_bytes = ( uint8_t * ) rs_malloc ( data_size ) ;
2016-01-13 12:22:55 -05:00
if ( item - > data_bytes = = NULL )
{
delete item ;
return NULL ;
}
2016-01-13 00:13:16 -05:00
memcpy ( item - > data_bytes , data_bytes , data_size ) ;
}
else
item - > data_bytes = NULL ;
2015-01-11 17:18:28 -05:00
2015-01-22 09:33:19 -05:00
return item ;
}
RsGRouterSignedReceiptItem * RsGRouterSignedReceiptItem : : duplicate ( ) const
{
RsGRouterSignedReceiptItem * item = new RsGRouterSignedReceiptItem ;
// copy all members
* item = * this ;
2013-12-22 12:04:13 -05:00
2015-01-11 17:18:28 -05:00
return item ;
}
2017-04-25 15:21:46 -04:00