mirror of
https://github.com/RetroShare/RetroShare.git
synced 2024-10-01 02:35:48 -04:00
388 lines
16 KiB
C++
388 lines
16 KiB
C++
/*******************************************************************************
|
|
* libretroshare/src/turtle: rsturtleitem.h *
|
|
* *
|
|
* libretroshare: retroshare core library *
|
|
* *
|
|
* Copyright 2009-2018 by Cyril Soler <csoler@users.sourceforge.net> *
|
|
* *
|
|
* This program is free software: you can redistribute it and/or modify *
|
|
* it under the terms of the GNU Lesser General Public License as *
|
|
* 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 *
|
|
* GNU Lesser General Public License for more details. *
|
|
* *
|
|
* You should have received a copy of the GNU Lesser General Public License *
|
|
* along with this program. If not, see <https://www.gnu.org/licenses/>. *
|
|
* *
|
|
*******************************************************************************/
|
|
#pragma once
|
|
|
|
#include "rsitems/rsserviceids.h"
|
|
#include "rsitems/rsitem.h"
|
|
#include "rsitems/itempriorities.h"
|
|
|
|
#include "serialiser/rsserial.h"
|
|
#include "serialiser/rstlvbase.h"
|
|
#include "serialiser/rsbaseserial.h"
|
|
|
|
#include "retroshare/rsturtle.h"
|
|
#include "retroshare/rsexpr.h"
|
|
#include "retroshare/rstypes.h"
|
|
#include "turtle/turtletypes.h"
|
|
|
|
#include "serialiser/rsserializer.h"
|
|
|
|
const uint8_t RS_TURTLE_SUBTYPE_STRING_SEARCH_REQUEST = 0x01 ;
|
|
const uint8_t RS_TURTLE_SUBTYPE_FT_SEARCH_RESULT = 0x02 ;
|
|
const uint8_t RS_TURTLE_SUBTYPE_OPEN_TUNNEL = 0x03 ;
|
|
const uint8_t RS_TURTLE_SUBTYPE_TUNNEL_OK = 0x04 ;
|
|
const uint8_t RS_TURTLE_SUBTYPE_FILE_REQUEST = 0x07 ;
|
|
const uint8_t RS_TURTLE_SUBTYPE_FILE_DATA = 0x08 ;
|
|
const uint8_t RS_TURTLE_SUBTYPE_REGEXP_SEARCH_REQUEST = 0x09 ;
|
|
const uint8_t RS_TURTLE_SUBTYPE_GENERIC_DATA = 0x0a ;
|
|
const uint8_t RS_TURTLE_SUBTYPE_GENERIC_SEARCH_REQUEST = 0x0b ;
|
|
const uint8_t RS_TURTLE_SUBTYPE_GENERIC_SEARCH_RESULT = 0x0c ;
|
|
const uint8_t RS_TURTLE_SUBTYPE_FILE_MAP = 0x10 ;
|
|
const uint8_t RS_TURTLE_SUBTYPE_FILE_MAP_REQUEST = 0x11 ;
|
|
// const uint8_t RS_TURTLE_SUBTYPE_FILE_CRC = 0x12 ; // unused
|
|
// const uint8_t RS_TURTLE_SUBTYPE_FILE_CRC_REQUEST = 0x13 ;
|
|
const uint8_t RS_TURTLE_SUBTYPE_CHUNK_CRC = 0x14 ;
|
|
const uint8_t RS_TURTLE_SUBTYPE_CHUNK_CRC_REQUEST = 0x15 ;
|
|
const uint8_t RS_TURTLE_SUBTYPE_GENERIC_FAST_DATA = 0x16 ;
|
|
|
|
|
|
class TurtleSearchRequestInfo ;
|
|
|
|
/***********************************************************************************/
|
|
/* Basic Turtle Item Class */
|
|
/***********************************************************************************/
|
|
|
|
class RsTurtleItem: public RsItem
|
|
{
|
|
public:
|
|
RsTurtleItem(uint8_t turtle_subtype) : RsItem(RS_PKT_VERSION_SERVICE,RS_SERVICE_TYPE_TURTLE,turtle_subtype) {}
|
|
};
|
|
|
|
/***********************************************************************************/
|
|
/* Turtle Search Item classes */
|
|
/* Specific packets */
|
|
/***********************************************************************************/
|
|
|
|
// Class hierarchy is
|
|
//
|
|
// RsTurtleItem
|
|
// |
|
|
// +---- RsTurtleSearchRequestItem
|
|
// | |
|
|
// | +---- RsTurtleFileSearchRequestItem
|
|
// | | |
|
|
// | | +---- RsTurtleStringSearchRequestItem
|
|
// | | |
|
|
// | | +---- RsTurtleReqExpSearchRequestItem
|
|
// | |
|
|
// | +---- RsTurtleGenericSearchRequestItem
|
|
// |
|
|
// +---- RsTurtleSearchResultItem
|
|
// |
|
|
// +---- RsTurtleFTSearchResultItem
|
|
// |
|
|
// +---- RsTurtleGenericSearchResultItem
|
|
//
|
|
|
|
class RsTurtleSearchResultItem ;
|
|
|
|
class RsTurtleSearchRequestItem: public RsTurtleItem
|
|
{
|
|
public:
|
|
RsTurtleSearchRequestItem(uint32_t subtype) : RsTurtleItem(subtype), request_id(0), depth(0) { setPriorityLevel(QOS_PRIORITY_RS_TURTLE_SEARCH_REQUEST) ;}
|
|
virtual ~RsTurtleSearchRequestItem() {}
|
|
|
|
virtual RsTurtleSearchRequestItem *clone() const = 0 ; // used for cloning in routing methods
|
|
|
|
virtual std::string GetKeywords() = 0;
|
|
virtual uint16_t serviceId() const= 0 ;
|
|
|
|
uint32_t request_id ; // randomly generated request id.
|
|
uint16_t depth ; // Used for limiting search depth.
|
|
};
|
|
|
|
class RsTurtleFileSearchRequestItem: public RsTurtleSearchRequestItem
|
|
{
|
|
public:
|
|
RsTurtleFileSearchRequestItem(uint32_t subtype) : RsTurtleSearchRequestItem(subtype) {}
|
|
virtual ~RsTurtleFileSearchRequestItem() {}
|
|
|
|
virtual uint16_t serviceId() const { return RS_SERVICE_TYPE_FILE_TRANSFER ; }
|
|
virtual void search(std::list<TurtleFileInfo> &) const =0;
|
|
};
|
|
|
|
class RsTurtleStringSearchRequestItem: public RsTurtleFileSearchRequestItem
|
|
{
|
|
public:
|
|
RsTurtleStringSearchRequestItem() : RsTurtleFileSearchRequestItem(RS_TURTLE_SUBTYPE_STRING_SEARCH_REQUEST) {}
|
|
virtual ~RsTurtleStringSearchRequestItem() {}
|
|
|
|
virtual void search(std::list<TurtleFileInfo> &) const ;
|
|
|
|
std::string match_string ; // string to match
|
|
std::string GetKeywords() { return match_string; }
|
|
|
|
virtual RsTurtleSearchRequestItem *clone() const { return new RsTurtleStringSearchRequestItem(*this) ; }
|
|
|
|
void clear() { match_string.clear() ; }
|
|
|
|
protected:
|
|
void serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx);
|
|
};
|
|
|
|
class RsTurtleRegExpSearchRequestItem: public RsTurtleFileSearchRequestItem
|
|
{
|
|
public:
|
|
RsTurtleRegExpSearchRequestItem() : RsTurtleFileSearchRequestItem(RS_TURTLE_SUBTYPE_REGEXP_SEARCH_REQUEST) {}
|
|
virtual ~RsTurtleRegExpSearchRequestItem() {}
|
|
|
|
RsRegularExpression::LinearizedExpression expr ; // Reg Exp in linearised mode
|
|
|
|
std::string GetKeywords()
|
|
{
|
|
RsRegularExpression::Expression *ex = RsRegularExpression::LinearizedExpression::toExpr(expr);
|
|
std::string exs = ex->toStdString();
|
|
delete ex;
|
|
return exs;
|
|
}
|
|
|
|
virtual void search(std::list<TurtleFileInfo> &) const ;
|
|
|
|
virtual RsTurtleSearchRequestItem *clone() const { return new RsTurtleRegExpSearchRequestItem(*this) ; }
|
|
void clear() { expr = RsRegularExpression::LinearizedExpression(); }
|
|
protected:
|
|
void serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx);
|
|
};
|
|
|
|
class RsTurtleGenericSearchRequestItem: public RsTurtleSearchRequestItem
|
|
{
|
|
public:
|
|
RsTurtleGenericSearchRequestItem()
|
|
: RsTurtleSearchRequestItem(RS_TURTLE_SUBTYPE_GENERIC_SEARCH_REQUEST),
|
|
service_id(0),
|
|
search_data_len(0),
|
|
request_type(0),
|
|
search_data(nullptr)
|
|
{}
|
|
virtual ~RsTurtleGenericSearchRequestItem() { clear(); }
|
|
|
|
uint16_t service_id ; // service to search
|
|
uint32_t search_data_len ;
|
|
uint8_t request_type ; // type of request. This is used to limit the number of responses.
|
|
unsigned char *search_data ;
|
|
|
|
std::string GetKeywords() ;
|
|
virtual uint16_t serviceId() const { return service_id ; }
|
|
|
|
virtual RsTurtleSearchRequestItem *clone() const ;
|
|
virtual uint32_t requestType() const { return request_type; }
|
|
|
|
void clear() { free(search_data); search_data=NULL; search_data_len=0; }
|
|
|
|
protected:
|
|
void serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx);
|
|
|
|
private:
|
|
RsTurtleGenericSearchRequestItem(const RsTurtleGenericSearchRequestItem&); // make the object non copi-able.
|
|
RsTurtleGenericSearchRequestItem& operator=(const RsTurtleGenericSearchRequestItem&) { return *this;}
|
|
};
|
|
class RsTurtleSearchResultItem: public RsTurtleItem
|
|
{
|
|
public:
|
|
RsTurtleSearchResultItem(uint8_t subtype) : RsTurtleItem(subtype), request_id(0) { setPriorityLevel(QOS_PRIORITY_RS_TURTLE_SEARCH_RESULT) ;}
|
|
|
|
TurtleSearchRequestId request_id ; // Randomly generated request id.
|
|
|
|
virtual uint32_t count() const =0;
|
|
virtual void pop() =0;
|
|
|
|
virtual void serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx)=0;
|
|
virtual RsTurtleSearchResultItem *duplicate() const =0;
|
|
};
|
|
|
|
class RsTurtleFTSearchResultItem: public RsTurtleSearchResultItem
|
|
{
|
|
public:
|
|
RsTurtleFTSearchResultItem() : RsTurtleSearchResultItem(RS_TURTLE_SUBTYPE_FT_SEARCH_RESULT){}
|
|
|
|
std::list<TurtleFileInfo> result ;
|
|
|
|
void clear() { result.clear() ; }
|
|
uint32_t count() const { return result.size() ; }
|
|
virtual void pop() { result.pop_back() ;}
|
|
virtual RsTurtleSearchResultItem *duplicate() const { return new RsTurtleFTSearchResultItem(*this) ; }
|
|
protected:
|
|
void serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx);
|
|
};
|
|
|
|
class RsTurtleGenericSearchResultItem: public RsTurtleSearchResultItem
|
|
{
|
|
public:
|
|
RsTurtleGenericSearchResultItem()
|
|
: RsTurtleSearchResultItem(RS_TURTLE_SUBTYPE_GENERIC_SEARCH_RESULT),
|
|
result_data(nullptr),
|
|
result_data_len(0)
|
|
{}
|
|
virtual ~RsTurtleGenericSearchResultItem() {}
|
|
|
|
uint32_t count() const { return result_data_len/50 ; } // This is a blind size estimate. We should probably use the actual size to limit search results.
|
|
virtual void pop() {}
|
|
|
|
unsigned char *result_data ;
|
|
uint32_t result_data_len ;
|
|
|
|
virtual RsTurtleSearchResultItem *duplicate() const ;
|
|
void clear() { free(result_data); result_data=NULL; result_data_len=0; }
|
|
protected:
|
|
void serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx);
|
|
};
|
|
|
|
/***********************************************************************************/
|
|
/* Turtle Tunnel Item classes */
|
|
/***********************************************************************************/
|
|
|
|
class RsTurtleOpenTunnelItem: public RsTurtleItem
|
|
{
|
|
public:
|
|
RsTurtleOpenTunnelItem() : RsTurtleItem(RS_TURTLE_SUBTYPE_OPEN_TUNNEL), request_id(0), partial_tunnel_id(0), depth(0) { setPriorityLevel(QOS_PRIORITY_RS_TURTLE_OPEN_TUNNEL) ;}
|
|
|
|
TurtleFileHash file_hash ; // hash to match
|
|
uint32_t request_id ; // randomly generated request id.
|
|
uint32_t partial_tunnel_id ; // uncomplete tunnel id. Will be completed at destination.
|
|
uint16_t depth ; // Used for limiting search depth.
|
|
|
|
void clear() { file_hash.clear() ;}
|
|
protected:
|
|
void serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx);
|
|
};
|
|
|
|
class RsTurtleTunnelOkItem: public RsTurtleItem
|
|
{
|
|
public:
|
|
RsTurtleTunnelOkItem() : RsTurtleItem(RS_TURTLE_SUBTYPE_TUNNEL_OK), tunnel_id(0), request_id(0) { setPriorityLevel(QOS_PRIORITY_RS_TURTLE_TUNNEL_OK) ;}
|
|
|
|
uint32_t tunnel_id ; // id of the tunnel. Should be identical for a tunnel between two same peers for the same hash.
|
|
uint32_t request_id ; // randomly generated request id corresponding to the intial request.
|
|
|
|
void clear() {}
|
|
protected:
|
|
void serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx);
|
|
};
|
|
|
|
/***********************************************************************************/
|
|
/* Generic turtle packets for tunnels */
|
|
/***********************************************************************************/
|
|
|
|
class RsTurtleGenericTunnelItem: public RsTurtleItem
|
|
{
|
|
public:
|
|
RsTurtleGenericTunnelItem(uint8_t sub_packet_id) : RsTurtleItem(sub_packet_id), direction(0), tunnel_id(0) { setPriorityLevel(QOS_PRIORITY_RS_TURTLE_GENERIC_ITEM);}
|
|
virtual ~RsTurtleGenericTunnelItem() {}
|
|
|
|
typedef uint32_t Direction ;
|
|
static const Direction DIRECTION_CLIENT = 0x001 ;
|
|
static const Direction DIRECTION_SERVER = 0x002 ;
|
|
|
|
/// Does this packet stamps tunnels when it passes through ?
|
|
/// This is used for keeping trace weither tunnels are active or not.
|
|
|
|
virtual bool shouldStampTunnel() const = 0 ;
|
|
|
|
/// All tunnels derived from RsTurtleGenericTunnelItem should have a tunnel id to
|
|
/// indicate which tunnel they are travelling through.
|
|
|
|
virtual TurtleTunnelId tunnelId() const { return tunnel_id ; }
|
|
|
|
/// Indicate weither the packet is a client packet (goign back to the
|
|
/// client) or a server packet (going to the server. Typically file
|
|
/// requests are server packets, whereas file data are client packets.
|
|
|
|
virtual Direction travelingDirection() const { return direction ; }
|
|
virtual void setTravelingDirection(Direction d) { direction = d; }
|
|
|
|
Direction direction ; // This does not need to be serialised. It's only used by the client services, optionnally,
|
|
// and is set by the turtle router according to which direction the item travels.
|
|
|
|
uint32_t tunnel_id ; // Id of the tunnel to travel through
|
|
};
|
|
|
|
/***********************************************************************************/
|
|
/* Specific Turtle Transfer items */
|
|
/***********************************************************************************/
|
|
|
|
// This item can be used by any service to pass-on arbitrary data into a tunnel.
|
|
//
|
|
class RsTurtleGenericDataItem: public RsTurtleGenericTunnelItem
|
|
{
|
|
public:
|
|
RsTurtleGenericDataItem() : RsTurtleGenericTunnelItem(RS_TURTLE_SUBTYPE_GENERIC_DATA), data_size(0), data_bytes(0) { setPriorityLevel(QOS_PRIORITY_RS_TURTLE_GENERIC_DATA);}
|
|
virtual ~RsTurtleGenericDataItem() { if(data_bytes != NULL) free(data_bytes) ; }
|
|
|
|
virtual bool shouldStampTunnel() const { return true ; }
|
|
|
|
uint32_t data_size ;
|
|
void *data_bytes ;
|
|
|
|
void clear()
|
|
{
|
|
free(data_bytes) ;
|
|
data_bytes = NULL ;
|
|
data_size = 0;
|
|
}
|
|
protected:
|
|
void serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx);
|
|
};
|
|
|
|
// Same, but with a fact priority. Can rather be used for e.g. distant chat.
|
|
//
|
|
class RsTurtleGenericFastDataItem: public RsTurtleGenericTunnelItem
|
|
{
|
|
public:
|
|
RsTurtleGenericFastDataItem() : RsTurtleGenericTunnelItem(RS_TURTLE_SUBTYPE_GENERIC_FAST_DATA), data_size(0), data_bytes(0) { setPriorityLevel(QOS_PRIORITY_RS_TURTLE_GENERIC_FAST_DATA);}
|
|
virtual ~RsTurtleGenericFastDataItem() { if(data_bytes != NULL) free(data_bytes) ; }
|
|
|
|
virtual bool shouldStampTunnel() const { return true ; }
|
|
|
|
uint32_t data_size ;
|
|
void *data_bytes ;
|
|
|
|
void clear()
|
|
{
|
|
free(data_bytes) ;
|
|
data_bytes = NULL ;
|
|
data_size = 0;
|
|
}
|
|
protected:
|
|
void serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx);
|
|
};
|
|
/***********************************************************************************/
|
|
/* Turtle Serialiser class */
|
|
/***********************************************************************************/
|
|
|
|
class RsTurtleSerialiser: public RsServiceSerializer
|
|
{
|
|
public:
|
|
RsTurtleSerialiser() : RsServiceSerializer(RS_SERVICE_TYPE_TURTLE) {}
|
|
|
|
virtual RsItem *create_item(uint16_t service,uint8_t item_subtype) const;
|
|
|
|
// This is used by the turtle router to add services to its serialiser.
|
|
// Client services are only used for deserialising, since the serialisation is
|
|
// performed using the overloaded virtual functions above.
|
|
//
|
|
void registerClientService(RsTurtleClientService *service) { _client_services.push_back(service) ; }
|
|
|
|
private:
|
|
std::vector<RsTurtleClientService *> _client_services ;
|
|
};
|
|
|