2008-07-02 09:19:59 -04:00
/*
* libretroshare / src / ft : ftserver . cc
*
* File Transfer for RetroShare .
*
* Copyright 2008 by Robert Fernie .
*
* This library is free software ; you can redistribute it and / or
* modify it under the terms of the GNU Library General Public
* License Version 2 as published by the Free Software Foundation .
*
* This library is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the GNU
* Library General Public License for more details .
*
* You should have received a copy of the GNU Library General Public
* License along with this library ; if not , write to the Free Software
* Foundation , Inc . , 59 Temple Place , Suite 330 , Boston , MA 02111 - 1307
* USA .
*
* Please report all bugs and problems to " retroshare@lunamutt.com " .
*
*/
2012-04-12 19:29:39 -04:00
# include <iostream>
2013-10-21 07:00:49 -04:00
# include <time.h>
2008-08-03 08:45:53 -04:00
# include "util/rsdebug.h"
2009-08-11 16:00:08 -04:00
# include "util/rsdir.h"
2010-08-06 05:40:23 -04:00
# include "retroshare/rstypes.h"
2013-04-01 17:18:58 -04:00
# include "retroshare/rspeers.h"
2008-08-03 08:45:53 -04:00
const int ftserverzone = 29539 ;
2016-07-30 15:52:42 -04:00
# include "file_sharing/p3filelists.h"
2013-04-06 05:21:01 -04:00
# include "ft/ftturtlefiletransferitem.h"
2008-08-03 08:45:53 -04:00
# include "ft/ftserver.h"
# include "ft/ftextralist.h"
# include "ft/ftfilesearch.h"
# include "ft/ftcontroller.h"
2009-01-22 16:06:54 -05:00
# include "ft/ftfileprovider.h"
2008-08-03 08:45:53 -04:00
# include "ft/ftdatamultiplex.h"
2010-03-06 18:29:47 -05:00
//#include "ft/ftdwlqueue.h"
2009-05-26 17:42:45 -04:00
# include "turtle/p3turtle.h"
2014-01-07 17:51:22 -05:00
# include "pqi/p3notify.h"
# include "rsserver/p3face.h"
2008-08-03 08:45:53 -04:00
# include "pqi/pqi.h"
2011-07-09 14:39:34 -04:00
# include "pqi/p3linkmgr.h"
2008-08-03 08:45:53 -04:00
2013-10-01 04:11:15 -04:00
# include "serialiser/rsfiletransferitems.h"
2008-08-09 13:03:24 -04:00
# include "serialiser/rsserviceids.h"
2008-08-17 11:23:11 -04:00
/***
2013-10-02 15:56:01 -04:00
* # define SERVER_DEBUG 1
* # define SERVER_DEBUG_CACHE 1
2008-08-17 11:23:11 -04:00
* * */
2013-10-01 04:11:15 -04:00
static const time_t FILE_TRANSFER_LOW_PRIORITY_TASKS_PERIOD = 5 ; // low priority tasks handling every 5 seconds
2008-07-02 09:19:59 -04:00
/* Setup */
2014-03-28 23:57:44 -04:00
ftServer : : ftServer ( p3PeerMgr * pm , p3ServiceControl * sc )
2014-03-21 23:53:44 -04:00
: p3Service ( ) ,
2016-07-30 15:52:42 -04:00
mPeerMgr ( pm ) , mServiceCtrl ( sc ) ,
mFileDatabase ( NULL ) ,
2008-12-07 12:51:11 -05:00
mFtController ( NULL ) , mFtExtra ( NULL ) ,
2011-07-04 18:59:39 -04:00
mFtDataplex ( NULL ) , mFtSearch ( NULL ) , srvMutex ( " ftServer " )
2008-07-02 09:19:59 -04:00
{
2013-10-02 15:56:01 -04:00
addSerialType ( new RsFileTransferSerialiser ( ) ) ;
2008-08-03 08:45:53 -04:00
}
2014-03-21 23:53:44 -04:00
const std : : string FILE_TRANSFER_APP_NAME = " ft " ;
const uint16_t FILE_TRANSFER_APP_MAJOR_VERSION = 1 ;
const uint16_t FILE_TRANSFER_APP_MINOR_VERSION = 0 ;
const uint16_t FILE_TRANSFER_MIN_MAJOR_VERSION = 1 ;
const uint16_t FILE_TRANSFER_MIN_MINOR_VERSION = 0 ;
RsServiceInfo ftServer : : getServiceInfo ( )
{
return RsServiceInfo ( RS_SERVICE_TYPE_FILE_TRANSFER ,
FILE_TRANSFER_APP_NAME ,
FILE_TRANSFER_APP_MAJOR_VERSION ,
FILE_TRANSFER_APP_MINOR_VERSION ,
FILE_TRANSFER_MIN_MAJOR_VERSION ,
FILE_TRANSFER_MIN_MINOR_VERSION ) ;
}
2008-08-03 08:45:53 -04:00
void ftServer : : setConfigDirectory ( std : : string path )
{
mConfigPath = path ;
2008-08-17 11:23:11 -04:00
/* Must update the sub classes ... if they exist
* TODO .
*/
2010-02-10 15:32:21 -05:00
std : : string basecachedir = mConfigPath + " /cache " ;
2008-08-17 11:23:11 -04:00
std : : string localcachedir = mConfigPath + " /cache/local " ;
std : : string remotecachedir = mConfigPath + " /cache/remote " ;
2010-02-10 15:32:21 -05:00
RsDirUtil : : checkCreateDirectory ( basecachedir ) ;
2009-08-11 16:00:08 -04:00
RsDirUtil : : checkCreateDirectory ( localcachedir ) ;
RsDirUtil : : checkCreateDirectory ( remotecachedir ) ;
2008-08-03 08:45:53 -04:00
}
/* Control Interface */
/* add Config Items (Extra, Controller) */
2011-08-12 09:42:30 -04:00
void ftServer : : addConfigComponents ( p3ConfigMgr */ * mgr */ )
2008-08-03 08:45:53 -04:00
{
/* NOT SURE ABOUT THIS ONE */
}
2014-03-17 16:56:06 -04:00
const RsPeerId & ftServer : : OwnId ( )
2008-10-29 16:58:23 -04:00
{
2014-03-17 16:56:06 -04:00
static RsPeerId null_id ;
2014-03-28 23:57:44 -04:00
if ( mServiceCtrl )
return mServiceCtrl - > getOwnId ( ) ;
2014-03-17 16:56:06 -04:00
else
return null_id ;
2008-10-29 16:58:23 -04:00
}
2008-07-02 09:19:59 -04:00
/* Final Setup (once everything is assigned) */
2014-01-07 17:51:22 -05:00
void ftServer : : SetupFtServer ( )
2008-07-02 09:19:59 -04:00
{
/* setup FiStore/Monitor */
2008-08-09 13:03:24 -04:00
std : : string localcachedir = mConfigPath + " /cache/local " ;
std : : string remotecachedir = mConfigPath + " /cache/remote " ;
2014-03-28 23:57:44 -04:00
RsPeerId ownId = mServiceCtrl - > getOwnId ( ) ;
2008-07-02 09:19:59 -04:00
2008-08-17 11:23:11 -04:00
/* search/extras List */
mFtExtra = new ftExtraList ( ) ;
mFtSearch = new ftFileSearch ( ) ;
/* Transport */
2009-05-26 17:42:45 -04:00
mFtDataplex = new ftDataMultiplex ( ownId , this , mFtSearch ) ;
2008-08-17 11:23:11 -04:00
/* make Controller */
2016-07-30 15:52:42 -04:00
mFtController = new ftController ( mFtDataplex , mServiceCtrl , getServiceInfo ( ) . mServiceType ) ;
2008-11-09 17:17:20 -05:00
mFtController - > setFtSearchNExtra ( mFtSearch , mFtExtra ) ;
2008-08-29 21:07:24 -04:00
std : : string tmppath = " . " ;
2008-08-17 11:23:11 -04:00
mFtController - > setPartialsDirectory ( tmppath ) ;
mFtController - > setDownloadDirectory ( tmppath ) ;
/* complete search setup */
2008-08-03 08:45:53 -04:00
mFtSearch - > addSearchMode ( mFtExtra , RS_FILE_HINTS_EXTRA ) ;
2008-08-09 13:03:24 -04:00
2014-03-28 23:57:44 -04:00
mServiceCtrl - > registerServiceMonitor ( mFtController , getServiceInfo ( ) . mServiceType ) ;
2008-08-17 11:23:11 -04:00
2008-07-02 09:19:59 -04:00
return ;
}
2016-08-13 04:15:02 -04:00
void ftServer : : connectToFileDatabase ( p3FileDatabase * fdb )
{
mFileDatabase = fdb ;
mFtSearch - > addSearchMode ( fdb , RS_FILE_HINTS_LOCAL | RS_FILE_HINTS_REMOTE ) ;
}
2009-05-26 17:42:45 -04:00
void ftServer : : connectToTurtleRouter ( p3turtle * fts )
{
mTurtleRouter = fts ;
mFtController - > setTurtleRouter ( fts ) ;
2013-04-06 05:21:01 -04:00
mFtController - > setFtServer ( this ) ;
mTurtleRouter - > registerTunnelService ( this ) ;
2009-05-26 17:42:45 -04:00
}
2008-07-02 09:19:59 -04:00
2008-08-03 08:45:53 -04:00
void ftServer : : StartupThreads ( )
2008-07-02 09:19:59 -04:00
{
2008-08-03 08:45:53 -04:00
/* start up order - important for dependencies */
2008-07-02 09:19:59 -04:00
2008-08-03 08:45:53 -04:00
/* self contained threads */
/* startup ExtraList Thread */
2016-06-01 10:18:19 -04:00
mFtExtra - > start ( " ft extra lst " ) ;
2008-07-02 09:19:59 -04:00
2008-08-03 08:45:53 -04:00
/* startup Monitor Thread */
/* startup the FileMonitor (after cache load) */
/* start it up */
2016-07-30 15:52:42 -04:00
mFileDatabase - > startThreads ( ) ;
2008-07-02 09:19:59 -04:00
2008-08-03 08:45:53 -04:00
/* Controller thread */
2016-06-01 10:18:19 -04:00
mFtController - > start ( " ft ctrl " ) ;
2008-08-17 11:23:11 -04:00
2008-08-29 21:07:24 -04:00
/* Dataplex */
2016-06-01 10:18:19 -04:00
mFtDataplex - > start ( " ft dataplex " ) ;
2008-07-02 09:19:59 -04:00
}
2010-05-29 11:14:25 -04:00
void ftServer : : StopThreads ( )
{
/* stop Dataplex */
mFtDataplex - > join ( ) ;
/* stop Controller thread */
mFtController - > join ( ) ;
/* self contained threads */
/* stop ExtraList Thread */
mFtExtra - > join ( ) ;
delete ( mFtDataplex ) ;
mFtDataplex = NULL ;
delete ( mFtController ) ;
mFtController = NULL ;
delete ( mFtExtra ) ;
mFtExtra = NULL ;
2016-07-30 15:52:42 -04:00
/* stop Monitor Thread */
mFileDatabase - > stopThreads ( ) ;
delete mFileDatabase ;
mFileDatabase = NULL ;
2008-07-02 09:19:59 -04:00
}
2013-10-01 04:11:15 -04:00
/***************************************************************/
/********************** RsFiles Interface **********************/
/***************************************************************/
2008-08-03 08:45:53 -04:00
2013-10-01 04:11:15 -04:00
/***************************************************************/
/********************** Controller Access **********************/
/***************************************************************/
2008-07-02 09:19:59 -04:00
2013-10-01 04:11:15 -04:00
bool ftServer : : ResumeTransfers ( )
{
mFtController - > activate ( ) ;
2008-07-02 09:19:59 -04:00
2013-10-01 04:11:15 -04:00
return true ;
}
2008-07-02 09:19:59 -04:00
2015-03-08 09:46:07 -04:00
bool ftServer : : getFileData ( const RsFileHash & hash , uint64_t offset , uint32_t & requested_size , uint8_t * data )
{
return mFtDataplex - > getFileData ( hash , offset , requested_size , data ) ;
}
2014-03-17 16:56:06 -04:00
bool ftServer : : alreadyHaveFile ( const RsFileHash & hash , FileInfo & info )
2010-10-05 16:39:14 -04:00
{
2016-08-16 17:44:48 -04:00
return mFileDatabase - > search ( hash , RS_FILE_HINTS_LOCAL , info ) ;
2010-10-05 16:39:14 -04:00
}
2014-03-17 16:56:06 -04:00
bool ftServer : : FileRequest ( const std : : string & fname , const RsFileHash & hash , uint64_t size , const std : : string & dest , TransferRequestFlags flags , const std : : list < RsPeerId > & srcIds )
2008-07-02 09:19:59 -04:00
{
2016-07-30 15:52:42 -04:00
std : : cerr < < " Requesting " < < fname < < std : : endl ;
2010-01-16 10:42:26 -05:00
2010-03-06 18:29:47 -05:00
if ( ! mFtController - > FileRequest ( fname , hash , size , dest , flags , srcIds ) )
2010-01-16 10:42:26 -05:00
return false ;
2009-08-03 15:43:52 -04:00
return true ;
2008-07-02 09:19:59 -04:00
}
2014-03-17 16:56:06 -04:00
bool ftServer : : setDestinationName ( const RsFileHash & hash , const std : : string & name )
2013-02-27 11:59:16 -05:00
{
return mFtController - > setDestinationName ( hash , name ) ;
}
2014-03-17 16:56:06 -04:00
bool ftServer : : setDestinationDirectory ( const RsFileHash & hash , const std : : string & directory )
2013-02-27 11:59:16 -05:00
{
return mFtController - > setDestinationDirectory ( hash , directory ) ;
}
2014-03-17 16:56:06 -04:00
bool ftServer : : setChunkStrategy ( const RsFileHash & hash , FileChunksInfo : : ChunkStrategy s )
2009-12-08 17:29:52 -05:00
{
return mFtController - > setChunkStrategy ( hash , s ) ;
}
2010-05-21 16:49:48 -04:00
uint32_t ftServer : : freeDiskSpaceLimit ( ) const
{
return mFtController - > freeDiskSpaceLimit ( ) ;
}
void ftServer : : setFreeDiskSpaceLimit ( uint32_t s )
{
mFtController - > setFreeDiskSpaceLimit ( s ) ;
}
2010-04-30 17:07:21 -04:00
void ftServer : : setDefaultChunkStrategy ( FileChunksInfo : : ChunkStrategy s )
2010-03-21 17:07:12 -04:00
{
2010-04-30 17:07:21 -04:00
mFtController - > setDefaultChunkStrategy ( s ) ;
2010-03-21 17:07:12 -04:00
}
FileChunksInfo : : ChunkStrategy ftServer : : defaultChunkStrategy ( )
{
return mFtController - > defaultChunkStrategy ( ) ;
}
2014-03-17 16:56:06 -04:00
bool ftServer : : FileCancel ( const RsFileHash & hash )
2008-07-02 09:19:59 -04:00
{
2010-01-26 18:25:00 -05:00
// Remove from both queue and ftController, by default.
//
mFtController - > FileCancel ( hash ) ;
return true ;
2008-07-02 09:19:59 -04:00
}
2014-03-17 16:56:06 -04:00
bool ftServer : : FileControl ( const RsFileHash & hash , uint32_t flags )
2008-07-02 09:19:59 -04:00
{
return mFtController - > FileControl ( hash , flags ) ;
}
2008-08-03 08:45:53 -04:00
bool ftServer : : FileClearCompleted ( )
2008-07-02 09:19:59 -04:00
{
return mFtController - > FileClearCompleted ( ) ;
}
2010-03-06 18:29:47 -05:00
void ftServer : : setQueueSize ( uint32_t s )
{
mFtController - > setQueueSize ( s ) ;
}
uint32_t ftServer : : getQueueSize ( )
{
return mFtController - > getQueueSize ( ) ;
}
2009-07-26 11:00:29 -04:00
/* Control of Downloads Priority. */
2014-03-17 16:56:06 -04:00
bool ftServer : : changeQueuePosition ( const RsFileHash & hash , QueueMove mv )
2009-07-26 11:00:29 -04:00
{
2010-03-06 18:29:47 -05:00
mFtController - > moveInQueue ( hash , mv ) ;
return true ;
2010-01-26 18:25:00 -05:00
}
2014-03-17 16:56:06 -04:00
bool ftServer : : changeDownloadSpeed ( const RsFileHash & hash , int speed )
2010-01-26 18:25:00 -05:00
{
mFtController - > setPriority ( hash , ( DwlSpeed ) speed ) ;
2010-01-26 15:40:21 -05:00
return true ;
2009-07-26 11:00:29 -04:00
}
2014-03-17 16:56:06 -04:00
bool ftServer : : getDownloadSpeed ( const RsFileHash & hash , int & speed )
2010-01-26 18:25:00 -05:00
{
DwlSpeed _speed ;
int ret = mFtController - > getPriority ( hash , _speed ) ;
if ( ret )
speed = _speed ;
2009-07-26 11:00:29 -04:00
2010-01-26 18:25:00 -05:00
return ret ;
}
2014-03-17 16:56:06 -04:00
bool ftServer : : clearDownload ( const RsFileHash & /*hash*/ )
2009-07-26 11:00:29 -04:00
{
2010-01-27 03:24:39 -05:00
return true ;
2009-07-26 11:00:29 -04:00
}
2014-03-17 16:56:06 -04:00
bool ftServer : : FileDownloadChunksDetails ( const RsFileHash & hash , FileChunksInfo & info )
2010-01-11 11:00:42 -05:00
{
return mFtController - > getFileDownloadChunksDetails ( hash , info ) ;
2009-11-17 07:45:06 -05:00
}
2016-09-11 11:52:12 -04:00
void ftServer : : requestDirUpdate ( void * ref )
{
mFileDatabase - > requestDirUpdate ( ref ) ;
}
/* Directory Handling */
2008-07-02 09:19:59 -04:00
void ftServer : : setDownloadDirectory ( std : : string path )
{
2008-08-03 08:45:53 -04:00
mFtController - > setDownloadDirectory ( path ) ;
2008-07-02 09:19:59 -04:00
}
std : : string ftServer : : getDownloadDirectory ( )
{
return mFtController - > getDownloadDirectory ( ) ;
}
2008-08-03 08:45:53 -04:00
void ftServer : : setPartialsDirectory ( std : : string path )
2008-07-02 09:19:59 -04:00
{
2008-08-03 08:45:53 -04:00
mFtController - > setPartialsDirectory ( path ) ;
2008-07-02 09:19:59 -04:00
}
2008-08-03 08:45:53 -04:00
std : : string ftServer : : getPartialsDirectory ( )
2008-07-02 09:19:59 -04:00
{
return mFtController - > getPartialsDirectory ( ) ;
}
2016-07-30 15:52:42 -04:00
/***************************************************************/
/************************* Other Access ************************/
/***************************************************************/
2008-07-02 09:19:59 -04:00
2016-07-30 15:52:42 -04:00
bool ftServer : : copyFile ( const std : : string & source , const std : : string & dest )
{
return mFtController - > copyFile ( source , dest ) ;
}
2008-07-02 09:19:59 -04:00
2015-03-08 09:46:07 -04:00
void ftServer : : FileDownloads ( std : : list < RsFileHash > & hashs )
2008-08-09 13:03:24 -04:00
{
2015-03-08 09:46:07 -04:00
mFtController - > FileDownloads ( hashs ) ;
2008-08-09 13:03:24 -04:00
}
2014-03-17 16:56:06 -04:00
bool ftServer : : FileUploadChunksDetails ( const RsFileHash & hash , const RsPeerId & peer_id , CompressedChunkMap & cmap )
2010-01-11 11:00:42 -05:00
{
return mFtDataplex - > getClientChunkMap ( hash , peer_id , cmap ) ;
}
2014-03-17 16:56:06 -04:00
bool ftServer : : FileUploads ( std : : list < RsFileHash > & hashs )
2008-07-02 09:19:59 -04:00
{
2008-08-09 13:03:24 -04:00
return mFtDataplex - > FileUploads ( hashs ) ;
2008-07-02 09:19:59 -04:00
}
2014-03-17 16:56:06 -04:00
bool ftServer : : FileDetails ( const RsFileHash & hash , FileSearchFlags hintflags , FileInfo & info )
2008-07-02 09:19:59 -04:00
{
2008-11-30 12:17:28 -05:00
if ( hintflags & RS_FILE_HINTS_DOWNLOAD )
2010-01-02 16:30:19 -05:00
if ( mFtController - > FileDetails ( hash , info ) )
return true ;
2008-07-02 09:19:59 -04:00
2010-01-02 16:30:19 -05:00
if ( hintflags & RS_FILE_HINTS_UPLOAD )
if ( mFtDataplex - > FileDetails ( hash , hintflags , info ) )
2011-10-01 17:10:03 -04:00
{
// We also check if the file is a DL as well. In such a case we use
// the DL as the file name, to replace the hash. If the file is a cache
// file, we skip the call to fileDetails() for efficiency reasons.
//
FileInfo info2 ;
2016-07-30 15:52:42 -04:00
if ( mFtController - > FileDetails ( hash , info2 ) )
2011-10-01 17:10:03 -04:00
info . fname = info2 . fname ;
2010-01-02 16:30:19 -05:00
return true ;
2011-10-01 17:10:03 -04:00
}
2010-01-02 16:30:19 -05:00
if ( hintflags & ~ ( RS_FILE_HINTS_UPLOAD | RS_FILE_HINTS_DOWNLOAD ) )
2010-01-11 11:00:42 -05:00
if ( mFtSearch - > search ( hash , hintflags , info ) )
2010-01-02 16:30:19 -05:00
return true ;
return false ;
2008-07-02 09:19:59 -04:00
}
2013-04-06 05:21:01 -04:00
RsTurtleGenericTunnelItem * ftServer : : deserialiseItem ( void * data , uint32_t size ) const
{
uint32_t rstype = getRsItemId ( data ) ;
# ifdef SERVER_DEBUG
std : : cerr < < " p3turtle: deserialising packet: " < < std : : endl ;
# endif
if ( ( RS_PKT_VERSION_SERVICE ! = getRsItemVersion ( rstype ) ) | | ( RS_SERVICE_TYPE_TURTLE ! = getRsItemService ( rstype ) ) )
{
std : : cerr < < " Wrong type !! " < < std : : endl ;
return NULL ; /* wrong type */
}
2016-01-11 23:49:00 -05:00
try
{
2013-04-06 05:21:01 -04:00
switch ( getRsItemSubType ( rstype ) )
{
case RS_TURTLE_SUBTYPE_FILE_REQUEST : return new RsTurtleFileRequestItem ( data , size ) ;
case RS_TURTLE_SUBTYPE_FILE_DATA : return new RsTurtleFileDataItem ( data , size ) ;
case RS_TURTLE_SUBTYPE_FILE_MAP_REQUEST : return new RsTurtleFileMapRequestItem ( data , size ) ;
case RS_TURTLE_SUBTYPE_FILE_MAP : return new RsTurtleFileMapItem ( data , size ) ;
case RS_TURTLE_SUBTYPE_CHUNK_CRC_REQUEST : return new RsTurtleChunkCrcRequestItem ( data , size ) ;
case RS_TURTLE_SUBTYPE_CHUNK_CRC : return new RsTurtleChunkCrcItem ( data , size ) ;
default :
return NULL ;
}
2016-01-11 23:49:00 -05:00
}
catch ( std : : exception & e )
{
std : : cerr < < " (EE) deserialisation error in " < < __PRETTY_FUNCTION__ < < " : " < < e . what ( ) < < std : : endl ;
2016-01-12 21:10:11 -05:00
return NULL ;
2016-01-11 23:49:00 -05:00
}
2013-04-06 05:21:01 -04:00
}
2013-04-20 14:56:06 -04:00
void ftServer : : addVirtualPeer ( const TurtleFileHash & hash , const TurtleVirtualPeerId & virtual_peer_id , RsTurtleGenericTunnelItem : : Direction dir )
2013-04-10 04:52:52 -04:00
{
2013-04-20 14:56:06 -04:00
if ( dir = = RsTurtleGenericTunnelItem : : DIRECTION_SERVER )
mFtController - > addFileSource ( hash , virtual_peer_id ) ;
2013-04-10 04:52:52 -04:00
}
void ftServer : : removeVirtualPeer ( const TurtleFileHash & hash , const TurtleVirtualPeerId & virtual_peer_id )
{
mFtController - > removeFileSource ( hash , virtual_peer_id ) ;
}
2014-03-17 16:56:06 -04:00
bool ftServer : : handleTunnelRequest ( const RsFileHash & hash , const RsPeerId & peer_id )
2013-04-01 17:18:58 -04:00
{
2014-11-29 12:26:06 -05:00
FileInfo info ;
bool res = FileDetails ( hash , RS_FILE_HINTS_NETWORK_WIDE | RS_FILE_HINTS_LOCAL | RS_FILE_HINTS_EXTRA | RS_FILE_HINTS_SPEC_ONLY , info ) ;
if ( ( ! res ) & & FileDetails ( hash , RS_FILE_HINTS_DOWNLOAD , info ) )
{
// This file is currently being downloaded. Let's look if we already have a chunk or not. If not, no need to
// share the file!
FileChunksInfo info2 ;
if ( rsFiles - > FileDownloadChunksDetails ( hash , info2 ) )
for ( uint32_t i = 0 ; i < info2 . chunks . size ( ) ; + + i )
if ( info2 . chunks [ i ] = = FileChunksInfo : : CHUNK_DONE )
{
res = true ;
break ;
}
}
2013-04-01 17:18:58 -04:00
# 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 ) ) ;
return res ;
}
2016-07-30 15:52:42 -04:00
/***************************************************************/
/******************* ExtraFileList Access **********************/
/***************************************************************/
2008-07-02 09:19:59 -04:00
2016-07-30 15:52:42 -04:00
bool ftServer : : ExtraFileAdd ( std : : string fname , const RsFileHash & hash , uint64_t size , uint32_t period , TransferRequestFlags flags )
2008-07-02 09:19:59 -04:00
{
return mFtExtra - > addExtraFile ( fname , hash , size , period , flags ) ;
}
2014-03-17 16:56:06 -04:00
bool ftServer : : ExtraFileRemove ( const RsFileHash & hash , TransferRequestFlags flags )
2008-07-02 09:19:59 -04:00
{
return mFtExtra - > removeExtraFile ( hash , flags ) ;
}
2012-11-02 09:52:29 -04:00
bool ftServer : : ExtraFileHash ( std : : string localpath , uint32_t period , TransferRequestFlags flags )
2008-07-02 09:19:59 -04:00
{
return mFtExtra - > hashExtraFile ( localpath , period , flags ) ;
}
2008-08-03 08:45:53 -04:00
bool ftServer : : ExtraFileStatus ( std : : string localpath , FileInfo & info )
2008-07-02 09:19:59 -04:00
{
return mFtExtra - > hashExtraFileDone ( localpath , info ) ;
}
2016-07-30 15:52:42 -04:00
bool ftServer : : ExtraFileMove ( std : : string fname , const RsFileHash & hash , uint64_t size , std : : string destpath )
2008-11-27 16:23:46 -05:00
{
return mFtExtra - > moveExtraFile ( fname , hash , size , destpath ) ;
}
2016-07-30 15:52:42 -04:00
/***************************************************************/
/******************** Directory Listing ************************/
/***************************************************************/
2008-07-02 09:19:59 -04:00
2014-03-17 16:56:06 -04:00
int ftServer : : RequestDirDetails ( const RsPeerId & uid , const std : : string & path , DirDetails & details )
2008-07-02 09:19:59 -04:00
{
2016-07-30 15:52:42 -04:00
return mFileDatabase - > RequestDirDetails ( uid , path , details ) ;
2008-07-02 09:19:59 -04:00
}
2009-07-12 09:22:31 -04:00
2012-11-02 09:52:29 -04:00
int ftServer : : RequestDirDetails ( void * ref , DirDetails & details , FileSearchFlags flags )
2008-07-02 09:19:59 -04:00
{
2016-07-30 15:52:42 -04:00
return mFileDatabase - > RequestDirDetails ( ref , details , flags ) ;
2008-07-02 09:19:59 -04:00
}
2012-11-02 09:52:29 -04:00
uint32_t ftServer : : getType ( void * ref , FileSearchFlags flags )
2011-04-03 15:59:12 -04:00
{
2016-07-30 15:52:42 -04:00
return mFileDatabase - > getType ( ref ) ;
2011-04-03 15:59:12 -04:00
}
2016-07-31 09:59:58 -04:00
/***************************************************************/
/******************** Search Interface *************************/
/***************************************************************/
2008-07-02 09:19:59 -04:00
2012-11-02 09:52:29 -04:00
int ftServer : : SearchKeywords ( std : : list < std : : string > keywords , std : : list < DirDetails > & results , FileSearchFlags flags )
2012-11-01 06:06:12 -04:00
{
2016-07-30 15:52:42 -04:00
return mFileDatabase - > SearchKeywords ( keywords , results , flags , RsPeerId ( ) ) ;
2012-11-01 06:06:12 -04:00
}
2014-03-17 16:56:06 -04:00
int ftServer : : SearchKeywords ( std : : list < std : : string > keywords , std : : list < DirDetails > & results , FileSearchFlags flags , const RsPeerId & peer_id )
2008-07-02 09:19:59 -04:00
{
2016-07-30 15:52:42 -04:00
return mFileDatabase - > SearchKeywords ( keywords , results , flags , peer_id ) ;
2008-07-02 09:19:59 -04:00
}
2009-07-12 09:22:31 -04:00
2016-09-13 06:05:22 -04:00
int ftServer : : SearchBoolExp ( RsRegularExpression : : Expression * exp , std : : list < DirDetails > & results , FileSearchFlags flags )
2008-07-02 09:19:59 -04:00
{
2016-07-30 15:52:42 -04:00
return mFileDatabase - > SearchBoolExp ( exp , results , flags , RsPeerId ( ) ) ;
2012-11-01 06:06:12 -04:00
}
2016-09-13 06:05:22 -04:00
int ftServer : : SearchBoolExp ( RsRegularExpression : : Expression * exp , std : : list < DirDetails > & results , FileSearchFlags flags , const RsPeerId & peer_id )
2012-11-01 06:06:12 -04:00
{
2016-07-30 15:52:42 -04:00
return mFileDatabase - > SearchBoolExp ( exp , results , flags , peer_id ) ;
2008-07-02 09:19:59 -04:00
}
/***************************************************************/
/*************** Local Shared Dir Interface ********************/
/***************************************************************/
2009-07-12 09:22:31 -04:00
2016-07-30 15:52:42 -04:00
bool ftServer : : ConvertSharedFilePath ( std : : string path , std : : string & fullpath )
2008-07-02 09:19:59 -04:00
{
2016-07-30 15:52:42 -04:00
return mFileDatabase - > convertSharedFilePath ( path , fullpath ) ;
2008-07-02 09:19:59 -04:00
}
2009-07-12 09:22:31 -04:00
2012-11-12 17:51:27 -05:00
void ftServer : : updateSinceGroupPermissionsChanged ( )
{
2016-07-30 15:52:42 -04:00
mFileDatabase - > forceSyncWithPeers ( ) ;
2012-11-12 17:51:27 -05:00
}
2008-07-02 09:19:59 -04:00
void ftServer : : ForceDirectoryCheck ( )
{
2016-07-30 15:52:42 -04:00
mFileDatabase - > forceDirectoryCheck ( ) ;
2008-07-02 09:19:59 -04:00
return ;
}
2009-07-12 09:22:31 -04:00
2008-07-02 09:19:59 -04:00
bool ftServer : : InDirectoryCheck ( )
{
2016-07-30 15:52:42 -04:00
return mFileDatabase - > inDirectoryCheck ( ) ;
2010-10-31 15:29:26 -04:00
}
2009-08-03 15:43:52 -04:00
bool ftServer : : getSharedDirectories ( std : : list < SharedDirInfo > & dirs )
2008-07-02 09:19:59 -04:00
{
2016-07-30 15:52:42 -04:00
mFileDatabase - > getSharedDirectories ( dirs ) ;
2008-08-09 13:03:24 -04:00
return true ;
}
2009-08-03 15:43:52 -04:00
bool ftServer : : setSharedDirectories ( std : : list < SharedDirInfo > & dirs )
2008-08-09 13:03:24 -04:00
{
2016-07-30 15:52:42 -04:00
mFileDatabase - > setSharedDirectories ( dirs ) ;
2008-08-09 13:03:24 -04:00
return true ;
2008-07-02 09:19:59 -04:00
}
2010-09-17 15:21:14 -04:00
bool ftServer : : addSharedDirectory ( const SharedDirInfo & dir )
2008-07-02 09:19:59 -04:00
{
2011-05-15 08:42:55 -04:00
SharedDirInfo _dir = dir ;
_dir . filename = RsDirUtil : : convertPathToUnix ( _dir . filename ) ;
2009-08-03 15:43:52 -04:00
std : : list < SharedDirInfo > dirList ;
2016-07-30 15:52:42 -04:00
mFileDatabase - > getSharedDirectories ( dirList ) ;
2009-08-03 15:43:52 -04:00
// check that the directory is not already in the list.
for ( std : : list < SharedDirInfo > : : const_iterator it ( dirList . begin ( ) ) ; it ! = dirList . end ( ) ; + + it )
2011-05-15 08:42:55 -04:00
if ( ( * it ) . filename = = _dir . filename )
2009-08-03 15:43:52 -04:00
return false ;
2009-08-10 15:01:27 -04:00
2009-08-03 15:43:52 -04:00
// ok then, add the shared directory.
2011-05-15 08:42:55 -04:00
dirList . push_back ( _dir ) ;
2008-08-09 13:03:24 -04:00
2016-07-30 15:52:42 -04:00
mFileDatabase - > setSharedDirectories ( dirList ) ;
2008-08-09 13:03:24 -04:00
return true ;
2008-07-02 09:19:59 -04:00
}
2009-08-03 15:43:52 -04:00
bool ftServer : : updateShareFlags ( const SharedDirInfo & info )
{
2016-07-30 15:52:42 -04:00
mFileDatabase - > updateShareFlags ( info ) ;
2009-08-03 15:43:52 -04:00
return true ;
}
2008-07-02 09:19:59 -04:00
bool ftServer : : removeSharedDirectory ( std : : string dir )
{
2011-05-15 08:42:55 -04:00
dir = RsDirUtil : : convertPathToUnix ( dir ) ;
2009-08-03 15:43:52 -04:00
std : : list < SharedDirInfo > dirList ;
std : : list < SharedDirInfo > : : iterator it ;
2008-08-09 13:03:24 -04:00
2009-07-12 09:22:31 -04:00
# ifdef SERVER_DEBUG
2008-11-15 15:00:29 -05:00
std : : cerr < < " ftServer::removeSharedDirectory( " < < dir < < " ) " ;
std : : cerr < < std : : endl ;
# endif
2016-07-30 15:52:42 -04:00
mFileDatabase - > getSharedDirectories ( dirList ) ;
2008-08-09 13:03:24 -04:00
2009-07-12 09:22:31 -04:00
# ifdef SERVER_DEBUG
2014-10-24 18:07:26 -04:00
for ( it = dirList . begin ( ) ; it ! = dirList . end ( ) ; + + it )
2008-11-15 15:00:29 -05:00
{
std : : cerr < < " ftServer::removeSharedDirectory() " ;
2009-08-03 15:43:52 -04:00
std : : cerr < < " existing: " < < ( * it ) . filename ;
2008-11-15 15:00:29 -05:00
std : : cerr < < std : : endl ;
}
# endif
2009-08-03 15:43:52 -04:00
for ( it = dirList . begin ( ) ; it ! = dirList . end ( ) & & ( * it ) . filename ! = dir ; + + it ) ;
if ( it = = dirList . end ( ) )
2008-08-09 13:03:24 -04:00
{
2016-07-30 15:52:42 -04:00
std : : cerr < < " (EE) ftServer::removeSharedDirectory(): Cannot Find Directory... Fail " < < std : : endl ;
2008-08-09 13:03:24 -04:00
return false ;
}
2008-11-15 15:00:29 -05:00
2009-07-12 09:22:31 -04:00
# ifdef SERVER_DEBUG
2008-11-15 15:00:29 -05:00
std : : cerr < < " ftServer::removeSharedDirectory() " ;
std : : cerr < < " Updating Directories " ;
std : : cerr < < std : : endl ;
# endif
2008-08-09 13:03:24 -04:00
dirList . erase ( it ) ;
2016-07-30 15:52:42 -04:00
mFileDatabase - > setSharedDirectories ( dirList ) ;
2008-08-09 13:03:24 -04:00
return true ;
2008-07-02 09:19:59 -04:00
}
2011-03-28 17:52:21 -04:00
void ftServer : : setWatchPeriod ( int minutes )
{
2016-07-30 15:52:42 -04:00
mFileDatabase - > setWatchPeriod ( minutes * 60 ) ;
2011-03-28 17:52:21 -04:00
}
int ftServer : : watchPeriod ( ) const
{
2016-07-30 15:52:42 -04:00
return mFileDatabase - > watchPeriod ( ) / 60 ;
2011-03-28 17:52:21 -04:00
}
2010-10-31 16:35:31 -04:00
void ftServer : : setRememberHashFiles ( bool b )
{
2016-07-30 15:52:42 -04:00
mFileDatabase - > setRememberHashCache ( b ) ;
2010-10-31 16:35:31 -04:00
}
bool ftServer : : rememberHashFiles ( ) const
{
2016-07-30 15:52:42 -04:00
return mFileDatabase - > rememberHashCache ( ) ;
2010-10-31 16:35:31 -04:00
}
void ftServer : : setRememberHashFilesDuration ( uint32_t days )
{
2016-07-30 15:52:42 -04:00
mFileDatabase - > setRememberHashCacheDuration ( days ) ;
2010-10-31 16:35:31 -04:00
}
uint32_t ftServer : : rememberHashFilesDuration ( ) const
{
2016-07-30 15:52:42 -04:00
return mFileDatabase - > rememberHashCacheDuration ( ) ;
2010-10-31 16:35:31 -04:00
}
void ftServer : : clearHashCache ( )
{
2016-07-30 15:52:42 -04:00
mFileDatabase - > clearHashCache ( ) ;
2010-10-31 16:35:31 -04:00
}
2008-07-02 09:19:59 -04:00
2009-07-12 09:22:31 -04:00
bool ftServer : : getShareDownloadDirectory ( )
{
2011-03-08 15:05:36 -05:00
std : : list < SharedDirInfo > dirList ;
2016-07-30 15:52:42 -04:00
mFileDatabase - > getSharedDirectories ( dirList ) ;
2009-07-12 09:22:31 -04:00
2011-03-08 15:05:36 -05:00
std : : string dir = mFtController - > getDownloadDirectory ( ) ;
// check if the download directory is in the list.
for ( std : : list < SharedDirInfo > : : const_iterator it ( dirList . begin ( ) ) ; it ! = dirList . end ( ) ; + + it )
if ( ( * it ) . filename = = dir )
return true ;
2009-08-03 15:43:52 -04:00
2011-03-08 15:05:36 -05:00
return false ;
2009-07-12 09:22:31 -04:00
}
2011-03-08 15:05:36 -05:00
bool ftServer : : shareDownloadDirectory ( bool share )
2009-07-12 09:22:31 -04:00
{
2016-07-30 15:52:42 -04:00
if ( share )
{
2011-03-08 15:05:36 -05:00
/* Share */
SharedDirInfo inf ;
inf . filename = mFtController - > getDownloadDirectory ( ) ;
2012-11-01 06:06:12 -04:00
inf . shareflags = DIR_FLAGS_NETWORK_WIDE_OTHERS ;
2011-03-08 15:05:36 -05:00
return addSharedDirectory ( inf ) ;
}
2016-07-30 15:52:42 -04:00
else
{
/* Unshare */
std : : string dir = mFtController - > getDownloadDirectory ( ) ;
return removeSharedDirectory ( dir ) ;
}
2009-07-12 09:22:31 -04:00
}
2008-07-02 09:19:59 -04:00
/***************************************************************/
/****************** End of RsFiles Interface *******************/
/***************************************************************/
2016-07-30 15:52:42 -04:00
//bool ftServer::loadConfigMap(std::map<std::string, std::string> &/*configMap*/)
//{
// return true;
//}
2008-08-03 08:45:53 -04:00
/***************************************************************/
/********************** Data Flow **********************/
/***************************************************************/
/* Client Send */
2014-03-17 16:56:06 -04:00
bool ftServer : : sendDataRequest ( const RsPeerId & peerId , const RsFileHash & hash , uint64_t size , uint64_t offset , uint32_t chunksize )
2008-08-03 08:45:53 -04:00
{
2013-10-02 15:56:01 -04:00
# ifdef SERVER_DEBUG
std : : cerr < < " ftServer::sendDataRequest() to peer " < < peerId < < " for hash " < < hash < < " , offset= " < < offset < < " , chunk size= " < < chunksize < < std : : endl ;
# endif
2009-05-26 17:42:45 -04:00
if ( mTurtleRouter - > isTurtlePeer ( peerId ) )
2013-04-06 05:21:01 -04:00
{
RsTurtleFileRequestItem * item = new RsTurtleFileRequestItem ;
item - > chunk_offset = offset ;
item - > chunk_size = chunksize ;
mTurtleRouter - > sendTurtleData ( peerId , item ) ;
}
2009-05-26 17:42:45 -04:00
else
2014-10-30 15:54:21 -04:00
{
2009-05-26 17:42:45 -04:00
/* create a packet */
/* push to networking part */
2013-10-01 04:11:15 -04:00
RsFileTransferDataRequestItem * rfi = new RsFileTransferDataRequestItem ( ) ;
2008-08-03 08:45:53 -04:00
2009-05-26 17:42:45 -04:00
/* id */
rfi - > PeerId ( peerId ) ;
2008-08-03 08:45:53 -04:00
2009-05-26 17:42:45 -04:00
/* file info */
rfi - > file . filesize = size ;
rfi - > file . hash = hash ; /* ftr->hash; */
2008-08-03 08:45:53 -04:00
2009-05-26 17:42:45 -04:00
/* offsets */
rfi - > fileoffset = offset ; /* ftr->offset; */
rfi - > chunksize = chunksize ; /* ftr->chunk; */
2008-08-03 08:45:53 -04:00
2013-10-01 04:11:15 -04:00
sendItem ( rfi ) ;
2009-05-26 17:42:45 -04:00
}
2008-08-09 13:03:24 -04:00
return true ;
2008-08-03 08:45:53 -04:00
}
2014-03-17 16:56:06 -04:00
bool ftServer : : sendChunkMapRequest ( const RsPeerId & peerId , const RsFileHash & hash , bool is_client )
2010-01-11 11:00:42 -05:00
{
2013-10-02 15:56:01 -04:00
# ifdef SERVER_DEBUG
std : : cerr < < " ftServer::sendChunkMapRequest() to peer " < < peerId < < " for hash " < < hash < < std : : endl ;
# endif
2010-01-11 11:00:42 -05:00
if ( mTurtleRouter - > isTurtlePeer ( peerId ) )
2013-04-06 05:21:01 -04:00
{
RsTurtleFileMapRequestItem * item = new RsTurtleFileMapRequestItem ;
mTurtleRouter - > sendTurtleData ( peerId , item ) ;
}
2010-07-21 19:14:10 -04:00
else
2010-07-25 15:04:31 -04:00
{
/* create a packet */
/* push to networking part */
2013-10-01 04:11:15 -04:00
RsFileTransferChunkMapRequestItem * rfi = new RsFileTransferChunkMapRequestItem ( ) ;
2010-07-25 15:04:31 -04:00
/* id */
rfi - > PeerId ( peerId ) ;
/* file info */
rfi - > hash = hash ; /* ftr->hash; */
rfi - > is_client = is_client ;
2013-10-01 04:11:15 -04:00
sendItem ( rfi ) ;
2010-07-25 15:04:31 -04:00
}
2010-01-11 11:00:42 -05:00
return true ;
}
2014-03-17 16:56:06 -04:00
bool ftServer : : sendChunkMap ( const RsPeerId & peerId , const RsFileHash & hash , const CompressedChunkMap & map , bool is_client )
2010-01-11 11:00:42 -05:00
{
2013-10-02 15:56:01 -04:00
# ifdef SERVER_DEBUG
std : : cerr < < " ftServer::sendChunkMap() to peer " < < peerId < < " for hash " < < hash < < std : : endl ;
# endif
2010-01-11 11:00:42 -05:00
if ( mTurtleRouter - > isTurtlePeer ( peerId ) )
2013-04-06 05:21:01 -04:00
{
RsTurtleFileMapItem * item = new RsTurtleFileMapItem ;
item - > compressed_map = map ;
mTurtleRouter - > sendTurtleData ( peerId , item ) ;
}
2010-07-21 19:14:10 -04:00
else
2010-07-25 15:04:31 -04:00
{
/* create a packet */
/* push to networking part */
2013-10-01 04:11:15 -04:00
RsFileTransferChunkMapItem * rfi = new RsFileTransferChunkMapItem ( ) ;
2010-07-25 15:04:31 -04:00
/* id */
rfi - > PeerId ( peerId ) ;
/* file info */
rfi - > hash = hash ; /* ftr->hash; */
rfi - > is_client = is_client ; /* ftr->hash; */
rfi - > compressed_map = map ; /* ftr->hash; */
2013-10-01 04:11:15 -04:00
sendItem ( rfi ) ;
2010-07-25 15:04:31 -04:00
}
2010-01-11 11:00:42 -05:00
return true ;
}
2013-04-06 05:21:01 -04:00
2014-03-17 16:56:06 -04:00
bool ftServer : : sendSingleChunkCRCRequest ( const RsPeerId & peerId , const RsFileHash & hash , uint32_t chunk_number )
2012-03-15 15:55:43 -04:00
{
2013-10-02 15:56:01 -04:00
# ifdef SERVER_DEBUG
std : : cerr < < " ftServer::sendSingleCRCRequest() to peer " < < peerId < < " for hash " < < hash < < " , chunk number= " < < chunk_number < < std : : endl ;
# endif
2012-03-15 15:55:43 -04:00
if ( mTurtleRouter - > isTurtlePeer ( peerId ) )
2013-04-06 05:21:01 -04:00
{
RsTurtleChunkCrcRequestItem * item = new RsTurtleChunkCrcRequestItem ;
item - > chunk_number = chunk_number ;
mTurtleRouter - > sendTurtleData ( peerId , item ) ;
}
2012-03-15 15:55:43 -04:00
else
{
/* create a packet */
/* push to networking part */
2013-10-01 04:11:15 -04:00
RsFileTransferSingleChunkCrcRequestItem * rfi = new RsFileTransferSingleChunkCrcRequestItem ( ) ;
2012-03-15 15:55:43 -04:00
/* id */
rfi - > PeerId ( peerId ) ;
/* file info */
rfi - > hash = hash ; /* ftr->hash; */
rfi - > chunk_number = chunk_number ;
2013-10-01 04:11:15 -04:00
sendItem ( rfi ) ;
2012-03-15 15:55:43 -04:00
}
2010-07-21 19:14:10 -04:00
return true ;
}
2014-03-17 16:56:06 -04:00
bool ftServer : : sendSingleChunkCRC ( const RsPeerId & peerId , const RsFileHash & hash , uint32_t chunk_number , const Sha1CheckSum & crc )
2012-03-15 15:55:43 -04:00
{
2013-10-02 15:56:01 -04:00
# ifdef SERVER_DEBUG
std : : cerr < < " ftServer::sendSingleCRC() to peer " < < peerId < < " for hash " < < hash < < " , chunk number= " < < chunk_number < < std : : endl ;
# endif
2012-03-15 15:55:43 -04:00
if ( mTurtleRouter - > isTurtlePeer ( peerId ) )
2013-04-06 05:21:01 -04:00
{
RsTurtleChunkCrcItem * item = new RsTurtleChunkCrcItem ;
item - > chunk_number = chunk_number ;
item - > check_sum = crc ;
mTurtleRouter - > sendTurtleData ( peerId , item ) ;
}
2012-03-15 15:55:43 -04:00
else
{
/* create a packet */
/* push to networking part */
2013-10-01 04:11:15 -04:00
RsFileTransferSingleChunkCrcItem * rfi = new RsFileTransferSingleChunkCrcItem ( ) ;
2012-03-15 15:55:43 -04:00
/* id */
rfi - > PeerId ( peerId ) ;
/* file info */
rfi - > hash = hash ; /* ftr->hash; */
rfi - > check_sum = crc ;
rfi - > chunk_number = chunk_number ;
2013-10-01 04:11:15 -04:00
sendItem ( rfi ) ;
2012-03-15 15:55:43 -04:00
}
2010-07-21 19:14:10 -04:00
return true ;
}
2010-01-11 11:00:42 -05:00
2008-08-03 08:45:53 -04:00
/* Server Send */
2014-03-17 16:56:06 -04:00
bool ftServer : : sendData ( const RsPeerId & peerId , const RsFileHash & hash , uint64_t size , uint64_t baseoffset , uint32_t chunksize , void * data )
2008-08-03 08:45:53 -04:00
{
/* create a packet */
/* push to networking part */
uint32_t tosend = chunksize ;
uint64_t offset = 0 ;
uint32_t chunk ;
2009-07-12 09:22:31 -04:00
# ifdef SERVER_DEBUG
2008-10-29 16:58:23 -04:00
std : : cerr < < " ftServer::sendData() to " < < peerId < < std : : endl ;
std : : cerr < < " hash: " < < hash ;
2008-11-02 06:38:11 -05:00
std : : cerr < < " offset: " < < baseoffset ;
std : : cerr < < " chunk: " < < chunksize ;
2008-10-29 16:58:23 -04:00
std : : cerr < < " data: " < < data ;
std : : cerr < < std : : endl ;
# endif
2008-08-03 08:45:53 -04:00
while ( tosend > 0 )
{
2013-10-01 04:11:15 -04:00
//static const uint32_t MAX_FT_CHUNK = 32 * 1024; /* 32K */
//static const uint32_t MAX_FT_CHUNK = 16 * 1024; /* 16K */
//
static const uint32_t MAX_FT_CHUNK = 8 * 1024 ; /* 16K */
2008-08-03 08:45:53 -04:00
/* workout size */
chunk = MAX_FT_CHUNK ;
if ( chunk > tosend )
{
chunk = tosend ;
}
2008-07-02 09:19:59 -04:00
2008-08-03 08:45:53 -04:00
/******** New Serialiser Type *******/
2008-07-02 09:19:59 -04:00
2009-05-26 17:42:45 -04:00
if ( mTurtleRouter - > isTurtlePeer ( peerId ) )
2013-04-06 05:21:01 -04:00
{
RsTurtleFileDataItem * item = new RsTurtleFileDataItem ;
2013-04-06 09:16:54 -04:00
item - > chunk_offset = offset + baseoffset ;
item - > chunk_size = chunk ;
2016-01-12 21:43:04 -05:00
item - > chunk_data = rs_malloc ( chunk ) ;
2013-04-06 05:21:01 -04:00
if ( item - > chunk_data = = NULL )
{
delete item ;
return false ;
}
2013-04-06 09:16:54 -04:00
memcpy ( item - > chunk_data , & ( ( ( uint8_t * ) data ) [ offset ] ) , chunk ) ;
2013-04-06 05:21:01 -04:00
mTurtleRouter - > sendTurtleData ( peerId , item ) ;
}
2009-05-26 17:42:45 -04:00
else
{
2013-10-01 04:11:15 -04:00
RsFileTransferDataItem * rfd = new RsFileTransferDataItem ( ) ;
2008-08-03 08:45:53 -04:00
2009-05-26 17:42:45 -04:00
/* set id */
rfd - > PeerId ( peerId ) ;
2008-08-03 08:45:53 -04:00
2009-05-26 17:42:45 -04:00
/* file info */
rfd - > fd . file . filesize = size ;
rfd - > fd . file . hash = hash ;
rfd - > fd . file . name = " " ; /* blank other data */
rfd - > fd . file . path = " " ;
rfd - > fd . file . pop = 0 ;
rfd - > fd . file . age = 0 ;
2008-08-03 08:45:53 -04:00
2009-05-26 17:42:45 -04:00
rfd - > fd . file_offset = baseoffset + offset ;
2008-08-03 08:45:53 -04:00
2009-05-26 17:42:45 -04:00
/* file data */
rfd - > fd . binData . setBinData ( & ( ( ( uint8_t * ) data ) [ offset ] ) , chunk ) ;
2008-08-03 08:45:53 -04:00
2013-10-01 04:11:15 -04:00
sendItem ( rfd ) ;
2009-05-26 17:42:45 -04:00
/* print the data pointer */
2009-07-12 09:22:31 -04:00
# ifdef SERVER_DEBUG
2009-05-26 17:42:45 -04:00
std : : cerr < < " ftServer::sendData() Packet: " < < std : : endl ;
std : : cerr < < " offset: " < < rfd - > fd . file_offset ;
std : : cerr < < " chunk: " < < chunk ;
std : : cerr < < " len: " < < rfd - > fd . binData . bin_len ;
std : : cerr < < " data: " < < rfd - > fd . binData . bin_data ;
std : : cerr < < std : : endl ;
2008-10-29 16:58:23 -04:00
# endif
2009-05-26 17:42:45 -04:00
}
2008-08-03 08:45:53 -04:00
offset + = chunk ;
tosend - = chunk ;
}
/* clean up data */
free ( data ) ;
2008-08-09 13:03:24 -04:00
return true ;
2008-08-03 08:45:53 -04:00
}
2013-10-01 04:11:15 -04:00
// Dont delete the item. The client (p3turtle) is doing it after calling this.
//
2013-04-06 05:21:01 -04:00
void ftServer : : receiveTurtleData ( RsTurtleGenericTunnelItem * i ,
2014-03-17 16:56:06 -04:00
const RsFileHash & hash ,
const RsPeerId & virtual_peer_id ,
2013-04-06 05:21:01 -04:00
RsTurtleGenericTunnelItem : : Direction direction )
{
switch ( i - > PacketSubType ( ) )
{
case RS_TURTLE_SUBTYPE_FILE_REQUEST :
{
RsTurtleFileRequestItem * item = dynamic_cast < RsTurtleFileRequestItem * > ( i ) ;
2015-07-11 21:16:16 -04:00
if ( item )
{
2013-10-02 15:56:01 -04:00
# ifdef SERVER_DEBUG
2015-07-11 21:16:16 -04:00
std : : cerr < < " ftServer::receiveTurtleData(): received file data request for " < < hash < < " from peer " < < virtual_peer_id < < std : : endl ;
2013-10-02 15:56:01 -04:00
# endif
2015-07-11 21:16:16 -04:00
getMultiplexer ( ) - > recvDataRequest ( virtual_peer_id , hash , 0 , item - > chunk_offset , item - > chunk_size ) ;
}
2013-04-06 05:21:01 -04:00
}
break ;
case RS_TURTLE_SUBTYPE_FILE_DATA :
{
RsTurtleFileDataItem * item = dynamic_cast < RsTurtleFileDataItem * > ( i ) ;
2015-07-11 21:16:16 -04:00
if ( item )
{
2013-10-02 15:56:01 -04:00
# ifdef SERVER_DEBUG
2015-07-11 21:16:16 -04:00
std : : cerr < < " ftServer::receiveTurtleData(): received file data for " < < hash < < " from peer " < < virtual_peer_id < < std : : endl ;
2013-10-02 15:56:01 -04:00
# endif
2015-07-11 21:16:16 -04:00
getMultiplexer ( ) - > recvData ( virtual_peer_id , hash , 0 , item - > chunk_offset , item - > chunk_size , item - > chunk_data ) ;
2013-04-06 05:21:01 -04:00
2015-07-11 21:16:16 -04:00
item - > chunk_data = NULL ; // this prevents deletion in the destructor of RsFileDataItem, because data will be deleted
// down _ft_server->getMultiplexer()->recvData()...in ftTransferModule::recvFileData
}
2013-04-06 05:21:01 -04:00
}
break ;
case RS_TURTLE_SUBTYPE_FILE_MAP :
{
RsTurtleFileMapItem * item = dynamic_cast < RsTurtleFileMapItem * > ( i ) ;
2015-07-11 21:16:16 -04:00
if ( item )
{
2013-10-02 15:56:01 -04:00
# ifdef SERVER_DEBUG
2015-07-11 21:16:16 -04:00
std : : cerr < < " ftServer::receiveTurtleData(): received chunk map for hash " < < hash < < " from peer " < < virtual_peer_id < < std : : endl ;
2013-10-02 15:56:01 -04:00
# endif
2015-07-11 21:16:16 -04:00
getMultiplexer ( ) - > recvChunkMap ( virtual_peer_id , hash , item - > compressed_map , direction = = RsTurtleGenericTunnelItem : : DIRECTION_CLIENT ) ;
}
2013-04-06 05:21:01 -04:00
}
break ;
case RS_TURTLE_SUBTYPE_FILE_MAP_REQUEST :
{
2013-10-01 04:11:15 -04:00
//RsTurtleFileMapRequestItem *item = dynamic_cast<RsTurtleFileMapRequestItem *>(i) ;
2013-10-02 15:56:01 -04:00
# ifdef SERVER_DEBUG
std : : cerr < < " ftServer::receiveTurtleData(): received chunkmap request for hash " < < hash < < " from peer " < < virtual_peer_id < < std : : endl ;
# endif
2013-04-06 05:21:01 -04:00
getMultiplexer ( ) - > recvChunkMapRequest ( virtual_peer_id , hash , direction = = RsTurtleGenericTunnelItem : : DIRECTION_CLIENT ) ;
}
break ;
case RS_TURTLE_SUBTYPE_CHUNK_CRC :
{
RsTurtleChunkCrcItem * item = dynamic_cast < RsTurtleChunkCrcItem * > ( i ) ;
2015-07-11 21:16:16 -04:00
if ( item )
{
2013-10-02 15:56:01 -04:00
# ifdef SERVER_DEBUG
2015-07-11 21:16:16 -04:00
std : : cerr < < " ftServer::receiveTurtleData(): received single chunk CRC for hash " < < hash < < " from peer " < < virtual_peer_id < < std : : endl ;
2013-10-02 15:56:01 -04:00
# endif
2015-07-11 21:16:16 -04:00
getMultiplexer ( ) - > recvSingleChunkCRC ( virtual_peer_id , hash , item - > chunk_number , item - > check_sum ) ;
}
2013-04-06 05:21:01 -04:00
}
break ;
case RS_TURTLE_SUBTYPE_CHUNK_CRC_REQUEST :
{
RsTurtleChunkCrcRequestItem * item = dynamic_cast < RsTurtleChunkCrcRequestItem * > ( i ) ;
2015-07-11 21:16:16 -04:00
if ( item )
{
2013-10-02 15:56:01 -04:00
# ifdef SERVER_DEBUG
2015-07-11 21:16:16 -04:00
std : : cerr < < " ftServer::receiveTurtleData(): received single chunk CRC request for hash " < < hash < < " from peer " < < virtual_peer_id < < std : : endl ;
2013-10-02 15:56:01 -04:00
# endif
2015-07-11 21:16:16 -04:00
getMultiplexer ( ) - > recvSingleChunkCRCRequest ( virtual_peer_id , hash , item - > chunk_number ) ;
}
2013-04-06 05:21:01 -04:00
}
break ;
default :
std : : cerr < < " WARNING: Unknown packet type received: sub_id= " < < reinterpret_cast < void * > ( i - > PacketSubType ( ) ) < < " . Is somebody trying to poison you ? " < < std : : endl ;
}
}
2008-11-02 06:38:11 -05:00
/* NB: The rsCore lock must be activated before calling this.
* This Lock should be moved lower into the system . . .
* most likely destination is in ftServer .
*/
2008-08-03 08:45:53 -04:00
int ftServer : : tick ( )
{
2013-10-01 04:11:15 -04:00
bool moreToTick = false ;
2008-08-03 08:45:53 -04:00
2013-10-02 15:56:01 -04:00
if ( handleIncoming ( ) )
moreToTick = true ;
2008-08-17 11:23:11 -04:00
2013-10-01 04:11:15 -04:00
static time_t last_law_priority_tasks_handling_time = 0 ;
time_t now = time ( NULL ) ;
2008-08-03 08:45:53 -04:00
2013-10-01 04:11:15 -04:00
if ( last_law_priority_tasks_handling_time + FILE_TRANSFER_LOW_PRIORITY_TASKS_PERIOD < now )
2008-08-03 08:45:53 -04:00
{
2013-10-01 04:11:15 -04:00
last_law_priority_tasks_handling_time = now ;
2008-08-03 08:45:53 -04:00
2013-10-01 04:11:15 -04:00
mFtDataplex - > deleteUnusedServers ( ) ;
mFtDataplex - > handlePendingCrcRequests ( ) ;
mFtDataplex - > dispatchReceivedChunkCheckSum ( ) ;
2008-08-03 08:45:53 -04:00
}
2008-08-09 13:03:24 -04:00
2008-12-07 09:53:57 -05:00
return moreToTick ;
2008-08-03 08:45:53 -04:00
}
2013-10-01 04:11:15 -04:00
int ftServer : : handleIncoming ( )
2008-08-03 08:45:53 -04:00
{
// now File Input.
2013-10-01 04:11:15 -04:00
int nhandled = 0 ;
2008-08-03 08:45:53 -04:00
2013-10-01 04:11:15 -04:00
RsItem * item = NULL ;
2009-07-12 09:22:31 -04:00
# ifdef SERVER_DEBUG
2013-10-02 15:56:01 -04:00
std : : cerr < < " ftServer::handleIncoming() " < < std : : endl ;
2008-08-03 08:45:53 -04:00
# endif
2013-10-01 04:11:15 -04:00
while ( NULL ! = ( item = recvItem ( ) ) )
2008-08-03 08:45:53 -04:00
{
2013-10-01 04:11:15 -04:00
nhandled + + ;
2008-10-29 16:58:23 -04:00
2013-10-01 04:11:15 -04:00
switch ( item - > PacketSubType ( ) )
2008-08-03 08:45:53 -04:00
{
2013-10-01 04:11:15 -04:00
case RS_PKT_SUBTYPE_FT_DATA_REQUEST :
{
RsFileTransferDataRequestItem * f = dynamic_cast < RsFileTransferDataRequestItem * > ( item ) ;
2015-07-11 21:08:33 -04:00
if ( f )
{
2010-07-25 15:04:31 -04:00
# ifdef SERVER_DEBUG
2015-07-11 21:08:33 -04:00
std : : cerr < < " ftServer::handleIncoming: received data request for hash " < < f - > file . hash < < " , offset= " < < f - > fileoffset < < " , chunk size= " < < f - > chunksize < < std : : endl ;
2010-07-25 15:04:31 -04:00
# endif
2015-07-11 21:08:33 -04:00
mFtDataplex - > recvDataRequest ( f - > PeerId ( ) , f - > file . hash , f - > file . filesize , f - > fileoffset , f - > chunksize ) ;
}
2013-10-01 04:11:15 -04:00
}
break ;
2010-07-25 15:04:31 -04:00
2013-10-01 04:11:15 -04:00
case RS_PKT_SUBTYPE_FT_DATA :
{
RsFileTransferDataItem * f = dynamic_cast < RsFileTransferDataItem * > ( item ) ;
2015-07-11 21:08:33 -04:00
if ( f )
{
2010-07-25 15:04:31 -04:00
# ifdef SERVER_DEBUG
2015-07-11 21:08:33 -04:00
std : : cerr < < " ftServer::handleIncoming: received data for hash " < < f - > fd . file . hash < < " , offset= " < < f - > fd . file_offset < < " , chunk size= " < < f - > fd . binData . bin_len < < std : : endl ;
2010-07-25 15:04:31 -04:00
# endif
2015-07-11 21:08:33 -04:00
mFtDataplex - > recvData ( f - > PeerId ( ) , f - > fd . file . hash , f - > fd . file . filesize , f - > fd . file_offset , f - > fd . binData . bin_len , f - > fd . binData . bin_data ) ;
2008-08-03 08:45:53 -04:00
2015-07-11 21:08:33 -04:00
/* we've stolen the data part -> so blank before delete
*/
f - > fd . binData . TlvShallowClear ( ) ;
}
2013-10-01 04:11:15 -04:00
}
break ;
2010-07-25 15:04:31 -04:00
2013-10-01 04:11:15 -04:00
case RS_PKT_SUBTYPE_FT_CHUNK_MAP_REQUEST :
{
RsFileTransferChunkMapRequestItem * f = dynamic_cast < RsFileTransferChunkMapRequestItem * > ( item ) ;
2015-07-11 21:08:33 -04:00
if ( f )
{
2010-07-29 17:07:07 -04:00
# ifdef SERVER_DEBUG
2015-07-11 21:08:33 -04:00
std : : cerr < < " ftServer::handleIncoming: received chunkmap request for hash " < < f - > hash < < " , client= " < < f - > is_client < < std : : endl ;
2010-07-29 17:07:07 -04:00
# endif
2015-07-11 21:08:33 -04:00
mFtDataplex - > recvChunkMapRequest ( f - > PeerId ( ) , f - > hash , f - > is_client ) ;
}
2013-10-01 04:11:15 -04:00
}
break ;
2010-07-29 17:07:07 -04:00
2013-10-01 04:11:15 -04:00
case RS_PKT_SUBTYPE_FT_CHUNK_MAP :
{
RsFileTransferChunkMapItem * f = dynamic_cast < RsFileTransferChunkMapItem * > ( item ) ;
2015-07-11 21:08:33 -04:00
if ( f )
{
2010-07-29 17:07:07 -04:00
# ifdef SERVER_DEBUG
2015-07-11 21:08:33 -04:00
std : : cerr < < " ftServer::handleIncoming: received chunkmap for hash " < < f - > hash < < " , client= " < < f - > is_client < < /*", map=" << f->compressed_map <<*/ std : : endl ;
2010-07-29 17:07:07 -04:00
# endif
2015-07-11 21:08:33 -04:00
mFtDataplex - > recvChunkMap ( f - > PeerId ( ) , f - > hash , f - > compressed_map , f - > is_client ) ;
}
2013-10-01 04:11:15 -04:00
}
break ;
2010-07-29 17:07:07 -04:00
2013-10-01 04:11:15 -04:00
case RS_PKT_SUBTYPE_FT_CHUNK_CRC_REQUEST :
{
RsFileTransferSingleChunkCrcRequestItem * f = dynamic_cast < RsFileTransferSingleChunkCrcRequestItem * > ( item ) ;
2015-07-11 21:08:33 -04:00
if ( f )
{
2012-03-15 15:55:43 -04:00
# ifdef SERVER_DEBUG
2015-07-11 21:08:33 -04:00
std : : cerr < < " ftServer::handleIncoming: received single chunk crc req for hash " < < f - > hash < < " , chunk number= " < < f - > chunk_number < < std : : endl ;
2012-03-15 15:55:43 -04:00
# endif
2015-07-11 21:08:33 -04:00
mFtDataplex - > recvSingleChunkCRCRequest ( f - > PeerId ( ) , f - > hash , f - > chunk_number ) ;
}
2013-10-01 04:11:15 -04:00
}
break ;
2012-03-15 15:55:43 -04:00
2013-10-01 04:11:15 -04:00
case RS_PKT_SUBTYPE_FT_CHUNK_CRC :
{
RsFileTransferSingleChunkCrcItem * f = dynamic_cast < RsFileTransferSingleChunkCrcItem * > ( item ) ;
2015-07-11 21:08:33 -04:00
if ( f )
{
2012-03-15 15:55:43 -04:00
# ifdef SERVER_DEBUG
2015-07-11 21:08:33 -04:00
std : : cerr < < " ftServer::handleIncoming: received single chunk crc req for hash " < < f - > hash < < " , chunk number= " < < f - > chunk_number < < " , checksum = " < < f - > check_sum < < std : : endl ;
2012-03-15 15:55:43 -04:00
# endif
2015-07-11 21:08:33 -04:00
mFtDataplex - > recvSingleChunkCRC ( f - > PeerId ( ) , f - > hash , f - > chunk_number , f - > check_sum ) ;
}
2013-10-01 04:11:15 -04:00
}
break ;
}
2012-03-15 15:55:43 -04:00
2013-10-01 04:11:15 -04:00
delete item ;
2008-08-03 08:45:53 -04:00
}
2013-10-01 04:11:15 -04:00
return nhandled ;
2008-08-03 08:45:53 -04:00
}
/**********************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2008-11-15 15:00:29 -05:00
/***************************** CONFIG ****************************/
bool ftServer : : addConfiguration ( p3ConfigMgr * cfgmgr )
{
/* add all the subbits to config mgr */
2016-07-30 15:52:42 -04:00
cfgmgr - > addConfiguration ( " ft_database.cfg " , mFileDatabase ) ;
2008-11-15 15:00:29 -05:00
cfgmgr - > addConfiguration ( " ft_extra.cfg " , mFtExtra ) ;
cfgmgr - > addConfiguration ( " ft_transfers.cfg " , mFtController ) ;
2009-07-12 09:22:31 -04:00
2008-11-15 15:00:29 -05:00
return true ;
}