- removed _sharing_strategy and the methods that go with it, as its behavior is handled by the sessionEnabled() method

- added generic tunnel data item, along with item priority consts. Serialization still missing.
- added new class for turtle client services, and entry point methods.
- removed file name and file size ffrom _outgoing_file_hashes and _incoming_file_hashes. They are not needed.
- changed some names to more generic ones.



git-svn-id: http://svn.code.sf.net/p/retroshare/code/branches/v0.5-GenericTunneling@6285 b45a01b8-16f6-495d-af2f-9b41ad6348cc
This commit is contained in:
csoler 2013-04-01 21:18:58 +00:00
parent 3bf08d809b
commit 270abcdc94
10 changed files with 349 additions and 272 deletions

View File

@ -644,7 +644,7 @@ void ftController::locked_checkQueueElement(uint32_t pos)
_queue[pos]->mState = ftFileControl::DOWNLOADING ; _queue[pos]->mState = ftFileControl::DOWNLOADING ;
if(_queue[pos]->mFlags & RS_FILE_REQ_ANONYMOUS_ROUTING) if(_queue[pos]->mFlags & RS_FILE_REQ_ANONYMOUS_ROUTING)
mTurtle->monitorFileTunnels(_queue[pos]->mName,_queue[pos]->mHash,_queue[pos]->mSize) ; mTurtle->monitorTunnels(_queue[pos]->mHash) ;
} }
if(pos >= _max_active_downloads && _queue[pos]->mState != ftFileControl::QUEUED && _queue[pos]->mState != ftFileControl::PAUSED) if(pos >= _max_active_downloads && _queue[pos]->mState != ftFileControl::QUEUED && _queue[pos]->mState != ftFileControl::PAUSED)
@ -653,7 +653,7 @@ void ftController::locked_checkQueueElement(uint32_t pos)
_queue[pos]->mCreator->closeFile() ; _queue[pos]->mCreator->closeFile() ;
if(_queue[pos]->mFlags & RS_FILE_REQ_ANONYMOUS_ROUTING) if(_queue[pos]->mFlags & RS_FILE_REQ_ANONYMOUS_ROUTING)
mTurtle->stopMonitoringFileTunnels(_queue[pos]->mHash) ; mTurtle->stopMonitoringTunnels(_queue[pos]->mHash) ;
} }
} }
@ -897,7 +897,7 @@ bool ftController::completeFile(std::string hash)
mDownloads.erase(it); mDownloads.erase(it);
if(flags & RS_FILE_REQ_ANONYMOUS_ROUTING) if(flags & RS_FILE_REQ_ANONYMOUS_ROUTING)
mTurtle->stopMonitoringFileTunnels(hash_to_suppress) ; mTurtle->stopMonitoringTunnels(hash_to_suppress) ;
} /******* UNLOCKED ********/ } /******* UNLOCKED ********/
@ -1262,7 +1262,7 @@ bool ftController::FileRequest(const std::string& fname, const std::string& has
// We check that flags are consistent. // We check that flags are consistent.
if(flags & RS_FILE_REQ_ANONYMOUS_ROUTING) if(flags & RS_FILE_REQ_ANONYMOUS_ROUTING)
mTurtle->monitorFileTunnels(fname,hash,size) ; mTurtle->monitorTunnels(hash) ;
bool assume_availability = flags & RS_FILE_REQ_CACHE ; // assume availability for cache files bool assume_availability = flags & RS_FILE_REQ_CACHE ; // assume availability for cache files
@ -1363,7 +1363,7 @@ bool ftController::setChunkStrategy(const std::string& hash,FileChunksInfo::Chun
bool ftController::FileCancel(const std::string& hash) bool ftController::FileCancel(const std::string& hash)
{ {
rsTurtle->stopMonitoringFileTunnels(hash) ; rsTurtle->stopMonitoringTunnels(hash) ;
#ifdef CONTROL_DEBUG #ifdef CONTROL_DEBUG
std::cerr << "ftController::FileCancel" << std::endl; std::cerr << "ftController::FileCancel" << std::endl;

View File

@ -1085,7 +1085,7 @@ bool ftDataMultiplex::locked_handleServerRequest(ftFileProvider *provider,
std::string peerId, std::string hash, uint64_t size, std::string peerId, std::string hash, uint64_t size,
uint64_t offset, uint32_t chunksize) uint64_t offset, uint32_t chunksize)
{ {
if(chunksize > std::min(size,uint64_t(10*1024*1024))) if(chunksize > uint32_t(10*1024*1024))
{ {
std::cerr << "Warning: peer " << peerId << " is asking a large chunk (s=" << chunksize << ") for hash " << hash << ", filesize=" << size << ". This is unexpected." << std::endl ; std::cerr << "Warning: peer " << peerId << " is asking a large chunk (s=" << chunksize << ") for hash " << hash << ", filesize=" << size << ". This is unexpected." << std::endl ;
return false ; return false ;

View File

@ -153,6 +153,12 @@ bool ftFileProvider::getFileData(const std::string& peer_id,uint64_t offset, uin
* FIXME: Warning of comparison between unsigned and signed int? * FIXME: Warning of comparison between unsigned and signed int?
*/ */
if(offset >= mSize)
{
std::cerr << "ftFileProvider::getFileData(): request (" << offset << ") exceeds file size (" << mSize << "! " << std::endl;
return false ;
}
uint32_t data_size = chunk_size; uint32_t data_size = chunk_size;
uint64_t base_loc = offset; uint64_t base_loc = offset;

View File

@ -28,6 +28,7 @@
#include "util/rsdebug.h" #include "util/rsdebug.h"
#include "util/rsdir.h" #include "util/rsdir.h"
#include "retroshare/rstypes.h" #include "retroshare/rstypes.h"
#include "retroshare/rspeers.h"
const int ftserverzone = 29539; const int ftserverzone = 29539;
#include "ft/ftserver.h" #include "ft/ftserver.h"
@ -153,6 +154,7 @@ void ftServer::connectToTurtleRouter(p3turtle *fts)
mTurtleRouter = fts ; mTurtleRouter = fts ;
mFtController->setTurtleRouter(fts) ; mFtController->setTurtleRouter(fts) ;
fts->registerTunnelService(this) ;
} }
void ftServer::StartupThreads() void ftServer::StartupThreads()
@ -450,6 +452,37 @@ bool ftServer::FileDetails(const std::string &hash, FileSearchFlags hintflags, F
return false; return false;
} }
bool ftServer::handleTunnelRequest(const std::string& hash,const std::string& peer_id,std::string& description_info_string)
{
FileInfo info ;
bool res = FileDetails(hash, RS_FILE_HINTS_NETWORK_WIDE | RS_FILE_HINTS_LOCAL | RS_FILE_HINTS_EXTRA | RS_FILE_HINTS_SPEC_ONLY | RS_FILE_HINTS_DOWNLOAD, info);
#ifdef SERVER_DEBUG
std::cerr << "ftServer: performing local hash search for hash " << hash << std::endl;
if(res)
{
std::cerr << "Found hash: " << std::endl;
std::cerr << " hash = " << hash << std::endl;
std::cerr << " peer = " << peer_id << std::endl;
std::cerr << " flags = " << info.storage_permission_flags << std::endl;
std::cerr << " local = " << rsFiles->FileDetails(hash, RS_FILE_HINTS_NETWORK_WIDE | RS_FILE_HINTS_LOCAL | RS_FILE_HINTS_EXTRA | RS_FILE_HINTS_SPEC_ONLY | RS_FILE_HINTS_DOWNLOAD, info) << std::endl;
std::cerr << " groups= " ; for(std::list<std::string>::const_iterator it(info.parent_groups.begin());it!=info.parent_groups.end();++it) std::cerr << (*it) << ", " ; std::cerr << std::endl;
std::cerr << " clear = " << rsPeers->computePeerPermissionFlags(peer_id,info.storage_permission_flags,info.parent_groups) << std::endl;
}
#endif
// The call to computeHashPeerClearance() return a combination of RS_FILE_HINTS_NETWORK_WIDE and RS_FILE_HINTS_BROWSABLE
// This is an additional computation cost, but the way it's written here, it's only called when res is true.
//
res = res && (RS_FILE_HINTS_NETWORK_WIDE & rsPeers->computePeerPermissionFlags(peer_id,info.storage_permission_flags,info.parent_groups)) ;
if(res)
description_info_string = info.fname ;
return res ;
}
/***************************************************************/ /***************************************************************/
/******************* ExtraFileList Access **********************/ /******************* ExtraFileList Access **********************/
/***************************************************************/ /***************************************************************/

View File

@ -44,6 +44,7 @@
#include <iostream> #include <iostream>
#include "ft/ftdata.h" #include "ft/ftdata.h"
#include "turtle/turtleclientservice.h"
#include "retroshare/rsfiles.h" #include "retroshare/rsfiles.h"
//#include "dbase/cachestrapper.h" //#include "dbase/cachestrapper.h"
@ -72,7 +73,7 @@ class ftDwlQueue;
class p3PeerMgr; class p3PeerMgr;
class p3LinkMgr; class p3LinkMgr;
class ftServer: public RsFiles, public ftDataSend, public RsThread class ftServer: public RsFiles, public ftDataSend, public RsTurtleClientService, public RsThread
{ {
public: public:
@ -111,6 +112,10 @@ virtual void run();
// string bugs. // string bugs.
static bool checkHash(const std::string& hash,std::string& error_string) ; static bool checkHash(const std::string& hash,std::string& error_string) ;
// Implements RsTurtleClientService
//
virtual bool handleTunnelRequest(const std::string& hash,const std::string& peer_id,std::string& description_info_string) ;
/***************************************************************/ /***************************************************************/
/*************** Control Interface *****************************/ /*************** Control Interface *****************************/
/************** (Implements RsFiles) ***************************/ /************** (Implements RsFiles) ***************************/

View File

@ -34,6 +34,7 @@
#include <vector> #include <vector>
class LinearizedExpression ; class LinearizedExpression ;
class RsTurtleClientService ;
class RsTurtle; class RsTurtle;
extern RsTurtle *rsTurtle ; extern RsTurtle *rsTurtle ;
@ -83,8 +84,6 @@ class TurtleTrafficStatisticsInfo
class RsTurtle class RsTurtle
{ {
public: public:
enum FileSharingStrategy { SHARE_ENTIRE_NETWORK, SHARE_FRIENDS_ONLY } ;
RsTurtle() {} RsTurtle() {}
virtual ~RsTurtle() {} virtual ~RsTurtle() {}
@ -103,23 +102,27 @@ class RsTurtle
virtual TurtleRequestId turtleSearch(const std::string& match_string) = 0 ; virtual TurtleRequestId turtleSearch(const std::string& match_string) = 0 ;
virtual TurtleRequestId turtleSearch(const LinearizedExpression& expr) = 0 ; virtual TurtleRequestId turtleSearch(const LinearizedExpression& expr) = 0 ;
// Sets the file sharing strategy. It concerns all local files. It would
// be better to handle this for each file, of course.
void setFileSharingStrategy(FileSharingStrategy f) { _sharing_strategy = f ; }
// Initiates tunnel handling for the given file hash. tunnels. Launches // Initiates tunnel handling for the given file hash. tunnels. Launches
// an exception if an error occurs during the initialization process. The // an exception if an error occurs during the initialization process. The
// turtle router itself does not initiate downloads, it only maintains // turtle router itself does not initiate downloads, it only maintains
// tunnels for the given hash. The download should be driven by the file // tunnels for the given hash. The download should be driven by the file
// transfer module by calling ftServer::FileRequest(). // transfer module by calling ftServer::FileRequest().
// //
virtual void monitorFileTunnels(const std::string& name,const std::string& file_hash,uint64_t size) = 0 ; virtual void monitorTunnels(const std::string& file_hash) = 0 ;
// Tells the turtle router to stop handling tunnels for the given file hash. Traditionally this should // Tells the turtle router to stop handling tunnels for the given file hash. Traditionally this should
// be called after calling ftServer::fileCancel(). // be called after calling ftServer::fileCancel().
// //
virtual void stopMonitoringFileTunnels(const std::string& file_hash) = 0 ; virtual void stopMonitoringTunnels(const std::string& file_hash) = 0 ;
/// Adds a client tunnel service. This means that the service will be added
/// to the list of services that might respond to tunnel requests.
/// Example tunnel services include:
///
/// p3ChatService: tunnels correspond to private distant chatting
/// ftServer : tunnels correspond to file data transfer
///
virtual void registerTunnelService(RsTurtleClientService *service) = 0;
// Get info from the turtle router. I use std strings to hide the internal structs. // Get info from the turtle router. I use std strings to hide the internal structs.
// //
@ -136,8 +139,6 @@ class RsTurtle
// Hardcore handles // Hardcore handles
virtual void setMaxTRForwardRate(int max_tr_up_rate) = 0 ; virtual void setMaxTRForwardRate(int max_tr_up_rate) = 0 ;
virtual int getMaxTRForwardRate() const = 0 ; virtual int getMaxTRForwardRate() const = 0 ;
protected:
FileSharingStrategy _sharing_strategy ;
}; };
#endif #endif

View File

@ -45,6 +45,7 @@ const uint8_t QOS_PRIORITY_RS_TURTLE_CHUNK_CRC = 5 ;
const uint8_t QOS_PRIORITY_RS_TURTLE_FILE_MAP = 3 ; const uint8_t QOS_PRIORITY_RS_TURTLE_FILE_MAP = 3 ;
const uint8_t QOS_PRIORITY_RS_TURTLE_GENERIC_ITEM = 3 ; const uint8_t QOS_PRIORITY_RS_TURTLE_GENERIC_ITEM = 3 ;
const uint8_t QOS_PRIORITY_RS_TURTLE_FORWARD_FILE_DATA= 2 ; const uint8_t QOS_PRIORITY_RS_TURTLE_FORWARD_FILE_DATA= 2 ;
const uint8_t QOS_PRIORITY_RS_TURTLE_GENERIC_DATA = 5 ;
// File transfer // File transfer
// //

View File

@ -120,7 +120,6 @@ p3turtle::p3turtle(p3LinkMgr *lm,ftServer *fs)
_last_tunnel_speed_estimate_time = 0 ; _last_tunnel_speed_estimate_time = 0 ;
_traffic_info.reset() ; _traffic_info.reset() ;
_sharing_strategy = SHARE_ENTIRE_NETWORK ;
_max_tr_up_rate = MAX_TR_FORWARD_PER_SEC ; _max_tr_up_rate = MAX_TR_FORWARD_PER_SEC ;
} }
@ -349,7 +348,7 @@ void p3turtle::manageTunnels()
// digg new tunnels if no tunnels are available and force digg new tunnels at regular (large) interval // digg new tunnels if no tunnels are available and force digg new tunnels at regular (large) interval
// //
for(std::map<TurtleFileHash,TurtleFileHashInfo>::const_iterator it(_incoming_file_hashes.begin());it!=_incoming_file_hashes.end();++it) for(std::map<TurtleFileHash,TurtleHashInfo>::const_iterator it(_incoming_file_hashes.begin());it!=_incoming_file_hashes.end();++it)
{ {
// get total tunnel speed. // get total tunnel speed.
// //
@ -418,7 +417,7 @@ void p3turtle::autoWash()
for(unsigned int i=0;i<_hashes_to_remove.size();++i) for(unsigned int i=0;i<_hashes_to_remove.size();++i)
{ {
std::map<TurtleFileHash,TurtleFileHashInfo>::iterator it(_incoming_file_hashes.find(_hashes_to_remove[i])) ; std::map<TurtleFileHash,TurtleHashInfo>::iterator it(_incoming_file_hashes.find(_hashes_to_remove[i])) ;
if(it == _incoming_file_hashes.end()) if(it == _incoming_file_hashes.end())
{ {
@ -567,7 +566,7 @@ void p3turtle::locked_closeTunnel(TurtleTunnelId tid,std::vector<std::pair<Turtl
if(_virtual_peers.find(vpid) != _virtual_peers.end()) if(_virtual_peers.find(vpid) != _virtual_peers.end())
_virtual_peers.erase(_virtual_peers.find(vpid)) ; _virtual_peers.erase(_virtual_peers.find(vpid)) ;
std::map<TurtleFileHash,TurtleFileHashInfo>::iterator it(_incoming_file_hashes.find(hash)) ; std::map<TurtleFileHash,TurtleHashInfo>::iterator it(_incoming_file_hashes.find(hash)) ;
if(it != _incoming_file_hashes.end()) if(it != _incoming_file_hashes.end())
{ {
@ -592,7 +591,7 @@ void p3turtle::locked_closeTunnel(TurtleTunnelId tid,std::vector<std::pair<Turtl
#ifdef P3TURTLE_DEBUG #ifdef P3TURTLE_DEBUG
std::cerr << " Tunnel is a ending point. Also removing associated outgoing hash." ; std::cerr << " Tunnel is a ending point. Also removing associated outgoing hash." ;
#endif #endif
std::map<TurtleFileHash,FileInfo>::iterator itHash = _outgoing_file_hashes.find(it->second.hash); std::map<TurtleFileHash,std::string>::iterator itHash = _outgoing_file_hashes.find(it->second.hash);
if(itHash != _outgoing_file_hashes.end()) if(itHash != _outgoing_file_hashes.end())
_outgoing_file_hashes.erase(itHash) ; _outgoing_file_hashes.erase(itHash) ;
} }
@ -600,7 +599,7 @@ void p3turtle::locked_closeTunnel(TurtleTunnelId tid,std::vector<std::pair<Turtl
_local_tunnels.erase(it) ; _local_tunnels.erase(it) ;
} }
void p3turtle::stopMonitoringFileTunnels(const std::string& hash) void p3turtle::stopMonitoringTunnels(const std::string& hash)
{ {
RsStackMutex stack(mTurtleMtx); /********** STACK LOCKED MTX ******/ RsStackMutex stack(mTurtleMtx); /********** STACK LOCKED MTX ******/
@ -836,8 +835,7 @@ void p3turtle::handleSearchRequest(RsTurtleSearchRequestItem *item)
#ifdef P3TURTLE_DEBUG #ifdef P3TURTLE_DEBUG
std::cerr << " Request not from us. Performing local search" << std::endl ; std::cerr << " Request not from us. Performing local search" << std::endl ;
#endif #endif
if(_sharing_strategy != SHARE_FRIENDS_ONLY || item->depth < 2)
{
std::list<TurtleFileInfo> result ; std::list<TurtleFileInfo> result ;
item->performLocalSearch(result) ; item->performLocalSearch(result) ;
@ -878,7 +876,7 @@ void p3turtle::handleSearchRequest(RsTurtleSearchRequestItem *item)
res_item = NULL ; res_item = NULL ;
} }
} }
}
#ifdef P3TURTLE_DEBUG #ifdef P3TURTLE_DEBUG
else else
std::cerr << " Rejecting local search because strategy is FRIENDS_ONLY and item depth=" << item->depth << std::endl ; std::cerr << " Rejecting local search because strategy is FRIENDS_ONLY and item depth=" << item->depth << std::endl ;
@ -1121,7 +1119,7 @@ void p3turtle::handleRecvFileRequest(RsTurtleFileRequestItem *item)
} }
TurtleTunnel& tunnel(it2->second) ; TurtleTunnel& tunnel(it2->second) ;
std::map<TurtleFileHash,FileInfo>::const_iterator it(_outgoing_file_hashes.find(tunnel.hash)) ; std::map<TurtleFileHash,std::string>::const_iterator it(_outgoing_file_hashes.find(tunnel.hash)) ;
#ifdef P3TURTLE_DEBUG #ifdef P3TURTLE_DEBUG
assert(!tunnel.hash.empty()) ; assert(!tunnel.hash.empty()) ;
assert(it != _outgoing_file_hashes.end()) ; assert(it != _outgoing_file_hashes.end()) ;
@ -1130,7 +1128,7 @@ void p3turtle::handleRecvFileRequest(RsTurtleFileRequestItem *item)
std::cerr << " Forwarding data request to the multiplexer." << std::endl ; std::cerr << " Forwarding data request to the multiplexer." << std::endl ;
std::cerr << " using peer_id=" << tunnel.vpid << ", hash=" << tunnel.hash << std::endl ; std::cerr << " using peer_id=" << tunnel.vpid << ", hash=" << tunnel.hash << std::endl ;
#endif #endif
size = it->second.size ; size = 0 ; //it->second.size ; Not used by ftDataMultiplex actually
vpid = tunnel.vpid ; vpid = tunnel.vpid ;
hash = tunnel.hash ; hash = tunnel.hash ;
} }
@ -1167,7 +1165,7 @@ void p3turtle::handleRecvFileData(RsTurtleFileDataItem *item)
} }
TurtleTunnel& tunnel(it2->second) ; TurtleTunnel& tunnel(it2->second) ;
std::map<TurtleFileHash,TurtleFileHashInfo>::iterator it( _incoming_file_hashes.find(tunnel.hash) ) ; std::map<TurtleFileHash,TurtleHashInfo>::iterator it( _incoming_file_hashes.find(tunnel.hash) ) ;
#ifdef P3TURTLE_DEBUG #ifdef P3TURTLE_DEBUG
assert(!tunnel.hash.empty()) ; assert(!tunnel.hash.empty()) ;
#endif #endif
@ -1179,7 +1177,6 @@ void p3turtle::handleRecvFileData(RsTurtleFileDataItem *item)
return ; return ;
} }
const TurtleFileHashInfo& hash_info(it->second) ;
#ifdef P3TURTLE_DEBUG #ifdef P3TURTLE_DEBUG
std::cerr << " This is an endpoint for this data chunk." << std::endl ; std::cerr << " This is an endpoint for this data chunk." << std::endl ;
std::cerr << " Forwarding data to the multiplexer." << std::endl ; std::cerr << " Forwarding data to the multiplexer." << std::endl ;
@ -1188,7 +1185,7 @@ void p3turtle::handleRecvFileData(RsTurtleFileDataItem *item)
//_ft_server->getMultiplexer()->recvData(tunnel.vpid,tunnel.hash,hash_info.size,item->chunk_offset,item->chunk_size,item->chunk_data) ; //_ft_server->getMultiplexer()->recvData(tunnel.vpid,tunnel.hash,hash_info.size,item->chunk_offset,item->chunk_size,item->chunk_data) ;
vpid = tunnel.vpid ; vpid = tunnel.vpid ;
hash = tunnel.hash ; hash = tunnel.hash ;
size = hash_info.size ; size = 0 ; // Not used by ftDataMultiplex, see ftDataMultiplex:handleRecvData()
// also update the hash time stamp to show that it's actually being downloaded. // also update the hash time stamp to show that it's actually being downloaded.
//it->second.time_stamp = time(NULL) ; //it->second.time_stamp = time(NULL) ;
@ -1893,14 +1890,14 @@ void p3turtle::handleTunnelRequest(RsTurtleOpenTunnelItem *item)
// We're off-mutex here. // We're off-mutex here.
bool found = false ; bool found = false ;
FileInfo info ; std::string info ;
if(item->PeerId() != mLinkMgr->getOwnId()) if(item->PeerId() != mLinkMgr->getOwnId())
{ {
#ifdef P3TURTLE_DEBUG #ifdef P3TURTLE_DEBUG
std::cerr << " Request not from us. Performing local search" << std::endl ; std::cerr << " Request not from us. Performing local search" << std::endl ;
#endif #endif
found = (_sharing_strategy != SHARE_FRIENDS_ONLY || item->depth < 2) && performLocalHashSearch(item->file_hash,item->PeerId(),info) ; found = performLocalHashSearch(item->file_hash,item->PeerId(),info) ;
} }
{ {
@ -1936,7 +1933,7 @@ void p3turtle::handleTunnelRequest(RsTurtleOpenTunnelItem *item)
// //
locked_addDistantPeer(item->file_hash,res_item->tunnel_id) ; locked_addDistantPeer(item->file_hash,res_item->tunnel_id) ;
// Store the size of the file, to be able to re-form data requests to the multiplexer. // Store some info string about the tunnel.
// //
_outgoing_file_hashes[item->file_hash] = info ; _outgoing_file_hashes[item->file_hash] = info ;
@ -2101,7 +2098,7 @@ void p3turtle::handleTunnelResult(RsTurtleTunnelOkItem *item)
// and this mostly prevents from sending the hash back in the tunnel. // and this mostly prevents from sending the hash back in the tunnel.
bool found = false ; bool found = false ;
for(std::map<TurtleFileHash,TurtleFileHashInfo>::iterator it(_incoming_file_hashes.begin());it!=_incoming_file_hashes.end();++it) for(std::map<TurtleFileHash,TurtleHashInfo>::iterator it(_incoming_file_hashes.begin());it!=_incoming_file_hashes.end();++it)
if(it->second.last_request == item->request_id) if(it->second.last_request == item->request_id)
{ {
found = true ; found = true ;
@ -2305,7 +2302,7 @@ TurtleRequestId p3turtle::turtleSearch(const LinearizedExpression& expr)
return id ; return id ;
} }
void p3turtle::monitorFileTunnels(const std::string& name,const std::string& file_hash,uint64_t size) void p3turtle::monitorTunnels(const std::string& hash)
{ {
{ {
RsStackMutex stack(mTurtleMtx); /********** STACK LOCKED MTX ******/ RsStackMutex stack(mTurtleMtx); /********** STACK LOCKED MTX ******/
@ -2313,36 +2310,34 @@ void p3turtle::monitorFileTunnels(const std::string& name,const std::string& fil
// First, check if the hash is tagged for removal (there's a delay) // First, check if the hash is tagged for removal (there's a delay)
for(uint32_t i=0;i<_hashes_to_remove.size();++i) for(uint32_t i=0;i<_hashes_to_remove.size();++i)
if(_hashes_to_remove[i] == file_hash) if(_hashes_to_remove[i] == hash)
{ {
_hashes_to_remove[i] = _hashes_to_remove.back() ; _hashes_to_remove[i] = _hashes_to_remove.back() ;
_hashes_to_remove.pop_back() ; _hashes_to_remove.pop_back() ;
#ifdef P3TURTLE_DEBUG #ifdef P3TURTLE_DEBUG
std::cerr << "p3turtle: File hash " << file_hash << " Was scheduled for removal. Canceling the removal." << std::endl ; std::cerr << "p3turtle: File hash " << hash << " Was scheduled for removal. Canceling the removal." << std::endl ;
#endif #endif
} }
// Then, check if the hash is already there // Then, check if the hash is already there
// //
if(_incoming_file_hashes.find(file_hash) != _incoming_file_hashes.end()) // download already asked. if(_incoming_file_hashes.find(hash) != _incoming_file_hashes.end()) // download already asked.
{ {
#ifdef P3TURTLE_DEBUG #ifdef P3TURTLE_DEBUG
std::cerr << "p3turtle: File hash " << file_hash << " already in pool. Returning." << std::endl ; std::cerr << "p3turtle: File hash " << hash << " already in pool. Returning." << std::endl ;
#endif #endif
return ; return ;
} }
#ifdef P3TURTLE_DEBUG #ifdef P3TURTLE_DEBUG
std::cerr << "p3turtle: Received order for turtle download fo hash " << file_hash << std::endl ; std::cerr << "p3turtle: Received order for turtle download fo hash " << hash << std::endl ;
#endif #endif
// No tunnels at start, but this triggers digging new tunnels. // No tunnels at start, but this triggers digging new tunnels.
// //
_incoming_file_hashes[file_hash].tunnels.clear(); _incoming_file_hashes[hash].tunnels.clear();
// also should send associated request to the file transfer module. // also should send associated request to the file transfer module.
_incoming_file_hashes[file_hash].size = size ; _incoming_file_hashes[hash].last_digg_time = RSRandom::random_u32()%10 ;
_incoming_file_hashes[file_hash].name = name ;
_incoming_file_hashes[file_hash].last_digg_time = RSRandom::random_u32()%10 ;
} }
IndicateConfigChanged() ; // initiates saving of handled hashes. IndicateConfigChanged() ; // initiates saving of handled hashes.
@ -2362,31 +2357,29 @@ void p3turtle::returnSearchResult(RsTurtleSearchResultItem *item)
/// Warning: this function should never be called while the turtle mutex is locked. /// Warning: this function should never be called while the turtle mutex is locked.
/// Otherwize this is a possible source of cross-lock with the File mutex. /// Otherwize this is a possible source of cross-lock with the File mutex.
// //
bool p3turtle::performLocalHashSearch(const TurtleFileHash& hash,const std::string& peer_id,FileInfo& info) bool p3turtle::performLocalHashSearch(const TurtleFileHash& hash,const std::string& peer_id,std::string& description_string)
{ {
bool res = rsFiles->FileDetails(hash, RS_FILE_HINTS_NETWORK_WIDE | RS_FILE_HINTS_LOCAL | RS_FILE_HINTS_EXTRA | RS_FILE_HINTS_SPEC_ONLY | RS_FILE_HINTS_DOWNLOAD, info); if(_registered_services.empty())
std::cerr << "Turtle router has no services registered. Tunnel requests cannot be handled." << std::endl;
#ifdef P3TURTLE_DEBUG for(std::list<RsTurtleClientService*>::const_iterator it(_registered_services.begin());it!=_registered_services.end();++it)
std::cerr << "p3turtle: performing local hash search for hash " << hash << std::endl; if( (*it)->handleTunnelRequest(hash,peer_id,description_string))
return true ;
if(res) return false ;
{
std::cerr << "Found hash: " << std::endl;
std::cerr << " hash = " << hash << std::endl;
std::cerr << " peer = " << peer_id << std::endl;
std::cerr << " flags = " << info.storage_permission_flags << std::endl;
std::cerr << " local = " << rsFiles->FileDetails(hash, RS_FILE_HINTS_NETWORK_WIDE | RS_FILE_HINTS_LOCAL | RS_FILE_HINTS_EXTRA | RS_FILE_HINTS_SPEC_ONLY | RS_FILE_HINTS_DOWNLOAD, info) << std::endl;
std::cerr << " groups= " ; for(std::list<std::string>::const_iterator it(info.parent_groups.begin());it!=info.parent_groups.end();++it) std::cerr << (*it) << ", " ; std::cerr << std::endl;
std::cerr << " clear = " << rsPeers->computePeerPermissionFlags(peer_id,info.storage_permission_flags,info.parent_groups) << std::endl;
} }
void p3turtle::registerTunnelService(RsTurtleClientService *service)
{
#ifdef P3TURTLE_DEBUG
for(std::list<RsTurtleClientService*>::const_iterator it(_registered_services.begin());it!=_registered_services.end();++it)
if(service == *it)
throw std::runtime_error("p3turtle::registerTunnelService(): Cannot register the same service twice. Please fix the code!") ;
#endif #endif
std::cerr << "p3turtle: registered new tunnel service " << (void*)service << std::endl;
// The call to computeHashPeerClearance() return a combination of RS_FILE_HINTS_NETWORK_WIDE and RS_FILE_HINTS_BROWSABLE _registered_services.push_back(service) ;
// This is an additional computation cost, but the way it's written here, it's only called when res is true.
//
res = res && (RS_FILE_HINTS_NETWORK_WIDE & rsPeers->computePeerPermissionFlags(peer_id,info.storage_permission_flags,info.parent_groups)) ;
return res ;
} }
static std::string printFloatNumber(float num,bool friendly=false) static std::string printFloatNumber(float num,bool friendly=false)
@ -2471,14 +2464,15 @@ void p3turtle::getInfo( std::vector<std::vector<std::string> >& hashes_info,
hashes_info.clear() ; hashes_info.clear() ;
for(std::map<TurtleFileHash,TurtleFileHashInfo>::const_iterator it(_incoming_file_hashes.begin());it!=_incoming_file_hashes.end();++it) for(std::map<TurtleFileHash,TurtleHashInfo>::const_iterator it(_incoming_file_hashes.begin());it!=_incoming_file_hashes.end();++it)
{ {
hashes_info.push_back(std::vector<std::string>()) ; hashes_info.push_back(std::vector<std::string>()) ;
std::vector<std::string>& hashes(hashes_info.back()) ; std::vector<std::string>& hashes(hashes_info.back()) ;
hashes.push_back(it->first) ; hashes.push_back(it->first) ;
hashes.push_back(it->second.name) ; //hashes.push_back(it->second.name) ;
hashes.push_back("Name not available") ;
hashes.push_back(printNumber(it->second.tunnels.size())) ; hashes.push_back(printNumber(it->second.tunnels.size())) ;
//hashes.push_back(printNumber(now - it->second.time_stamp)+" secs ago") ; //hashes.push_back(printNumber(now - it->second.time_stamp)+" secs ago") ;
} }
@ -2547,7 +2541,7 @@ void p3turtle::dumpState()
std::cerr << std::endl ; std::cerr << std::endl ;
std::cerr << "********************** Turtle router dump ******************" << std::endl ; std::cerr << "********************** Turtle router dump ******************" << std::endl ;
std::cerr << " Active incoming file hashes: " << _incoming_file_hashes.size() << std::endl ; std::cerr << " Active incoming file hashes: " << _incoming_file_hashes.size() << std::endl ;
for(std::map<TurtleFileHash,TurtleFileHashInfo>::const_iterator it(_incoming_file_hashes.begin());it!=_incoming_file_hashes.end();++it) for(std::map<TurtleFileHash,TurtleHashInfo>::const_iterator it(_incoming_file_hashes.begin());it!=_incoming_file_hashes.end();++it)
{ {
std::cerr << " hash=0x" << it->first << ", name=" << it->second.name << ", size=" << it->second.size << ", tunnel ids =" ; std::cerr << " hash=0x" << it->first << ", name=" << it->second.name << ", size=" << it->second.size << ", tunnel ids =" ;
for(std::vector<TurtleTunnelId>::const_iterator it2(it->second.tunnels.begin());it2!=it->second.tunnels.end();++it2) for(std::vector<TurtleTunnelId>::const_iterator it2(it->second.tunnels.begin());it2!=it->second.tunnels.end();++it2)

View File

@ -150,6 +150,7 @@
#include "ft/ftsearch.h" #include "ft/ftsearch.h"
#include "retroshare/rsturtle.h" #include "retroshare/rsturtle.h"
#include "rsturtleitem.h" #include "rsturtleitem.h"
#include "turtleclientservice.h"
#include "turtlestatistics.h" #include "turtlestatistics.h"
//#define TUNNEL_STATISTICS //#define TUNNEL_STATISTICS
@ -191,15 +192,13 @@ class TurtleTunnel
// This class keeps trace of the activity for the file hashes the turtle router is asked to monitor. // This class keeps trace of the activity for the file hashes the turtle router is asked to monitor.
// //
class TurtleFileHashInfo
class TurtleHashInfo
{ {
public: public:
std::vector<TurtleTunnelId> tunnels ; // list of active tunnel ids for this file hash std::vector<TurtleTunnelId> tunnels ; // list of active tunnel ids for this file hash
TurtleRequestId last_request ; // last request for the tunnels of this hash TurtleRequestId last_request ; // last request for the tunnels of this hash
TurtleFileName name ;
time_t last_digg_time ; time_t last_digg_time ;
uint64_t size ;
}; };
// Subclassing: // Subclassing:
@ -232,6 +231,9 @@ class p3turtle: public p3Service, public RsTurtle, public p3Config
// the request id, which will be further used by the gui to store results // the request id, which will be further used by the gui to store results
// as they come back. // as they come back.
// //
// Eventually, search requests should be handled by client services. We will therefore
// remove the specific file search packets from the turtle router.
//
virtual TurtleSearchRequestId turtleSearch(const std::string& string_to_match) ; virtual TurtleSearchRequestId turtleSearch(const std::string& string_to_match) ;
virtual TurtleSearchRequestId turtleSearch(const LinearizedExpression& expr) ; virtual TurtleSearchRequestId turtleSearch(const LinearizedExpression& expr) ;
@ -247,12 +249,21 @@ class p3turtle: public p3Service, public RsTurtle, public p3Config
// This function should be called in addition to ftServer::FileRequest() so that the turtle router // This function should be called in addition to ftServer::FileRequest() so that the turtle router
// automatically provide tunnels for the file to download. // automatically provide tunnels for the file to download.
// //
virtual void monitorFileTunnels(const std::string& name,const std::string& file_hash,uint64_t size) ; virtual void monitorTunnels(const std::string& file_hash) ;
/// This should be called when canceling a file download, so that the turtle router stops /// This should be called when canceling a file download, so that the turtle router stops
/// handling tunnels for this file. /// handling tunnels for this file.
/// ///
virtual void stopMonitoringFileTunnels(const std::string& file_hash) ; virtual void stopMonitoringTunnels(const std::string& file_hash) ;
/// Adds a client tunnel service. This means that the service will be added
/// to the list of services that might respond to tunnel requests.
/// Example tunnel services include:
///
/// p3ChatService: tunnels correspond to private distant chatting
/// ftServer : tunnels correspond to file data transfer
///
virtual void registerTunnelService(RsTurtleClientService *service) ;
/// get info about tunnels /// get info about tunnels
virtual void getInfo(std::vector<std::vector<std::string> >&, virtual void getInfo(std::vector<std::vector<std::string> >&,
@ -382,7 +393,7 @@ class p3turtle: public p3Service, public RsTurtle, public p3Config
void returnSearchResult(RsTurtleSearchResultItem *item) ; void returnSearchResult(RsTurtleSearchResultItem *item) ;
/// Returns true if the file with given hash is hosted locally, and accessible in anonymous mode the supplied peer. /// Returns true if the file with given hash is hosted locally, and accessible in anonymous mode the supplied peer.
virtual bool performLocalHashSearch(const TurtleFileHash& hash,const std::string& client_peer_id,FileInfo& info) ; virtual bool performLocalHashSearch(const TurtleFileHash& hash,const std::string& client_peer_id,std::string& info) ;
//--------------------------- Local variables --------------------------------// //--------------------------- Local variables --------------------------------//
@ -400,10 +411,10 @@ class p3turtle: public p3Service, public RsTurtle, public p3Config
std::map<TurtleTunnelRequestId,TurtleRequestInfo> _tunnel_requests_origins ; std::map<TurtleTunnelRequestId,TurtleRequestInfo> _tunnel_requests_origins ;
/// stores adequate tunnels for each file hash locally managed /// stores adequate tunnels for each file hash locally managed
std::map<TurtleFileHash,TurtleFileHashInfo> _incoming_file_hashes ; std::map<TurtleFileHash,TurtleHashInfo> _incoming_file_hashes ;
/// stores file info for each file we provide. /// stores file info for each file we provide.
std::map<TurtleFileHash,FileInfo> _outgoing_file_hashes ; std::map<TurtleFileHash,std::string> _outgoing_file_hashes ;
/// local tunnels, stored by ids (Either transiting or ending). /// local tunnels, stored by ids (Either transiting or ending).
std::map<TurtleTunnelId,TurtleTunnel > _local_tunnels ; std::map<TurtleTunnelId,TurtleTunnel > _local_tunnels ;
@ -414,6 +425,9 @@ class p3turtle: public p3Service, public RsTurtle, public p3Config
/// Hashes marked to be deleted. /// Hashes marked to be deleted.
std::vector<TurtleFileHash> _hashes_to_remove ; std::vector<TurtleFileHash> _hashes_to_remove ;
/// List of client services that have regitered.
std::list<RsTurtleClientService*> _registered_services ;
time_t _last_clean_time ; time_t _last_clean_time ;
time_t _last_tunnel_management_time ; time_t _last_tunnel_management_time ;
time_t _last_tunnel_campaign_time ; time_t _last_tunnel_campaign_time ;

View File

@ -18,6 +18,7 @@ const uint8_t RS_TURTLE_SUBTYPE_TUNNEL_CLOSED = 0x06 ;
const uint8_t RS_TURTLE_SUBTYPE_FILE_REQUEST = 0x07 ; const uint8_t RS_TURTLE_SUBTYPE_FILE_REQUEST = 0x07 ;
const uint8_t RS_TURTLE_SUBTYPE_FILE_DATA = 0x08 ; 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_REGEXP_SEARCH_REQUEST = 0x09 ;
const uint8_t RS_TURTLE_SUBTYPE_GENERIC_DATA = 0x0a ;
const uint8_t RS_TURTLE_SUBTYPE_FILE_MAP = 0x10 ; 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_MAP_REQUEST = 0x11 ;
const uint8_t RS_TURTLE_SUBTYPE_FILE_CRC = 0x12 ; const uint8_t RS_TURTLE_SUBTYPE_FILE_CRC = 0x12 ;
@ -204,6 +205,28 @@ class RsTurtleFileRequestItem: public RsTurtleGenericTunnelItem
virtual uint32_t serial_size() ; 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 class RsTurtleFileDataItem: public RsTurtleGenericTunnelItem
{ {
public: public: