Added ability for turtle router to take client services

- new class RsTurtleClientService, from which should inherit the services
- turtle serialisation takes client services for deserialising
- added a client to p3turtle::monitorTunnels()
- added a generic turtle item to pass on arbitrary data

Moved ftServer as a subclass of RsTurtleClientService. 
- moved file transfer items that inherited from RsTurtleGenericTunnelItem into a separate file
- moved deserialisation triage into ftServer
- moved sending/receiving methods in ftServer (much less code, much more consistent!)

One bug remains: the TR cannot work as a server.

Changes should be 100% backward compatible.



git-svn-id: http://svn.code.sf.net/p/retroshare/code/branches/v0.5-GenericTunneling@6293 b45a01b8-16f6-495d-af2f-9b41ad6348cc
This commit is contained in:
csoler 2013-04-06 09:21:01 +00:00
parent 270abcdc94
commit 0abb21d962
14 changed files with 1278 additions and 1504 deletions

View File

@ -47,6 +47,7 @@
#include "ft/ftsearch.h"
#include "ft/ftdatamultiplex.h"
#include "ft/ftextralist.h"
#include "ft/ftserver.h"
#include "turtle/p3turtle.h"
@ -101,6 +102,7 @@ ftController::ftController(CacheStrapper *cs, ftDataMultiplex *dm, std::string /
last_clean_time(0),
mDataplex(dm),
mTurtle(NULL),
mFtServer(NULL),
ctrlMutex("ftController"),
doneMutex("ftController"),
mFtActive(false),
@ -111,10 +113,9 @@ ftController::ftController(CacheStrapper *cs, ftDataMultiplex *dm, std::string /
/* TODO */
}
void ftController::setTurtleRouter(p3turtle *pt)
{
mTurtle = pt ;
}
void ftController::setTurtleRouter(p3turtle *pt) { mTurtle = pt ; }
void ftController::setFtServer(ftServer *ft) { mFtServer = ft ; }
void ftController::setFtSearchNExtra(ftSearch *search, ftExtraList *list)
{
mSearch = search;
@ -644,7 +645,7 @@ void ftController::locked_checkQueueElement(uint32_t pos)
_queue[pos]->mState = ftFileControl::DOWNLOADING ;
if(_queue[pos]->mFlags & RS_FILE_REQ_ANONYMOUS_ROUTING)
mTurtle->monitorTunnels(_queue[pos]->mHash) ;
mTurtle->monitorTunnels(_queue[pos]->mHash,mFtServer) ;
}
if(pos >= _max_active_downloads && _queue[pos]->mState != ftFileControl::QUEUED && _queue[pos]->mState != ftFileControl::PAUSED)
@ -1262,7 +1263,7 @@ bool ftController::FileRequest(const std::string& fname, const std::string& has
// We check that flags are consistent.
if(flags & RS_FILE_REQ_ANONYMOUS_ROUTING)
mTurtle->monitorTunnels(hash) ;
mTurtle->monitorTunnels(hash,mFtServer) ;
bool assume_availability = flags & RS_FILE_REQ_CACHE ; // assume availability for cache files

View File

@ -42,6 +42,7 @@ class ftFileCreator;
class ftTransferModule;
class ftFileProvider;
class ftSearch;
class ftServer;
class ftExtraList;
class ftDataMultiplex;
class p3turtle ;
@ -119,6 +120,7 @@ class ftController: public CacheTransfer, public RsThread, public pqiMonitor, pu
void setFtSearchNExtra(ftSearch *, ftExtraList *);
void setTurtleRouter(p3turtle *) ;
void setFtServer(ftServer *) ;
bool activate();
bool isActiveAndNoPending();
@ -234,6 +236,7 @@ class ftController: public CacheTransfer, public RsThread, public pqiMonitor, pu
ftDataMultiplex *mDataplex;
ftExtraList *mExtraList;
p3turtle *mTurtle ;
ftServer *mFtServer ;
RsMutex ctrlMutex;

View File

@ -31,6 +31,7 @@
#include "retroshare/rspeers.h"
const int ftserverzone = 29539;
#include "ft/ftturtlefiletransferitem.h"
#include "ft/ftserver.h"
#include "ft/ftextralist.h"
#include "ft/ftfilesearch.h"
@ -154,7 +155,9 @@ void ftServer::connectToTurtleRouter(p3turtle *fts)
mTurtleRouter = fts ;
mFtController->setTurtleRouter(fts) ;
fts->registerTunnelService(this) ;
mFtController->setFtServer(this) ;
mTurtleRouter->registerTunnelService(this) ;
}
void ftServer::StartupThreads()
@ -452,6 +455,39 @@ bool ftServer::FileDetails(const std::string &hash, FileSearchFlags hintflags, F
return false;
}
RsTurtleGenericTunnelItem *ftServer::deserialiseItem(void *data,uint32_t size) const
{
uint32_t rstype = getRsItemId(data);
#ifdef SERVER_DEBUG
std::cerr << "p3turtle: deserialising packet: " << std::endl ;
#endif
#ifdef SERVER_DEBUG
if ((RS_PKT_VERSION_SERVICE != getRsItemVersion(rstype)) || (RS_SERVICE_TYPE_TURTLE != getRsItemService(rstype)))
{
#ifdef SERVER_DEBUG
std::cerr << " Wrong type !!" << std::endl ;
#endif
return NULL; /* wrong type */
}
#endif
switch(getRsItemSubType(rstype))
{
case RS_TURTLE_SUBTYPE_FILE_REQUEST : return new RsTurtleFileRequestItem(data,size) ;
case RS_TURTLE_SUBTYPE_FILE_DATA : return new RsTurtleFileDataItem(data,size) ;
case RS_TURTLE_SUBTYPE_FILE_MAP_REQUEST : return new RsTurtleFileMapRequestItem(data,size) ;
case RS_TURTLE_SUBTYPE_FILE_MAP : return new RsTurtleFileMapItem(data,size) ;
case RS_TURTLE_SUBTYPE_FILE_CRC_REQUEST : return new RsTurtleFileCrcRequestItem(data,size) ;
case RS_TURTLE_SUBTYPE_FILE_CRC : return new RsTurtleFileCrcItem(data,size) ;
case RS_TURTLE_SUBTYPE_CHUNK_CRC_REQUEST : return new RsTurtleChunkCrcRequestItem(data,size) ;
case RS_TURTLE_SUBTYPE_CHUNK_CRC : return new RsTurtleChunkCrcItem(data,size) ;
default:
return NULL ;
}
}
bool ftServer::handleTunnelRequest(const std::string& hash,const std::string& peer_id,std::string& description_info_string)
{
FileInfo info ;
@ -842,7 +878,14 @@ bool ftServer::loadConfigMap(std::map<std::string, std::string> &/*configMap*/)
bool ftServer::sendDataRequest(const std::string& peerId, const std::string& hash, uint64_t size, uint64_t offset, uint32_t chunksize)
{
if(mTurtleRouter->isTurtlePeer(peerId))
mTurtleRouter->sendDataRequest(peerId,hash,size,offset,chunksize) ;
{
RsTurtleFileRequestItem *item = new RsTurtleFileRequestItem ;
item->chunk_offset = offset ;
item->chunk_size = chunksize ;
mTurtleRouter->sendTurtleData(peerId,item) ;
}
else
{
/* create a packet */
@ -869,7 +912,10 @@ bool ftServer::sendDataRequest(const std::string& peerId, const std::string& has
bool ftServer::sendChunkMapRequest(const std::string& peerId,const std::string& hash,bool is_client)
{
if(mTurtleRouter->isTurtlePeer(peerId))
mTurtleRouter->sendChunkMapRequest(peerId,hash,is_client) ;
{
RsTurtleFileMapRequestItem *item = new RsTurtleFileMapRequestItem ;
mTurtleRouter->sendTurtleData(peerId,item) ;
}
else
{
/* create a packet */
@ -892,7 +938,11 @@ bool ftServer::sendChunkMapRequest(const std::string& peerId,const std::string&
bool ftServer::sendChunkMap(const std::string& peerId,const std::string& hash,const CompressedChunkMap& map,bool is_client)
{
if(mTurtleRouter->isTurtlePeer(peerId))
mTurtleRouter->sendChunkMap(peerId,hash,map,is_client) ;
{
RsTurtleFileMapItem *item = new RsTurtleFileMapItem ;
item->compressed_map = map ;
mTurtleRouter->sendTurtleData(peerId,item) ;
}
else
{
/* create a packet */
@ -915,7 +965,11 @@ bool ftServer::sendChunkMap(const std::string& peerId,const std::string& hash,co
bool ftServer::sendCRC32MapRequest(const std::string& peerId,const std::string& hash)
{
if(mTurtleRouter->isTurtlePeer(peerId))
mTurtleRouter->sendCRC32MapRequest(peerId,hash) ;
{
RsTurtleFileCrcRequestItem *item = new RsTurtleFileCrcRequestItem;
mTurtleRouter->sendTurtleData(peerId,item) ;
}
else
{
/* create a packet */
@ -936,7 +990,12 @@ bool ftServer::sendCRC32MapRequest(const std::string& peerId,const std::string&
bool ftServer::sendSingleChunkCRCRequest(const std::string& peerId,const std::string& hash,uint32_t chunk_number)
{
if(mTurtleRouter->isTurtlePeer(peerId))
mTurtleRouter->sendSingleChunkCRCRequest(peerId,hash,chunk_number) ;
{
RsTurtleChunkCrcRequestItem *item = new RsTurtleChunkCrcRequestItem;
item->chunk_number = chunk_number ;
mTurtleRouter->sendTurtleData(peerId,item) ;
}
else
{
/* create a packet */
@ -959,7 +1018,12 @@ bool ftServer::sendSingleChunkCRCRequest(const std::string& peerId,const std::st
bool ftServer::sendCRC32Map(const std::string& peerId,const std::string& hash,const CRC32Map& crcmap)
{
if(mTurtleRouter->isTurtlePeer(peerId))
mTurtleRouter->sendCRC32Map(peerId,hash,crcmap) ;
{
RsTurtleFileCrcItem *item = new RsTurtleFileCrcItem ;
item->crc_map = crcmap ;
mTurtleRouter->sendTurtleData(peerId,item) ;
}
else
{
/* create a packet */
@ -981,7 +1045,13 @@ bool ftServer::sendCRC32Map(const std::string& peerId,const std::string& hash,co
bool ftServer::sendSingleChunkCRC(const std::string& peerId,const std::string& hash,uint32_t chunk_number,const Sha1CheckSum& crc)
{
if(mTurtleRouter->isTurtlePeer(peerId))
mTurtleRouter->sendSingleChunkCRC(peerId,hash,chunk_number,crc) ;
{
RsTurtleChunkCrcItem *item = new RsTurtleChunkCrcItem;
item->chunk_number = chunk_number ;
item->check_sum = crc ;
mTurtleRouter->sendTurtleData(peerId,item) ;
}
else
{
/* create a packet */
@ -1036,7 +1106,23 @@ bool ftServer::sendData(const std::string& peerId, const std::string& hash, uint
/******** New Serialiser Type *******/
if(mTurtleRouter->isTurtlePeer(peerId))
mTurtleRouter->sendFileData(peerId,hash,size,baseoffset+offset,chunk,&(((uint8_t *) data)[offset])) ;
{
RsTurtleFileDataItem *item = new RsTurtleFileDataItem ;
item->chunk_offset = offset ;
item->chunk_size = chunksize ;
item->chunk_data = malloc(chunksize) ;
if(item->chunk_data == NULL)
{
std::cerr << "p3turtle: Warning: failed malloc of " << chunksize << " bytes for sending data packet." << std::endl ;
delete item;
return false;
}
memcpy(item->chunk_data,(void*)((uint8_t*)data),chunksize) ;
mTurtleRouter->sendTurtleData(peerId,item) ;
}
else
{
RsFileData *rfd = new RsFileData();
@ -1080,6 +1166,76 @@ bool ftServer::sendData(const std::string& peerId, const std::string& hash, uint
return true;
}
void ftServer::receiveTurtleData(RsTurtleGenericTunnelItem *i,
const std::string& hash,
const std::string& virtual_peer_id,
RsTurtleGenericTunnelItem::Direction direction)
{
switch(i->PacketSubType())
{
case RS_TURTLE_SUBTYPE_FILE_REQUEST:
{
RsTurtleFileRequestItem *item = dynamic_cast<RsTurtleFileRequestItem *>(i) ;
getMultiplexer()->recvDataRequest(virtual_peer_id,hash,0,item->chunk_offset,item->chunk_size) ;
}
break ;
case RS_TURTLE_SUBTYPE_FILE_DATA :
{
RsTurtleFileDataItem *item = dynamic_cast<RsTurtleFileDataItem *>(i) ;
getMultiplexer()->recvData(virtual_peer_id,hash,0,item->chunk_offset,item->chunk_size,item->chunk_data) ;
item->chunk_data = NULL ; // this prevents deletion in the destructor of RsFileDataItem, because data will be deleted
// down _ft_server->getMultiplexer()->recvData()...in ftTransferModule::recvFileData
}
break ;
case RS_TURTLE_SUBTYPE_FILE_MAP :
{
RsTurtleFileMapItem *item = dynamic_cast<RsTurtleFileMapItem *>(i) ;
getMultiplexer()->recvChunkMap(virtual_peer_id,hash,item->compressed_map,direction == RsTurtleGenericTunnelItem::DIRECTION_CLIENT) ;
}
break ;
case RS_TURTLE_SUBTYPE_FILE_MAP_REQUEST:
{
RsTurtleFileMapRequestItem *item = dynamic_cast<RsTurtleFileMapRequestItem *>(i) ;
getMultiplexer()->recvChunkMapRequest(virtual_peer_id,hash,direction == RsTurtleGenericTunnelItem::DIRECTION_CLIENT) ;
}
break ;
case RS_TURTLE_SUBTYPE_FILE_CRC :
{
RsTurtleFileCrcItem *item = dynamic_cast<RsTurtleFileCrcItem *>(i) ;
getMultiplexer()->recvCRC32Map(virtual_peer_id,hash,item->crc_map) ;
}
break ;
case RS_TURTLE_SUBTYPE_FILE_CRC_REQUEST:
{
getMultiplexer()->recvCRC32MapRequest(virtual_peer_id,hash) ;
}
break ;
case RS_TURTLE_SUBTYPE_CHUNK_CRC :
{
RsTurtleChunkCrcItem *item = dynamic_cast<RsTurtleChunkCrcItem *>(i) ;
getMultiplexer()->recvSingleChunkCRC(virtual_peer_id,hash,item->chunk_number,item->check_sum) ;
}
break ;
case RS_TURTLE_SUBTYPE_CHUNK_CRC_REQUEST:
{
RsTurtleChunkCrcRequestItem *item = dynamic_cast<RsTurtleChunkCrcRequestItem *>(i) ;
getMultiplexer()->recvSingleChunkCRCRequest(virtual_peer_id,hash,item->chunk_number) ;
}
break ;
default:
std::cerr << "WARNING: Unknown packet type received: sub_id=" << reinterpret_cast<void*>(i->PacketSubType()) << ". Is somebody trying to poison you ?" << std::endl ;
}
}
/* NB: The rsCore lock must be activated before calling this.
* This Lock should be moved lower into the system...

View File

@ -115,6 +115,8 @@ class ftServer: public RsFiles, public ftDataSend, public RsTurtleClientService,
// Implements RsTurtleClientService
//
virtual bool handleTunnelRequest(const std::string& hash,const std::string& peer_id,std::string& description_info_string) ;
virtual void receiveTurtleData(RsTurtleGenericTunnelItem *item,const std::string& hash,const std::string& virtual_peer_id,RsTurtleGenericTunnelItem::Direction direction) ;
virtual RsTurtleGenericTunnelItem *deserialiseItem(void *data,uint32_t size) const ;
/***************************************************************/
/*************** Control Interface *****************************/

View File

@ -0,0 +1,739 @@
/*
* libretroshare/src/services: ftturtlefiletransferitem.cc
*
* Services for RetroShare.
*
* Copyright 2013 by Cyril Soler
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License Version 2 as published by the Free Software Foundation.
*
* This library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
* USA.
*
* Please report all bugs and problems to "csoler@users.sourceforge.net".
*
*/
#include <iostream>
#include <stdexcept>
#include <serialiser/itempriorities.h>
#include <ft/ftturtlefiletransferitem.h>
uint32_t RsTurtleFileRequestItem::serial_size()
{
uint32_t s = 0 ;
s += 8 ; // header
s += 4 ; // tunnel id
s += 8 ; // file offset
s += 4 ; // chunk size
return s ;
}
uint32_t RsTurtleFileDataItem::serial_size()
{
uint32_t s = 0 ;
s += 8 ; // header
s += 4 ; // tunnel id
s += 8 ; // file offset
s += 4 ; // chunk size
s += chunk_size ; // actual data size.
return s ;
}
uint32_t RsTurtleFileMapRequestItem::serial_size()
{
uint32_t s = 0 ;
s += 8 ; // header
s += 4 ; // tunnel id
s += 4 ; // direction
return s ;
}
uint32_t RsTurtleFileMapItem::serial_size()
{
uint32_t s = 0 ;
s += 8 ; // header
s += 4 ; // tunnel id
s += 4 ; // direction
s += 4 ; // compressed_map.size()
s += 4 * compressed_map._map.size() ;
return s ;
}
uint32_t RsTurtleFileCrcRequestItem::serial_size()
{
uint32_t s = 0 ;
s += 8 ; // header
s += 4 ; // tunnel id
return s ;
}
uint32_t RsTurtleChunkCrcItem::serial_size()
{
uint32_t s = 0 ;
s += 8 ; // header
s += 4 ; // tunnel id
s += 4 ; // chunk number
s += 20 ; // check_sum
return s ;
}
uint32_t RsTurtleChunkCrcRequestItem::serial_size()
{
uint32_t s = 0 ;
s += 8 ; // header
s += 4 ; // tunnel id
s += 4 ; // chunk number
return s ;
}
uint32_t RsTurtleFileCrcItem::serial_size()
{
uint32_t s = 0 ;
s += 8 ; // header
s += 4 ; // tunnel id
s += 4 ; // size of _map
s += 4 ; // size of _crcs
s += 4 * crc_map._crcs.size() ;
s += 4 * crc_map._ccmap._map.size() ;
return s ;
}
bool RsTurtleFileMapRequestItem::serialize(void *data,uint32_t& pktsize)
{
uint32_t tlvsize = serial_size();
uint32_t offset = 0;
if (pktsize < tlvsize)
return false; /* not enough space */
pktsize = tlvsize;
bool ok = true;
ok &= setRsItemHeader(data,tlvsize,PacketId(), tlvsize);
/* skip the header */
offset += 8;
/* add mandatory parts first */
ok &= setRawUInt32(data, tlvsize, &offset, tunnel_id);
ok &= setRawUInt32(data, tlvsize, &offset, direction);
if (offset != tlvsize)
{
ok = false;
#ifdef RSSERIAL_DEBUG
std::cerr << "RsFileConfigSerialiser::serialiseTransfer() Size Error! " << std::endl;
#endif
}
return ok;
}
bool RsTurtleFileMapItem::serialize(void *data,uint32_t& pktsize)
{
uint32_t tlvsize = serial_size();
uint32_t offset = 0;
if (pktsize < tlvsize)
return false; /* not enough space */
pktsize = tlvsize;
bool ok = true;
ok &= setRsItemHeader(data,tlvsize,PacketId(), tlvsize);
/* skip the header */
offset += 8;
/* add mandatory parts first */
ok &= setRawUInt32(data, tlvsize, &offset, tunnel_id);
ok &= setRawUInt32(data, tlvsize, &offset, direction);
ok &= setRawUInt32(data, tlvsize, &offset, compressed_map._map.size());
for(uint32_t i=0;i<compressed_map._map.size() && ok;++i)
ok &= setRawUInt32(data, tlvsize, &offset, compressed_map._map[i]);
if (offset != tlvsize)
{
ok = false;
#ifdef RSSERIAL_DEBUG
std::cerr << "RsFileConfigSerialiser::serialiseTransfer() Size Error! " << std::endl;
#endif
}
return ok;
}
bool RsTurtleFileCrcRequestItem::serialize(void *data,uint32_t& pktsize)
{
#ifdef P3TURTLE_DEBUG
std::cerr << "RsTurtleFileCrcRequestItem::serialize(): serializing packet:" << std::endl ;
print(std::cerr,2) ;
#endif
uint32_t tlvsize = serial_size();
uint32_t offset = 0;
if (pktsize < tlvsize)
return false; /* not enough space */
pktsize = tlvsize;
bool ok = true;
ok &= setRsItemHeader(data,tlvsize,PacketId(), tlvsize);
/* skip the header */
offset += 8;
/* add mandatory parts first */
ok &= setRawUInt32(data, tlvsize, &offset, tunnel_id);
if (offset != tlvsize)
{
ok = false;
std::cerr << "RsFileConfigSerialiser::serialiseTransfer() Size Error! " << std::endl;
}
return ok;
}
bool RsTurtleChunkCrcRequestItem::serialize(void *data,uint32_t& pktsize)
{
#ifdef P3TURTLE_DEBUG
std::cerr << "RsTurtleChunkCrcRequestItem::serialize(): serializing packet:" << std::endl ;
print(std::cerr,2) ;
#endif
uint32_t tlvsize = serial_size();
uint32_t offset = 0;
if (pktsize < tlvsize)
return false; /* not enough space */
pktsize = tlvsize;
bool ok = true;
ok &= setRsItemHeader(data,tlvsize,PacketId(), tlvsize);
/* skip the header */
offset += 8;
/* add mandatory parts first */
ok &= setRawUInt32(data, tlvsize, &offset, tunnel_id);
ok &= setRawUInt32(data, tlvsize, &offset, chunk_number);
if (offset != tlvsize)
{
ok = false;
std::cerr << "RsFileConfigSerialiser::serialiseTransfer() Size Error! " << std::endl;
}
return ok;
}
bool RsTurtleFileCrcItem::serialize(void *data,uint32_t& pktsize)
{
#ifdef P3TURTLE_DEBUG
std::cerr << "RsTurtleFileCrcItem::serialize(): serializing packet:" << std::endl ;
print(std::cerr,2) ;
#endif
uint32_t tlvsize = serial_size();
uint32_t offset = 0;
if (pktsize < tlvsize)
return false; /* not enough space */
pktsize = tlvsize;
bool ok = true;
ok &= setRsItemHeader(data,tlvsize,PacketId(), tlvsize);
/* skip the header */
offset += 8;
/* add mandatory parts first */
ok &= setRawUInt32(data, tlvsize, &offset, tunnel_id);
ok &= setRawUInt32(data, tlvsize, &offset, crc_map._ccmap._map.size());
ok &= setRawUInt32(data, tlvsize, &offset, crc_map._crcs.size());
for(uint32_t i=0;i<crc_map._ccmap._map.size() && ok;++i)
ok &= setRawUInt32(data, tlvsize, &offset, crc_map._ccmap._map[i]);
for(uint32_t i=0;i<crc_map._crcs.size() && ok;++i)
ok &= setRawUInt32(data, tlvsize, &offset, crc_map._crcs[i]);
if (offset != tlvsize)
{
ok = false;
std::cerr << "RsFileConfigSerialiser::serialiseTransfer() Size Error! " << std::endl;
}
return ok;
}
bool RsTurtleChunkCrcItem::serialize(void *data,uint32_t& pktsize)
{
#ifdef P3TURTLE_DEBUG
std::cerr << "RsTurtleChunkCrcRequestItem::serialize(): serializing packet:" << std::endl ;
print(std::cerr,2) ;
#endif
uint32_t tlvsize = serial_size();
uint32_t offset = 0;
if (pktsize < tlvsize)
return false; /* not enough space */
pktsize = tlvsize;
bool ok = true;
ok &= setRsItemHeader(data,tlvsize,PacketId(), tlvsize);
/* skip the header */
offset += 8;
/* add mandatory parts first */
ok &= setRawUInt32(data, tlvsize, &offset, tunnel_id);
ok &= setRawUInt32(data, tlvsize, &offset, chunk_number);
ok &= setRawUInt32(data, tlvsize, &offset, check_sum.fourbytes[0]);
ok &= setRawUInt32(data, tlvsize, &offset, check_sum.fourbytes[1]);
ok &= setRawUInt32(data, tlvsize, &offset, check_sum.fourbytes[2]);
ok &= setRawUInt32(data, tlvsize, &offset, check_sum.fourbytes[3]);
ok &= setRawUInt32(data, tlvsize, &offset, check_sum.fourbytes[4]);
if (offset != tlvsize)
{
ok = false;
std::cerr << "RsFileConfigSerialiser::serialiseTransfer() Size Error! " << std::endl;
}
return ok;
}
RsTurtleFileMapItem::RsTurtleFileMapItem(void *data,uint32_t pktsize)
: RsTurtleGenericTunnelItem(RS_TURTLE_SUBTYPE_FILE_MAP)
{
setPriorityLevel(QOS_PRIORITY_RS_TURTLE_FILE_MAP) ;
#ifdef P3TURTLE_DEBUG
std::cerr << " type = file map item" << std::endl ;
#endif
uint32_t offset = 8; // skip the header
/* add mandatory parts first */
bool ok = true ;
uint32_t s,d ;
ok &= getRawUInt32(data, pktsize, &offset, &tunnel_id);
ok &= getRawUInt32(data, pktsize, &offset, &d);
direction = d ;
ok &= getRawUInt32(data, pktsize, &offset, &s) ;
compressed_map._map.resize(s) ;
for(uint32_t i=0;i<s && ok;++i)
ok &= getRawUInt32(data, pktsize, &offset, &(compressed_map._map[i])) ;
#ifdef WINDOWS_SYS // No Exceptions in Windows compile. (drbobs).
#else
if (offset != pktsize)
throw std::runtime_error("Size error while deserializing.") ;
if (!ok)
throw std::runtime_error("Unknown error while deserializing.") ;
#endif
}
RsTurtleFileMapRequestItem::RsTurtleFileMapRequestItem(void *data,uint32_t pktsize)
: RsTurtleGenericTunnelItem(RS_TURTLE_SUBTYPE_FILE_MAP_REQUEST)
{
setPriorityLevel(QOS_PRIORITY_RS_TURTLE_FILE_MAP_REQUEST) ;
#ifdef P3TURTLE_DEBUG
std::cerr << " type = file map request item" << std::endl ;
#endif
uint32_t offset = 8; // skip the header
/* add mandatory parts first */
bool ok = true ;
ok &= getRawUInt32(data, pktsize, &offset, &tunnel_id);
ok &= getRawUInt32(data, pktsize, &offset, &direction);
#ifdef WINDOWS_SYS // No Exceptions in Windows compile. (drbobs).
#else
if (offset != pktsize)
throw std::runtime_error("Size error while deserializing.") ;
if (!ok)
throw std::runtime_error("Unknown error while deserializing.") ;
#endif
}
RsTurtleFileCrcItem::RsTurtleFileCrcItem(void *data,uint32_t pktsize)
: RsTurtleGenericTunnelItem(RS_TURTLE_SUBTYPE_FILE_CRC)
{
setPriorityLevel(QOS_PRIORITY_RS_TURTLE_FILE_CRC) ;
#ifdef P3TURTLE_DEBUG
std::cerr << " type = file map item" << std::endl ;
#endif
uint32_t offset = 8; // skip the header
/* add mandatory parts first */
bool ok = true ;
uint32_t s1,s2 ;
ok &= getRawUInt32(data, pktsize, &offset, &tunnel_id);
ok &= getRawUInt32(data, pktsize, &offset, &s1) ;
ok &= getRawUInt32(data, pktsize, &offset, &s2) ;
crc_map._ccmap._map.resize(s1) ;
crc_map._crcs.resize(s2) ;
for(uint32_t i=0;i<s1 && ok;++i)
ok &= getRawUInt32(data, pktsize, &offset, &(crc_map._ccmap._map[i])) ;
for(uint32_t i=0;i<s2 && ok;++i)
ok &= getRawUInt32(data, pktsize, &offset, &(crc_map._crcs[i])) ;
#ifdef WINDOWS_SYS // No Exceptions in Windows compile. (drbobs).
#else
if (offset != pktsize)
throw std::runtime_error("Size error while deserializing.") ;
if (!ok)
throw std::runtime_error("Unknown error while deserializing.") ;
#endif
}
RsTurtleChunkCrcItem::RsTurtleChunkCrcItem(void *data,uint32_t pktsize)
: RsTurtleGenericTunnelItem(RS_TURTLE_SUBTYPE_CHUNK_CRC)
{
setPriorityLevel(QOS_PRIORITY_RS_TURTLE_CHUNK_CRC) ;
#ifdef P3TURTLE_DEBUG
std::cerr << " type = file map item" << std::endl ;
#endif
uint32_t offset = 8; // skip the header
/* add mandatory parts first */
bool ok = true ;
ok &= getRawUInt32(data, pktsize, &offset, &tunnel_id) ;
ok &= getRawUInt32(data, pktsize, &offset, &chunk_number) ;
ok &= getRawUInt32(data, pktsize, &offset, &check_sum.fourbytes[0]) ;
ok &= getRawUInt32(data, pktsize, &offset, &check_sum.fourbytes[1]) ;
ok &= getRawUInt32(data, pktsize, &offset, &check_sum.fourbytes[2]) ;
ok &= getRawUInt32(data, pktsize, &offset, &check_sum.fourbytes[3]) ;
ok &= getRawUInt32(data, pktsize, &offset, &check_sum.fourbytes[4]) ;
#ifdef WINDOWS_SYS // No Exceptions in Windows compile. (drbobs).
#else
if (offset != pktsize)
throw std::runtime_error("Size error while deserializing.") ;
if (!ok)
throw std::runtime_error("Unknown error while deserializing.") ;
#endif
}
RsTurtleFileCrcRequestItem::RsTurtleFileCrcRequestItem(void *data,uint32_t pktsize)
: RsTurtleGenericTunnelItem(RS_TURTLE_SUBTYPE_FILE_CRC_REQUEST)
{
setPriorityLevel(QOS_PRIORITY_RS_TURTLE_FILE_CRC_REQUEST) ;
#ifdef P3TURTLE_DEBUG
std::cerr << " type = file map request item" << std::endl ;
#endif
uint32_t offset = 8; // skip the header
/* add mandatory parts first */
bool ok = true ;
ok &= getRawUInt32(data, pktsize, &offset, &tunnel_id);
#ifdef WINDOWS_SYS // No Exceptions in Windows compile. (drbobs).
#else
if (offset != pktsize)
throw std::runtime_error("Size error while deserializing.") ;
if (!ok)
throw std::runtime_error("Unknown error while deserializing.") ;
#endif
}
RsTurtleChunkCrcRequestItem::RsTurtleChunkCrcRequestItem(void *data,uint32_t pktsize)
: RsTurtleGenericTunnelItem(RS_TURTLE_SUBTYPE_CHUNK_CRC_REQUEST)
{
setPriorityLevel(QOS_PRIORITY_RS_TURTLE_CHUNK_CRC_REQUEST) ;
#ifdef P3TURTLE_DEBUG
std::cerr << " type = file map item" << std::endl ;
#endif
uint32_t offset = 8; // skip the header
/* add mandatory parts first */
bool ok = true ;
ok &= getRawUInt32(data, pktsize, &offset, &tunnel_id) ;
ok &= getRawUInt32(data, pktsize, &offset, &chunk_number) ;
#ifdef WINDOWS_SYS // No Exceptions in Windows compile. (drbobs).
#else
if (offset != pktsize)
throw std::runtime_error("Size error while deserializing.") ;
if (!ok)
throw std::runtime_error("Unknown error while deserializing.") ;
#endif
}
bool RsTurtleFileRequestItem::serialize(void *data,uint32_t& pktsize)
{
uint32_t tlvsize = serial_size();
uint32_t offset = 0;
if (pktsize < tlvsize)
return false; /* not enough space */
pktsize = tlvsize;
bool ok = true;
ok &= setRsItemHeader(data,tlvsize,PacketId(), tlvsize);
/* skip the header */
offset += 8;
/* add mandatory parts first */
ok &= setRawUInt32(data, tlvsize, &offset, tunnel_id) ;
ok &= setRawUInt64(data, tlvsize, &offset, chunk_offset);
ok &= setRawUInt32(data, tlvsize, &offset, chunk_size);
if (offset != tlvsize)
{
ok = false;
#ifdef RSSERIAL_DEBUG
std::cerr << "RsTurtleTunnelOkItem::serialiseTransfer() Size Error! " << std::endl;
#endif
}
return ok;
}
RsTurtleFileRequestItem::RsTurtleFileRequestItem(void *data,uint32_t pktsize)
: RsTurtleGenericTunnelItem(RS_TURTLE_SUBTYPE_FILE_REQUEST)
{
setPriorityLevel(QOS_PRIORITY_RS_TURTLE_FILE_REQUEST) ;
#ifdef P3TURTLE_DEBUG
std::cerr << " type = file request" << std::endl ;
#endif
uint32_t offset = 8; // skip the header
uint32_t rssize = getRsItemSize(data);
/* add mandatory parts first */
bool ok = true ;
ok &= getRawUInt32(data, pktsize, &offset, &tunnel_id) ;
ok &= getRawUInt64(data, pktsize, &offset, &chunk_offset);
ok &= getRawUInt32(data, pktsize, &offset, &chunk_size);
#ifdef P3TURTLE_DEBUG
std::cerr << " tunnel_id=" << (void*)tunnel_id << ", chunk_offset=" << chunk_offset << ", chunk_size=" << chunk_size << std::endl ;
#endif
#ifdef WINDOWS_SYS // No Exceptions in Windows compile. (drbobs).
UNREFERENCED_LOCAL_VARIABLE(rssize);
#else
if (offset != rssize)
throw std::runtime_error("RsTurtleTunnelOkItem::() error while deserializing.") ;
if (!ok)
throw std::runtime_error("RsTurtleTunnelOkItem::() unknown error while deserializing.") ;
#endif
}
RsTurtleFileDataItem::~RsTurtleFileDataItem()
{
free(chunk_data) ;
}
RsTurtleFileDataItem::RsTurtleFileDataItem(void *data,uint32_t pktsize)
: RsTurtleGenericTunnelItem(RS_TURTLE_SUBTYPE_FILE_DATA)
{
setPriorityLevel(QOS_PRIORITY_RS_TURTLE_FILE_DATA) ;
#ifdef P3TURTLE_DEBUG
std::cerr << " type = file request" << std::endl ;
#endif
uint32_t offset = 8; // skip the header
uint32_t rssize = getRsItemSize(data);
/* add mandatory parts first */
bool ok = true ;
ok &= getRawUInt32(data, pktsize, &offset, &tunnel_id) ;
ok &= getRawUInt64(data, pktsize, &offset, &chunk_offset);
ok &= getRawUInt32(data, pktsize, &offset, &chunk_size);
chunk_data = (void*)malloc(chunk_size) ;
memcpy(chunk_data,(void*)((unsigned char*)data+offset),chunk_size) ;
offset += chunk_size ;
#ifdef P3TURTLE_DEBUG
std::cerr << " tunnel_id=" << (void*)tunnel_id << ", chunk_offset=" << chunk_offset << ", chunk_size=" << chunk_size << std::endl ;
#endif
#ifdef WINDOWS_SYS // No Exceptions in Windows compile. (drbobs).
UNREFERENCED_LOCAL_VARIABLE(rssize);
#else
if (offset != rssize)
throw std::runtime_error("RsTurtleFileDataItem::() error while deserializing.") ;
if (!ok)
throw std::runtime_error("RsTurtleFileDataItem::() unknown error while deserializing.") ;
#endif
}
bool RsTurtleFileDataItem::serialize(void *data,uint32_t& pktsize)
{
uint32_t tlvsize = serial_size();
uint32_t offset = 0;
if (pktsize < tlvsize)
return false; /* not enough space */
pktsize = tlvsize;
bool ok = true;
ok &= setRsItemHeader(data,tlvsize,PacketId(), tlvsize);
/* skip the header */
offset += 8;
/* add mandatory parts first */
ok &= setRawUInt32(data, tlvsize, &offset, tunnel_id) ;
ok &= setRawUInt64(data, tlvsize, &offset, chunk_offset);
ok &= setRawUInt32(data, tlvsize, &offset, chunk_size);
memcpy((void*)((unsigned char*)data+offset),chunk_data,chunk_size) ;
offset += chunk_size ;
if (offset != tlvsize)
{
ok = false;
#ifdef RSSERIAL_DEBUG
std::cerr << "RsTurtleTunnelOkItem::serialiseTransfer() Size Error! " << std::endl;
#endif
}
return ok;
}
std::ostream& RsTurtleFileRequestItem::print(std::ostream& o, uint16_t)
{
o << "File request item:" << std::endl ;
o << " tunnel id : " << std::hex << tunnel_id << std::dec << std::endl ;
o << " offset : " << chunk_offset << std::endl ;
o << " chunk size: " << chunk_size << std::endl ;
return o ;
}
std::ostream& RsTurtleFileDataItem::print(std::ostream& o, uint16_t)
{
o << "File request item:" << std::endl ;
o << " tunnel id : " << std::hex << tunnel_id << std::dec << std::endl ;
o << " offset : " << chunk_offset << std::endl ;
o << " chunk size: " << chunk_size << std::endl ;
o << " data : " << std::hex << chunk_data << std::dec << std::endl ;
return o ;
}
std::ostream& RsTurtleFileMapItem::print(std::ostream& o, uint16_t)
{
o << "File map item:" << std::endl ;
o << " tunnel id : " << std::hex << tunnel_id << std::dec << std::endl ;
o << " direction : " << direction << std::endl ;
o << " map : " ;
for(uint32_t i=0;i<compressed_map._map.size();++i)
o << std::hex << compressed_map._map[i] << std::dec << std::endl ;
return o ;
}
std::ostream& RsTurtleFileMapRequestItem::print(std::ostream& o, uint16_t)
{
o << "File map request item:" << std::endl ;
o << " tunnel id : " << std::hex << tunnel_id << std::dec << std::endl ;
o << " direction : " << direction << std::endl ;
return o ;
}
std::ostream& RsTurtleFileCrcItem::print(std::ostream& o, uint16_t)
{
o << "File CRC item:" << std::endl ;
o << " tunnel id : " << std::hex << tunnel_id << std::dec << std::endl ;
o << " map : " ;
for(uint32_t i=0;i<crc_map._ccmap._map.size();++i)
o << std::hex << crc_map._ccmap._map[i] << std::endl ;
o << " CRC : " ;
for(uint32_t i=0;i<crc_map._crcs.size();++i)
o << std::hex << crc_map._crcs[i] << std::dec << std::endl ;
return o ;
}
std::ostream& RsTurtleFileCrcRequestItem::print(std::ostream& o, uint16_t)
{
o << "File CRC request item:" << std::endl ;
o << " tunnel id : " << std::hex << tunnel_id << std::dec << std::endl ;
return o ;
}
std::ostream& RsTurtleChunkCrcRequestItem::print(std::ostream& o, uint16_t)
{
o << "Chunk CRC request item:" << std::endl ;
o << " tunnel id : " << std::hex << tunnel_id << std::dec << std::endl ;
o << " chunk num : " << chunk_number << std::endl ;
return o ;
}
std::ostream& RsTurtleChunkCrcItem::print(std::ostream& o, uint16_t)
{
o << "Chunk CRC request item:" << std::endl ;
o << " tunnel id : " << std::hex << tunnel_id << std::dec << std::endl ;
o << " chunk num : " << chunk_number << std::endl ;
o << " sha1 sum : " << check_sum.toStdString() << std::endl ;
return o ;
}

View File

@ -0,0 +1,168 @@
/*
* libretroshare/src/services: ftturtlefiletransferitem.h
*
* Services for RetroShare.
*
* Copyright 2013 by Cyril Soler
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License Version 2 as published by the Free Software Foundation.
*
* This library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
* USA.
*
* Please report all bugs and problems to "csoler@users.sourceforge.net".
*
*/
#include <stdint.h>
#include <turtle/rsturtleitem.h>
/***********************************************************************************/
/* Turtle File Transfer item classes */
/***********************************************************************************/
class RsTurtleFileRequestItem: public RsTurtleGenericTunnelItem
{
public:
RsTurtleFileRequestItem() : RsTurtleGenericTunnelItem(RS_TURTLE_SUBTYPE_FILE_REQUEST) { setPriorityLevel(QOS_PRIORITY_RS_TURTLE_FILE_REQUEST);}
RsTurtleFileRequestItem(void *data,uint32_t size) ; // deserialization
virtual bool shouldStampTunnel() const { return false ; }
virtual Direction travelingDirection() const { return DIRECTION_SERVER ; }
uint64_t chunk_offset ;
uint32_t chunk_size ;
virtual std::ostream& print(std::ostream& o, uint16_t) ;
protected:
virtual bool serialize(void *data,uint32_t& size) ;
virtual uint32_t serial_size() ;
};
class RsTurtleFileDataItem: public RsTurtleGenericTunnelItem
{
public:
RsTurtleFileDataItem() : RsTurtleGenericTunnelItem(RS_TURTLE_SUBTYPE_FILE_DATA) { setPriorityLevel(QOS_PRIORITY_RS_TURTLE_FILE_DATA) ;}
~RsTurtleFileDataItem() ;
RsTurtleFileDataItem(void *data,uint32_t size) ; // deserialization
virtual bool shouldStampTunnel() const { return true ; }
virtual Direction travelingDirection() const { return DIRECTION_CLIENT ; }
uint64_t chunk_offset ; // offset in the file
uint32_t chunk_size ; // size of the file chunk
void *chunk_data ; // actual data.
virtual std::ostream& print(std::ostream& o, uint16_t) ;
virtual bool serialize(void *data,uint32_t& size) ;
virtual uint32_t serial_size() ;
};
class RsTurtleFileMapRequestItem: public RsTurtleGenericTunnelItem
{
public:
RsTurtleFileMapRequestItem() : RsTurtleGenericTunnelItem(RS_TURTLE_SUBTYPE_FILE_MAP_REQUEST) { setPriorityLevel(QOS_PRIORITY_RS_TURTLE_FILE_MAP_REQUEST) ;}
RsTurtleFileMapRequestItem(void *data,uint32_t size) ; // deserialization
virtual bool shouldStampTunnel() const { return false ; }
virtual std::ostream& print(std::ostream& o, uint16_t) ;
virtual bool serialize(void *data,uint32_t& size) ;
virtual uint32_t serial_size() ;
};
class RsTurtleFileMapItem: public RsTurtleGenericTunnelItem
{
public:
RsTurtleFileMapItem() : RsTurtleGenericTunnelItem(RS_TURTLE_SUBTYPE_FILE_MAP) { setPriorityLevel(QOS_PRIORITY_RS_TURTLE_FILE_MAP) ;}
RsTurtleFileMapItem(void *data,uint32_t size) ; // deserialization
virtual bool shouldStampTunnel() const { return false ; }
CompressedChunkMap compressed_map ; // Map info for the file in compressed format. Each *bit* in the array uint's says "I have" or "I don't have"
// by default, we suppose the peer has all the chunks. This info will thus be and-ed
// with the default file map for this source.
virtual std::ostream& print(std::ostream& o, uint16_t) ;
virtual bool serialize(void *data,uint32_t& size) ;
virtual uint32_t serial_size() ;
};
class RsTurtleFileCrcRequestItem: public RsTurtleGenericTunnelItem
{
public:
RsTurtleFileCrcRequestItem() : RsTurtleGenericTunnelItem(RS_TURTLE_SUBTYPE_FILE_CRC_REQUEST) { setPriorityLevel(QOS_PRIORITY_RS_FILE_CRC_REQUEST);}
RsTurtleFileCrcRequestItem(void *data,uint32_t size) ; // deserialization
virtual bool shouldStampTunnel() const { return false ; }
virtual Direction travelingDirection() const { return DIRECTION_SERVER ; }
virtual std::ostream& print(std::ostream& o, uint16_t) ;
virtual bool serialize(void *data,uint32_t& size) ;
virtual uint32_t serial_size() ;
};
class RsTurtleChunkCrcRequestItem: public RsTurtleGenericTunnelItem
{
public:
RsTurtleChunkCrcRequestItem() : RsTurtleGenericTunnelItem(RS_TURTLE_SUBTYPE_CHUNK_CRC_REQUEST) { setPriorityLevel(QOS_PRIORITY_RS_CHUNK_CRC_REQUEST);}
RsTurtleChunkCrcRequestItem(void *data,uint32_t size) ; // deserialization
virtual bool shouldStampTunnel() const { return false ; }
virtual Direction travelingDirection() const { return DIRECTION_SERVER ; }
uint32_t chunk_number ; // id of the chunk to CRC.
virtual std::ostream& print(std::ostream& o, uint16_t) ;
virtual bool serialize(void *data,uint32_t& size) ;
virtual uint32_t serial_size() ;
};
class RsTurtleFileCrcItem: public RsTurtleGenericTunnelItem
{
public:
RsTurtleFileCrcItem() : RsTurtleGenericTunnelItem(RS_TURTLE_SUBTYPE_FILE_CRC) { setPriorityLevel(QOS_PRIORITY_RS_FILE_CRC);}
RsTurtleFileCrcItem(void *data,uint32_t size) ; // deserialization
virtual bool shouldStampTunnel() const { return true ; }
virtual Direction travelingDirection() const { return DIRECTION_CLIENT ; }
CRC32Map crc_map ;// Map info for the file in compressed format. Each *bit* in the array uint's says "I have" or "I don't have"
// by default, we suppose the peer has all the chunks. This info will thus be and-ed
// with the default file map for this source.
virtual std::ostream& print(std::ostream& o, uint16_t) ;
virtual bool serialize(void *data,uint32_t& size) ;
virtual uint32_t serial_size() ;
};
class RsTurtleChunkCrcItem: public RsTurtleGenericTunnelItem
{
public:
RsTurtleChunkCrcItem() : RsTurtleGenericTunnelItem(RS_TURTLE_SUBTYPE_CHUNK_CRC) { setPriorityLevel(QOS_PRIORITY_RS_CHUNK_CRC);}
RsTurtleChunkCrcItem(void *data,uint32_t size) ; // deserialization
virtual bool shouldStampTunnel() const { return true ; }
virtual Direction travelingDirection() const { return DIRECTION_CLIENT ; }
uint32_t chunk_number ;
Sha1CheckSum check_sum ;
virtual std::ostream& print(std::ostream& o, uint16_t) ;
virtual bool serialize(void *data,uint32_t& size) ;
virtual uint32_t serial_size() ;
};

View File

@ -308,7 +308,8 @@ HEADERS += ft/ftchunkmap.h \
ft/ftfilesearch.h \
ft/ftsearch.h \
ft/ftserver.h \
ft/fttransfermodule.h
ft/fttransfermodule.h \
ft/ftturtlefiletransferitem.h
HEADERS += pqi/authssl.h \
pqi/authgpg.h \
@ -448,6 +449,7 @@ SOURCES += ft/ftchunkmap.cc \
ft/ftfilesearch.cc \
ft/ftserver.cc \
ft/fttransfermodule.cc \
ft/ftturtlefiletransferitem.cc
SOURCES += pqi/authgpg.cc \
pqi/authssl.cc \

View File

@ -108,7 +108,7 @@ class RsTurtle
// tunnels for the given hash. The download should be driven by the file
// transfer module by calling ftServer::FileRequest().
//
virtual void monitorTunnels(const std::string& file_hash) = 0 ;
virtual void monitorTunnels(const std::string& file_hash,RsTurtleClientService *client_service) = 0 ;
// Tells the turtle router to stop handling tunnels for the given file hash. Traditionally this should
// be called after calling ftServer::fileCancel().

View File

@ -23,6 +23,10 @@
*
*/
#pragma once
#include <stdint.h>
// This file centralises QoS priorities for all transfer RsItems.
//
const uint8_t QOS_PRIORITY_UNKNOWN = 0 ;

View File

@ -111,8 +111,9 @@ p3turtle::p3turtle(p3LinkMgr *lm,ftServer *fs)
_ft_controller = fs->getController() ;
_random_bias = RSRandom::random_u32() ;
_serialiser = new RsTurtleSerialiser() ;
addSerialType(new RsTurtleSerialiser());
addSerialType(_serialiser);
_last_clean_time = 0 ;
_last_tunnel_management_time = 0 ;
@ -995,7 +996,6 @@ void p3turtle::routeGenericTunnelItem(RsTurtleGenericTunnelItem *item)
std::cerr << "p3Turtle: treating generic tunnel item:" << std::endl ;
item->print(std::cerr,1) ;
#endif
RsTurtleGenericTunnelItem::Direction direction = item->travelingDirection() ;
{
RsStackMutex stack(mTurtleMtx); /********** STACK LOCKED MTX ******/
@ -1021,9 +1021,16 @@ void p3turtle::routeGenericTunnelItem(RsTurtleGenericTunnelItem *item)
tunnel.transfered_bytes += static_cast<RsTurtleItem*>(item)->serial_size() ;
if(item->PeerId() == tunnel.local_dst)
item->setTravelingDirection(RsTurtleGenericTunnelItem::DIRECTION_CLIENT) ;
else if(item->PeerId() == tunnel.local_src)
item->setTravelingDirection(RsTurtleGenericTunnelItem::DIRECTION_SERVER) ;
else
std::cerr << "(EE) critical error in p3turtle::routeGenericTunnelItem(): item mismatches tunnel src/dst ids." << std::endl;
// Let's figure out whether this packet is for us or not.
if(direction == RsTurtleGenericTunnelItem::DIRECTION_CLIENT && tunnel.local_src != mLinkMgr->getOwnId())
if(item->PeerId() == tunnel.local_dst && tunnel.local_src != mLinkMgr->getOwnId()) //direction == RsTurtleGenericTunnelItem::DIRECTION_CLIENT &&
{
#ifdef P3TURTLE_DEBUG
std::cerr << " Forwarding generic item to peer " << tunnel.local_src << std::endl ;
@ -1032,14 +1039,16 @@ void p3turtle::routeGenericTunnelItem(RsTurtleGenericTunnelItem *item)
_traffic_info_buffer.unknown_updn_Bps += static_cast<RsTurtleItem*>(item)->serial_size() ;
if(dynamic_cast<RsTurtleFileDataItem*>(item) != NULL)
item->setPriorityLevel(QOS_PRIORITY_RS_TURTLE_FORWARD_FILE_DATA) ;
// This has been disabled for compilation reasons. Not sure we actually need it.
//
//if(dynamic_cast<RsTurtleFileDataItem*>(item) != NULL)
// item->setPriorityLevel(QOS_PRIORITY_RS_TURTLE_FORWARD_FILE_DATA) ;
sendItem(item) ;
return ;
}
if(direction == RsTurtleGenericTunnelItem::DIRECTION_SERVER && tunnel.local_dst != mLinkMgr->getOwnId())
if(item->PeerId() == tunnel.local_src && tunnel.local_dst != mLinkMgr->getOwnId()) //direction == RsTurtleGenericTunnelItem::DIRECTION_SERVER &&
{
#ifdef P3TURTLE_DEBUG
std::cerr << " Forwarding generic item to peer " << tunnel.local_dst << std::endl ;
@ -1057,198 +1066,31 @@ void p3turtle::routeGenericTunnelItem(RsTurtleGenericTunnelItem *item)
// This is done off-mutex, to avoid various deadlocks
//
switch(item->PacketSubType())
{
case RS_TURTLE_SUBTYPE_FILE_REQUEST: handleRecvFileRequest(dynamic_cast<RsTurtleFileRequestItem *>(item)) ;
break ;
case RS_TURTLE_SUBTYPE_FILE_DATA : handleRecvFileData(dynamic_cast<RsTurtleFileDataItem *>(item)) ;
break ;
case RS_TURTLE_SUBTYPE_FILE_MAP : handleRecvFileMap(dynamic_cast<RsTurtleFileMapItem *>(item)) ;
break ;
case RS_TURTLE_SUBTYPE_FILE_MAP_REQUEST: handleRecvFileMapRequest(dynamic_cast<RsTurtleFileMapRequestItem *>(item)) ;
break ;
case RS_TURTLE_SUBTYPE_FILE_CRC : handleRecvFileCRC32Map(dynamic_cast<RsTurtleFileCrcItem *>(item)) ;
break ;
case RS_TURTLE_SUBTYPE_FILE_CRC_REQUEST: handleRecvFileCRC32MapRequest(dynamic_cast<RsTurtleFileCrcRequestItem *>(item)) ;
break ;
case RS_TURTLE_SUBTYPE_CHUNK_CRC : handleRecvChunkCRC(dynamic_cast<RsTurtleChunkCrcItem *>(item)) ;
break ;
case RS_TURTLE_SUBTYPE_CHUNK_CRC_REQUEST: handleRecvChunkCRCRequest(dynamic_cast<RsTurtleChunkCrcRequestItem *>(item)) ;
break ;
default:
std::cerr << "WARNING: Unknown packet type received: id=" << reinterpret_cast<void*>(item->PacketSubType()) << ". Is somebody trying to poison you ?" << std::endl ;
#ifdef P3TURTLE_DEBUG
exit(-1) ;
#endif
}
handleRecvGenericTunnelItem(item) ;
delete item ;
}
void p3turtle::handleRecvFileRequest(RsTurtleFileRequestItem *item)
void p3turtle::handleRecvGenericTunnelItem(RsTurtleGenericTunnelItem *item)
{
#ifdef P3TURTLE_DEBUG
std::cerr << "p3Turtle: received file request item:" << std::endl ;
std::cerr << "p3Turtle: received Generic tunnel item:" << std::endl ;
item->print(std::cerr,1) ;
#endif
// This is a new request. Let's add it to the request map, and forward it to
// open peers.
TurtleVirtualPeerId vpid ;
uint64_t size ;
TurtleFileHash hash ;
std::string hash ;
std::string vpid ;
RsTurtleClientService *service ;
// Now lock the router
{
RsStackMutex stack(mTurtleMtx); /********** STACK LOCKED MTX ******/
std::map<TurtleTunnelId,TurtleTunnel>::iterator it2(_local_tunnels.find(item->tunnel_id)) ;
std::map<TurtleTunnelId,TurtleTunnel>::iterator it2(_local_tunnels.find(item->tunnelId())) ;
if(it2 == _local_tunnels.end())
{
#ifdef P3TURTLE_DEBUG
std::cerr << "p3turtle: got file request with unknown tunnel id " << (void*)item->tunnel_id << std::endl ;
#endif
return ;
}
TurtleTunnel& tunnel(it2->second) ;
std::map<TurtleFileHash,std::string>::const_iterator it(_outgoing_file_hashes.find(tunnel.hash)) ;
#ifdef P3TURTLE_DEBUG
assert(!tunnel.hash.empty()) ;
assert(it != _outgoing_file_hashes.end()) ;
std::cerr << " This is an endpoint for this file request." << std::endl ;
std::cerr << " Forwarding data request to the multiplexer." << std::endl ;
std::cerr << " using peer_id=" << tunnel.vpid << ", hash=" << tunnel.hash << std::endl ;
#endif
size = 0 ; //it->second.size ; Not used by ftDataMultiplex actually
vpid = tunnel.vpid ;
hash = tunnel.hash ;
}
// This call is voluntarily off-mutex gards because it can cause cross mutex locks with the multiplexer.
// (Yeah, this bug was a shity hard one to catch).
//
_ft_server->getMultiplexer()->recvDataRequest(vpid,hash,size,item->chunk_offset,item->chunk_size) ;
}
void p3turtle::handleRecvFileData(RsTurtleFileDataItem *item)
{
#ifdef P3TURTLE_DEBUG
std::cerr << "p3Turtle: received file data item:" << std::endl ;
item->print(std::cerr,1) ;
#endif
TurtleVirtualPeerId vpid ;
uint64_t size ;
TurtleFileHash hash ;
{
RsStackMutex stack(mTurtleMtx); /********** STACK LOCKED MTX ******/
_traffic_info_buffer.data_dn_Bps += static_cast<RsTurtleItem*>(item)->serial_size() ;
std::map<TurtleTunnelId,TurtleTunnel>::iterator it2(_local_tunnels.find(item->tunnel_id)) ;
if(it2 == _local_tunnels.end())
{
#ifdef P3TURTLE_DEBUG
std::cerr << "p3turtle: got file data with unknown tunnel id " << (void*)item->tunnel_id << std::endl ;
#endif
return ;
}
TurtleTunnel& tunnel(it2->second) ;
std::map<TurtleFileHash,TurtleHashInfo>::iterator it( _incoming_file_hashes.find(tunnel.hash) ) ;
#ifdef P3TURTLE_DEBUG
assert(!tunnel.hash.empty()) ;
#endif
if(it==_incoming_file_hashes.end())
{
#ifdef P3TURTLE_DEBUG
std::cerr << "No tunnel for incoming data. Maybe the tunnel is being closed." << std::endl ;
#endif
return ;
}
#ifdef P3TURTLE_DEBUG
std::cerr << " This is an endpoint for this data chunk." << std::endl ;
std::cerr << " Forwarding data to the multiplexer." << std::endl ;
std::cerr << " using peer_id=" << tunnel.vpid << ", hash=" << tunnel.hash << std::endl ;
#endif
//_ft_server->getMultiplexer()->recvData(tunnel.vpid,tunnel.hash,hash_info.size,item->chunk_offset,item->chunk_size,item->chunk_data) ;
vpid = tunnel.vpid ;
hash = tunnel.hash ;
size = 0 ; // Not used by ftDataMultiplex, see ftDataMultiplex:handleRecvData()
// also update the hash time stamp to show that it's actually being downloaded.
//it->second.time_stamp = time(NULL) ;
}
_ft_server->getMultiplexer()->recvData(vpid,hash,size,item->chunk_offset,item->chunk_size,item->chunk_data) ;
item->chunk_data = NULL ; // this prevents deletion in the destructor of RsFileDataItem, because data will be deleted
// down _ft_server->getMultiplexer()->recvData()...in ftTransferModule::recvFileData
}
void p3turtle::handleRecvFileMapRequest(RsTurtleFileMapRequestItem *item)
{
#ifdef P3TURTLE_DEBUG
std::cerr << "p3Turtle: received file Map item:" << std::endl ;
item->print(std::cerr,1) ;
#endif
std::string hash,vpid ;
{
RsStackMutex stack(mTurtleMtx); /********** STACK LOCKED MTX ******/
std::map<TurtleTunnelId,TurtleTunnel>::iterator it2(_local_tunnels.find(item->tunnel_id)) ;
if(it2 == _local_tunnels.end())
{
#ifdef P3TURTLE_DEBUG
std::cerr << "p3turtle: got file data with unknown tunnel id " << (void*)item->tunnel_id << std::endl ;
#endif
return ;
}
TurtleTunnel& tunnel(it2->second) ;
#ifdef P3TURTLE_DEBUG
assert(!tunnel.hash.empty()) ;
std::cerr << " This is an endpoint for this file map request." << std::endl ;
std::cerr << " Forwarding data to the multiplexer." << std::endl ;
std::cerr << " using peer_id=" << tunnel.vpid << ", hash=" << tunnel.hash << std::endl ;
#endif
// we should check that there is no backward call to the turtle router!
//
hash = tunnel.hash ;
vpid = tunnel.vpid ;
}
_ft_server->getMultiplexer()->recvChunkMapRequest(vpid,hash,item->direction == RsTurtleGenericTunnelItem::DIRECTION_CLIENT) ;
}
void p3turtle::handleRecvFileMap(RsTurtleFileMapItem *item)
{
#ifdef P3TURTLE_DEBUG
std::cerr << "p3Turtle: received file Map item:" << std::endl ;
item->print(std::cerr,1) ;
#endif
std::string hash,vpid ;
{
RsStackMutex stack(mTurtleMtx); /********** STACK LOCKED MTX ******/
std::map<TurtleTunnelId,TurtleTunnel>::iterator it2(_local_tunnels.find(item->tunnel_id)) ;
if(it2 == _local_tunnels.end())
{
#ifdef P3TURTLE_DEBUG
std::cerr << "p3turtle: got file data with unknown tunnel id " << (void*)item->tunnel_id << std::endl ;
std::cerr << "p3turtle: got file CRC32 map with unknown tunnel id " << (void*)item->tunnelId() << std::endl ;
#endif
return ;
}
@ -1266,161 +1108,29 @@ void p3turtle::handleRecvFileMap(RsTurtleFileMapItem *item)
//
vpid = tunnel.vpid ;
hash = tunnel.hash ;
}
_ft_server->getMultiplexer()->recvChunkMap(vpid,hash,item->compressed_map,item->direction == RsTurtleGenericTunnelItem::DIRECTION_CLIENT) ;
}
void p3turtle::handleRecvFileCRC32MapRequest(RsTurtleFileCrcRequestItem *item)
{
#ifdef P3TURTLE_DEBUG
std::cerr << "p3Turtle: received file CRC32 Map Request item:" << std::endl ;
item->print(std::cerr,1) ;
#endif
std::string hash,vpid ;
{
RsStackMutex stack(mTurtleMtx); /********** STACK LOCKED MTX ******/
std::map<TurtleFileHash,TurtleHashInfo>::const_iterator it = _incoming_file_hashes.find(hash) ;
std::map<TurtleTunnelId,TurtleTunnel>::iterator it2(_local_tunnels.find(item->tunnel_id)) ;
if(it2 == _local_tunnels.end())
if(it == _incoming_file_hashes.end())
{
#ifdef P3TURTLE_DEBUG
std::cerr << "p3turtle: got file data with unknown tunnel id " << (void*)item->tunnel_id << std::endl ;
#endif
std::cerr << "p3turtle::handleRecvGenericTunnelItem(): hash " << hash << " for tunnel " << (void*)(it2->first) << " has no attached service! Dropping the item. This is a serious consistency error." << std::endl;
return ;
}
TurtleTunnel& tunnel(it2->second) ;
#ifdef P3TURTLE_DEBUG
assert(!tunnel.hash.empty()) ;
std::cerr << " This is an endpoint for this file crc request." << std::endl ;
std::cerr << " Forwarding data to the multiplexer." << std::endl ;
std::cerr << " using peer_id=" << tunnel.vpid << ", hash=" << tunnel.hash << std::endl ;
#endif
// we should check that there is no backward call to the turtle router!
//
hash = tunnel.hash ;
vpid = tunnel.vpid ;
service = it->second.service ;
}
_ft_server->getMultiplexer()->recvCRC32MapRequest(vpid,hash) ;
service->receiveTurtleData(item,hash,vpid,item->travelingDirection()) ;
}
void p3turtle::handleRecvChunkCRC(RsTurtleChunkCrcItem *item)
{
#ifdef P3TURTLE_DEBUG
std::cerr << "p3Turtle: received file CRC32 Map Request item:" << std::endl ;
item->print(std::cerr,1) ;
#endif
std::string hash,vpid ;
{
RsStackMutex stack(mTurtleMtx); /********** STACK LOCKED MTX ******/
std::map<TurtleTunnelId,TurtleTunnel>::iterator it2(_local_tunnels.find(item->tunnel_id)) ;
if(it2 == _local_tunnels.end())
{
#ifdef P3TURTLE_DEBUG
std::cerr << "p3turtle: chunk crc request with unknown tunnel id " << (void*)item->tunnel_id << std::endl ;
#endif
return ;
}
TurtleTunnel& tunnel(it2->second) ;
#ifdef P3TURTLE_DEBUG
assert(!tunnel.hash.empty()) ;
std::cerr << " This is an endpoint for this file crc request." << std::endl ;
std::cerr << " Forwarding data to the multiplexer." << std::endl ;
std::cerr << " using peer_id=" << tunnel.vpid << ", hash=" << tunnel.hash << std::endl ;
#endif
// we should check that there is no backward call to the turtle router!
//
hash = tunnel.hash ;
vpid = tunnel.vpid ;
}
_ft_server->getMultiplexer()->recvSingleChunkCRC(vpid,hash,item->chunk_number,item->check_sum) ;
}
void p3turtle::handleRecvChunkCRCRequest(RsTurtleChunkCrcRequestItem *item)
{
#ifdef P3TURTLE_DEBUG
std::cerr << "p3Turtle: received file CRC32 Map Request item:" << std::endl ;
item->print(std::cerr,1) ;
#endif
std::string hash,vpid ;
{
RsStackMutex stack(mTurtleMtx); /********** STACK LOCKED MTX ******/
std::map<TurtleTunnelId,TurtleTunnel>::iterator it2(_local_tunnels.find(item->tunnel_id)) ;
if(it2 == _local_tunnels.end())
{
#ifdef P3TURTLE_DEBUG
std::cerr << "p3turtle: chunk crc request with unknown tunnel id " << (void*)item->tunnel_id << std::endl ;
#endif
return ;
}
TurtleTunnel& tunnel(it2->second) ;
#ifdef P3TURTLE_DEBUG
assert(!tunnel.hash.empty()) ;
std::cerr << " This is an endpoint for this file crc request." << std::endl ;
std::cerr << " Forwarding data to the multiplexer." << std::endl ;
std::cerr << " using peer_id=" << tunnel.vpid << ", hash=" << tunnel.hash << std::endl ;
#endif
// we should check that there is no backward call to the turtle router!
//
hash = tunnel.hash ;
vpid = tunnel.vpid ;
}
_ft_server->getMultiplexer()->recvSingleChunkCRCRequest(vpid,hash,item->chunk_number) ;
}
void p3turtle::handleRecvFileCRC32Map(RsTurtleFileCrcItem *item)
{
#ifdef P3TURTLE_DEBUG
std::cerr << "p3Turtle: received file CRC32 Map item:" << std::endl ;
item->print(std::cerr,1) ;
#endif
std::string hash,vpid ;
{
RsStackMutex stack(mTurtleMtx); /********** STACK LOCKED MTX ******/
std::map<TurtleTunnelId,TurtleTunnel>::iterator it2(_local_tunnels.find(item->tunnel_id)) ;
if(it2 == _local_tunnels.end())
{
#ifdef P3TURTLE_DEBUG
std::cerr << "p3turtle: got file CRC32 map with unknown tunnel id " << (void*)item->tunnel_id << std::endl ;
#endif
return ;
}
TurtleTunnel& tunnel(it2->second) ;
#ifdef P3TURTLE_DEBUG
assert(!tunnel.hash.empty()) ;
std::cerr << " This is an endpoint for this file map." << std::endl ;
std::cerr << " Forwarding data to the multiplexer." << std::endl ;
std::cerr << " using peer_id=" << tunnel.vpid << ", hash=" << tunnel.hash << std::endl ;
#endif
// We should check that there is no backward call to the turtle router!
//
vpid = tunnel.vpid ;
hash = tunnel.hash ;
}
_ft_server->getMultiplexer()->recvCRC32Map(vpid,hash,item->crc_map) ;
}
// Send a data request into the correct tunnel for the given file hash
void p3turtle::sendDataRequest(const std::string& peerId, const std::string& , uint64_t, uint64_t offset, uint32_t chunksize)
//
void p3turtle::sendTurtleData(const std::string& virtual_peer_id,RsTurtleGenericTunnelItem *item)
{
RsStackMutex stack(mTurtleMtx); /********** STACK LOCKED MTX ******/
// get the proper tunnel for this file hash and peer id.
std::map<TurtleVirtualPeerId,TurtleTunnelId>::const_iterator it(_virtual_peers.find(peerId)) ;
std::map<TurtleVirtualPeerId,TurtleTunnelId>::const_iterator it(_virtual_peers.find(virtual_peer_id)) ;
if(it == _virtual_peers.end())
{
@ -1432,255 +1142,31 @@ void p3turtle::sendDataRequest(const std::string& peerId, const std::string& , u
TurtleTunnelId tunnel_id = it->second ;
TurtleTunnel& tunnel(_local_tunnels[tunnel_id]) ;
RsTurtleFileRequestItem *item = new RsTurtleFileRequestItem ;
item->tunnel_id = tunnel_id ; // we should randomly select a tunnel, or something more clever.
item->chunk_offset = offset ;
item->chunk_size = chunksize ;
item->PeerId(tunnel.local_dst) ;
#ifdef P3TURTLE_DEBUG
std::cerr << "p3turtle: sending file req (chunksize=" << item->chunk_size << ", offset=" << item->chunk_offset << ", hash=0x" << tunnel.hash << ") through tunnel " << (void*)item->tunnel_id << ", next peer=" << tunnel.local_dst << std::endl ;
#endif
sendItem(item) ;
}
// Send file data into the correct tunnel for the given file hash
void p3turtle::sendFileData(const std::string& peerId, const std::string& , uint64_t, uint64_t offset, uint32_t chunksize, void *data)
{
RsStackMutex stack(mTurtleMtx); /********** STACK LOCKED MTX ******/
// get the proper tunnel for this file hash and peer id.
std::map<TurtleVirtualPeerId,TurtleTunnelId>::const_iterator it(_virtual_peers.find(peerId)) ;
if(it == _virtual_peers.end())
{
#ifdef P3TURTLE_DEBUG
std::cerr << "p3turtle::sendData: cannot find virtual peer " << peerId << " in VP list." << std::endl ;
#endif
return ;
}
TurtleTunnelId tunnel_id = it->second ;
TurtleTunnel& tunnel(_local_tunnels[tunnel_id]) ;
tunnel.time_stamp = time(NULL) ;
RsTurtleFileDataItem *item = new RsTurtleFileDataItem ;
item->tunnel_id = tunnel_id ;
item->chunk_offset = offset ;
item->chunk_size = chunksize ;
item->chunk_data = malloc(chunksize) ;
tunnel.transfered_bytes += static_cast<RsTurtleItem*>(item)->serial_size();
if(item->chunk_data == NULL)
{
std::cerr << "p3turtle: Warning: failed malloc of " << chunksize << " bytes for sending data packet." << std::endl ;
delete item;
return ;
}
memcpy(item->chunk_data,(void*)((uint8_t*)data),chunksize) ;
item->PeerId(tunnel.local_src) ;
#ifdef P3TURTLE_DEBUG
std::cerr << "p3turtle: sending file data (chunksize=" << item->chunk_size << ", offset=" << item->chunk_offset << ", hash=0x" << tunnel.hash << ") through tunnel " << (void*)item->tunnel_id << ", next peer=" << tunnel.local_src << std::endl ;
#endif
_traffic_info_buffer.data_up_Bps += static_cast<RsTurtleItem*>(item)->serial_size() ;
sendItem(item) ;
}
void p3turtle::sendChunkMapRequest(const std::string& peerId,const std::string& ,bool is_client)
{
RsStackMutex stack(mTurtleMtx); /********** STACK LOCKED MTX ******/
// get the proper tunnel for this file hash and peer id.
std::map<TurtleVirtualPeerId,TurtleTunnelId>::const_iterator it(_virtual_peers.find(peerId)) ;
if(it == _virtual_peers.end())
{
#ifdef P3TURTLE_DEBUG
std::cerr << "p3turtle::senddataRequest: cannot find virtual peer " << peerId << " in VP list." << std::endl ;
#endif
return ;
}
TurtleTunnelId tunnel_id = it->second ;
TurtleTunnel& tunnel(_local_tunnels[tunnel_id]) ;
RsTurtleFileMapRequestItem *item = new RsTurtleFileMapRequestItem ;
item->tunnel_id = tunnel_id ;
std::string ownid = mLinkMgr->getOwnId() ;
if(tunnel.local_src == ownid)
{
assert(!is_client) ;
item->direction = RsTurtleGenericTunnelItem::DIRECTION_SERVER ;
item->setTravelingDirection(RsTurtleGenericTunnelItem::DIRECTION_SERVER) ;
item->PeerId(tunnel.local_dst) ;
_traffic_info_buffer.data_dn_Bps += item->serial_size() ;
}
else if(tunnel.local_dst == ownid)
{
assert(is_client) ;
item->direction = RsTurtleGenericTunnelItem::DIRECTION_CLIENT ;
item->setTravelingDirection(RsTurtleGenericTunnelItem::DIRECTION_CLIENT) ;
item->PeerId(tunnel.local_src) ;
_traffic_info_buffer.data_up_Bps += item->serial_size() ;
}
else
std::cerr << "p3turtle::sendChunkMapRequest: consistency error!" << std::endl ;
#ifdef P3TURTLE_DEBUG
std::cerr << "p3turtle: sending chunk map req to peer " << peerId << ", hash=0x" << tunnel.hash << ") through tunnel " << (void*)item->tunnel_id << ", next peer=" << item->PeerId() << std::endl ;
#endif
sendItem(item) ;
}
void p3turtle::sendChunkMap(const std::string& peerId,const std::string& ,const CompressedChunkMap& cmap,bool is_client)
{
RsStackMutex stack(mTurtleMtx); /********** STACK LOCKED MTX ******/
// get the proper tunnel for this file hash and peer id.
std::map<TurtleVirtualPeerId,TurtleTunnelId>::const_iterator it(_virtual_peers.find(peerId)) ;
if(it == _virtual_peers.end())
{
#ifdef P3TURTLE_DEBUG
std::cerr << "p3turtle::senddataRequest: cannot find virtual peer " << peerId << " in VP list." << std::endl ;
#endif
std::cerr << "p3Turtle::sendTurtleData(): asked to send a packet into a tunnel that is not registered. Dropping packet." << std::endl ;
delete item ;
return ;
}
TurtleTunnelId tunnel_id = it->second ;
TurtleTunnel& tunnel(_local_tunnels[tunnel_id]) ;
RsTurtleFileMapItem *item = new RsTurtleFileMapItem ;
item->tunnel_id = tunnel_id ;
item->compressed_map = cmap ;
std::string ownid = mLinkMgr->getOwnId() ;
if(tunnel.local_src == ownid)
{
assert(!is_client) ;
item->direction = RsTurtleGenericTunnelItem::DIRECTION_SERVER ;
item->PeerId(tunnel.local_dst) ;
}
else if(tunnel.local_dst == ownid)
{
assert(is_client) ;
item->direction = RsTurtleGenericTunnelItem::DIRECTION_CLIENT ;
item->PeerId(tunnel.local_src) ;
}
else
std::cerr << "p3turtle::sendChunkMap: consistency error!" << std::endl ;
#ifdef P3TURTLE_DEBUG
std::cerr << "p3turtle: sending chunk map to peer " << peerId << ", hash=0x" << tunnel.hash << ") through tunnel " << (void*)item->tunnel_id << ", next peer=" << item->PeerId() << std::endl ;
#endif
sendItem(item) ;
}
void p3turtle::sendSingleChunkCRC(const std::string& peerId,const std::string&,uint32_t chunk_number,const Sha1CheckSum& crc)
{
RsStackMutex stack(mTurtleMtx); /********** STACK LOCKED MTX ******/
// get the proper tunnel for this file hash and peer id.
std::map<TurtleVirtualPeerId,TurtleTunnelId>::const_iterator it(_virtual_peers.find(peerId)) ;
if(it == _virtual_peers.end())
{
#ifdef P3TURTLE_DEBUG
std::cerr << "p3turtle::sendCRC32MapRequest: cannot find virtual peer " << peerId << " in VP list." << std::endl ;
#endif
return ;
}
TurtleTunnelId tunnel_id = it->second ;
TurtleTunnel& tunnel(_local_tunnels[tunnel_id]) ;
RsTurtleChunkCrcItem *item = new RsTurtleChunkCrcItem;
item->tunnel_id = tunnel_id ;
item->chunk_number = chunk_number ;
item->check_sum = crc ;
item->PeerId(tunnel.local_dst) ;
#ifdef P3TURTLE_DEBUG
std::cerr << "p3turtle: sending CRC32 map request to peer " << peerId << ", hash=0x" << tunnel.hash << ") through tunnel " << (void*)item->tunnel_id << ", next peer=" << item->PeerId() << std::endl ;
#endif
sendItem(item) ;
}
void p3turtle::sendSingleChunkCRCRequest(const std::string& peerId,const std::string&,uint32_t chunk_number)
{
RsStackMutex stack(mTurtleMtx); /********** STACK LOCKED MTX ******/
// get the proper tunnel for this file hash and peer id.
std::map<TurtleVirtualPeerId,TurtleTunnelId>::const_iterator it(_virtual_peers.find(peerId)) ;
if(it == _virtual_peers.end())
{
#ifdef P3TURTLE_DEBUG
std::cerr << "p3turtle::sendCRC32MapRequest: cannot find virtual peer " << peerId << " in VP list." << std::endl ;
#endif
return ;
}
TurtleTunnelId tunnel_id = it->second ;
TurtleTunnel& tunnel(_local_tunnels[tunnel_id]) ;
RsTurtleChunkCrcRequestItem *item = new RsTurtleChunkCrcRequestItem;
item->tunnel_id = tunnel_id ;
item->chunk_number = chunk_number ;
item->PeerId(tunnel.local_dst) ;
#ifdef P3TURTLE_DEBUG
std::cerr << "p3turtle: sending CRC32 map request to peer " << peerId << ", hash=0x" << tunnel.hash << ") through tunnel " << (void*)item->tunnel_id << ", next peer=" << item->PeerId() << std::endl ;
#endif
sendItem(item) ;
}
void p3turtle::sendCRC32MapRequest(const std::string& peerId,const std::string& )
{
RsStackMutex stack(mTurtleMtx); /********** STACK LOCKED MTX ******/
// get the proper tunnel for this file hash and peer id.
std::map<TurtleVirtualPeerId,TurtleTunnelId>::const_iterator it(_virtual_peers.find(peerId)) ;
if(it == _virtual_peers.end())
{
#ifdef P3TURTLE_DEBUG
std::cerr << "p3turtle::sendCRC32MapRequest: cannot find virtual peer " << peerId << " in VP list." << std::endl ;
#endif
return ;
}
TurtleTunnelId tunnel_id = it->second ;
TurtleTunnel& tunnel(_local_tunnels[tunnel_id]) ;
RsTurtleFileCrcRequestItem *item = new RsTurtleFileCrcRequestItem;
item->tunnel_id = tunnel_id ;
// item->crc_map = cmap ;
item->PeerId(tunnel.local_dst) ;
#ifdef P3TURTLE_DEBUG
std::cerr << "p3turtle: sending CRC32 map request to peer " << peerId << ", hash=0x" << tunnel.hash << ") through tunnel " << (void*)item->tunnel_id << ", next peer=" << item->PeerId() << std::endl ;
#endif
sendItem(item) ;
}
void p3turtle::sendCRC32Map(const std::string& peerId,const std::string& ,const CRC32Map& cmap)
{
RsStackMutex stack(mTurtleMtx); /********** STACK LOCKED MTX ******/
// get the proper tunnel for this file hash and peer id.
std::map<TurtleVirtualPeerId,TurtleTunnelId>::const_iterator it(_virtual_peers.find(peerId)) ;
if(it == _virtual_peers.end())
{
#ifdef P3TURTLE_DEBUG
std::cerr << "p3turtle::senddataRequest: cannot find virtual peer " << peerId << " in VP list." << std::endl ;
#endif
return ;
}
TurtleTunnelId tunnel_id = it->second ;
TurtleTunnel& tunnel(_local_tunnels[tunnel_id]) ;
RsTurtleFileCrcItem *item = new RsTurtleFileCrcItem ;
item->tunnel_id = tunnel_id ;
item->crc_map = cmap ;
item->PeerId(tunnel.local_src) ;
#ifdef P3TURTLE_DEBUG
std::cerr << "p3turtle: sending CRC32 map to peer " << peerId << ", hash=0x" << tunnel.hash << ") through tunnel " << (void*)item->tunnel_id << ", next peer=" << item->PeerId() << std::endl ;
std::cerr << "p3turtle: sending service packet to virtual peer id " << virtual_peer_id << ", hash=0x" << tunnel.hash << ", tunnel = " << (void*)item->tunnel_id << ", next peer=" << tunnel.local_dst << std::endl ;
#endif
sendItem(item) ;
}
@ -2302,7 +1788,7 @@ TurtleRequestId p3turtle::turtleSearch(const LinearizedExpression& expr)
return id ;
}
void p3turtle::monitorTunnels(const std::string& hash)
void p3turtle::monitorTunnels(const std::string& hash,RsTurtleClientService *client_service)
{
{
RsStackMutex stack(mTurtleMtx); /********** STACK LOCKED MTX ******/
@ -2338,6 +1824,7 @@ void p3turtle::monitorTunnels(const std::string& hash)
// also should send associated request to the file transfer module.
_incoming_file_hashes[hash].last_digg_time = RSRandom::random_u32()%10 ;
_incoming_file_hashes[hash].service = client_service ;
}
IndicateConfigChanged() ; // initiates saving of handled hashes.
@ -2380,6 +1867,7 @@ void p3turtle::registerTunnelService(RsTurtleClientService *service)
std::cerr << "p3turtle: registered new tunnel service " << (void*)service << std::endl;
_registered_services.push_back(service) ;
_serialiser->registerClientService(service) ;
}
static std::string printFloatNumber(float num,bool friendly=false)

View File

@ -198,7 +198,8 @@ class TurtleHashInfo
public:
std::vector<TurtleTunnelId> tunnels ; // list of active tunnel ids for this file hash
TurtleRequestId last_request ; // last request for the tunnels of this hash
time_t last_digg_time ;
time_t last_digg_time ; // last time the tunnel digging happenned.
RsTurtleClientService *service ; // client service to which items should be sent. Never NULL.
};
// Subclassing:
@ -249,7 +250,7 @@ class p3turtle: public p3Service, public RsTurtle, public p3Config
// This function should be called in addition to ftServer::FileRequest() so that the turtle router
// automatically provide tunnels for the file to download.
//
virtual void monitorTunnels(const std::string& file_hash) ;
virtual void monitorTunnels(const std::string& file_hash,RsTurtleClientService *client_service) ;
/// This should be called when canceling a file download, so that the turtle router stops
/// handling tunnels for this file.
@ -288,7 +289,7 @@ class p3turtle: public p3Service, public RsTurtle, public p3Config
virtual bool saveList(bool& cleanup, std::list<RsItem*>&) ;
virtual bool loadList(std::list<RsItem*>& /*load*/) ;
/************* Communication with ftserver *******************/
/************* Communication with clients *******************/
/// Does the turtle router manages tunnels to this peer ? (this is not a
/// real id, but a fake one, that the turtle router is capable of connecting with a tunnel id).
virtual bool isTurtlePeer(const std::string& peer_id) const ;
@ -307,28 +308,7 @@ class p3turtle: public p3Service, public RsTurtle, public p3Config
void getVirtualPeersList(std::list<pqipeer>& list) ;
/// Send a data request into the correct tunnel for the given file hash
void sendDataRequest(const std::string& peerId, const std::string& hash, uint64_t size, uint64_t offset, uint32_t chunksize) ;
/// Send file data into the correct tunnel for the given file hash
void sendFileData(const std::string& peerId, const std::string& hash, uint64_t size, uint64_t baseoffset, uint32_t chunksize, void *data) ;
/// Send a request for the chunk map of this file to the given peer
void sendChunkMapRequest(const std::string& peerId, const std::string& hash,bool is_client) ;
/// Send a chunk map of this file to the given peer
void sendChunkMap(const std::string& peerId, const std::string& hash,const CompressedChunkMap& cmap,bool is_client) ;
/// Send a request for the crc32 map of this file to the given peer
void sendCRC32MapRequest(const std::string& peerId, const std::string& hash) ;
/// Send a crc32 map of this file to the given peer
void sendCRC32Map(const std::string& peerId, const std::string& hash,const CRC32Map& cmap) ;
/// Send a request for the CRC of a single chunk of this file to the given peer
void sendSingleChunkCRCRequest(const std::string& peerId, const std::string& hash,uint32_t chunk_number) ;
/// Send a crc32 map of this file to the given peer
void sendSingleChunkCRC(const std::string& peerId, const std::string& hash,uint32_t chunk_number,const Sha1CheckSum& sum) ;
void sendTurtleData(const std::string& virtual_peer_id, RsTurtleGenericTunnelItem *item) ;
private:
//--------------------------- Admin/Helper functions -------------------------//
@ -371,18 +351,13 @@ class p3turtle: public p3Service, public RsTurtle, public p3Config
void routeGenericTunnelItem(RsTurtleGenericTunnelItem *item) ;
/// specific routing functions for handling particular packets.
void handleRecvGenericTunnelItem(RsTurtleGenericTunnelItem *item);
// following functions should go to ftServer
void handleSearchRequest(RsTurtleSearchRequestItem *item);
void handleSearchResult(RsTurtleSearchResultItem *item);
void handleTunnelRequest(RsTurtleOpenTunnelItem *item);
void handleTunnelResult(RsTurtleTunnelOkItem *item);
void handleRecvFileRequest(RsTurtleFileRequestItem *item);
void handleRecvFileData(RsTurtleFileDataItem *item);
void handleRecvFileMapRequest(RsTurtleFileMapRequestItem*);
void handleRecvFileMap(RsTurtleFileMapItem*);
void handleRecvFileCRC32MapRequest(RsTurtleFileCrcRequestItem*);
void handleRecvFileCRC32Map(RsTurtleFileCrcItem*);
void handleRecvChunkCRCRequest(RsTurtleChunkCrcRequestItem*);
void handleRecvChunkCRC(RsTurtleChunkCrcItem*);
//------ Functions connecting the turtle router to other components.----------//
@ -401,6 +376,7 @@ class p3turtle: public p3Service, public RsTurtle, public p3Config
p3LinkMgr *mLinkMgr;
ftServer *_ft_server ;
ftController *_ft_controller ;
RsTurtleSerialiser *_serialiser ;
mutable RsMutex mTurtleMtx;

View File

@ -4,6 +4,7 @@
#include <iostream>
#include "turtletypes.h"
#include "rsturtleitem.h"
#include "turtleclientservice.h"
//#define P3TURTLE_DEBUG
// -----------------------------------------------------------------------------------//
@ -90,101 +91,6 @@ uint32_t RsTurtleTunnelOkItem::serial_size()
return s ;
}
uint32_t RsTurtleFileRequestItem::serial_size()
{
uint32_t s = 0 ;
s += 8 ; // header
s += 4 ; // tunnel id
s += 8 ; // file offset
s += 4 ; // chunk size
return s ;
}
uint32_t RsTurtleFileDataItem::serial_size()
{
uint32_t s = 0 ;
s += 8 ; // header
s += 4 ; // tunnel id
s += 8 ; // file offset
s += 4 ; // chunk size
s += chunk_size ; // actual data size.
return s ;
}
uint32_t RsTurtleFileMapRequestItem::serial_size()
{
uint32_t s = 0 ;
s += 8 ; // header
s += 4 ; // tunnel id
s += 4 ; // direction
return s ;
}
uint32_t RsTurtleFileMapItem::serial_size()
{
uint32_t s = 0 ;
s += 8 ; // header
s += 4 ; // tunnel id
s += 4 ; // direction
s += 4 ; // compressed_map.size()
s += 4 * compressed_map._map.size() ;
return s ;
}
uint32_t RsTurtleFileCrcRequestItem::serial_size()
{
uint32_t s = 0 ;
s += 8 ; // header
s += 4 ; // tunnel id
return s ;
}
uint32_t RsTurtleChunkCrcItem::serial_size()
{
uint32_t s = 0 ;
s += 8 ; // header
s += 4 ; // tunnel id
s += 4 ; // chunk number
s += 20 ; // check_sum
return s ;
}
uint32_t RsTurtleChunkCrcRequestItem::serial_size()
{
uint32_t s = 0 ;
s += 8 ; // header
s += 4 ; // tunnel id
s += 4 ; // chunk number
return s ;
}
uint32_t RsTurtleFileCrcItem::serial_size()
{
uint32_t s = 0 ;
s += 8 ; // header
s += 4 ; // tunnel id
s += 4 ; // size of _map
s += 4 ; // size of _crcs
s += 4 * crc_map._crcs.size() ;
s += 4 * crc_map._ccmap._map.size() ;
return s ;
}
//
// ---------------------------------- Serialization ----------------------------------//
//
@ -216,19 +122,31 @@ RsItem *RsTurtleSerialiser::deserialise(void *data, uint32_t *size)
case RS_TURTLE_SUBTYPE_SEARCH_RESULT : return new RsTurtleSearchResultItem(data,*size) ;
case RS_TURTLE_SUBTYPE_OPEN_TUNNEL : return new RsTurtleOpenTunnelItem(data,*size) ;
case RS_TURTLE_SUBTYPE_TUNNEL_OK : return new RsTurtleTunnelOkItem(data,*size) ;
case RS_TURTLE_SUBTYPE_FILE_REQUEST : return new RsTurtleFileRequestItem(data,*size) ;
case RS_TURTLE_SUBTYPE_FILE_DATA : return new RsTurtleFileDataItem(data,*size) ;
case RS_TURTLE_SUBTYPE_FILE_MAP_REQUEST : return new RsTurtleFileMapRequestItem(data,*size) ;
case RS_TURTLE_SUBTYPE_FILE_MAP : return new RsTurtleFileMapItem(data,*size) ;
case RS_TURTLE_SUBTYPE_FILE_CRC_REQUEST : return new RsTurtleFileCrcRequestItem(data,*size) ;
case RS_TURTLE_SUBTYPE_FILE_CRC : return new RsTurtleFileCrcItem(data,*size) ;
case RS_TURTLE_SUBTYPE_CHUNK_CRC_REQUEST : return new RsTurtleChunkCrcRequestItem(data,*size) ;
case RS_TURTLE_SUBTYPE_CHUNK_CRC : return new RsTurtleChunkCrcItem(data,*size) ;
// We need to call some client serialiser from there.
//
// case RS_TURTLE_SUBTYPE_FILE_REQUEST : return new RsTurtleFileRequestItem(data,*size) ;
// case RS_TURTLE_SUBTYPE_FILE_DATA : return new RsTurtleFileDataItem(data,*size) ;
// case RS_TURTLE_SUBTYPE_FILE_MAP_REQUEST : return new RsTurtleFileMapRequestItem(data,*size) ;
// case RS_TURTLE_SUBTYPE_FILE_MAP : return new RsTurtleFileMapItem(data,*size) ;
// case RS_TURTLE_SUBTYPE_FILE_CRC_REQUEST : return new RsTurtleFileCrcRequestItem(data,*size) ;
// case RS_TURTLE_SUBTYPE_FILE_CRC : return new RsTurtleFileCrcItem(data,*size) ;
// case RS_TURTLE_SUBTYPE_CHUNK_CRC_REQUEST : return new RsTurtleChunkCrcRequestItem(data,*size) ;
// case RS_TURTLE_SUBTYPE_CHUNK_CRC : return new RsTurtleChunkCrcItem(data,*size) ;
default:
std::cerr << "Unknown packet type in RsTurtle!" << std::endl ;
return NULL ;
break ;
}
// now try all client services
//
RsItem *item = NULL ;
for(uint32_t i=0;i<_client_services.size();++i)
if((item = _client_services[i]->deserialiseItem(data,*size)) != NULL)
return item ;
std::cerr << "Unknown packet type in RsTurtle (not even handled by client services)!" << std::endl ;
return NULL ;
#ifndef WINDOWS_SYS
}
catch(std::exception& e)
@ -240,224 +158,6 @@ RsItem *RsTurtleSerialiser::deserialise(void *data, uint32_t *size)
}
bool RsTurtleFileMapRequestItem::serialize(void *data,uint32_t& pktsize)
{
uint32_t tlvsize = serial_size();
uint32_t offset = 0;
if (pktsize < tlvsize)
return false; /* not enough space */
pktsize = tlvsize;
bool ok = true;
ok &= setRsItemHeader(data,tlvsize,PacketId(), tlvsize);
/* skip the header */
offset += 8;
/* add mandatory parts first */
ok &= setRawUInt32(data, tlvsize, &offset, tunnel_id);
ok &= setRawUInt32(data, tlvsize, &offset, direction);
if (offset != tlvsize)
{
ok = false;
#ifdef RSSERIAL_DEBUG
std::cerr << "RsFileConfigSerialiser::serialiseTransfer() Size Error! " << std::endl;
#endif
}
return ok;
}
bool RsTurtleFileMapItem::serialize(void *data,uint32_t& pktsize)
{
uint32_t tlvsize = serial_size();
uint32_t offset = 0;
if (pktsize < tlvsize)
return false; /* not enough space */
pktsize = tlvsize;
bool ok = true;
ok &= setRsItemHeader(data,tlvsize,PacketId(), tlvsize);
/* skip the header */
offset += 8;
/* add mandatory parts first */
ok &= setRawUInt32(data, tlvsize, &offset, tunnel_id);
ok &= setRawUInt32(data, tlvsize, &offset, direction);
ok &= setRawUInt32(data, tlvsize, &offset, compressed_map._map.size());
for(uint32_t i=0;i<compressed_map._map.size() && ok;++i)
ok &= setRawUInt32(data, tlvsize, &offset, compressed_map._map[i]);
if (offset != tlvsize)
{
ok = false;
#ifdef RSSERIAL_DEBUG
std::cerr << "RsFileConfigSerialiser::serialiseTransfer() Size Error! " << std::endl;
#endif
}
return ok;
}
bool RsTurtleFileCrcRequestItem::serialize(void *data,uint32_t& pktsize)
{
#ifdef P3TURTLE_DEBUG
std::cerr << "RsTurtleFileCrcRequestItem::serialize(): serializing packet:" << std::endl ;
print(std::cerr,2) ;
#endif
uint32_t tlvsize = serial_size();
uint32_t offset = 0;
if (pktsize < tlvsize)
return false; /* not enough space */
pktsize = tlvsize;
bool ok = true;
ok &= setRsItemHeader(data,tlvsize,PacketId(), tlvsize);
/* skip the header */
offset += 8;
/* add mandatory parts first */
ok &= setRawUInt32(data, tlvsize, &offset, tunnel_id);
if (offset != tlvsize)
{
ok = false;
std::cerr << "RsFileConfigSerialiser::serialiseTransfer() Size Error! " << std::endl;
}
return ok;
}
bool RsTurtleChunkCrcRequestItem::serialize(void *data,uint32_t& pktsize)
{
#ifdef P3TURTLE_DEBUG
std::cerr << "RsTurtleChunkCrcRequestItem::serialize(): serializing packet:" << std::endl ;
print(std::cerr,2) ;
#endif
uint32_t tlvsize = serial_size();
uint32_t offset = 0;
if (pktsize < tlvsize)
return false; /* not enough space */
pktsize = tlvsize;
bool ok = true;
ok &= setRsItemHeader(data,tlvsize,PacketId(), tlvsize);
/* skip the header */
offset += 8;
/* add mandatory parts first */
ok &= setRawUInt32(data, tlvsize, &offset, tunnel_id);
ok &= setRawUInt32(data, tlvsize, &offset, chunk_number);
if (offset != tlvsize)
{
ok = false;
std::cerr << "RsFileConfigSerialiser::serialiseTransfer() Size Error! " << std::endl;
}
return ok;
}
bool RsTurtleFileCrcItem::serialize(void *data,uint32_t& pktsize)
{
#ifdef P3TURTLE_DEBUG
std::cerr << "RsTurtleFileCrcItem::serialize(): serializing packet:" << std::endl ;
print(std::cerr,2) ;
#endif
uint32_t tlvsize = serial_size();
uint32_t offset = 0;
if (pktsize < tlvsize)
return false; /* not enough space */
pktsize = tlvsize;
bool ok = true;
ok &= setRsItemHeader(data,tlvsize,PacketId(), tlvsize);
/* skip the header */
offset += 8;
/* add mandatory parts first */
ok &= setRawUInt32(data, tlvsize, &offset, tunnel_id);
ok &= setRawUInt32(data, tlvsize, &offset, crc_map._ccmap._map.size());
ok &= setRawUInt32(data, tlvsize, &offset, crc_map._crcs.size());
for(uint32_t i=0;i<crc_map._ccmap._map.size() && ok;++i)
ok &= setRawUInt32(data, tlvsize, &offset, crc_map._ccmap._map[i]);
for(uint32_t i=0;i<crc_map._crcs.size() && ok;++i)
ok &= setRawUInt32(data, tlvsize, &offset, crc_map._crcs[i]);
if (offset != tlvsize)
{
ok = false;
std::cerr << "RsFileConfigSerialiser::serialiseTransfer() Size Error! " << std::endl;
}
return ok;
}
bool RsTurtleChunkCrcItem::serialize(void *data,uint32_t& pktsize)
{
#ifdef P3TURTLE_DEBUG
std::cerr << "RsTurtleChunkCrcRequestItem::serialize(): serializing packet:" << std::endl ;
print(std::cerr,2) ;
#endif
uint32_t tlvsize = serial_size();
uint32_t offset = 0;
if (pktsize < tlvsize)
return false; /* not enough space */
pktsize = tlvsize;
bool ok = true;
ok &= setRsItemHeader(data,tlvsize,PacketId(), tlvsize);
/* skip the header */
offset += 8;
/* add mandatory parts first */
ok &= setRawUInt32(data, tlvsize, &offset, tunnel_id);
ok &= setRawUInt32(data, tlvsize, &offset, chunk_number);
ok &= setRawUInt32(data, tlvsize, &offset, check_sum.fourbytes[0]);
ok &= setRawUInt32(data, tlvsize, &offset, check_sum.fourbytes[1]);
ok &= setRawUInt32(data, tlvsize, &offset, check_sum.fourbytes[2]);
ok &= setRawUInt32(data, tlvsize, &offset, check_sum.fourbytes[3]);
ok &= setRawUInt32(data, tlvsize, &offset, check_sum.fourbytes[4]);
if (offset != tlvsize)
{
ok = false;
std::cerr << "RsFileConfigSerialiser::serialiseTransfer() Size Error! " << std::endl;
}
return ok;
}
bool RsTurtleStringSearchRequestItem::serialize(void *data,uint32_t& pktsize)
{
uint32_t tlvsize = serial_size();
@ -648,169 +348,6 @@ bool RsTurtleSearchResultItem::serialize(void *data,uint32_t& pktsize)
return ok;
}
RsTurtleFileMapItem::RsTurtleFileMapItem(void *data,uint32_t pktsize)
: RsTurtleGenericTunnelItem(RS_TURTLE_SUBTYPE_FILE_MAP)
{
setPriorityLevel(QOS_PRIORITY_RS_TURTLE_FILE_MAP) ;
#ifdef P3TURTLE_DEBUG
std::cerr << " type = file map item" << std::endl ;
#endif
uint32_t offset = 8; // skip the header
/* add mandatory parts first */
bool ok = true ;
uint32_t s,d ;
ok &= getRawUInt32(data, pktsize, &offset, &tunnel_id);
ok &= getRawUInt32(data, pktsize, &offset, &d);
direction = d ;
ok &= getRawUInt32(data, pktsize, &offset, &s) ;
compressed_map._map.resize(s) ;
for(uint32_t i=0;i<s && ok;++i)
ok &= getRawUInt32(data, pktsize, &offset, &(compressed_map._map[i])) ;
#ifdef WINDOWS_SYS // No Exceptions in Windows compile. (drbobs).
#else
if (offset != pktsize)
throw std::runtime_error("Size error while deserializing.") ;
if (!ok)
throw std::runtime_error("Unknown error while deserializing.") ;
#endif
}
RsTurtleFileMapRequestItem::RsTurtleFileMapRequestItem(void *data,uint32_t pktsize)
: RsTurtleGenericTunnelItem(RS_TURTLE_SUBTYPE_FILE_MAP_REQUEST)
{
setPriorityLevel(QOS_PRIORITY_RS_TURTLE_FILE_MAP_REQUEST) ;
#ifdef P3TURTLE_DEBUG
std::cerr << " type = file map request item" << std::endl ;
#endif
uint32_t offset = 8; // skip the header
/* add mandatory parts first */
bool ok = true ;
ok &= getRawUInt32(data, pktsize, &offset, &tunnel_id);
ok &= getRawUInt32(data, pktsize, &offset, &direction);
#ifdef WINDOWS_SYS // No Exceptions in Windows compile. (drbobs).
#else
if (offset != pktsize)
throw std::runtime_error("Size error while deserializing.") ;
if (!ok)
throw std::runtime_error("Unknown error while deserializing.") ;
#endif
}
RsTurtleFileCrcItem::RsTurtleFileCrcItem(void *data,uint32_t pktsize)
: RsTurtleGenericTunnelItem(RS_TURTLE_SUBTYPE_FILE_CRC)
{
setPriorityLevel(QOS_PRIORITY_RS_TURTLE_FILE_CRC) ;
#ifdef P3TURTLE_DEBUG
std::cerr << " type = file map item" << std::endl ;
#endif
uint32_t offset = 8; // skip the header
/* add mandatory parts first */
bool ok = true ;
uint32_t s1,s2 ;
ok &= getRawUInt32(data, pktsize, &offset, &tunnel_id);
ok &= getRawUInt32(data, pktsize, &offset, &s1) ;
ok &= getRawUInt32(data, pktsize, &offset, &s2) ;
crc_map._ccmap._map.resize(s1) ;
crc_map._crcs.resize(s2) ;
for(uint32_t i=0;i<s1 && ok;++i)
ok &= getRawUInt32(data, pktsize, &offset, &(crc_map._ccmap._map[i])) ;
for(uint32_t i=0;i<s2 && ok;++i)
ok &= getRawUInt32(data, pktsize, &offset, &(crc_map._crcs[i])) ;
#ifdef WINDOWS_SYS // No Exceptions in Windows compile. (drbobs).
#else
if (offset != pktsize)
throw std::runtime_error("Size error while deserializing.") ;
if (!ok)
throw std::runtime_error("Unknown error while deserializing.") ;
#endif
}
RsTurtleChunkCrcItem::RsTurtleChunkCrcItem(void *data,uint32_t pktsize)
: RsTurtleGenericTunnelItem(RS_TURTLE_SUBTYPE_CHUNK_CRC)
{
setPriorityLevel(QOS_PRIORITY_RS_TURTLE_CHUNK_CRC) ;
#ifdef P3TURTLE_DEBUG
std::cerr << " type = file map item" << std::endl ;
#endif
uint32_t offset = 8; // skip the header
/* add mandatory parts first */
bool ok = true ;
ok &= getRawUInt32(data, pktsize, &offset, &tunnel_id) ;
ok &= getRawUInt32(data, pktsize, &offset, &chunk_number) ;
ok &= getRawUInt32(data, pktsize, &offset, &check_sum.fourbytes[0]) ;
ok &= getRawUInt32(data, pktsize, &offset, &check_sum.fourbytes[1]) ;
ok &= getRawUInt32(data, pktsize, &offset, &check_sum.fourbytes[2]) ;
ok &= getRawUInt32(data, pktsize, &offset, &check_sum.fourbytes[3]) ;
ok &= getRawUInt32(data, pktsize, &offset, &check_sum.fourbytes[4]) ;
#ifdef WINDOWS_SYS // No Exceptions in Windows compile. (drbobs).
#else
if (offset != pktsize)
throw std::runtime_error("Size error while deserializing.") ;
if (!ok)
throw std::runtime_error("Unknown error while deserializing.") ;
#endif
}
RsTurtleFileCrcRequestItem::RsTurtleFileCrcRequestItem(void *data,uint32_t pktsize)
: RsTurtleGenericTunnelItem(RS_TURTLE_SUBTYPE_FILE_CRC_REQUEST)
{
setPriorityLevel(QOS_PRIORITY_RS_TURTLE_FILE_CRC_REQUEST) ;
#ifdef P3TURTLE_DEBUG
std::cerr << " type = file map request item" << std::endl ;
#endif
uint32_t offset = 8; // skip the header
/* add mandatory parts first */
bool ok = true ;
ok &= getRawUInt32(data, pktsize, &offset, &tunnel_id);
#ifdef WINDOWS_SYS // No Exceptions in Windows compile. (drbobs).
#else
if (offset != pktsize)
throw std::runtime_error("Size error while deserializing.") ;
if (!ok)
throw std::runtime_error("Unknown error while deserializing.") ;
#endif
}
RsTurtleChunkCrcRequestItem::RsTurtleChunkCrcRequestItem(void *data,uint32_t pktsize)
: RsTurtleGenericTunnelItem(RS_TURTLE_SUBTYPE_CHUNK_CRC_REQUEST)
{
setPriorityLevel(QOS_PRIORITY_RS_TURTLE_CHUNK_CRC_REQUEST) ;
#ifdef P3TURTLE_DEBUG
std::cerr << " type = file map item" << std::endl ;
#endif
uint32_t offset = 8; // skip the header
/* add mandatory parts first */
bool ok = true ;
ok &= getRawUInt32(data, pktsize, &offset, &tunnel_id) ;
ok &= getRawUInt32(data, pktsize, &offset, &chunk_number) ;
#ifdef WINDOWS_SYS // No Exceptions in Windows compile. (drbobs).
#else
if (offset != pktsize)
throw std::runtime_error("Size error while deserializing.") ;
if (!ok)
throw std::runtime_error("Unknown error while deserializing.") ;
#endif
}
RsTurtleSearchResultItem::RsTurtleSearchResultItem(void *data,uint32_t pktsize)
: RsTurtleItem(RS_TURTLE_SUBTYPE_SEARCH_RESULT)
{
@ -983,146 +520,6 @@ RsTurtleTunnelOkItem::RsTurtleTunnelOkItem(void *data,uint32_t pktsize)
#endif
}
bool RsTurtleFileRequestItem::serialize(void *data,uint32_t& pktsize)
{
uint32_t tlvsize = serial_size();
uint32_t offset = 0;
if (pktsize < tlvsize)
return false; /* not enough space */
pktsize = tlvsize;
bool ok = true;
ok &= setRsItemHeader(data,tlvsize,PacketId(), tlvsize);
/* skip the header */
offset += 8;
/* add mandatory parts first */
ok &= setRawUInt32(data, tlvsize, &offset, tunnel_id) ;
ok &= setRawUInt64(data, tlvsize, &offset, chunk_offset);
ok &= setRawUInt32(data, tlvsize, &offset, chunk_size);
if (offset != tlvsize)
{
ok = false;
#ifdef RSSERIAL_DEBUG
std::cerr << "RsTurtleTunnelOkItem::serialiseTransfer() Size Error! " << std::endl;
#endif
}
return ok;
}
RsTurtleFileRequestItem::RsTurtleFileRequestItem(void *data,uint32_t pktsize)
: RsTurtleGenericTunnelItem(RS_TURTLE_SUBTYPE_FILE_REQUEST)
{
setPriorityLevel(QOS_PRIORITY_RS_TURTLE_FILE_REQUEST) ;
#ifdef P3TURTLE_DEBUG
std::cerr << " type = file request" << std::endl ;
#endif
uint32_t offset = 8; // skip the header
uint32_t rssize = getRsItemSize(data);
/* add mandatory parts first */
bool ok = true ;
ok &= getRawUInt32(data, pktsize, &offset, &tunnel_id) ;
ok &= getRawUInt64(data, pktsize, &offset, &chunk_offset);
ok &= getRawUInt32(data, pktsize, &offset, &chunk_size);
#ifdef P3TURTLE_DEBUG
std::cerr << " tunnel_id=" << (void*)tunnel_id << ", chunk_offset=" << chunk_offset << ", chunk_size=" << chunk_size << std::endl ;
#endif
#ifdef WINDOWS_SYS // No Exceptions in Windows compile. (drbobs).
UNREFERENCED_LOCAL_VARIABLE(rssize);
#else
if (offset != rssize)
throw std::runtime_error("RsTurtleTunnelOkItem::() error while deserializing.") ;
if (!ok)
throw std::runtime_error("RsTurtleTunnelOkItem::() unknown error while deserializing.") ;
#endif
}
RsTurtleFileDataItem::~RsTurtleFileDataItem()
{
free(chunk_data) ;
}
RsTurtleFileDataItem::RsTurtleFileDataItem(void *data,uint32_t pktsize)
: RsTurtleGenericTunnelItem(RS_TURTLE_SUBTYPE_FILE_DATA)
{
setPriorityLevel(QOS_PRIORITY_RS_TURTLE_FILE_DATA) ;
#ifdef P3TURTLE_DEBUG
std::cerr << " type = file request" << std::endl ;
#endif
uint32_t offset = 8; // skip the header
uint32_t rssize = getRsItemSize(data);
/* add mandatory parts first */
bool ok = true ;
ok &= getRawUInt32(data, pktsize, &offset, &tunnel_id) ;
ok &= getRawUInt64(data, pktsize, &offset, &chunk_offset);
ok &= getRawUInt32(data, pktsize, &offset, &chunk_size);
chunk_data = (void*)malloc(chunk_size) ;
memcpy(chunk_data,(void*)((unsigned char*)data+offset),chunk_size) ;
offset += chunk_size ;
#ifdef P3TURTLE_DEBUG
std::cerr << " tunnel_id=" << (void*)tunnel_id << ", chunk_offset=" << chunk_offset << ", chunk_size=" << chunk_size << std::endl ;
#endif
#ifdef WINDOWS_SYS // No Exceptions in Windows compile. (drbobs).
UNREFERENCED_LOCAL_VARIABLE(rssize);
#else
if (offset != rssize)
throw std::runtime_error("RsTurtleFileDataItem::() error while deserializing.") ;
if (!ok)
throw std::runtime_error("RsTurtleFileDataItem::() unknown error while deserializing.") ;
#endif
}
bool RsTurtleFileDataItem::serialize(void *data,uint32_t& pktsize)
{
uint32_t tlvsize = serial_size();
uint32_t offset = 0;
if (pktsize < tlvsize)
return false; /* not enough space */
pktsize = tlvsize;
bool ok = true;
ok &= setRsItemHeader(data,tlvsize,PacketId(), tlvsize);
/* skip the header */
offset += 8;
/* add mandatory parts first */
ok &= setRawUInt32(data, tlvsize, &offset, tunnel_id) ;
ok &= setRawUInt64(data, tlvsize, &offset, chunk_offset);
ok &= setRawUInt32(data, tlvsize, &offset, chunk_size);
memcpy((void*)((unsigned char*)data+offset),chunk_data,chunk_size) ;
offset += chunk_size ;
if (offset != tlvsize)
{
ok = false;
#ifdef RSSERIAL_DEBUG
std::cerr << "RsTurtleTunnelOkItem::serialiseTransfer() Size Error! " << std::endl;
#endif
}
return ok;
}
// -----------------------------------------------------------------------------------//
// ------------------------------------- IO --------------------------------------- //
// -----------------------------------------------------------------------------------//
@ -1190,95 +587,3 @@ std::ostream& RsTurtleTunnelOkItem::print(std::ostream& o, uint16_t)
return o ;
}
std::ostream& RsTurtleFileRequestItem::print(std::ostream& o, uint16_t)
{
o << "File request item:" << std::endl ;
o << " tunnel id : " << std::hex << tunnel_id << std::dec << std::endl ;
o << " offset : " << chunk_offset << std::endl ;
o << " chunk size: " << chunk_size << std::endl ;
return o ;
}
std::ostream& RsTurtleFileDataItem::print(std::ostream& o, uint16_t)
{
o << "File request item:" << std::endl ;
o << " tunnel id : " << std::hex << tunnel_id << std::dec << std::endl ;
o << " offset : " << chunk_offset << std::endl ;
o << " chunk size: " << chunk_size << std::endl ;
o << " data : " << std::hex << chunk_data << std::dec << std::endl ;
return o ;
}
std::ostream& RsTurtleFileMapItem::print(std::ostream& o, uint16_t)
{
o << "File map item:" << std::endl ;
o << " tunnel id : " << std::hex << tunnel_id << std::dec << std::endl ;
o << " direction : " << direction << std::endl ;
o << " map : " ;
for(uint32_t i=0;i<compressed_map._map.size();++i)
o << std::hex << compressed_map._map[i] << std::dec << std::endl ;
return o ;
}
std::ostream& RsTurtleFileMapRequestItem::print(std::ostream& o, uint16_t)
{
o << "File map request item:" << std::endl ;
o << " tunnel id : " << std::hex << tunnel_id << std::dec << std::endl ;
o << " direction : " << direction << std::endl ;
return o ;
}
std::ostream& RsTurtleFileCrcItem::print(std::ostream& o, uint16_t)
{
o << "File CRC item:" << std::endl ;
o << " tunnel id : " << std::hex << tunnel_id << std::dec << std::endl ;
o << " map : " ;
for(uint32_t i=0;i<crc_map._ccmap._map.size();++i)
o << std::hex << crc_map._ccmap._map[i] << std::endl ;
o << " CRC : " ;
for(uint32_t i=0;i<crc_map._crcs.size();++i)
o << std::hex << crc_map._crcs[i] << std::dec << std::endl ;
return o ;
}
std::ostream& RsTurtleFileCrcRequestItem::print(std::ostream& o, uint16_t)
{
o << "File CRC request item:" << std::endl ;
o << " tunnel id : " << std::hex << tunnel_id << std::dec << std::endl ;
return o ;
}
std::ostream& RsTurtleChunkCrcRequestItem::print(std::ostream& o, uint16_t)
{
o << "Chunk CRC request item:" << std::endl ;
o << " tunnel id : " << std::hex << tunnel_id << std::dec << std::endl ;
o << " chunk num : " << chunk_number << std::endl ;
return o ;
}
std::ostream& RsTurtleChunkCrcItem::print(std::ostream& o, uint16_t)
{
o << "Chunk CRC request item:" << std::endl ;
o << " tunnel id : " << std::hex << tunnel_id << std::dec << std::endl ;
o << " chunk num : " << chunk_number << std::endl ;
o << " sha1 sum : " << check_sum.toStdString() << std::endl ;
return o ;
}

View File

@ -172,32 +172,35 @@ class RsTurtleGenericTunnelItem: public RsTurtleItem
/// All tunnels derived from RsTurtleGenericTunnelItem should have a tunnel id to
/// indicate which tunnel they are travelling through.
virtual TurtleTunnelId tunnelId() const = 0 ;
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 = 0 ;
virtual Direction travelingDirection() const { return direction ; }
virtual void setTravelingDirection(Direction d) { direction = d; }
Direction direction ;
uint32_t tunnel_id ; // id of the tunnel to travel through
};
/***********************************************************************************/
/* Turtle File Transfer item classes */
/* Specific Turtle Transfer items */
/***********************************************************************************/
class RsTurtleFileRequestItem: public RsTurtleGenericTunnelItem
// This item can be used by any service to pass-on data into a tunnel.
//
class RsTurtleGenericDataItem: public RsTurtleGenericTunnelItem
{
public:
RsTurtleFileRequestItem() : RsTurtleGenericTunnelItem(RS_TURTLE_SUBTYPE_FILE_REQUEST) { setPriorityLevel(QOS_PRIORITY_RS_TURTLE_FILE_REQUEST);}
RsTurtleFileRequestItem(void *data,uint32_t size) ; // deserialization
RsTurtleGenericDataItem() : RsTurtleGenericTunnelItem(RS_TURTLE_SUBTYPE_GENERIC_DATA) { setPriorityLevel(QOS_PRIORITY_RS_TURTLE_FILE_REQUEST);}
RsTurtleGenericDataItem(void *data,uint32_t size) ; // deserialization
virtual bool shouldStampTunnel() const { return false ; }
virtual TurtleTunnelId tunnelId() const { return tunnel_id ; }
virtual Direction travelingDirection() const { return DIRECTION_SERVER ; }
virtual bool shouldStampTunnel() const { return true ; }
uint32_t tunnel_id ; // id of the tunnel to travel through
uint64_t chunk_offset ;
uint32_t chunk_size ;
uint32_t data_size ;
void *data ;
virtual std::ostream& print(std::ostream& o, uint16_t) ;
protected:
@ -205,176 +208,6 @@ class RsTurtleFileRequestItem: public RsTurtleGenericTunnelItem
virtual uint32_t serial_size() ;
};
class RsTurtleGenericDataItem: public RsTurtleGenericTunnelItem
{
public:
RsTurtleGenericDataItem() : RsTurtleGenericTunnelItem(RS_TURTLE_SUBTYPE_GENERIC_DATA) { setPriorityLevel(QOS_PRIORITY_RS_TURTLE_GENERIC_DATA) ;}
~RsTurtleGenericDataItem() ;
RsTurtleGenericDataItem(void *data,uint32_t size) ; // deserialization
virtual bool shouldStampTunnel() const { return true ; }
virtual TurtleTunnelId tunnelId() const { return tunnel_id ; }
virtual Direction travelingDirection() const { return direction ; }
Direction direction ; // travel direction for this packet (server/client)
uint32_t tunnel_id ; // id of the tunnel to travel through
uint32_t data_size ; // size of the file chunk
void *data ; // actual data.
virtual std::ostream& print(std::ostream& o, uint16_t) ;
virtual bool serialize(void *data,uint32_t& size) ;
virtual uint32_t serial_size() ;
};
class RsTurtleFileDataItem: public RsTurtleGenericTunnelItem
{
public:
RsTurtleFileDataItem() : RsTurtleGenericTunnelItem(RS_TURTLE_SUBTYPE_FILE_DATA) { setPriorityLevel(QOS_PRIORITY_RS_TURTLE_FILE_DATA) ;}
~RsTurtleFileDataItem() ;
RsTurtleFileDataItem(void *data,uint32_t size) ; // deserialization
virtual bool shouldStampTunnel() const { return true ; }
virtual TurtleTunnelId tunnelId() const { return tunnel_id ; }
virtual Direction travelingDirection() const { return DIRECTION_CLIENT ; }
uint32_t tunnel_id ; // id of the tunnel to travel through
uint64_t chunk_offset ; // offset in the file
uint32_t chunk_size ; // size of the file chunk
void *chunk_data ; // actual data.
virtual std::ostream& print(std::ostream& o, uint16_t) ;
virtual bool serialize(void *data,uint32_t& size) ;
virtual uint32_t serial_size() ;
};
class RsTurtleFileMapRequestItem: public RsTurtleGenericTunnelItem
{
public:
RsTurtleFileMapRequestItem() : RsTurtleGenericTunnelItem(RS_TURTLE_SUBTYPE_FILE_MAP_REQUEST) { setPriorityLevel(QOS_PRIORITY_RS_TURTLE_FILE_MAP_REQUEST) ;}
RsTurtleFileMapRequestItem(void *data,uint32_t size) ; // deserialization
virtual bool shouldStampTunnel() const { return false ; }
virtual TurtleTunnelId tunnelId() const { return tunnel_id ; }
virtual Direction travelingDirection() const { return direction ; }
Direction direction ; // travel direction for this packet (server/client)
uint32_t tunnel_id ; // id of the tunnel to travel through. Also used for identifying the file source
// this info from the file size, but this allows a security check.
virtual std::ostream& print(std::ostream& o, uint16_t) ;
virtual bool serialize(void *data,uint32_t& size) ;
virtual uint32_t serial_size() ;
};
class RsTurtleFileMapItem: public RsTurtleGenericTunnelItem
{
public:
RsTurtleFileMapItem() : RsTurtleGenericTunnelItem(RS_TURTLE_SUBTYPE_FILE_MAP) { setPriorityLevel(QOS_PRIORITY_RS_TURTLE_FILE_MAP) ;}
RsTurtleFileMapItem(void *data,uint32_t size) ; // deserialization
virtual bool shouldStampTunnel() const { return false ; }
virtual TurtleTunnelId tunnelId() const { return tunnel_id ; }
virtual Direction travelingDirection() const { return direction ; }
Direction direction ; // travel direction for this packet (server/client)
uint32_t tunnel_id ; // id of the tunnel to travel through. Also used for identifying the file source
// this info from the file size, but this allows a security check.
CompressedChunkMap compressed_map ; // Map info for the file in compressed format. Each *bit* in the array uint's says "I have" or "I don't have"
// by default, we suppose the peer has all the chunks. This info will thus be and-ed
// with the default file map for this source.
virtual std::ostream& print(std::ostream& o, uint16_t) ;
virtual bool serialize(void *data,uint32_t& size) ;
virtual uint32_t serial_size() ;
};
class RsTurtleFileCrcRequestItem: public RsTurtleGenericTunnelItem
{
public:
RsTurtleFileCrcRequestItem() : RsTurtleGenericTunnelItem(RS_TURTLE_SUBTYPE_FILE_CRC_REQUEST) { setPriorityLevel(QOS_PRIORITY_RS_FILE_CRC_REQUEST);}
RsTurtleFileCrcRequestItem(void *data,uint32_t size) ; // deserialization
virtual bool shouldStampTunnel() const { return false ; }
virtual TurtleTunnelId tunnelId() const { return tunnel_id ; }
virtual Direction travelingDirection() const { return DIRECTION_SERVER ; }
uint32_t tunnel_id ; // id of the tunnel to travel through. Also used for identifying the file source
// this info from the file size, but this allows a security check.
virtual std::ostream& print(std::ostream& o, uint16_t) ;
virtual bool serialize(void *data,uint32_t& size) ;
virtual uint32_t serial_size() ;
};
class RsTurtleChunkCrcRequestItem: public RsTurtleGenericTunnelItem
{
public:
RsTurtleChunkCrcRequestItem() : RsTurtleGenericTunnelItem(RS_TURTLE_SUBTYPE_CHUNK_CRC_REQUEST) { setPriorityLevel(QOS_PRIORITY_RS_CHUNK_CRC_REQUEST);}
RsTurtleChunkCrcRequestItem(void *data,uint32_t size) ; // deserialization
virtual bool shouldStampTunnel() const { return false ; }
virtual TurtleTunnelId tunnelId() const { return tunnel_id ; }
virtual Direction travelingDirection() const { return DIRECTION_SERVER ; }
uint32_t tunnel_id ; // id of the tunnel to travel through. Also used for identifying the file source
// this info from the file size, but this allows a security check.
uint32_t chunk_number ; // id of the chunk to CRC.
virtual std::ostream& print(std::ostream& o, uint16_t) ;
virtual bool serialize(void *data,uint32_t& size) ;
virtual uint32_t serial_size() ;
};
class RsTurtleFileCrcItem: public RsTurtleGenericTunnelItem
{
public:
RsTurtleFileCrcItem() : RsTurtleGenericTunnelItem(RS_TURTLE_SUBTYPE_FILE_CRC) { setPriorityLevel(QOS_PRIORITY_RS_FILE_CRC);}
RsTurtleFileCrcItem(void *data,uint32_t size) ; // deserialization
virtual bool shouldStampTunnel() const { return true ; }
virtual TurtleTunnelId tunnelId() const { return tunnel_id ; }
virtual Direction travelingDirection() const { return DIRECTION_CLIENT ; }
uint32_t tunnel_id ; // id of the tunnel to travel through. Also used for identifying the file source
// this info from the file size, but this allows a security check.
CRC32Map crc_map ;// Map info for the file in compressed format. Each *bit* in the array uint's says "I have" or "I don't have"
// by default, we suppose the peer has all the chunks. This info will thus be and-ed
// with the default file map for this source.
virtual std::ostream& print(std::ostream& o, uint16_t) ;
virtual bool serialize(void *data,uint32_t& size) ;
virtual uint32_t serial_size() ;
};
class RsTurtleChunkCrcItem: public RsTurtleGenericTunnelItem
{
public:
RsTurtleChunkCrcItem() : RsTurtleGenericTunnelItem(RS_TURTLE_SUBTYPE_CHUNK_CRC) { setPriorityLevel(QOS_PRIORITY_RS_CHUNK_CRC);}
RsTurtleChunkCrcItem(void *data,uint32_t size) ; // deserialization
virtual bool shouldStampTunnel() const { return true ; }
virtual TurtleTunnelId tunnelId() const { return tunnel_id ; }
virtual Direction travelingDirection() const { return DIRECTION_CLIENT ; }
uint32_t tunnel_id ; // id of the tunnel to travel through. Also used for identifying the file source
// this info from the file size, but this allows a security check.
uint32_t chunk_number ;
Sha1CheckSum check_sum ;
virtual std::ostream& print(std::ostream& o, uint16_t) ;
virtual bool serialize(void *data,uint32_t& size) ;
virtual uint32_t serial_size() ;
};
/***********************************************************************************/
/* Turtle Serialiser class */
/***********************************************************************************/
@ -393,5 +226,14 @@ class RsTurtleSerialiser: public RsSerialType
return dynamic_cast<RsTurtleItem *>(item)->serialize(data,*size) ;
}
virtual RsItem *deserialise (void *data, uint32_t *size) ;
// 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 ;
};

View File

@ -0,0 +1,88 @@
/*
* libretroshare/src/services: turtleclientservice.h
*
* Services for RetroShare.
*
* Copyright 2013 by Cyril Soler
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License Version 2 as published by the Free Software Foundation.
*
* This library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
* USA.
*
* Please report all bugs and problems to "csoler@users.sourceforge.net".
*
*/
// This class is the parent class for any service that will use the turtle router to distribute its packets.
// Typical representative clients include:
//
// p3ChatService: opens tunnels to distant peers for chatting
// ftServer: searches and open tunnels to distant sources for file transfer
//
#pragma once
#include <string>
#include <stdlib.h>
#include <serialiser/rsserial.h>
#include <turtle/rsturtleitem.h>
class RsItem ;
class RsTurtleClientService
{
public:
// Handling of tunnel request for the given hash. Most of the time, it's a search in a predefined list.
// The output info_string is used by the turtle router to display info about tunnels it manages. It is
// not passed to the tunnel.
virtual bool handleTunnelRequest(const std::string& hash,const std::string& peer_id,std::string& description_info_string) { return false ; }
// This method is called by the turtle router to send data that comes out of a turtle tunnel.
// The turtle router stays responsible for the memory management of data. Most of the time the
// data chunk is a serialized item to be de-serialized by the client service.
//
// Parameters:
// virtual_peer_id : name of the tunnel that sent the data
// data : memory chunk for the data
// size : size of data
// item->direction : direction of travel:
// RsTurtleGenericTunnelItem::DIRECTION_CLIENT: the service is acting as a client
// RsTurtleGenericTunnelItem::DIRECTION_CLIENT: the service is acting as a server
//
// Most of the time this parameter is not used by services, except when some info (such as chunk maps, chat items, etc) go
// both ways, and their nature cannot suffice to determine where they should be handled.
//
// By default (if not overloaded), the method will just free the data, as any subclass should do as well.
//
virtual void receiveTurtleData(void *data,uint32_t size,const std::string& hash,const std::string& virtual_peer_id,RsTurtleGenericTunnelItem::Direction direction)
{
std::cerr << "!!!!!! Received Data from turtle router, but the client service is not handling it !!!!!!!!!!" << std::endl ;
}
// This method does the exact same job, but the item is already de-serialized. It is kept for
// compatibility reasons only. New services should not use it, only the file transfer should.
virtual void receiveTurtleData(RsTurtleGenericTunnelItem *item,const std::string& hash,const std::string& virtual_peer_id,RsTurtleGenericTunnelItem::Direction direction)
{
std::cerr << "!!!!!! Received Data from turtle router, but the client service is not handling it !!!!!!!!!!" << std::endl ;
}
// Method for deserialising specific items of the client service. The
// method has a default behavior of not doing anything, since most client
// services might only use the generic item already provided by the turtle
// router: RsTurtleGenericDataItem
virtual RsTurtleGenericTunnelItem *deserialiseItem(void *data, uint32_t size) const { return NULL ; }
};