diff --git a/libretroshare/src/ft/ftcontroller.cc b/libretroshare/src/ft/ftcontroller.cc index 14b0359de..99a63e5ea 100644 --- a/libretroshare/src/ft/ftcontroller.cc +++ b/libretroshare/src/ft/ftcontroller.cc @@ -644,7 +644,7 @@ void ftController::locked_checkQueueElement(uint32_t pos) _queue[pos]->mState = ftFileControl::DOWNLOADING ; 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) @@ -653,7 +653,7 @@ void ftController::locked_checkQueueElement(uint32_t pos) _queue[pos]->mCreator->closeFile() ; 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); if(flags & RS_FILE_REQ_ANONYMOUS_ROUTING) - mTurtle->stopMonitoringFileTunnels(hash_to_suppress) ; + mTurtle->stopMonitoringTunnels(hash_to_suppress) ; } /******* UNLOCKED ********/ @@ -1262,7 +1262,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->monitorFileTunnels(fname,hash,size) ; + mTurtle->monitorTunnels(hash) ; 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) { - rsTurtle->stopMonitoringFileTunnels(hash) ; + rsTurtle->stopMonitoringTunnels(hash) ; #ifdef CONTROL_DEBUG std::cerr << "ftController::FileCancel" << std::endl; diff --git a/libretroshare/src/ft/ftdatamultiplex.cc b/libretroshare/src/ft/ftdatamultiplex.cc index bcc6c815c..6bbd32f30 100644 --- a/libretroshare/src/ft/ftdatamultiplex.cc +++ b/libretroshare/src/ft/ftdatamultiplex.cc @@ -1085,7 +1085,7 @@ bool ftDataMultiplex::locked_handleServerRequest(ftFileProvider *provider, std::string peerId, std::string hash, uint64_t size, 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 ; return false ; diff --git a/libretroshare/src/ft/ftfileprovider.cc b/libretroshare/src/ft/ftfileprovider.cc index c17d291c6..775e368b0 100644 --- a/libretroshare/src/ft/ftfileprovider.cc +++ b/libretroshare/src/ft/ftfileprovider.cc @@ -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? */ + if(offset >= mSize) + { + std::cerr << "ftFileProvider::getFileData(): request (" << offset << ") exceeds file size (" << mSize << "! " << std::endl; + return false ; + } + uint32_t data_size = chunk_size; uint64_t base_loc = offset; diff --git a/libretroshare/src/ft/ftserver.cc b/libretroshare/src/ft/ftserver.cc index 81fe25a7e..f12aba0e9 100644 --- a/libretroshare/src/ft/ftserver.cc +++ b/libretroshare/src/ft/ftserver.cc @@ -28,6 +28,7 @@ #include "util/rsdebug.h" #include "util/rsdir.h" #include "retroshare/rstypes.h" +#include "retroshare/rspeers.h" const int ftserverzone = 29539; #include "ft/ftserver.h" @@ -153,6 +154,7 @@ void ftServer::connectToTurtleRouter(p3turtle *fts) mTurtleRouter = fts ; mFtController->setTurtleRouter(fts) ; + fts->registerTunnelService(this) ; } void ftServer::StartupThreads() @@ -450,6 +452,37 @@ bool ftServer::FileDetails(const std::string &hash, FileSearchFlags hintflags, F 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::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 **********************/ /***************************************************************/ diff --git a/libretroshare/src/ft/ftserver.h b/libretroshare/src/ft/ftserver.h index c105bb2c7..e25585709 100644 --- a/libretroshare/src/ft/ftserver.h +++ b/libretroshare/src/ft/ftserver.h @@ -44,6 +44,7 @@ #include #include "ft/ftdata.h" +#include "turtle/turtleclientservice.h" #include "retroshare/rsfiles.h" //#include "dbase/cachestrapper.h" @@ -72,142 +73,146 @@ class ftDwlQueue; class p3PeerMgr; class p3LinkMgr; -class ftServer: public RsFiles, public ftDataSend, public RsThread +class ftServer: public RsFiles, public ftDataSend, public RsTurtleClientService, public RsThread { public: - /***************************************************************/ - /******************** Setup ************************************/ - /***************************************************************/ + /***************************************************************/ + /******************** Setup ************************************/ + /***************************************************************/ - ftServer(p3PeerMgr *peerMgr, p3LinkMgr *linkMgr); + ftServer(p3PeerMgr *peerMgr, p3LinkMgr *linkMgr); - /* Assign important variables */ -void setConfigDirectory(std::string path); + /* Assign important variables */ + void setConfigDirectory(std::string path); -void setP3Interface(P3Interface *pqi); + void setP3Interface(P3Interface *pqi); - /* add Config Items (Extra, Controller) */ -void addConfigComponents(p3ConfigMgr *mgr); + /* add Config Items (Extra, Controller) */ + void addConfigComponents(p3ConfigMgr *mgr); -virtual CacheStrapper *getCacheStrapper(); -virtual CacheTransfer *getCacheTransfer(); + virtual CacheStrapper *getCacheStrapper(); + virtual CacheTransfer *getCacheTransfer(); -std::string OwnId(); + std::string OwnId(); - /* Final Setup (once everything is assigned) */ -//void SetupFtServer(); -void SetupFtServer(NotifyBase *cb); -void connectToTurtleRouter(p3turtle *p) ; + /* Final Setup (once everything is assigned) */ + //void SetupFtServer(); + void SetupFtServer(NotifyBase *cb); + void connectToTurtleRouter(p3turtle *p) ; -void StartupThreads(); -void StopThreads(); + void StartupThreads(); + void StopThreads(); - /* own thread */ -virtual void run(); + /* own thread */ + virtual void run(); -// Checks that the given hash is well formed. Used to chase -// string bugs. -static bool checkHash(const std::string& hash,std::string& error_string) ; + // Checks that the given hash is well formed. Used to chase + // string bugs. + static bool checkHash(const std::string& hash,std::string& error_string) ; - /***************************************************************/ - /*************** Control Interface *****************************/ - /************** (Implements RsFiles) ***************************/ - /***************************************************************/ + // Implements RsTurtleClientService + // + virtual bool handleTunnelRequest(const std::string& hash,const std::string& peer_id,std::string& description_info_string) ; -// member access + /***************************************************************/ + /*************** Control Interface *****************************/ + /************** (Implements RsFiles) ***************************/ + /***************************************************************/ -ftDataMultiplex *getMultiplexer() const { return mFtDataplex ; } -ftController *getController() const { return mFtController ; } + // member access -/*** - * Control of Downloads - ***/ -virtual bool alreadyHaveFile(const std::string& hash, FileInfo &info); -virtual bool FileRequest(const std::string& fname, const std::string& hash, uint64_t size, const std::string& dest, TransferRequestFlags flags, const std::list& srcIds); -virtual bool FileCancel(const std::string& hash); -virtual bool FileControl(const std::string& hash, uint32_t flags); -virtual bool FileClearCompleted(); -virtual bool setDestinationDirectory(const std::string& hash,const std::string& new_path) ; -virtual bool setDestinationName(const std::string& hash,const std::string& new_name) ; -virtual bool setChunkStrategy(const std::string& hash,FileChunksInfo::ChunkStrategy s) ; -virtual void setDefaultChunkStrategy(FileChunksInfo::ChunkStrategy) ; -virtual FileChunksInfo::ChunkStrategy defaultChunkStrategy() ; -virtual uint32_t freeDiskSpaceLimit() const ; -virtual void setFreeDiskSpaceLimit(uint32_t size_in_mb) ; + ftDataMultiplex *getMultiplexer() const { return mFtDataplex ; } + ftController *getController() const { return mFtController ; } + + /*** + * Control of Downloads + ***/ + virtual bool alreadyHaveFile(const std::string& hash, FileInfo &info); + virtual bool FileRequest(const std::string& fname, const std::string& hash, uint64_t size, const std::string& dest, TransferRequestFlags flags, const std::list& srcIds); + virtual bool FileCancel(const std::string& hash); + virtual bool FileControl(const std::string& hash, uint32_t flags); + virtual bool FileClearCompleted(); + virtual bool setDestinationDirectory(const std::string& hash,const std::string& new_path) ; + virtual bool setDestinationName(const std::string& hash,const std::string& new_name) ; + virtual bool setChunkStrategy(const std::string& hash,FileChunksInfo::ChunkStrategy s) ; + virtual void setDefaultChunkStrategy(FileChunksInfo::ChunkStrategy) ; + virtual FileChunksInfo::ChunkStrategy defaultChunkStrategy() ; + virtual uint32_t freeDiskSpaceLimit() const ; + virtual void setFreeDiskSpaceLimit(uint32_t size_in_mb) ; -/*** - * Control of Downloads Priority. - ***/ -virtual uint32_t getMinPrioritizedTransfers() ; -virtual void setMinPrioritizedTransfers(uint32_t s) ; -virtual uint32_t getQueueSize() ; -virtual void setQueueSize(uint32_t s) ; -virtual bool changeQueuePosition(const std::string hash, QueueMove queue_mv); -virtual bool changeDownloadSpeed(const std::string hash, int speed); -virtual bool getDownloadSpeed(const std::string hash, int & speed); -virtual bool clearDownload(const std::string hash); -//virtual void getDwlDetails(std::list & details); + /*** + * Control of Downloads Priority. + ***/ + virtual uint32_t getMinPrioritizedTransfers() ; + virtual void setMinPrioritizedTransfers(uint32_t s) ; + virtual uint32_t getQueueSize() ; + virtual void setQueueSize(uint32_t s) ; + virtual bool changeQueuePosition(const std::string hash, QueueMove queue_mv); + virtual bool changeDownloadSpeed(const std::string hash, int speed); + virtual bool getDownloadSpeed(const std::string hash, int & speed); + virtual bool clearDownload(const std::string hash); + //virtual void getDwlDetails(std::list & details); -/*** - * Download/Upload Details - ***/ -virtual bool FileDownloads(std::list &hashs); -virtual bool FileUploads(std::list &hashs); -virtual bool FileDetails(const std::string &hash, FileSearchFlags hintflags, FileInfo &info); -virtual bool FileDownloadChunksDetails(const std::string& hash,FileChunksInfo& info) ; -virtual bool FileUploadChunksDetails(const std::string& hash,const std::string& peer_id,CompressedChunkMap& map) ; + /*** + * Download/Upload Details + ***/ + virtual bool FileDownloads(std::list &hashs); + virtual bool FileUploads(std::list &hashs); + virtual bool FileDetails(const std::string &hash, FileSearchFlags hintflags, FileInfo &info); + virtual bool FileDownloadChunksDetails(const std::string& hash,FileChunksInfo& info) ; + virtual bool FileUploadChunksDetails(const std::string& hash,const std::string& peer_id,CompressedChunkMap& map) ; -/*** - * Extra List Access - ***/ -virtual bool ExtraFileAdd(std::string fname, std::string hash, uint64_t size, uint32_t period, TransferRequestFlags flags); -virtual bool ExtraFileRemove(std::string hash, TransferRequestFlags flags); -virtual bool ExtraFileHash(std::string localpath, uint32_t period, TransferRequestFlags flags); -virtual bool ExtraFileStatus(std::string localpath, FileInfo &info); -virtual bool ExtraFileMove(std::string fname, std::string hash, uint64_t size, std::string destpath); + /*** + * Extra List Access + ***/ + virtual bool ExtraFileAdd(std::string fname, std::string hash, uint64_t size, uint32_t period, TransferRequestFlags flags); + virtual bool ExtraFileRemove(std::string hash, TransferRequestFlags flags); + virtual bool ExtraFileHash(std::string localpath, uint32_t period, TransferRequestFlags flags); + virtual bool ExtraFileStatus(std::string localpath, FileInfo &info); + virtual bool ExtraFileMove(std::string fname, std::string hash, uint64_t size, std::string destpath); -/*** - * Directory Listing / Search Interface - ***/ -virtual int RequestDirDetails(const std::string& uid, const std::string& path, DirDetails &details); -virtual int RequestDirDetails(void *ref, DirDetails &details, FileSearchFlags flags); -virtual uint32_t getType(void *ref,FileSearchFlags flags) ; + /*** + * Directory Listing / Search Interface + ***/ + virtual int RequestDirDetails(const std::string& uid, const std::string& path, DirDetails &details); + virtual int RequestDirDetails(void *ref, DirDetails &details, FileSearchFlags flags); + virtual uint32_t getType(void *ref,FileSearchFlags flags) ; -virtual int SearchKeywords(std::list keywords, std::list &results,FileSearchFlags flags); -virtual int SearchKeywords(std::list keywords, std::list &results,FileSearchFlags flags,const std::string& peer_id); -virtual int SearchBoolExp(Expression * exp, std::list &results,FileSearchFlags flags); -virtual int SearchBoolExp(Expression * exp, std::list &results,FileSearchFlags flags,const std::string& peer_id); + virtual int SearchKeywords(std::list keywords, std::list &results,FileSearchFlags flags); + virtual int SearchKeywords(std::list keywords, std::list &results,FileSearchFlags flags,const std::string& peer_id); + virtual int SearchBoolExp(Expression * exp, std::list &results,FileSearchFlags flags); + virtual int SearchBoolExp(Expression * exp, std::list &results,FileSearchFlags flags,const std::string& peer_id); -/*** - * Utility Functions - ***/ -virtual bool ConvertSharedFilePath(std::string path, std::string &fullpath); -virtual void ForceDirectoryCheck(); -virtual void updateSinceGroupPermissionsChanged() ; -virtual bool InDirectoryCheck(); -virtual bool CopyFile(const std::string& source, const std::string& dest); + /*** + * Utility Functions + ***/ + virtual bool ConvertSharedFilePath(std::string path, std::string &fullpath); + virtual void ForceDirectoryCheck(); + virtual void updateSinceGroupPermissionsChanged() ; + virtual bool InDirectoryCheck(); + virtual bool CopyFile(const std::string& source, const std::string& dest); -/*** - * Directory Handling - ***/ -virtual void setDownloadDirectory(std::string path); -virtual void setPartialsDirectory(std::string path); -virtual std::string getDownloadDirectory(); -virtual std::string getPartialsDirectory(); + /*** + * Directory Handling + ***/ + virtual void setDownloadDirectory(std::string path); + virtual void setPartialsDirectory(std::string path); + virtual std::string getDownloadDirectory(); + virtual std::string getPartialsDirectory(); -virtual bool getSharedDirectories(std::list &dirs); -virtual bool setSharedDirectories(std::list &dirs); -virtual bool addSharedDirectory(const SharedDirInfo& dir); -virtual bool updateShareFlags(const SharedDirInfo& dir); // updates the flags. The directory should already exist ! -virtual bool removeSharedDirectory(std::string dir); + virtual bool getSharedDirectories(std::list &dirs); + virtual bool setSharedDirectories(std::list &dirs); + virtual bool addSharedDirectory(const SharedDirInfo& dir); + virtual bool updateShareFlags(const SharedDirInfo& dir); // updates the flags. The directory should already exist ! + virtual bool removeSharedDirectory(std::string dir); -virtual bool getShareDownloadDirectory(); -virtual bool shareDownloadDirectory(bool share); + virtual bool getShareDownloadDirectory(); + virtual bool shareDownloadDirectory(bool share); virtual void setRememberHashFilesDuration(uint32_t days) ; virtual uint32_t rememberHashFilesDuration() const ; @@ -217,84 +222,84 @@ virtual bool shareDownloadDirectory(bool share); virtual void setWatchPeriod(int minutes) ; virtual int watchPeriod() const ; - /***************************************************************/ - /*************** Control Interface *****************************/ - /***************************************************************/ + /***************************************************************/ + /*************** Control Interface *****************************/ + /***************************************************************/ - /***************************************************************/ - /*************** Data Transfer Interface ***********************/ - /***************************************************************/ -public: -virtual bool sendData(const std::string& peerId, const std::string& hash, uint64_t size, uint64_t offset, uint32_t chunksize, void *data); -virtual bool sendDataRequest(const std::string& peerId, const std::string& hash, uint64_t size, uint64_t offset, uint32_t chunksize); -virtual bool sendChunkMapRequest(const std::string& peer_id,const std::string& hash,bool is_client) ; -virtual bool sendChunkMap(const std::string& peer_id,const std::string& hash,const CompressedChunkMap& cmap,bool is_client) ; -virtual bool sendCRC32MapRequest(const std::string&, const std::string&) ; -virtual bool sendCRC32Map(const std::string&, const std::string&, const CRC32Map&) ; -virtual bool sendSingleChunkCRCRequest(const std::string& peer_id,const std::string& hash,uint32_t chunk_number) ; -virtual bool sendSingleChunkCRC(const std::string& peer_id,const std::string& hash,uint32_t chunk_number,const Sha1CheckSum& crc) ; + /***************************************************************/ + /*************** Data Transfer Interface ***********************/ + /***************************************************************/ + public: + virtual bool sendData(const std::string& peerId, const std::string& hash, uint64_t size, uint64_t offset, uint32_t chunksize, void *data); + virtual bool sendDataRequest(const std::string& peerId, const std::string& hash, uint64_t size, uint64_t offset, uint32_t chunksize); + virtual bool sendChunkMapRequest(const std::string& peer_id,const std::string& hash,bool is_client) ; + virtual bool sendChunkMap(const std::string& peer_id,const std::string& hash,const CompressedChunkMap& cmap,bool is_client) ; + virtual bool sendCRC32MapRequest(const std::string&, const std::string&) ; + virtual bool sendCRC32Map(const std::string&, const std::string&, const CRC32Map&) ; + virtual bool sendSingleChunkCRCRequest(const std::string& peer_id,const std::string& hash,uint32_t chunk_number) ; + virtual bool sendSingleChunkCRC(const std::string& peer_id,const std::string& hash,uint32_t chunk_number,const Sha1CheckSum& crc) ; - /*************** Internal Transfer Fns *************************/ -virtual int tick(); + /*************** Internal Transfer Fns *************************/ + virtual int tick(); - /* Configuration */ -bool addConfiguration(p3ConfigMgr *cfgmgr); -bool ResumeTransfers(); + /* Configuration */ + bool addConfiguration(p3ConfigMgr *cfgmgr); + bool ResumeTransfers(); -private: -bool handleInputQueues(); -bool handleCacheData(); -bool handleFileData(); + private: + bool handleInputQueues(); + bool handleCacheData(); + bool handleFileData(); - /******************* p3 Config Overload ************************/ + /******************* p3 Config Overload ************************/ protected: - /* Key Functions to be overloaded for Full Configuration */ -virtual RsSerialiser *setupSerialiser(); -virtual bool saveList(bool &cleanup, std::list&); -virtual bool loadList(std::list& load); + /* Key Functions to be overloaded for Full Configuration */ + virtual RsSerialiser *setupSerialiser(); + virtual bool saveList(bool &cleanup, std::list&); + virtual bool loadList(std::list& load); private: -bool loadConfigMap(std::map &configMap); - /******************* p3 Config Overload ************************/ + bool loadConfigMap(std::map &configMap); + /******************* p3 Config Overload ************************/ -/*************************** p3 Config Overload ********************/ + /*************************** p3 Config Overload ********************/ private: - /**** INTERNAL FUNCTIONS ***/ -//virtual int reScanDirs(); -//virtual int check_dBUpdate(); + /**** INTERNAL FUNCTIONS ***/ + //virtual int reScanDirs(); + //virtual int check_dBUpdate(); private: - /* no need for Mutex protection - - * as each component is protected independently. - */ + /* no need for Mutex protection - + * as each component is protected independently. + */ - P3Interface *mP3iface; /* XXX THIS NEEDS PROTECTION */ + P3Interface *mP3iface; /* XXX THIS NEEDS PROTECTION */ - p3PeerMgr *mPeerMgr; - p3LinkMgr *mLinkMgr; - - ftCacheStrapper *mCacheStrapper; - ftFiStore *mFiStore; - ftFiMonitor *mFiMon; + p3PeerMgr *mPeerMgr; + p3LinkMgr *mLinkMgr; - ftController *mFtController; - ftExtraList *mFtExtra; + ftCacheStrapper *mCacheStrapper; + ftFiStore *mFiStore; + ftFiMonitor *mFiMon; - ftDataMultiplex *mFtDataplex; - p3turtle *mTurtleRouter ; + ftController *mFtController; + ftExtraList *mFtExtra; + + ftDataMultiplex *mFtDataplex; + p3turtle *mTurtleRouter ; - ftFileSearch *mFtSearch; + ftFileSearch *mFtSearch; - ftDwlQueue *mFtDwlQueue; + ftDwlQueue *mFtDwlQueue; - RsMutex srvMutex; - std::string mConfigPath; - std::string mDownloadPath; - std::string mPartialsPath; + RsMutex srvMutex; + std::string mConfigPath; + std::string mDownloadPath; + std::string mPartialsPath; }; diff --git a/libretroshare/src/retroshare/rsturtle.h b/libretroshare/src/retroshare/rsturtle.h index 29d7ccdc3..59fbffac8 100644 --- a/libretroshare/src/retroshare/rsturtle.h +++ b/libretroshare/src/retroshare/rsturtle.h @@ -34,6 +34,7 @@ #include class LinearizedExpression ; +class RsTurtleClientService ; class RsTurtle; extern RsTurtle *rsTurtle ; @@ -83,8 +84,6 @@ class TurtleTrafficStatisticsInfo class RsTurtle { public: - enum FileSharingStrategy { SHARE_ENTIRE_NETWORK, SHARE_FRIENDS_ONLY } ; - RsTurtle() {} virtual ~RsTurtle() {} @@ -103,23 +102,27 @@ class RsTurtle virtual TurtleRequestId turtleSearch(const std::string& match_string) = 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 // an exception if an error occurs during the initialization process. The // turtle router itself does not initiate downloads, it only maintains // tunnels for the given hash. The download should be driven by the file // 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 // 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. // @@ -136,8 +139,6 @@ class RsTurtle // Hardcore handles virtual void setMaxTRForwardRate(int max_tr_up_rate) = 0 ; virtual int getMaxTRForwardRate() const = 0 ; - protected: - FileSharingStrategy _sharing_strategy ; }; #endif diff --git a/libretroshare/src/serialiser/itempriorities.h b/libretroshare/src/serialiser/itempriorities.h index c1e78c31d..0dea7db1f 100644 --- a/libretroshare/src/serialiser/itempriorities.h +++ b/libretroshare/src/serialiser/itempriorities.h @@ -33,7 +33,7 @@ const uint8_t QOS_PRIORITY_TOP = 9 ; // const uint8_t QOS_PRIORITY_RS_TURTLE_OPEN_TUNNEL = 6 ; const uint8_t QOS_PRIORITY_RS_TURTLE_TUNNEL_OK = 6 ; -const uint8_t QOS_PRIORITY_RS_TURTLE_SEARCH_REQUEST = 6 ; +const uint8_t QOS_PRIORITY_RS_TURTLE_SEARCH_REQUEST = 6 ; const uint8_t QOS_PRIORITY_RS_TURTLE_FILE_REQUEST = 5 ; const uint8_t QOS_PRIORITY_RS_TURTLE_FILE_CRC_REQUEST = 5 ; const uint8_t QOS_PRIORITY_RS_TURTLE_CHUNK_CRC_REQUEST= 5 ; @@ -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_GENERIC_ITEM = 3 ; const uint8_t QOS_PRIORITY_RS_TURTLE_FORWARD_FILE_DATA= 2 ; +const uint8_t QOS_PRIORITY_RS_TURTLE_GENERIC_DATA = 5 ; // File transfer // diff --git a/libretroshare/src/turtle/p3turtle.cc b/libretroshare/src/turtle/p3turtle.cc index 3c66b9f73..7ce9a6fb2 100644 --- a/libretroshare/src/turtle/p3turtle.cc +++ b/libretroshare/src/turtle/p3turtle.cc @@ -120,7 +120,6 @@ p3turtle::p3turtle(p3LinkMgr *lm,ftServer *fs) _last_tunnel_speed_estimate_time = 0 ; _traffic_info.reset() ; - _sharing_strategy = SHARE_ENTIRE_NETWORK ; _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 // - for(std::map::const_iterator it(_incoming_file_hashes.begin());it!=_incoming_file_hashes.end();++it) + for(std::map::const_iterator it(_incoming_file_hashes.begin());it!=_incoming_file_hashes.end();++it) { // get total tunnel speed. // @@ -418,7 +417,7 @@ void p3turtle::autoWash() for(unsigned int i=0;i<_hashes_to_remove.size();++i) { - std::map::iterator it(_incoming_file_hashes.find(_hashes_to_remove[i])) ; + std::map::iterator it(_incoming_file_hashes.find(_hashes_to_remove[i])) ; if(it == _incoming_file_hashes.end()) { @@ -567,7 +566,7 @@ void p3turtle::locked_closeTunnel(TurtleTunnelId tid,std::vector::iterator it(_incoming_file_hashes.find(hash)) ; + std::map::iterator it(_incoming_file_hashes.find(hash)) ; if(it != _incoming_file_hashes.end()) { @@ -592,7 +591,7 @@ void p3turtle::locked_closeTunnel(TurtleTunnelId tid,std::vector::iterator itHash = _outgoing_file_hashes.find(it->second.hash); + std::map::iterator itHash = _outgoing_file_hashes.find(it->second.hash); if(itHash != _outgoing_file_hashes.end()) _outgoing_file_hashes.erase(itHash) ; } @@ -600,7 +599,7 @@ void p3turtle::locked_closeTunnel(TurtleTunnelId tid,std::vectordepth < 2) + + std::list result ; + + item->performLocalSearch(result) ; + + RsTurtleSearchResultItem *res_item = NULL ; + uint32_t item_size = 0 ; + +#ifdef P3TURTLE_DEBUG + if(!result.empty()) + std::cerr << " " << result.size() << " matches found. Sending back to origin (" << item->PeerId() << ")." << std::endl ; +#endif + while(!result.empty()) { - std::list result ; + // Let's chop search results items into several chunks of finite size to avoid exceeding streamer's capacity. + // + static const uint32_t RSTURTLE_MAX_SEARCH_RESPONSE_SIZE = 10000 ; - item->performLocalSearch(result) ; - - RsTurtleSearchResultItem *res_item = NULL ; - uint32_t item_size = 0 ; - -#ifdef P3TURTLE_DEBUG - if(!result.empty()) - std::cerr << " " << result.size() << " matches found. Sending back to origin (" << item->PeerId() << ")." << std::endl ; -#endif - while(!result.empty()) + if(res_item == NULL) { - // Let's chop search results items into several chunks of finite size to avoid exceeding streamer's capacity. - // - static const uint32_t RSTURTLE_MAX_SEARCH_RESPONSE_SIZE = 10000 ; + res_item = new RsTurtleSearchResultItem ; + item_size = 0 ; - if(res_item == NULL) - { - res_item = new RsTurtleSearchResultItem ; - item_size = 0 ; + res_item->depth = 0 ; + res_item->request_id = item->request_id ; + res_item->PeerId(item->PeerId()) ; // send back to the same guy + } + res_item->result.push_back(result.front()) ; - res_item->depth = 0 ; - res_item->request_id = item->request_id ; - res_item->PeerId(item->PeerId()) ; // send back to the same guy - } - res_item->result.push_back(result.front()) ; + item_size += 8 /* size */ + result.front().hash.size() + result.front().name.size() ; + result.pop_front() ; - item_size += 8 /* size */ + result.front().hash.size() + result.front().name.size() ; - result.pop_front() ; - - if(item_size > RSTURTLE_MAX_SEARCH_RESPONSE_SIZE || result.empty()) - { + if(item_size > RSTURTLE_MAX_SEARCH_RESPONSE_SIZE || result.empty()) + { #ifdef P3TURTLE_DEBUG - std::cerr << " Sending back chunk of size " << item_size << ", for " << res_item->result.size() << " elements." << std::endl ; + std::cerr << " Sending back chunk of size " << item_size << ", for " << res_item->result.size() << " elements." << std::endl ; #endif - sendItem(res_item) ; - res_item = NULL ; - } + sendItem(res_item) ; + res_item = NULL ; } } + #ifdef P3TURTLE_DEBUG else 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) ; - std::map::const_iterator it(_outgoing_file_hashes.find(tunnel.hash)) ; + std::map::const_iterator it(_outgoing_file_hashes.find(tunnel.hash)) ; #ifdef P3TURTLE_DEBUG assert(!tunnel.hash.empty()) ; 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 << " using peer_id=" << tunnel.vpid << ", hash=" << tunnel.hash << std::endl ; #endif - size = it->second.size ; + size = 0 ; //it->second.size ; Not used by ftDataMultiplex actually vpid = tunnel.vpid ; hash = tunnel.hash ; } @@ -1167,7 +1165,7 @@ void p3turtle::handleRecvFileData(RsTurtleFileDataItem *item) } TurtleTunnel& tunnel(it2->second) ; - std::map::iterator it( _incoming_file_hashes.find(tunnel.hash) ) ; + std::map::iterator it( _incoming_file_hashes.find(tunnel.hash) ) ; #ifdef P3TURTLE_DEBUG assert(!tunnel.hash.empty()) ; #endif @@ -1179,7 +1177,6 @@ void p3turtle::handleRecvFileData(RsTurtleFileDataItem *item) return ; } - const TurtleFileHashInfo& hash_info(it->second) ; #ifdef P3TURTLE_DEBUG std::cerr << " This is an endpoint for this data chunk." << 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) ; vpid = tunnel.vpid ; 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. //it->second.time_stamp = time(NULL) ; @@ -1893,14 +1890,14 @@ void p3turtle::handleTunnelRequest(RsTurtleOpenTunnelItem *item) // We're off-mutex here. bool found = false ; - FileInfo info ; + std::string info ; if(item->PeerId() != mLinkMgr->getOwnId()) { #ifdef P3TURTLE_DEBUG std::cerr << " Request not from us. Performing local search" << std::endl ; #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) ; - // 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 ; @@ -2101,7 +2098,7 @@ void p3turtle::handleTunnelResult(RsTurtleTunnelOkItem *item) // and this mostly prevents from sending the hash back in the tunnel. bool found = false ; - for(std::map::iterator it(_incoming_file_hashes.begin());it!=_incoming_file_hashes.end();++it) + for(std::map::iterator it(_incoming_file_hashes.begin());it!=_incoming_file_hashes.end();++it) if(it->second.last_request == item->request_id) { found = true ; @@ -2305,7 +2302,7 @@ TurtleRequestId p3turtle::turtleSearch(const LinearizedExpression& expr) 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 ******/ @@ -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) 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.pop_back() ; #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 } // 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 - 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 return ; } #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 // 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. - _incoming_file_hashes[file_hash].size = size ; - _incoming_file_hashes[file_hash].name = name ; - _incoming_file_hashes[file_hash].last_digg_time = RSRandom::random_u32()%10 ; + _incoming_file_hashes[hash].last_digg_time = RSRandom::random_u32()%10 ; } 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. /// 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; + for(std::list::const_iterator it(_registered_services.begin());it!=_registered_services.end();++it) + if( (*it)->handleTunnelRequest(hash,peer_id,description_string)) + return true ; + + return false ; +} + + +void p3turtle::registerTunnelService(RsTurtleClientService *service) +{ #ifdef P3TURTLE_DEBUG - std::cerr << "p3turtle: 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::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; - } + for(std::list::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 + 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 - // 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 ; + _registered_services.push_back(service) ; } static std::string printFloatNumber(float num,bool friendly=false) @@ -2471,14 +2464,15 @@ void p3turtle::getInfo( std::vector >& hashes_info, hashes_info.clear() ; - for(std::map::const_iterator it(_incoming_file_hashes.begin());it!=_incoming_file_hashes.end();++it) + for(std::map::const_iterator it(_incoming_file_hashes.begin());it!=_incoming_file_hashes.end();++it) { hashes_info.push_back(std::vector()) ; std::vector& hashes(hashes_info.back()) ; 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(now - it->second.time_stamp)+" secs ago") ; } @@ -2547,7 +2541,7 @@ void p3turtle::dumpState() std::cerr << std::endl ; std::cerr << "********************** Turtle router dump ******************" << std::endl ; std::cerr << " Active incoming file hashes: " << _incoming_file_hashes.size() << std::endl ; - for(std::map::const_iterator it(_incoming_file_hashes.begin());it!=_incoming_file_hashes.end();++it) + for(std::map::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 =" ; for(std::vector::const_iterator it2(it->second.tunnels.begin());it2!=it->second.tunnels.end();++it2) diff --git a/libretroshare/src/turtle/p3turtle.h b/libretroshare/src/turtle/p3turtle.h index 0d22a9107..afbb54530 100644 --- a/libretroshare/src/turtle/p3turtle.h +++ b/libretroshare/src/turtle/p3turtle.h @@ -150,6 +150,7 @@ #include "ft/ftsearch.h" #include "retroshare/rsturtle.h" #include "rsturtleitem.h" +#include "turtleclientservice.h" #include "turtlestatistics.h" //#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. // -class TurtleFileHashInfo + +class TurtleHashInfo { public: std::vector tunnels ; // list of active tunnel ids for this file hash TurtleRequestId last_request ; // last request for the tunnels of this hash - - TurtleFileName name ; time_t last_digg_time ; - uint64_t size ; }; // Subclassing: @@ -223,15 +222,18 @@ class p3turtle: public p3Service, public RsTurtle, public p3Config virtual void setEnabled(bool) ; virtual bool enabled() const ; - // This is temporary, used by Operating Mode. + // This is temporary, used by Operating Mode. // Turtle operates when both enabled() && sessionEnabled() are true. - virtual void setSessionEnabled(bool); - virtual bool sessionEnabled() const; + virtual void setSessionEnabled(bool); + virtual bool sessionEnabled() const; // Lauches a search request through the pipes, and immediately returns // the request id, which will be further used by the gui to store results // 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 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 // 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 /// 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 virtual void getInfo(std::vector >&, @@ -382,7 +393,7 @@ class p3turtle: public p3Service, public RsTurtle, public p3Config void returnSearchResult(RsTurtleSearchResultItem *item) ; /// 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 --------------------------------// @@ -400,10 +411,10 @@ class p3turtle: public p3Service, public RsTurtle, public p3Config std::map _tunnel_requests_origins ; /// stores adequate tunnels for each file hash locally managed - std::map _incoming_file_hashes ; + std::map _incoming_file_hashes ; /// stores file info for each file we provide. - std::map _outgoing_file_hashes ; + std::map _outgoing_file_hashes ; /// local tunnels, stored by ids (Either transiting or ending). std::map _local_tunnels ; @@ -414,6 +425,9 @@ class p3turtle: public p3Service, public RsTurtle, public p3Config /// Hashes marked to be deleted. std::vector _hashes_to_remove ; + /// List of client services that have regitered. + std::list _registered_services ; + time_t _last_clean_time ; time_t _last_tunnel_management_time ; time_t _last_tunnel_campaign_time ; diff --git a/libretroshare/src/turtle/rsturtleitem.h b/libretroshare/src/turtle/rsturtleitem.h index 4e6ef21dc..e4367b401 100644 --- a/libretroshare/src/turtle/rsturtleitem.h +++ b/libretroshare/src/turtle/rsturtleitem.h @@ -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_DATA = 0x08 ; const uint8_t RS_TURTLE_SUBTYPE_REGEXP_SEARCH_REQUEST = 0x09 ; +const uint8_t RS_TURTLE_SUBTYPE_GENERIC_DATA = 0x0a ; const uint8_t RS_TURTLE_SUBTYPE_FILE_MAP = 0x10 ; const uint8_t RS_TURTLE_SUBTYPE_FILE_MAP_REQUEST = 0x11 ; const uint8_t RS_TURTLE_SUBTYPE_FILE_CRC = 0x12 ; @@ -204,6 +205,28 @@ 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: