mirror of
https://github.com/RetroShare/RetroShare.git
synced 2024-12-27 08:29:26 -05:00
moved code of rsservicerserialiser into rsserializer.h/cc and renamed it into RsRawSerializer
This commit is contained in:
parent
e401b90e02
commit
14076de1e0
@ -699,7 +699,7 @@ pqiperson * pqipersongrpDummy::locked_createPerson(const RsPeerId& id, pqilisten
|
|||||||
NetBinDummy *d1 = new NetBinDummy(pqip, id, PQI_CONNECT_TCP);
|
NetBinDummy *d1 = new NetBinDummy(pqip, id, PQI_CONNECT_TCP);
|
||||||
|
|
||||||
RsSerialiser *rss = new RsSerialiser();
|
RsSerialiser *rss = new RsSerialiser();
|
||||||
rss->addSerialType(new RsServiceSerialiser());
|
rss->addSerialType(new RsRawSerialiser());
|
||||||
|
|
||||||
pqiconnect *pqic = new pqiconnect(pqip, rss, d1);
|
pqiconnect *pqic = new pqiconnect(pqip, rss, d1);
|
||||||
|
|
||||||
@ -709,7 +709,7 @@ pqiperson * pqipersongrpDummy::locked_createPerson(const RsPeerId& id, pqilisten
|
|||||||
NetBinDummy *d2 = new NetBinDummy(pqip, id, PQI_CONNECT_UDP);
|
NetBinDummy *d2 = new NetBinDummy(pqip, id, PQI_CONNECT_UDP);
|
||||||
|
|
||||||
RsSerialiser *rss2 = new RsSerialiser();
|
RsSerialiser *rss2 = new RsSerialiser();
|
||||||
rss2->addSerialType(new RsServiceSerialiser());
|
rss2->addSerialType(new RsRawSerialiser());
|
||||||
|
|
||||||
pqiconnect *pqic2 = new pqiconnect(pqip, rss2, d2);
|
pqiconnect *pqic2 = new pqiconnect(pqip, rss2, d2);
|
||||||
|
|
||||||
|
@ -87,7 +87,7 @@ pqiperson * pqisslpersongrp::locked_createPerson(const RsPeerId& id, pqilistener
|
|||||||
|
|
||||||
|
|
||||||
RsSerialiser *rss = new RsSerialiser();
|
RsSerialiser *rss = new RsSerialiser();
|
||||||
rss->addSerialType(new RsServiceSerialiser());
|
rss->addSerialType(new RsRawSerialiser());
|
||||||
|
|
||||||
pqiconnect *pqisc = new pqiconnect(pqip, rss, pqis);
|
pqiconnect *pqisc = new pqiconnect(pqip, rss, pqis);
|
||||||
|
|
||||||
@ -141,7 +141,7 @@ pqiperson * pqisslpersongrp::locked_createPerson(const RsPeerId& id, pqilistener
|
|||||||
ssl_tunnels[id] = pqis ; // keeps for getting crypt info per peer.
|
ssl_tunnels[id] = pqis ; // keeps for getting crypt info per peer.
|
||||||
|
|
||||||
RsSerialiser *rss = new RsSerialiser();
|
RsSerialiser *rss = new RsSerialiser();
|
||||||
rss->addSerialType(new RsServiceSerialiser());
|
rss->addSerialType(new RsRawSerialiser());
|
||||||
|
|
||||||
pqiconnect *pqisc = new pqiconnect(pqip, rss, pqis);
|
pqiconnect *pqisc = new pqiconnect(pqip, rss, pqis);
|
||||||
|
|
||||||
@ -151,7 +151,7 @@ pqiperson * pqisslpersongrp::locked_createPerson(const RsPeerId& id, pqilistener
|
|||||||
pqissludp *pqius = new pqissludp(pqip, mLinkMgr);
|
pqissludp *pqius = new pqissludp(pqip, mLinkMgr);
|
||||||
|
|
||||||
RsSerialiser *rss2 = new RsSerialiser();
|
RsSerialiser *rss2 = new RsSerialiser();
|
||||||
rss2->addSerialType(new RsServiceSerialiser());
|
rss2->addSerialType(new RsRawSerialiser());
|
||||||
|
|
||||||
pqiconnect *pqiusc = new pqiconnect(pqip, rss2, pqius);
|
pqiconnect *pqiusc = new pqiconnect(pqip, rss2, pqius);
|
||||||
|
|
||||||
|
@ -65,24 +65,7 @@ const uint8_t RS_PKT_CLASS_CONFIG = 0x02;
|
|||||||
const uint8_t RS_PKT_SUBTYPE_DEFAULT = 0x01; /* if only one subtype */
|
const uint8_t RS_PKT_SUBTYPE_DEFAULT = 0x01; /* if only one subtype */
|
||||||
|
|
||||||
class RsItem ;
|
class RsItem ;
|
||||||
|
class RsSerialType ;
|
||||||
class RsSerialType
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
RsSerialType(uint32_t t); /* only uses top 24bits */
|
|
||||||
RsSerialType(uint8_t ver, uint8_t cls, uint8_t t);
|
|
||||||
RsSerialType(uint8_t ver, uint16_t service);
|
|
||||||
|
|
||||||
virtual ~RsSerialType();
|
|
||||||
|
|
||||||
virtual uint32_t size(RsItem *);
|
|
||||||
virtual bool serialise (RsItem *item, void *data, uint32_t *size);
|
|
||||||
virtual RsItem * deserialise(void *data, uint32_t *size);
|
|
||||||
|
|
||||||
uint32_t PacketId() const;
|
|
||||||
private:
|
|
||||||
uint32_t type;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
class RsSerialiser
|
class RsSerialiser
|
||||||
|
@ -139,4 +139,77 @@ void RsGenericSerializer::print(RsItem *item)
|
|||||||
std::cerr << "******************************" << std::endl;
|
std::cerr << "******************************" << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint32_t RsRawSerialiser::size(RsItem *i)
|
||||||
|
{
|
||||||
|
RsRawItem *item = dynamic_cast<RsRawItem *>(i);
|
||||||
|
|
||||||
|
if (item)
|
||||||
|
{
|
||||||
|
return item->getRawLength();
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* serialise the data to the buffer */
|
||||||
|
bool RsRawSerialiser::serialise(RsItem *i, void *data, uint32_t *pktsize)
|
||||||
|
{
|
||||||
|
RsRawItem *item = dynamic_cast<RsRawItem *>(i);
|
||||||
|
if (!item)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef RSSERIAL_DEBUG
|
||||||
|
std::cerr << "RsRawSerialiser::serialise() serializing raw item. pktsize : " << *pktsize;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
uint32_t tlvsize = item->getRawLength();
|
||||||
|
#ifdef RSSERIAL_DEBUG
|
||||||
|
std::cerr << "tlvsize : " << tlvsize << std::endl;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (*pktsize < tlvsize)
|
||||||
|
return false; /* not enough space */
|
||||||
|
|
||||||
|
if (tlvsize > getRsPktMaxSize())
|
||||||
|
{
|
||||||
|
std::cerr << "(EE) Serialised packet is too big. Maximum allowed size is " << getRsPktMaxSize() << ". Serialised size is " << tlvsize << ". Please tune your service to correctly split packets" << std::endl;
|
||||||
|
return false; /* packet too big */
|
||||||
|
}
|
||||||
|
|
||||||
|
*pktsize = tlvsize;
|
||||||
|
|
||||||
|
/* its serialised already!!! */
|
||||||
|
memcpy(data, item->getRawData(), tlvsize);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
RsItem *RsRawSerialiser::deserialise(void *data, uint32_t *pktsize)
|
||||||
|
{
|
||||||
|
/* get the type and size */
|
||||||
|
uint32_t rstype = getRsItemId(data);
|
||||||
|
uint32_t rssize = getRsItemSize(data);
|
||||||
|
|
||||||
|
if (RS_PKT_VERSION_SERVICE != getRsItemVersion(rstype))
|
||||||
|
{
|
||||||
|
return NULL; /* wrong type */
|
||||||
|
}
|
||||||
|
|
||||||
|
if (*pktsize < rssize) /* check size */
|
||||||
|
return NULL; /* not enough data */
|
||||||
|
|
||||||
|
if (rssize > getRsPktMaxSize())
|
||||||
|
return NULL; /* packet too big */
|
||||||
|
|
||||||
|
/* set the packet length */
|
||||||
|
*pktsize = rssize;
|
||||||
|
|
||||||
|
RsRawItem *item = new RsRawItem(rstype, rssize);
|
||||||
|
void *item_data = item->getRawData();
|
||||||
|
|
||||||
|
memcpy(item_data, data, rssize);
|
||||||
|
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -1,5 +1,124 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Retroshare Serialization code //
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// Classes
|
||||||
|
// =======
|
||||||
|
//
|
||||||
|
// RsSerialiser ----------------+ std::map<uint32_t, RsSerialType*>
|
||||||
|
//
|
||||||
|
// RsSerialType
|
||||||
|
// |
|
||||||
|
// +----------- RsRawSerializer
|
||||||
|
// |
|
||||||
|
// +----------- RsGenericSerializer
|
||||||
|
// |
|
||||||
|
// +----------- RsConfigSerializer
|
||||||
|
// | |
|
||||||
|
// | +----------- Specific config serializers
|
||||||
|
// | +----------- ...
|
||||||
|
// |
|
||||||
|
// +----------- RsServiceSerializer
|
||||||
|
// |
|
||||||
|
// +----------- Specific service serializers
|
||||||
|
// +----------- ...
|
||||||
|
// +----------- ...
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// Steps to derive a serializer for a new service:
|
||||||
|
// ==============================================
|
||||||
|
//
|
||||||
|
// 1 - create a serializer class, and overload create_item() to create a new item of your own service for each item type constant:
|
||||||
|
//
|
||||||
|
// class MyServiceSerializer: public RsServiceSerializer
|
||||||
|
// {
|
||||||
|
// MyServiceSerializer() : RsServiceSerializer(MY_SERVICE_IDENTIFIER) {}
|
||||||
|
//
|
||||||
|
// RsItem *create_item(uint16_t service,uint8_t item_subtype)
|
||||||
|
// {
|
||||||
|
// if(service != MY_SERVICE_IDENTIFIER) return NULL ;
|
||||||
|
//
|
||||||
|
// switch(item_subtype)
|
||||||
|
// {
|
||||||
|
// case MY_ITEM_SUBTYPE_01: return new MyServiceItem();
|
||||||
|
// default:
|
||||||
|
// return NULL ;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// 2 - create your own items, and overload serial_process in order to define the serialized structure:
|
||||||
|
//
|
||||||
|
// class MyServiceItem: public RsItem
|
||||||
|
// {
|
||||||
|
// virtual void serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx)
|
||||||
|
// {
|
||||||
|
// RsTypeSerializer::serial_process<uint32_t> (j,ctx,count,"count") ; // uint32_t is not really needed here, except for explicitly avoiding int types convertion
|
||||||
|
// RsTypeSerializer::serial_process (j,ctx,update_times,"update_times") ; // will serialize the map and its content
|
||||||
|
// RsTypeSerializer::serial_process<RsTlvItem>(j,ctx,key,"key") ; // note the explicit call to TlvItem
|
||||||
|
// RsTypeSerializer::serial_process (j,ctx,dh_key,"dh_key") ; // template will automatically require serialise/deserialise/size/print_data for your type
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// private:
|
||||||
|
// uint32_t count ; // example of an int type. All int sizes are supported
|
||||||
|
// std::map<uint32_t,time_t> update_times ; // example of a std::map. All std containers are supported.
|
||||||
|
// RsTlvSecurityKey key ; // example of a TlvItem class.
|
||||||
|
// BIGNUM *dh_key; // example of a class that needs its own serializer (see below)
|
||||||
|
// };
|
||||||
|
//
|
||||||
|
// Some types may not be already handled by RsTypeSerializer, so in this case, you need to specialise the template for your own type. But this is quite unlikely to
|
||||||
|
// happen. In most cases, for instance in your structure types, serialization is directly done by calling RsTypeSerializer::serial_process() on each member of the type.
|
||||||
|
// In case you really need a specific serialization for soe particular type, here is how to do it, with the example of BIGNUM* (a crypto primitive):
|
||||||
|
//
|
||||||
|
// template<> bool RsTypeSerializer::serialize(uint8_t data[], uint32_t size, uint32_t &offset, BIGNUM * const & member)
|
||||||
|
// {
|
||||||
|
// uint32_t s = BN_num_bytes(member) ;
|
||||||
|
//
|
||||||
|
// if(size < offset + 4 + s)
|
||||||
|
// return false ;
|
||||||
|
//
|
||||||
|
// bool ok = true ;
|
||||||
|
// ok &= setRawUInt32(data, size, &offset, s);
|
||||||
|
//
|
||||||
|
// BN_bn2bin(member,&((unsigned char *)data)[offset]) ;
|
||||||
|
// offset += s ;
|
||||||
|
//
|
||||||
|
// return ok;
|
||||||
|
// }
|
||||||
|
// template<> bool RsTypeSerializer::deserialize(const uint8_t data[], uint32_t size, uint32_t &offset, BIGNUM *& member)
|
||||||
|
// {
|
||||||
|
// uint32_t s=0 ;
|
||||||
|
// bool ok = true ;
|
||||||
|
// ok &= getRawUInt32(data, size, &offset, &s);
|
||||||
|
//
|
||||||
|
// if(s > size || size - s < offset)
|
||||||
|
// return false ;
|
||||||
|
//
|
||||||
|
// member = BN_bin2bn(&((unsigned char *)data)[offset],s,NULL) ;
|
||||||
|
// offset += s ;
|
||||||
|
//
|
||||||
|
// return ok;
|
||||||
|
// }
|
||||||
|
// template<> uint32_t RsTypeSerializer::serial_size(BIGNUM * const & member)
|
||||||
|
// {
|
||||||
|
// return 4 + BN_num_bytes(member) ;
|
||||||
|
// }
|
||||||
|
// template<> void RsTypeSerializer::print_data(const std::string& name,BIGNUM * const & /* member */)
|
||||||
|
// {
|
||||||
|
// std::cerr << "[BIGNUM] : " << name << std::endl;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// 3 - in your service, overload the serialiser declaration to add your own:
|
||||||
|
//
|
||||||
|
// MyService::MyService()
|
||||||
|
// {
|
||||||
|
// addSerialType(new MyServiceSerializer()) ;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// 4 - in your service, recieve and send items by calling recvItem() and sendItem() respectively.
|
||||||
|
//
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
@ -12,6 +131,36 @@ class RsItem ;
|
|||||||
|
|
||||||
#define SERIALIZE_ERROR() std::cerr << __PRETTY_FUNCTION__ << " : "
|
#define SERIALIZE_ERROR() std::cerr << __PRETTY_FUNCTION__ << " : "
|
||||||
|
|
||||||
|
class RsSerialType
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
RsSerialType(uint32_t t); /* only uses top 24bits */
|
||||||
|
RsSerialType(uint8_t ver, uint8_t cls, uint8_t t);
|
||||||
|
RsSerialType(uint8_t ver, uint16_t service);
|
||||||
|
|
||||||
|
virtual ~RsSerialType();
|
||||||
|
|
||||||
|
virtual uint32_t size(RsItem *)=0;
|
||||||
|
virtual bool serialise (RsItem *item, void *data, uint32_t *size)=0;
|
||||||
|
virtual RsItem * deserialise(void *data, uint32_t *size)=0;
|
||||||
|
|
||||||
|
uint32_t PacketId() const;
|
||||||
|
private:
|
||||||
|
uint32_t type;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class RsRawSerialiser: public RsSerialType
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
RsRawSerialiser() :RsSerialType(RS_PKT_VERSION_SERVICE, 0, 0) {}
|
||||||
|
virtual ~RsRawSerialiser() { }
|
||||||
|
|
||||||
|
virtual uint32_t size(RsItem *);
|
||||||
|
virtual bool serialise (RsItem *item, void *data, uint32_t *size);
|
||||||
|
virtual RsItem * deserialise(void *data, uint32_t *size);
|
||||||
|
};
|
||||||
|
|
||||||
class RsGenericSerializer: public RsSerialType
|
class RsGenericSerializer: public RsSerialType
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@ -109,4 +258,3 @@ public:
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -26,78 +26,4 @@
|
|||||||
#include "rsitems/rsitem.h"
|
#include "rsitems/rsitem.h"
|
||||||
#include "rsserviceserialiser.h"
|
#include "rsserviceserialiser.h"
|
||||||
|
|
||||||
uint32_t RsServiceSerialiser::size(RsItem *i)
|
|
||||||
{
|
|
||||||
RsRawItem *item = dynamic_cast<RsRawItem *>(i);
|
|
||||||
|
|
||||||
if (item)
|
|
||||||
{
|
|
||||||
return item->getRawLength();
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* serialise the data to the buffer */
|
|
||||||
bool RsServiceSerialiser::serialise(RsItem *i, void *data, uint32_t *pktsize)
|
|
||||||
{
|
|
||||||
RsRawItem *item = dynamic_cast<RsRawItem *>(i);
|
|
||||||
if (!item)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef RSSERIAL_DEBUG
|
|
||||||
std::cerr << "RsServiceSerialiser::serialise() serializing raw item. pktsize : " << *pktsize;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
uint32_t tlvsize = item->getRawLength();
|
|
||||||
#ifdef RSSERIAL_DEBUG
|
|
||||||
std::cerr << "tlvsize : " << tlvsize << std::endl;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (*pktsize < tlvsize)
|
|
||||||
return false; /* not enough space */
|
|
||||||
|
|
||||||
if (tlvsize > getRsPktMaxSize())
|
|
||||||
{
|
|
||||||
std::cerr << "(EE) Serialised packet is too big. Maximum allowed size is " << getRsPktMaxSize() << ". Serialised size is " << tlvsize << ". Please tune your service to correctly split packets" << std::endl;
|
|
||||||
return false; /* packet too big */
|
|
||||||
}
|
|
||||||
|
|
||||||
*pktsize = tlvsize;
|
|
||||||
|
|
||||||
/* its serialised already!!! */
|
|
||||||
memcpy(data, item->getRawData(), tlvsize);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
RsItem *RsServiceSerialiser::deserialise(void *data, uint32_t *pktsize)
|
|
||||||
{
|
|
||||||
/* get the type and size */
|
|
||||||
uint32_t rstype = getRsItemId(data);
|
|
||||||
uint32_t rssize = getRsItemSize(data);
|
|
||||||
|
|
||||||
if (RS_PKT_VERSION_SERVICE != getRsItemVersion(rstype))
|
|
||||||
{
|
|
||||||
return NULL; /* wrong type */
|
|
||||||
}
|
|
||||||
|
|
||||||
if (*pktsize < rssize) /* check size */
|
|
||||||
return NULL; /* not enough data */
|
|
||||||
|
|
||||||
if (rssize > getRsPktMaxSize())
|
|
||||||
return NULL; /* packet too big */
|
|
||||||
|
|
||||||
/* set the packet length */
|
|
||||||
*pktsize = rssize;
|
|
||||||
|
|
||||||
RsRawItem *item = new RsRawItem(rstype, rssize);
|
|
||||||
void *item_data = item->getRawData();
|
|
||||||
|
|
||||||
memcpy(item_data, data, rssize);
|
|
||||||
|
|
||||||
return item;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -27,14 +27,4 @@
|
|||||||
|
|
||||||
#include "rsserial.h"
|
#include "rsserial.h"
|
||||||
|
|
||||||
class RsServiceSerialiser: public RsSerialType
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
RsServiceSerialiser() :RsSerialType(RS_PKT_VERSION_SERVICE, 0, 0) { }
|
|
||||||
virtual ~RsServiceSerialiser() { }
|
|
||||||
|
|
||||||
virtual uint32_t size(RsItem *);
|
|
||||||
virtual bool serialise (RsItem *item, void *data, uint32_t *size);
|
|
||||||
virtual RsItem * deserialise(void *data, uint32_t *size);
|
|
||||||
};
|
|
||||||
|
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
#include "serialization/rsserializer.h"
|
#include "serialiser/rsserializer.h"
|
||||||
#include "serialization/rstypeserializer.h"
|
#include "serialiser/rstypeserializer.h"
|
||||||
|
|
||||||
#include "serialiser/rsbaseserial.h"
|
#include "serialiser/rsbaseserial.h"
|
||||||
#include "serialiser/rstlvkeys.h"
|
#include "serialiser/rstlvkeys.h"
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user