mirror of
https://github.com/RetroShare/RetroShare.git
synced 2025-05-02 06:06:10 -04:00
First implementation of per-chunk CRC32 check. This is triggered
- by the right-click+Force Check on files. - when a global hash on a downloaded file does not match the announced hash. When a CRC map check is ordered, the CRC map is requested to one of the sources for the current file download. When received, all downloaded chunks are checked w.r.t the reference CRC and marked as not done if the CRCs do not match. The exchange of CRC32 map and requests has been tested, as well as CRC map checking during download (force check). To be implemented soon: - caching of CRC32 maps (although these are fast to compute) - CRC32 map packets for normal downloads. For now these work only for turtle tunnels. - handling of errors if the CRC never comes. For now, the download will stay stuck in "Checking..." mode. So, don't play too much with the force check feature for now... git-svn-id: http://svn.code.sf.net/p/retroshare/code/trunk@3310 b45a01b8-16f6-495d-af2f-9b41ad6348cc
This commit is contained in:
parent
db034b026f
commit
8bfc74485a
27 changed files with 1012 additions and 118 deletions
|
@ -23,6 +23,8 @@
|
|||
*
|
||||
*/
|
||||
|
||||
//#define P3TURTLE_DEBUG
|
||||
|
||||
#include <stdexcept>
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
|
@ -856,10 +858,16 @@ void p3turtle::routeGenericTunnelItem(RsTurtleGenericTunnelItem *item)
|
|||
|
||||
case RS_TURTLE_SUBTYPE_FILE_MAP_REQUEST: handleRecvFileMapRequest(dynamic_cast<RsTurtleFileMapRequestItem *>(item)) ;
|
||||
break ;
|
||||
default:
|
||||
std::cerr << "WARNING: Unknown packet type received: id=" << (void*)(item->PacketSubType()) << ". Is somebody trying to DOS you ?" << std::endl ;
|
||||
|
||||
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 ;
|
||||
default:
|
||||
std::cerr << "WARNING: Unknown packet type received: id=" << (void*)(item->PacketSubType()) << ". Is somebody trying to poison you ?" << std::endl ;
|
||||
#ifdef P3TURTLE_DEBUG
|
||||
exit(-1) ;
|
||||
exit(-1) ;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -1043,6 +1051,79 @@ void p3turtle::handleRecvFileMap(RsTurtleFileMapItem *item)
|
|||
_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<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 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()->recvCRCMapRequest(vpid,hash) ;
|
||||
}
|
||||
|
||||
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()->recvCRCMap(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& hash, uint64_t, uint64_t offset, uint32_t chunksize)
|
||||
{
|
||||
|
@ -1210,55 +1291,66 @@ void p3turtle::sendChunkMap(const std::string& peerId,const std::string& hash,co
|
|||
sendItem(item) ;
|
||||
}
|
||||
|
||||
// This function is actually not needed: Search request to the turtle router are:
|
||||
// - distant search requests, handled by the router
|
||||
// - search requests over files being downloaded, handled by rsFiles !!
|
||||
//
|
||||
//bool p3turtle::search(std::string hash, uint64_t, uint32_t hintflags, FileInfo &info) const
|
||||
//{
|
||||
// if(! (hintflags & RS_FILE_HINTS_TURTLE)) // this should not happen, but it's a security.
|
||||
// return false;
|
||||
//
|
||||
// RsStackMutex stack(mTurtleMtx); /********** STACK LOCKED MTX ******/
|
||||
//
|
||||
//#ifdef P3TURTLE_DEBUG
|
||||
// std::cerr << "p3turtle: received file search request for hash " << hash << "." << std::endl ;
|
||||
//#endif
|
||||
//
|
||||
// std::map<TurtleFileHash,TurtleFileHashInfo>::const_iterator it = _incoming_file_hashes.find(hash) ;
|
||||
//
|
||||
// if(_incoming_file_hashes.end() != it)
|
||||
// {
|
||||
// info.fname = it->second.name;
|
||||
// info.size = it->second.size;
|
||||
// info.hash = it->first;
|
||||
//
|
||||
// for(unsigned int i=0;i<it->second.tunnels.size();++i)
|
||||
// {
|
||||
// TransferInfo ti;
|
||||
// ti.peerId = getTurtlePeerId(it->second.tunnels[i]);
|
||||
// ti.name = "Distant peer for hash=" + hash ;
|
||||
// ti.tfRate = 0;
|
||||
// info.peers.push_back(ti);
|
||||
// }
|
||||
//
|
||||
//#ifdef P3TURTLE_DEBUG
|
||||
// std::cerr << " Found these tunnels for that hash:. "<< std::endl ;
|
||||
// for(unsigned int i=0;i<it->second.tunnels.size();++i)
|
||||
// std::cerr << " " << (void*)it->second.tunnels[i] << std::endl ;
|
||||
//
|
||||
// std::cerr << " answered yes. "<< std::endl ;
|
||||
//#endif
|
||||
// return true ;
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
//#ifdef P3TURTLE_DEBUG
|
||||
// std::cerr << " responding false." << std::endl ;
|
||||
//#endif
|
||||
// return false ;
|
||||
// }
|
||||
//}
|
||||
void p3turtle::sendCRC32MapRequest(const std::string& peerId,const std::string& hash)
|
||||
{
|
||||
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]) ;
|
||||
|
||||
#ifdef P3TURTLE_DEBUG
|
||||
assert(hash == tunnel.hash) ;
|
||||
#endif
|
||||
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" << 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& hash,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]) ;
|
||||
|
||||
#ifdef P3TURTLE_DEBUG
|
||||
assert(hash == tunnel.hash) ;
|
||||
#endif
|
||||
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" << hash << ") through tunnel " << (void*)item->tunnel_id << ", next peer=" << item->PeerId() << std::endl ;
|
||||
#endif
|
||||
sendItem(item) ;
|
||||
}
|
||||
|
||||
bool p3turtle::isTurtlePeer(const std::string& peer_id) const
|
||||
{
|
||||
|
|
|
@ -289,6 +289,12 @@ class p3turtle: public p3Service, public pqiMonitor, public RsTurtle,/* public f
|
|||
/// Send a chunk map of this file to the given peer
|
||||
void sendChunkMap(const std::string& peerId, const std::string& hash,const CompressedChunkMap& cmap) ;
|
||||
|
||||
/// 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) ;
|
||||
|
||||
private:
|
||||
//--------------------------- Admin/Helper functions -------------------------//
|
||||
|
||||
|
@ -338,6 +344,8 @@ class p3turtle: public p3Service, public pqiMonitor, public RsTurtle,/* public f
|
|||
void handleRecvFileData(RsTurtleFileDataItem *item);
|
||||
void handleRecvFileMapRequest(RsTurtleFileMapRequestItem*);
|
||||
void handleRecvFileMap(RsTurtleFileMapItem*);
|
||||
void handleRecvFileCRC32MapRequest(RsTurtleFileCrcRequestItem*);
|
||||
void handleRecvFileCRC32Map(RsTurtleFileCrcItem*);
|
||||
|
||||
//------ Functions connecting the turtle router to other components.----------//
|
||||
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
#include "turtletypes.h"
|
||||
#include "rsturtleitem.h"
|
||||
|
||||
//#define P3TURTLE_DEBUG
|
||||
// -----------------------------------------------------------------------------------//
|
||||
// -------------------------------- Serialization. --------------------------------- //
|
||||
// -----------------------------------------------------------------------------------//
|
||||
|
@ -139,6 +140,31 @@ uint32_t RsTurtleFileMapItem::serial_size()
|
|||
return s ;
|
||||
}
|
||||
|
||||
uint32_t RsTurtleFileCrcRequestItem::serial_size()
|
||||
{
|
||||
uint32_t s = 0 ;
|
||||
|
||||
s += 8 ; // header
|
||||
s += 4 ; // tunnel id
|
||||
|
||||
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._map._map.size() ;
|
||||
|
||||
return s ;
|
||||
}
|
||||
//
|
||||
// ---------------------------------- Serialization ----------------------------------//
|
||||
//
|
||||
|
@ -174,6 +200,8 @@ RsItem *RsTurtleSerialiser::deserialise(void *data, uint32_t *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) ;
|
||||
|
||||
default:
|
||||
std::cerr << "Unknown packet type in RsTurtle!" << std::endl ;
|
||||
|
@ -260,6 +288,82 @@ bool RsTurtleFileMapItem::serialize(void *data,uint32_t& pktsize)
|
|||
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 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._map._map.size());
|
||||
ok &= setRawUInt32(data, tlvsize, &offset, crc_map._crcs.size());
|
||||
|
||||
for(uint32_t i=0;i<crc_map._map._map.size() && ok;++i)
|
||||
ok &= setRawUInt32(data, tlvsize, &offset, crc_map._map._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 RsTurtleStringSearchRequestItem::serialize(void *data,uint32_t& pktsize)
|
||||
{
|
||||
uint32_t tlvsize = serial_size();
|
||||
|
@ -504,6 +608,62 @@ RsTurtleFileMapRequestItem::RsTurtleFileMapRequestItem(void *data,uint32_t pktsi
|
|||
#endif
|
||||
}
|
||||
|
||||
RsTurtleFileCrcItem::RsTurtleFileCrcItem(void *data,uint32_t pktsize)
|
||||
: RsTurtleGenericTunnelItem(RS_TURTLE_SUBTYPE_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._map._map.resize(s1) ;
|
||||
crc_map._crcs.resize(s2) ;
|
||||
|
||||
for(uint32_t i=0;i<s1 && ok;++i)
|
||||
ok &= getRawUInt32(data, pktsize, &offset, &(crc_map._map._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
|
||||
}
|
||||
|
||||
RsTurtleFileCrcRequestItem::RsTurtleFileCrcRequestItem(void *data,uint32_t pktsize)
|
||||
: RsTurtleGenericTunnelItem(RS_TURTLE_SUBTYPE_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
|
||||
}
|
||||
|
||||
RsTurtleSearchResultItem::RsTurtleSearchResultItem(void *data,uint32_t pktsize)
|
||||
: RsTurtleItem(RS_TURTLE_SUBTYPE_SEARCH_RESULT)
|
||||
{
|
||||
|
@ -925,3 +1085,28 @@ std::ostream& RsTurtleFileMapRequestItem::print(std::ostream& o, uint16_t)
|
|||
return o ;
|
||||
}
|
||||
|
||||
std::ostream& RsTurtleFileCrcItem::print(std::ostream& o, uint16_t)
|
||||
{
|
||||
o << "File CRC item:" << std::endl ;
|
||||
|
||||
o << " tunnel id : " << (void*)tunnel_id << std::endl ;
|
||||
o << " map : " ;
|
||||
|
||||
for(uint32_t i=0;i<crc_map._map._map.size();++i)
|
||||
o << (void*)crc_map._map._map[i] << std::endl ;
|
||||
|
||||
o << " CRC : " ;
|
||||
|
||||
for(uint32_t i=0;i<crc_map._crcs.size();++i)
|
||||
o << (void*)crc_map._crcs[i] << std::endl ;
|
||||
|
||||
return o ;
|
||||
}
|
||||
std::ostream& RsTurtleFileCrcRequestItem::print(std::ostream& o, uint16_t)
|
||||
{
|
||||
o << "File CRC request item:" << std::endl ;
|
||||
|
||||
o << " tunnel id : " << (void*)tunnel_id << std::endl ;
|
||||
|
||||
return o ;
|
||||
}
|
||||
|
|
|
@ -20,6 +20,8 @@ const uint8_t RS_TURTLE_SUBTYPE_FILE_DATA = 0x08 ;
|
|||
const uint8_t RS_TURTLE_SUBTYPE_REGEXP_SEARCH_REQUEST = 0x09 ;
|
||||
const uint8_t RS_TURTLE_SUBTYPE_FILE_MAP = 0x10 ;
|
||||
const uint8_t RS_TURTLE_SUBTYPE_FILE_MAP_REQUEST = 0x11 ;
|
||||
const uint8_t RS_TURTLE_SUBTYPE_FILE_CRC = 0x12 ;
|
||||
const uint8_t RS_TURTLE_SUBTYPE_FILE_CRC_REQUEST = 0xfe ; // test value
|
||||
|
||||
/***********************************************************************************/
|
||||
/* Basic Turtle Item Class */
|
||||
|
@ -269,6 +271,50 @@ class RsTurtleFileMapItem: public RsTurtleGenericTunnelItem
|
|||
virtual uint32_t serial_size() ;
|
||||
};
|
||||
|
||||
class RsTurtleFileCrcRequestItem: public RsTurtleGenericTunnelItem
|
||||
{
|
||||
public:
|
||||
RsTurtleFileCrcRequestItem() : RsTurtleGenericTunnelItem(RS_TURTLE_SUBTYPE_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.
|
||||
|
||||
// CompressedChunkMap _map ; // list of chunks for which we need the 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) {}
|
||||
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() ;
|
||||
};
|
||||
|
||||
/***********************************************************************************/
|
||||
/* Turtle Serialiser class */
|
||||
/***********************************************************************************/
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue