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"
2016-10-19 15:30:37 -04:00
# include "util/rsprint.h"
# include "crypto/chacha20.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"
2017-07-15 08:28:29 -04:00
//const int ftserverzone = 29539;
2008-08-03 08:45:53 -04:00
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
2017-04-18 15:11:37 -04:00
# include "rsitems/rsfiletransferitems.h"
# include "rsitems/rsserviceids.h"
2008-08-09 13:03:24 -04:00
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
* * */
2016-10-30 06:36:00 -04:00
# define FTSERVER_DEBUG() std::cerr << time(NULL) << " : FILE_SERVER : " << __FUNCTION__ << " : "
# define FTSERVER_ERROR() std::cerr << "(EE) FILE_SERVER ERROR : "
2017-05-08 16:00:51 -04:00
static const time_t FILE_TRANSFER_LOW_PRIORITY_TASKS_PERIOD = 5 ; // low priority tasks handling every 5 seconds
static const time_t FILE_TRANSFER_MAX_DELAY_BEFORE_DROP_USAGE_RECORD = 10 ; // keep usage records for 10 secs at most.
2013-10-01 04:11:15 -04:00
2016-11-03 03:50:13 -04:00
/* Setup */
2014-03-28 23:57:44 -04:00
ftServer : : ftServer ( p3PeerMgr * pm , p3ServiceControl * sc )
2017-04-24 08:14:34 -04:00
: p3Service ( ) , RsServiceSerializer ( RS_SERVICE_TYPE_TURTLE ) , // should be FT, but this is for backward compatibility
2016-11-03 03:50:13 -04:00
mPeerMgr ( pm ) , mServiceCtrl ( sc ) ,
mFileDatabase ( NULL ) ,
mFtController ( NULL ) , mFtExtra ( NULL ) ,
mFtDataplex ( NULL ) , mFtSearch ( NULL ) , srvMutex ( " ftServer " )
2008-07-02 09:19:59 -04:00
{
2016-11-03 03:50:13 -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 ( )
{
2016-11-03 03:50:13 -04:00
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 ) ;
2014-03-21 23:53:44 -04:00
}
2008-08-03 08:45:53 -04:00
void ftServer : : setConfigDirectory ( std : : string path )
{
2016-11-03 03:50:13 -04:00
mConfigPath = path ;
2008-08-17 11:23:11 -04:00
2016-11-03 03:50:13 -04:00
/* Must update the sub classes ... if they exist
* TODO .
*/
2008-08-17 11:23:11 -04:00
2016-11-03 03:50:13 -04:00
std : : string basecachedir = mConfigPath + " /cache " ;
std : : string localcachedir = mConfigPath + " /cache/local " ;
std : : string remotecachedir = mConfigPath + " /cache/remote " ;
2008-08-17 11:23:11 -04:00
2016-11-03 03:50:13 -04:00
RsDirUtil : : checkCreateDirectory ( basecachedir ) ;
RsDirUtil : : checkCreateDirectory ( localcachedir ) ;
RsDirUtil : : checkCreateDirectory ( remotecachedir ) ;
2008-08-03 08:45:53 -04:00
}
2016-11-03 03:50:13 -04:00
/* Control Interface */
2008-08-03 08:45:53 -04:00
2016-11-03 03:50:13 -04:00
/* 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
{
2016-11-03 03:50:13 -04:00
/* NOT SURE ABOUT THIS ONE */
2008-08-03 08:45:53 -04:00
}
2014-03-17 16:56:06 -04:00
const RsPeerId & ftServer : : OwnId ( )
2008-10-29 16:58:23 -04:00
{
2016-11-03 03:50:13 -04:00
static RsPeerId null_id ;
2014-03-17 16:56:06 -04:00
2016-11-03 03:50:13 -04:00
if ( mServiceCtrl )
return mServiceCtrl - > getOwnId ( ) ;
else
return null_id ;
2008-10-29 16:58:23 -04:00
}
2016-11-03 03:50:13 -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
{
2016-11-03 03:50:13 -04:00
/* setup FiStore/Monitor */
std : : string localcachedir = mConfigPath + " /cache/local " ;
std : : string remotecachedir = mConfigPath + " /cache/remote " ;
RsPeerId ownId = mServiceCtrl - > getOwnId ( ) ;
2008-07-02 09:19:59 -04:00
2016-11-03 03:50:13 -04:00
/* search/extras List */
mFtExtra = new ftExtraList ( ) ;
mFtSearch = new ftFileSearch ( ) ;
2008-08-17 11:23:11 -04:00
2016-11-03 03:50:13 -04:00
/* Transport */
mFtDataplex = new ftDataMultiplex ( ownId , this , mFtSearch ) ;
2008-08-17 11:23:11 -04:00
2016-11-03 03:50:13 -04:00
/* make Controller */
mFtController = new ftController ( mFtDataplex , mServiceCtrl , getServiceInfo ( ) . mServiceType ) ;
mFtController - > setFtSearchNExtra ( mFtSearch , mFtExtra ) ;
std : : string tmppath = " . " ;
mFtController - > setPartialsDirectory ( tmppath ) ;
mFtController - > setDownloadDirectory ( tmppath ) ;
2008-08-17 11:23:11 -04:00
2016-11-03 03:50:13 -04:00
/* complete search setup */
mFtSearch - > addSearchMode ( mFtExtra , RS_FILE_HINTS_EXTRA ) ;
2008-08-09 13:03:24 -04:00
2016-11-03 03:50:13 -04:00
mServiceCtrl - > registerServiceMonitor ( mFtController , getServiceInfo ( ) . mServiceType ) ;
2008-08-17 11:23:11 -04:00
2016-11-03 03:50:13 -04:00
return ;
2008-07-02 09:19:59 -04:00
}
2016-08-13 04:15:02 -04:00
void ftServer : : connectToFileDatabase ( p3FileDatabase * fdb )
{
2016-11-03 03:50:13 -04:00
mFileDatabase = fdb ;
2017-09-03 16:52:31 -04:00
mFtSearch - > addSearchMode ( fdb , RS_FILE_HINTS_LOCAL ) ; // due to a bug in addSearchModule, modules can only be added one by one. Using | between flags wont work.
mFtSearch - > addSearchMode ( fdb , RS_FILE_HINTS_REMOTE ) ;
2016-08-13 04:15:02 -04:00
}
2009-05-26 17:42:45 -04:00
void ftServer : : connectToTurtleRouter ( p3turtle * fts )
{
2016-11-03 03:50:13 -04:00
mTurtleRouter = fts ;
2009-05-26 17:42:45 -04:00
2016-11-03 03:50:13 -04:00
mFtController - > setTurtleRouter ( fts ) ;
mFtController - > setFtServer ( this ) ;
2013-04-06 05:21:01 -04:00
2016-11-03 03:50:13 -04:00
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
{
2016-11-03 03:50:13 -04:00
/* start up order - important for dependencies */
2008-07-02 09:19:59 -04:00
2016-11-03 03:50:13 -04:00
/* self contained threads */
/* startup ExtraList Thread */
mFtExtra - > start ( " ft extra lst " ) ;
2008-07-02 09:19:59 -04:00
2016-11-03 03:50:13 -04:00
/* startup Monitor Thread */
/* startup the FileMonitor (after cache load) */
/* start it up */
mFileDatabase - > startThreads ( ) ;
2008-07-02 09:19:59 -04:00
2016-11-03 03:50:13 -04:00
/* Controller thread */
mFtController - > start ( " ft ctrl " ) ;
2008-08-17 11:23:11 -04:00
2016-11-03 03:50:13 -04:00
/* Dataplex */
mFtDataplex - > start ( " ft dataplex " ) ;
2008-07-02 09:19:59 -04:00
}
2010-05-29 11:14:25 -04:00
void ftServer : : StopThreads ( )
{
2016-11-03 03:50:13 -04:00
/* stop Dataplex */
mFtDataplex - > join ( ) ;
2010-05-29 11:14:25 -04:00
2016-11-03 03:50:13 -04:00
/* stop Controller thread */
mFtController - > join ( ) ;
2010-05-29 11:14:25 -04:00
2016-11-03 03:50:13 -04:00
/* self contained threads */
/* stop ExtraList Thread */
mFtExtra - > join ( ) ;
2010-05-29 11:14:25 -04:00
2016-11-03 03:50:13 -04:00
delete ( mFtDataplex ) ;
mFtDataplex = NULL ;
2010-05-29 11:14:25 -04:00
2016-11-03 03:50:13 -04:00
delete ( mFtController ) ;
mFtController = NULL ;
2010-05-29 11:14:25 -04:00
2016-11-03 03:50:13 -04:00
delete ( mFtExtra ) ;
mFtExtra = NULL ;
2010-05-29 11:14:25 -04:00
2016-11-03 03:50:13 -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 ( )
{
2016-11-03 03:50:13 -04:00
mFtController - > activate ( ) ;
2008-07-02 09:19:59 -04:00
2016-11-03 03:50:13 -04:00
return true ;
2013-10-01 04:11:15 -04:00
}
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 )
{
2016-11-03 03:50:13 -04:00
return mFtDataplex - > getFileData ( hash , offset , requested_size , data ) ;
2015-03-08 09:46:07 -04:00
}
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-11-03 03:50:13 -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-10-30 10:33:05 -04:00
# ifdef SERVER_DEBUG
2016-11-03 03:50:13 -04:00
FTSERVER_DEBUG ( ) < < " Requesting " < < fname < < std : : endl ;
2016-10-30 10:33:05 -04:00
# endif
2010-01-16 10:42:26 -05:00
2016-11-03 03:50:13 -04:00
if ( ! mFtController - > FileRequest ( fname , hash , size , dest , flags , srcIds ) )
return false ;
2010-01-16 10:42:26 -05:00
2016-11-03 03:50:13 -04:00
return true ;
2008-07-02 09:19:59 -04:00
}
2016-11-02 15:51:42 -04:00
bool ftServer : : activateTunnels ( const RsFileHash & hash , uint32_t encryption_policy , TransferRequestFlags flags , bool onoff )
2016-10-29 11:59:03 -04:00
{
2016-11-03 03:50:13 -04:00
RsFileHash hash_of_hash ;
2016-10-29 11:59:03 -04:00
2016-11-03 03:50:13 -04:00
encryptHash ( hash , hash_of_hash ) ;
mEncryptedHashes . insert ( std : : make_pair ( hash_of_hash , hash ) ) ;
2016-10-29 11:59:03 -04:00
2016-11-03 03:50:13 -04:00
if ( onoff )
{
2016-10-30 10:33:05 -04:00
# ifdef SERVER_DEBUG
2016-11-03 03:50:13 -04:00
FTSERVER_DEBUG ( ) < < " Activating tunnels for hash " < < hash < < std : : endl ;
2016-10-30 10:33:05 -04:00
# endif
2016-11-03 03:50:13 -04:00
if ( flags & RS_FILE_REQ_ENCRYPTED )
{
2016-10-30 10:33:05 -04:00
# ifdef SERVER_DEBUG
2016-11-03 03:50:13 -04:00
FTSERVER_DEBUG ( ) < < " flags require end-to-end encryption. Requesting hash of hash " < < hash_of_hash < < std : : endl ;
2016-10-30 10:33:05 -04:00
# endif
2016-11-03 03:50:13 -04:00
mTurtleRouter - > monitorTunnels ( hash_of_hash , this , true ) ;
}
if ( ( flags & RS_FILE_REQ_UNENCRYPTED ) & & ( encryption_policy ! = RS_FILE_CTRL_ENCRYPTION_POLICY_STRICT ) )
{
2016-10-30 10:33:05 -04:00
# ifdef SERVER_DEBUG
2016-11-03 03:50:13 -04:00
FTSERVER_DEBUG ( ) < < " flags require no end-to-end encryption. Requesting hash " < < hash < < std : : endl ;
2016-10-30 10:33:05 -04:00
# endif
2016-11-03 03:50:13 -04:00
mTurtleRouter - > monitorTunnels ( hash , this , true ) ;
}
}
else
{
mTurtleRouter - > stopMonitoringTunnels ( hash_of_hash ) ;
mTurtleRouter - > stopMonitoringTunnels ( hash ) ;
}
return true ;
2016-10-29 11:59:03 -04:00
}
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
{
2016-11-03 03:50:13 -04:00
return mFtController - > setDestinationDirectory ( hash , directory ) ;
2013-02-27 11:59:16 -05:00
}
2017-06-26 17:35:01 -04:00
bool ftServer : : setDestinationName ( const RsFileHash & hash , const std : : string & name )
{
return mFtController - > setDestinationName ( hash , name ) ;
}
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
{
2016-11-03 03:50:13 -04:00
return mFtController - > setChunkStrategy ( hash , s ) ;
2009-12-08 17:29:52 -05:00
}
2017-06-26 17:35:01 -04:00
void ftServer : : setDefaultChunkStrategy ( FileChunksInfo : : ChunkStrategy s )
{
mFtController - > setDefaultChunkStrategy ( s ) ;
}
FileChunksInfo : : ChunkStrategy ftServer : : defaultChunkStrategy ( )
{
return mFtController - > defaultChunkStrategy ( ) ;
}
2010-05-21 16:49:48 -04:00
uint32_t ftServer : : freeDiskSpaceLimit ( ) const
{
2016-11-03 03:50:13 -04:00
return mFtController - > freeDiskSpaceLimit ( ) ;
2010-05-21 16:49:48 -04:00
}
void ftServer : : setFreeDiskSpaceLimit ( uint32_t s )
{
2016-11-03 03:50:13 -04:00
mFtController - > setFreeDiskSpaceLimit ( s ) ;
2010-05-21 16:49:48 -04:00
}
2017-06-26 17:35:01 -04:00
void ftServer : : setDefaultEncryptionPolicy ( uint32_t s )
2010-03-21 17:07:12 -04:00
{
2017-06-26 17:35:01 -04:00
mFtController - > setDefaultEncryptionPolicy ( s ) ;
2010-03-21 17:07:12 -04:00
}
2016-10-29 12:18:02 -04:00
uint32_t ftServer : : defaultEncryptionPolicy ( )
{
2016-11-03 03:50:13 -04:00
return mFtController - > defaultEncryptionPolicy ( ) ;
2016-10-29 12:18:02 -04:00
}
2017-05-08 16:00:51 -04:00
void ftServer : : setMaxUploadSlotsPerFriend ( uint32_t n )
{
mFtController - > setMaxUploadsPerFriend ( n ) ;
}
uint32_t ftServer : : getMaxUploadSlotsPerFriend ( )
{
return mFtController - > getMaxUploadsPerFriend ( ) ;
}
2017-06-26 17:35:01 -04:00
void ftServer : : setFilePermDirectDL ( uint32_t perm )
2016-10-29 12:18:02 -04:00
{
2017-06-26 17:35:01 -04:00
mFtController - > setFilePermDirectDL ( perm ) ;
2016-10-29 12:18:02 -04:00
}
2017-06-26 17:35:01 -04:00
uint32_t ftServer : : filePermDirectDL ( )
2010-03-21 17:07:12 -04:00
{
2017-06-26 17:35:01 -04:00
return mFtController - > filePermDirectDL ( ) ;
2010-03-21 17:07:12 -04:00
}
2017-06-26 17:35:01 -04:00
2014-03-17 16:56:06 -04:00
bool ftServer : : FileCancel ( const RsFileHash & hash )
2008-07-02 09:19:59 -04:00
{
2016-11-03 03:50:13 -04:00
// Remove from both queue and ftController, by default.
//
mFtController - > FileCancel ( hash ) ;
2010-01-26 18:25:00 -05:00
2016-11-03 03:50:13 -04:00
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
{
2016-11-03 03:50:13 -04:00
return mFtController - > FileControl ( hash , flags ) ;
2008-07-02 09:19:59 -04:00
}
2008-08-03 08:45:53 -04:00
bool ftServer : : FileClearCompleted ( )
2008-07-02 09:19:59 -04:00
{
2016-11-03 03:50:13 -04:00
return mFtController - > FileClearCompleted ( ) ;
2008-07-02 09:19:59 -04:00
}
2010-03-06 18:29:47 -05:00
void ftServer : : setQueueSize ( uint32_t s )
{
2016-11-03 03:50:13 -04:00
mFtController - > setQueueSize ( s ) ;
2010-03-06 18:29:47 -05:00
}
uint32_t ftServer : : getQueueSize ( )
{
2016-11-03 03:50:13 -04:00
return mFtController - > getQueueSize ( ) ;
2010-03-06 18:29:47 -05:00
}
2016-11-03 03:50:13 -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
{
2016-11-03 03:50:13 -04: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
{
2016-11-03 03:50:13 -04:00
mFtController - > setPriority ( hash , ( DwlSpeed ) speed ) ;
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
{
2016-11-03 03:50:13 -04:00
DwlSpeed _speed ;
int ret = mFtController - > getPriority ( hash , _speed ) ;
if ( ret )
speed = _speed ;
2009-07-26 11:00:29 -04:00
2016-11-03 03:50:13 -04:00
return ret ;
2010-01-26 18:25:00 -05:00
}
2014-03-17 16:56:06 -04:00
bool ftServer : : clearDownload ( const RsFileHash & /*hash*/ )
2009-07-26 11:00:29 -04:00
{
2016-11-03 03:50:13 -04: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
{
2016-11-03 03:50:13 -04: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 )
{
2016-11-03 03:50:13 -04:00
mFileDatabase - > requestDirUpdate ( ref ) ;
2016-09-11 11:52:12 -04:00
}
2016-11-03 03:50:13 -04:00
/* Directory Handling */
2008-07-02 09:19:59 -04:00
void ftServer : : setDownloadDirectory ( std : : string path )
{
2016-11-03 03:50:13 -04:00
mFtController - > setDownloadDirectory ( path ) ;
2008-07-02 09:19:59 -04:00
}
std : : string ftServer : : getDownloadDirectory ( )
{
2016-11-03 03:50:13 -04:00
return mFtController - > getDownloadDirectory ( ) ;
2008-07-02 09:19:59 -04:00
}
2008-08-03 08:45:53 -04:00
void ftServer : : setPartialsDirectory ( std : : string path )
2008-07-02 09:19:59 -04:00
{
2016-11-03 03:50:13 -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
{
2016-11-03 03:50:13 -04:00
return mFtController - > getPartialsDirectory ( ) ;
2008-07-02 09:19:59 -04:00
}
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 )
{
2016-11-22 17:39:09 -05:00
return RsDirUtil : : copyFile ( source , dest ) ;
2016-07-30 15:52:42 -04:00
}
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
{
2016-11-03 03:50:13 -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
{
2016-11-03 03:50:13 -04:00
return mFtDataplex - > getClientChunkMap ( hash , peer_id , cmap ) ;
2010-01-11 11:00:42 -05:00
}
2014-03-17 16:56:06 -04:00
bool ftServer : : FileUploads ( std : : list < RsFileHash > & hashs )
2008-07-02 09:19:59 -04:00
{
2016-11-03 03:50:13 -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
{
2016-11-03 03:50:13 -04:00
if ( hintflags & RS_FILE_HINTS_DOWNLOAD )
if ( mFtController - > FileDetails ( hash , info ) )
return true ;
2016-11-02 15:51:42 -04:00
2016-11-03 03:50:13 -04:00
if ( hintflags & RS_FILE_HINTS_UPLOAD )
if ( mFtDataplex - > FileDetails ( hash , hintflags , info ) )
{
// 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 ;
if ( mFtController - > FileDetails ( hash , info2 ) )
info . fname = info2 . fname ;
2011-10-01 17:10:03 -04:00
2016-11-03 03:50:13 -04:00
return true ;
}
2010-01-02 16:30:19 -05:00
2016-11-03 03:50:13 -04:00
if ( hintflags & ~ ( RS_FILE_HINTS_UPLOAD | RS_FILE_HINTS_DOWNLOAD ) )
if ( mFtSearch - > search ( hash , hintflags , info ) )
return true ;
2010-01-02 16:30:19 -05:00
2016-11-03 03:50:13 -04:00
return false ;
2008-07-02 09:19:59 -04:00
}
2017-04-16 13:59:22 -04:00
RsItem * ftServer : : create_item ( uint16_t service , uint8_t item_type ) const
2013-04-06 05:21:01 -04:00
{
# ifdef SERVER_DEBUG
2016-11-03 03:50:13 -04:00
FTSERVER_DEBUG ( ) < < " p3turtle: deserialising packet: " < < std : : endl ;
2013-04-06 05:21:01 -04:00
# endif
2017-04-15 12:46:44 -04:00
if ( RS_SERVICE_TYPE_TURTLE ! = service )
2016-11-03 03:50:13 -04:00
{
FTSERVER_ERROR ( ) < < " Wrong type !! " < < std : : endl ;
return NULL ; /* wrong type */
}
try
{
2017-04-15 12:46:44 -04:00
switch ( item_type )
2016-11-03 03:50:13 -04:00
{
2017-04-15 12:46:44 -04:00
case RS_TURTLE_SUBTYPE_FILE_REQUEST : return new RsTurtleFileRequestItem ( ) ;
case RS_TURTLE_SUBTYPE_FILE_DATA : return new RsTurtleFileDataItem ( ) ;
case RS_TURTLE_SUBTYPE_FILE_MAP_REQUEST : return new RsTurtleFileMapRequestItem ( ) ;
case RS_TURTLE_SUBTYPE_FILE_MAP : return new RsTurtleFileMapItem ( ) ;
case RS_TURTLE_SUBTYPE_CHUNK_CRC_REQUEST : return new RsTurtleChunkCrcRequestItem ( ) ;
case RS_TURTLE_SUBTYPE_CHUNK_CRC : return new RsTurtleChunkCrcItem ( ) ;
2016-11-03 03:50:13 -04:00
default :
return NULL ;
}
}
catch ( std : : exception & e )
{
FTSERVER_ERROR ( ) < < " (EE) deserialisation error in " < < __PRETTY_FUNCTION__ < < " : " < < e . what ( ) < < std : : endl ;
return NULL ;
}
2013-04-06 05:21:01 -04:00
}
2016-10-30 10:33:05 -04:00
bool ftServer : : isEncryptedSource ( const RsPeerId & virtual_peer_id )
{
2016-11-03 03:50:13 -04:00
RS_STACK_MUTEX ( srvMutex ) ;
2016-10-30 10:33:05 -04:00
2016-11-03 03:50:13 -04:00
return mEncryptedPeerIds . find ( virtual_peer_id ) ! = mEncryptedPeerIds . end ( ) ;
2016-10-30 10:33:05 -04:00
}
void ftServer : : addVirtualPeer ( const TurtleFileHash & hash , const TurtleVirtualPeerId & virtual_peer_id , RsTurtleGenericTunnelItem : : Direction dir )
2013-04-10 04:52:52 -04:00
{
2016-10-30 06:36:00 -04:00
# ifdef SERVER_DEBUG
2016-11-03 03:50:13 -04:00
FTSERVER_DEBUG ( ) < < " adding virtual peer. Direction= " < < dir < < " , hash= " < < hash < < " , vpid= " < < virtual_peer_id < < std : : endl ;
2016-10-30 06:36:00 -04:00
# endif
2016-11-03 03:50:13 -04:00
RsFileHash real_hash ;
{
if ( findRealHash ( hash , real_hash ) )
{
RS_STACK_MUTEX ( srvMutex ) ;
mEncryptedPeerIds [ virtual_peer_id ] = hash ;
}
else
real_hash = hash ;
}
if ( dir = = RsTurtleGenericTunnelItem : : DIRECTION_SERVER )
{
2016-10-30 06:36:00 -04:00
# ifdef SERVER_DEBUG
2016-11-03 03:50:13 -04:00
FTSERVER_DEBUG ( ) < < " direction is SERVER. Adding file source for end-to-end encrypted tunnel for real hash " < < real_hash < < " , virtual peer id = " < < virtual_peer_id < < std : : endl ;
2016-10-30 06:36:00 -04:00
# endif
2016-11-03 03:50:13 -04:00
mFtController - > addFileSource ( real_hash , virtual_peer_id ) ;
}
2013-04-10 04:52:52 -04:00
}
2016-10-30 10:11:22 -04:00
2016-11-02 15:51:42 -04:00
void ftServer : : removeVirtualPeer ( const TurtleFileHash & hash , const TurtleVirtualPeerId & virtual_peer_id )
2013-04-10 04:52:52 -04:00
{
2016-11-03 03:50:13 -04:00
RsFileHash real_hash ;
if ( findRealHash ( hash , real_hash ) )
mFtController - > removeFileSource ( real_hash , virtual_peer_id ) ;
else
mFtController - > removeFileSource ( hash , virtual_peer_id ) ;
2016-10-30 06:36:00 -04:00
2016-11-03 03:50:13 -04:00
RS_STACK_MUTEX ( srvMutex ) ;
mEncryptedPeerIds . erase ( virtual_peer_id ) ;
2013-04-10 04:52:52 -04:00
}
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
{
2016-11-03 03:50:13 -04:00
FileInfo info ;
RsFileHash real_hash ;
bool found = false ;
2014-11-29 12:26:06 -05:00
2016-11-03 03:50:13 -04:00
if ( FileDetails ( hash , RS_FILE_HINTS_NETWORK_WIDE | RS_FILE_HINTS_LOCAL | RS_FILE_HINTS_EXTRA | RS_FILE_HINTS_SPEC_ONLY , info ) )
{
if ( info . transfer_info_flags & RS_FILE_REQ_ENCRYPTED )
{
2016-10-30 10:33:05 -04:00
# ifdef SERVER_DEBUG
2016-11-03 03:50:13 -04:00
FTSERVER_DEBUG ( ) < < " handleTunnelRequest: openning encrypted FT tunnel for H(H(F))= " < < hash < < " and H(F)= " < < info . hash < < std : : endl ;
2016-10-30 10:33:05 -04:00
# endif
2016-11-03 03:50:13 -04:00
RS_STACK_MUTEX ( srvMutex ) ;
mEncryptedHashes [ hash ] = info . hash ;
real_hash = info . hash ;
}
else
real_hash = hash ;
found = true ;
}
else // try to see if we're already swarming the file
{
{
RS_STACK_MUTEX ( srvMutex ) ;
std : : map < RsFileHash , RsFileHash > : : const_iterator it = mEncryptedHashes . find ( hash ) ;
if ( it ! = mEncryptedHashes . end ( ) )
real_hash = it - > second ;
else
real_hash = hash ;
}
if ( FileDetails ( real_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 )
{
found = true ;
if ( info . transfer_info_flags & RS_FILE_REQ_ANONYMOUS_ROUTING )
info . storage_permission_flags = DIR_FLAGS_ANONYMOUS_DOWNLOAD ; // this is to allow swarming
break ;
}
}
}
2016-11-03 15:31:47 -04:00
if ( found & & mFtController - > defaultEncryptionPolicy ( ) = = RS_FILE_CTRL_ENCRYPTION_POLICY_STRICT & & hash = = real_hash )
2016-11-03 03:50:13 -04:00
{
2016-11-03 15:31:47 -04:00
# ifdef SERVER_DEBUG
2016-11-03 03:50:13 -04:00
std : : cerr < < " (WW) rejecting file transfer for hash " < < hash < < " because the hash is not encrypted and encryption policy requires it. " < < std : : endl ;
2016-11-03 15:31:47 -04:00
# endif
2016-11-03 03:50:13 -04:00
return false ;
}
2016-11-01 09:13:43 -04:00
2013-04-01 17:18:58 -04:00
# ifdef SERVER_DEBUG
2016-11-03 03:50:13 -04:00
FTSERVER_DEBUG ( ) < < " ftServer: performing local hash search for hash " < < hash < < std : : endl ;
if ( found )
{
FTSERVER_DEBUG ( ) < < " Found hash: " < < std : : endl ;
FTSERVER_DEBUG ( ) < < " hash = " < < real_hash < < std : : endl ;
FTSERVER_DEBUG ( ) < < " peer = " < < peer_id < < std : : endl ;
FTSERVER_DEBUG ( ) < < " flags = " < < info . storage_permission_flags < < std : : endl ;
FTSERVER_DEBUG ( ) < < " groups= " ;
for ( std : : list < RsNodeGroupId > : : const_iterator it ( info . parent_groups . begin ( ) ) ; it ! = info . parent_groups . end ( ) ; + + it )
FTSERVER_DEBUG ( ) < < ( * it ) < < " , " ;
FTSERVER_DEBUG ( ) < < std : : endl ;
FTSERVER_DEBUG ( ) < < " clear = " < < rsPeers - > computePeerPermissionFlags ( peer_id , info . storage_permission_flags , info . parent_groups ) < < std : : endl ;
}
2013-04-01 17:18:58 -04:00
# endif
2016-11-03 03:50:13 -04:00
// 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.
//
found = found & & ( RS_FILE_HINTS_NETWORK_WIDE & rsPeers - > computePeerPermissionFlags ( peer_id , info . storage_permission_flags , info . parent_groups ) ) ;
2013-04-01 17:18:58 -04:00
2016-11-03 03:50:13 -04:00
return found ;
2013-04-01 17:18:58 -04:00
}
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
{
2016-11-03 03:50:13 -04:00
return mFtExtra - > addExtraFile ( fname , hash , size , period , flags ) ;
2008-07-02 09:19:59 -04:00
}
2014-03-17 16:56:06 -04:00
bool ftServer : : ExtraFileRemove ( const RsFileHash & hash , TransferRequestFlags flags )
2008-07-02 09:19:59 -04:00
{
2016-11-03 03:50:13 -04:00
return mFtExtra - > removeExtraFile ( hash , flags ) ;
2008-07-02 09:19:59 -04:00
}
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
{
2016-11-03 03:50:13 -04:00
return mFtExtra - > hashExtraFile ( localpath , period , flags ) ;
2008-07-02 09:19:59 -04:00
}
2008-08-03 08:45:53 -04:00
bool ftServer : : ExtraFileStatus ( std : : string localpath , FileInfo & info )
2008-07-02 09:19:59 -04:00
{
2016-11-03 03:50:13 -04:00
return mFtExtra - > hashExtraFileDone ( localpath , info ) ;
2008-07-02 09:19:59 -04:00
}
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
{
2016-11-03 03:50:13 -04:00
return mFtExtra - > moveExtraFile ( fname , hash , size , destpath ) ;
2008-11-27 16:23:46 -05:00
}
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-11-03 03:50:13 -04:00
return mFileDatabase - > RequestDirDetails ( uid , path , details ) ;
2008-07-02 09:19:59 -04:00
}
2009-07-12 09:22:31 -04:00
2016-09-15 04:41:40 -04:00
bool ftServer : : findChildPointer ( void * ref , int row , void * & result , FileSearchFlags flags )
{
2016-11-03 03:50:13 -04:00
return mFileDatabase - > findChildPointer ( ref , row , result , flags ) ;
2016-09-15 04:41:40 -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-11-03 03:50:13 -04:00
return mFileDatabase - > RequestDirDetails ( ref , details , flags ) ;
2008-07-02 09:19:59 -04:00
}
2016-10-31 09:26:01 -04:00
uint32_t ftServer : : getType ( void * ref , FileSearchFlags /* flags */ )
2011-04-03 15:59:12 -04:00
{
2016-11-03 03:50:13 -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-11-03 03:50:13 -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-11-03 03:50:13 -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-11-03 03:50:13 -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-11-03 03:50:13 -04:00
return mFileDatabase - > SearchBoolExp ( exp , results , flags , peer_id ) ;
2008-07-02 09:19:59 -04:00
}
2016-11-11 14:25:11 -05:00
int ftServer : : getSharedDirStatistics ( const RsPeerId & pid , SharedDirStats & stats )
{
return mFileDatabase - > getSharedDirStatistics ( pid , stats ) ;
}
2008-07-02 09:19:59 -04:00
2016-11-03 03:50:13 -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-11-03 03:50:13 -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-11-03 03:50:13 -04:00
mFileDatabase - > forceSyncWithPeers ( ) ;
2012-11-12 17:51:27 -05:00
}
2008-07-02 09:19:59 -04:00
void ftServer : : ForceDirectoryCheck ( )
{
2016-11-03 03:50:13 -04:00
mFileDatabase - > forceDirectoryCheck ( ) ;
return ;
2008-07-02 09:19:59 -04:00
}
2009-07-12 09:22:31 -04:00
2008-07-02 09:19:59 -04:00
bool ftServer : : InDirectoryCheck ( )
{
2016-11-03 03:50:13 -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-11-03 03:50:13 -04:00
mFileDatabase - > getSharedDirectories ( dirs ) ;
return true ;
2008-08-09 13:03:24 -04:00
}
2016-10-31 11:28:26 -04:00
bool ftServer : : setSharedDirectories ( const std : : list < SharedDirInfo > & dirs )
2008-08-09 13:03:24 -04:00
{
2016-11-03 03:50:13 -04:00
mFileDatabase - > setSharedDirectories ( dirs ) ;
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
{
2016-11-03 03:50:13 -04:00
SharedDirInfo _dir = dir ;
_dir . filename = RsDirUtil : : convertPathToUnix ( _dir . filename ) ;
2011-05-15 08:42:55 -04:00
2016-11-03 03:50:13 -04:00
std : : list < SharedDirInfo > dirList ;
mFileDatabase - > getSharedDirectories ( dirList ) ;
2009-08-03 15:43:52 -04:00
2016-11-03 03:50:13 -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 )
if ( ( * it ) . filename = = _dir . filename )
return false ;
2009-08-10 15:01:27 -04:00
2016-11-03 03:50:13 -04:00
// ok then, add the shared directory.
dirList . push_back ( _dir ) ;
2008-08-09 13:03:24 -04:00
2016-11-03 03:50:13 -04:00
mFileDatabase - > setSharedDirectories ( dirList ) ;
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-11-03 03:50:13 -04:00
mFileDatabase - > updateShareFlags ( info ) ;
2009-08-03 15:43:52 -04:00
2016-11-03 03:50:13 -04:00
return true ;
2009-08-03 15:43:52 -04:00
}
2008-07-02 09:19:59 -04:00
bool ftServer : : removeSharedDirectory ( std : : string dir )
{
2016-11-03 03:50:13 -04:00
dir = RsDirUtil : : convertPathToUnix ( dir ) ;
2011-05-15 08:42:55 -04:00
2016-11-03 03:50:13 -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
2016-11-03 03:50:13 -04:00
FTSERVER_DEBUG ( ) < < " ftServer::removeSharedDirectory( " < < dir < < " ) " < < std : : endl ;
2008-11-15 15:00:29 -05:00
# endif
2016-11-03 03:50:13 -04:00
mFileDatabase - > getSharedDirectories ( dirList ) ;
2008-08-09 13:03:24 -04:00
2009-07-12 09:22:31 -04:00
# ifdef SERVER_DEBUG
2016-11-03 03:50:13 -04:00
for ( it = dirList . begin ( ) ; it ! = dirList . end ( ) ; + + it )
FTSERVER_DEBUG ( ) < < " existing: " < < ( * it ) . filename < < std : : endl ;
2008-11-15 15:00:29 -05:00
# endif
2016-11-03 03:50:13 -04:00
for ( it = dirList . begin ( ) ; it ! = dirList . end ( ) & & ( * it ) . filename ! = dir ; + + it ) ;
2009-08-03 15:43:52 -04:00
2016-11-03 03:50:13 -04:00
if ( it = = dirList . end ( ) )
{
FTSERVER_ERROR ( ) < < " (EE) ftServer::removeSharedDirectory(): Cannot Find Directory... Fail " < < std : : endl ;
return false ;
}
2008-08-09 13:03:24 -04:00
2008-11-15 15:00:29 -05:00
2009-07-12 09:22:31 -04:00
# ifdef SERVER_DEBUG
2016-11-03 03:50:13 -04:00
FTSERVER_DEBUG ( ) < < " Updating Directories " < < std : : endl ;
2008-11-15 15:00:29 -05:00
# endif
2016-11-03 03:50:13 -04:00
dirList . erase ( it ) ;
mFileDatabase - > setSharedDirectories ( dirList ) ;
2008-08-09 13:03:24 -04:00
2016-11-03 03:50:13 -04:00
return true ;
2008-07-02 09:19:59 -04:00
}
2017-09-10 13:58:57 -04:00
bool ftServer : : getIgnoreLists ( std : : list < std : : string > & ignored_prefixes , std : : list < std : : string > & ignored_suffixes , uint32_t & ignore_flags )
{
return mFileDatabase - > getIgnoreLists ( ignored_prefixes , ignored_suffixes , ignore_flags ) ;
}
void ftServer : : setIgnoreLists ( const std : : list < std : : string > & ignored_prefixes , const std : : list < std : : string > & ignored_suffixes , uint32_t ignore_flags )
{
mFileDatabase - > setIgnoreLists ( ignored_prefixes , ignored_suffixes , ignore_flags ) ;
}
2016-11-24 17:42:56 -05:00
bool ftServer : : watchEnabled ( ) { return mFileDatabase - > watchEnabled ( ) ; }
int ftServer : : watchPeriod ( ) const { return mFileDatabase - > watchPeriod ( ) / 60 ; }
bool ftServer : : followSymLinks ( ) const { return mFileDatabase - > followSymLinks ( ) ; }
2011-03-28 17:52:21 -04:00
2016-11-24 17:42:56 -05:00
void ftServer : : setWatchEnabled ( bool b ) { mFileDatabase - > setWatchEnabled ( b ) ; }
void ftServer : : setWatchPeriod ( int minutes ) { mFileDatabase - > setWatchPeriod ( minutes * 60 ) ; }
void ftServer : : setFollowSymLinks ( bool b ) { mFileDatabase - > setFollowSymLinks ( b ) ; }
2008-07-02 09:19:59 -04:00
2009-07-12 09:22:31 -04:00
bool ftServer : : getShareDownloadDirectory ( )
{
2016-11-03 03:50:13 -04:00
std : : list < SharedDirInfo > dirList ;
mFileDatabase - > getSharedDirectories ( dirList ) ;
2009-07-12 09:22:31 -04:00
2016-11-03 03:50:13 -04:00
std : : string dir = mFtController - > getDownloadDirectory ( ) ;
2011-03-08 15:05:36 -05:00
2016-11-03 03:50:13 -04:00
// 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
2016-11-03 03:50:13 -04: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-11-03 03:50:13 -04:00
if ( share )
{
/* Share */
SharedDirInfo inf ;
inf . filename = mFtController - > getDownloadDirectory ( ) ;
inf . shareflags = DIR_FLAGS_ANONYMOUS_DOWNLOAD ;
2011-03-08 15:05:36 -05:00
2016-11-03 03:50:13 -04:00
return addSharedDirectory ( inf ) ;
}
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
2016-11-03 03:50:13 -04:00
/***************************************************************/
/****************** End of RsFiles Interface *******************/
/***************************************************************/
2008-07-02 09:19:59 -04:00
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
2016-11-03 03:50:13 -04:00
/***************************************************************/
/********************** Data Flow **********************/
/***************************************************************/
2008-08-03 08:45:53 -04:00
2016-10-24 18:08:27 -04:00
bool ftServer : : sendTurtleItem ( const RsPeerId & peerId , const RsFileHash & hash , RsTurtleGenericTunnelItem * item )
{
2016-11-03 03:50:13 -04:00
// we cannot look in the encrypted hash map, since the same hash--on this side of the FT--can be used with both
// encrypted and unencrypted peers ids. So the information comes from the virtual peer Id.
2016-10-30 06:36:00 -04:00
2016-11-03 03:50:13 -04:00
RsFileHash encrypted_hash ;
2016-10-30 06:36:00 -04:00
2016-11-03 03:50:13 -04:00
if ( findEncryptedHash ( peerId , encrypted_hash ) )
{
// we encrypt the item
2016-10-24 18:08:27 -04:00
2016-10-30 06:36:00 -04:00
# ifdef SERVER_DEBUG
2016-11-03 03:50:13 -04:00
FTSERVER_DEBUG ( ) < < " Sending turtle item to peer ID " < < peerId < < " using encrypted tunnel. " < < std : : endl ;
2016-10-30 06:36:00 -04:00
# endif
2016-11-03 03:50:13 -04:00
RsTurtleGenericDataItem * encrypted_item ;
2016-10-24 18:08:27 -04:00
2016-11-03 03:50:13 -04:00
if ( ! encryptItem ( item , hash , encrypted_item ) )
return false ;
2016-10-24 18:08:27 -04:00
2016-11-03 03:50:13 -04:00
delete item ;
2016-10-24 18:08:27 -04:00
2016-11-03 03:50:13 -04:00
mTurtleRouter - > sendTurtleData ( peerId , encrypted_item ) ;
}
else
{
2016-10-30 06:36:00 -04:00
# ifdef SERVER_DEBUG
2016-11-03 03:50:13 -04:00
FTSERVER_DEBUG ( ) < < " Sending turtle item to peer ID " < < peerId < < " using non uncrypted tunnel. " < < std : : endl ;
2016-10-30 06:36:00 -04:00
# endif
2016-11-03 03:50:13 -04:00
mTurtleRouter - > sendTurtleData ( peerId , item ) ;
}
2016-10-30 06:36:00 -04:00
2016-11-03 03:50:13 -04:00
return true ;
2016-10-24 18:08:27 -04:00
}
2016-11-03 03:50:13 -04:00
/* 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
2016-11-03 03:50:13 -04:00
FTSERVER_DEBUG ( ) < < " ftServer::sendDataRequest() to peer " < < peerId < < " for hash " < < hash < < " , offset= " < < offset < < " , chunk size= " < < chunksize < < std : : endl ;
2013-10-02 15:56:01 -04:00
# endif
2016-11-03 03:50:13 -04:00
if ( mTurtleRouter - > isTurtlePeer ( peerId ) )
{
RsTurtleFileRequestItem * item = new RsTurtleFileRequestItem ;
2013-04-06 05:21:01 -04:00
2016-11-03 03:50:13 -04:00
item - > chunk_offset = offset ;
item - > chunk_size = chunksize ;
2013-04-06 05:21:01 -04:00
2016-11-03 03:50:13 -04:00
sendTurtleItem ( peerId , hash , item ) ;
}
else
{
/* create a packet */
/* push to networking part */
RsFileTransferDataRequestItem * rfi = new RsFileTransferDataRequestItem ( ) ;
2008-08-03 08:45:53 -04:00
2016-11-03 03:50:13 -04:00
/* id */
rfi - > PeerId ( peerId ) ;
2008-08-03 08:45:53 -04:00
2016-11-03 03:50:13 -04:00
/* file info */
rfi - > file . filesize = size ;
rfi - > file . hash = hash ; /* ftr->hash; */
2008-08-03 08:45:53 -04:00
2016-11-03 03:50:13 -04:00
/* offsets */
rfi - > fileoffset = offset ; /* ftr->offset; */
rfi - > chunksize = chunksize ; /* ftr->chunk; */
2008-08-03 08:45:53 -04:00
2016-11-03 03:50:13 -04:00
sendItem ( rfi ) ;
}
2008-08-09 13:03:24 -04:00
2016-11-03 03:50:13 -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
2016-11-03 03:50:13 -04:00
FTSERVER_DEBUG ( ) < < " ftServer::sendChunkMapRequest() to peer " < < peerId < < " for hash " < < hash < < std : : endl ;
2013-10-02 15:56:01 -04:00
# endif
2016-11-03 03:50:13 -04:00
if ( mTurtleRouter - > isTurtlePeer ( peerId ) )
{
RsTurtleFileMapRequestItem * item = new RsTurtleFileMapRequestItem ;
sendTurtleItem ( peerId , hash , item ) ;
}
else
{
/* create a packet */
/* push to networking part */
RsFileTransferChunkMapRequestItem * rfi = new RsFileTransferChunkMapRequestItem ( ) ;
2010-07-25 15:04:31 -04:00
2016-11-03 03:50:13 -04:00
/* id */
rfi - > PeerId ( peerId ) ;
2010-07-25 15:04:31 -04:00
2016-11-03 03:50:13 -04:00
/* file info */
rfi - > hash = hash ; /* ftr->hash; */
rfi - > is_client = is_client ;
2010-07-25 15:04:31 -04:00
2016-11-03 03:50:13 -04:00
sendItem ( rfi ) ;
}
2010-01-11 11:00:42 -05:00
2016-11-03 03:50:13 -04:00
return true ;
2010-01-11 11:00:42 -05:00
}
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
2016-11-03 03:50:13 -04:00
FTSERVER_DEBUG ( ) < < " ftServer::sendChunkMap() to peer " < < peerId < < " for hash " < < hash < < std : : endl ;
2013-10-02 15:56:01 -04:00
# endif
2016-11-03 03:50:13 -04:00
if ( mTurtleRouter - > isTurtlePeer ( peerId ) )
{
RsTurtleFileMapItem * item = new RsTurtleFileMapItem ;
item - > compressed_map = map ;
sendTurtleItem ( peerId , hash , item ) ;
}
else
{
/* create a packet */
/* push to networking part */
RsFileTransferChunkMapItem * rfi = new RsFileTransferChunkMapItem ( ) ;
2010-07-25 15:04:31 -04:00
2016-11-03 03:50:13 -04:00
/* id */
rfi - > PeerId ( peerId ) ;
2010-07-25 15:04:31 -04:00
2016-11-03 03:50:13 -04:00
/* file info */
rfi - > hash = hash ; /* ftr->hash; */
rfi - > is_client = is_client ; /* ftr->hash; */
rfi - > compressed_map = map ; /* ftr->hash; */
2010-07-25 15:04:31 -04:00
2016-11-03 03:50:13 -04:00
sendItem ( rfi ) ;
}
2010-01-11 11:00:42 -05:00
2016-11-03 03:50:13 -04:00
return true ;
2010-01-11 11:00:42 -05:00
}
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
2016-11-03 03:50:13 -04:00
FTSERVER_DEBUG ( ) < < " ftServer::sendSingleCRCRequest() to peer " < < peerId < < " for hash " < < hash < < " , chunk number= " < < chunk_number < < std : : endl ;
2013-10-02 15:56:01 -04:00
# endif
2016-11-03 03:50:13 -04:00
if ( mTurtleRouter - > isTurtlePeer ( peerId ) )
{
RsTurtleChunkCrcRequestItem * item = new RsTurtleChunkCrcRequestItem ;
item - > chunk_number = chunk_number ;
2013-04-06 05:21:01 -04:00
2016-11-03 03:50:13 -04:00
sendTurtleItem ( peerId , hash , item ) ;
}
else
{
/* create a packet */
/* push to networking part */
RsFileTransferSingleChunkCrcRequestItem * rfi = new RsFileTransferSingleChunkCrcRequestItem ( ) ;
2012-03-15 15:55:43 -04:00
2016-11-03 03:50:13 -04:00
/* id */
rfi - > PeerId ( peerId ) ;
2012-03-15 15:55:43 -04:00
2016-11-03 03:50:13 -04:00
/* file info */
rfi - > hash = hash ; /* ftr->hash; */
rfi - > chunk_number = chunk_number ;
2012-03-15 15:55:43 -04:00
2016-11-03 03:50:13 -04:00
sendItem ( rfi ) ;
}
2012-03-15 15:55:43 -04:00
2016-11-03 03:50:13 -04:00
return true ;
2010-07-21 19:14:10 -04:00
}
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
2016-11-03 03:50:13 -04:00
FTSERVER_DEBUG ( ) < < " ftServer::sendSingleCRC() to peer " < < peerId < < " for hash " < < hash < < " , chunk number= " < < chunk_number < < std : : endl ;
2013-10-02 15:56:01 -04:00
# endif
2016-11-03 03:50:13 -04:00
if ( mTurtleRouter - > isTurtlePeer ( peerId ) )
{
RsTurtleChunkCrcItem * item = new RsTurtleChunkCrcItem ;
item - > chunk_number = chunk_number ;
item - > check_sum = crc ;
2013-04-06 05:21:01 -04:00
2016-11-03 03:50:13 -04:00
sendTurtleItem ( peerId , hash , item ) ;
}
else
{
/* create a packet */
/* push to networking part */
RsFileTransferSingleChunkCrcItem * rfi = new RsFileTransferSingleChunkCrcItem ( ) ;
2012-03-15 15:55:43 -04:00
2016-11-03 03:50:13 -04:00
/* id */
rfi - > PeerId ( peerId ) ;
2012-03-15 15:55:43 -04:00
2016-11-03 03:50:13 -04:00
/* file info */
rfi - > hash = hash ; /* ftr->hash; */
rfi - > check_sum = crc ;
rfi - > chunk_number = chunk_number ;
2012-03-15 15:55:43 -04:00
2016-11-03 03:50:13 -04:00
sendItem ( rfi ) ;
}
2012-03-15 15:55:43 -04:00
2016-11-03 03:50:13 -04:00
return true ;
2010-07-21 19:14:10 -04:00
}
2010-01-11 11:00:42 -05:00
2016-11-03 03:50:13 -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
{
2016-11-03 03:50:13 -04:00
/* create a packet */
/* push to networking part */
uint32_t tosend = chunksize ;
uint64_t offset = 0 ;
uint32_t chunk ;
2008-08-03 08:45:53 -04:00
2009-07-12 09:22:31 -04:00
# ifdef SERVER_DEBUG
2016-11-03 03:50:13 -04:00
FTSERVER_DEBUG ( ) < < " ftServer::sendData() to " < < peerId < < " , hash: " < < hash < < " offset: " < < baseoffset < < " chunk: " < < chunksize < < " data: " < < data < < std : : endl ;
2008-10-29 16:58:23 -04:00
# endif
2008-08-03 08:45:53 -04:00
2016-11-03 03:50:13 -04:00
while ( tosend > 0 )
{
//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 */
/* workout size */
chunk = MAX_FT_CHUNK ;
if ( chunk > tosend )
{
chunk = tosend ;
}
/******** New Serialiser Type *******/
if ( mTurtleRouter - > isTurtlePeer ( peerId ) )
{
RsTurtleFileDataItem * item = new RsTurtleFileDataItem ;
item - > chunk_offset = offset + baseoffset ;
item - > chunk_size = chunk ;
item - > chunk_data = rs_malloc ( chunk ) ;
if ( item - > chunk_data = = NULL )
{
delete item ;
return false ;
}
memcpy ( item - > chunk_data , & ( ( ( uint8_t * ) data ) [ offset ] ) , chunk ) ;
sendTurtleItem ( peerId , hash , item ) ;
}
else
{
RsFileTransferDataItem * rfd = new RsFileTransferDataItem ( ) ;
/* set id */
rfd - > PeerId ( peerId ) ;
/* 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 ;
rfd - > fd . file_offset = baseoffset + offset ;
/* file data */
rfd - > fd . binData . setBinData ( & ( ( ( uint8_t * ) data ) [ offset ] ) , chunk ) ;
sendItem ( rfd ) ;
/* print the data pointer */
2009-07-12 09:22:31 -04:00
# ifdef SERVER_DEBUG
2016-11-03 03:50:13 -04:00
FTSERVER_DEBUG ( ) < < " ftServer::sendData() Packet: " < < " offset: " < < rfd - > fd . file_offset < < " chunk: " < < chunk < < " len: " < < rfd - > fd . binData . bin_len < < " data: " < < rfd - > fd . binData . bin_data < < std : : endl ;
2008-10-29 16:58:23 -04:00
# endif
2016-11-03 03:50:13 -04:00
}
2008-08-03 08:45:53 -04:00
2016-11-03 03:50:13 -04:00
offset + = chunk ;
tosend - = chunk ;
}
2008-08-03 08:45:53 -04:00
2016-11-03 03:50:13 -04:00
/* clean up data */
free ( data ) ;
2008-08-09 13:03:24 -04:00
2016-11-03 03:50:13 -04:00
return true ;
2008-08-03 08:45:53 -04:00
}
2016-10-19 15:30:37 -04:00
// Encrypts the given item using aead-chacha20-poly1305
//
// The format is the following
//
// [encryption format] [random initialization vector] [encrypted data size] [encrypted data] [authentication tag]
// 4 bytes 12 bytes 4 bytes variable 16 bytes
//
// +-------------------- authenticated data part ----------------------+
//
//
// Encryption format:
2016-10-26 16:05:56 -04:00
// ae ad 01 01 : encryption using AEAD, format 01 (authed with Poly1305 ), version 01
// ae ad 02 01 : encryption using AEAD, format 02 (authed with HMAC Sha256), version 01
2016-10-19 15:30:37 -04:00
//
//
void ftServer : : deriveEncryptionKey ( const RsFileHash & hash , uint8_t * key )
{
2016-11-03 03:50:13 -04:00
// The encryption key is simply the 256 hash of the
SHA256_CTX sha_ctx ;
2016-10-19 15:30:37 -04:00
2016-11-03 03:50:13 -04:00
if ( SHA256_DIGEST_LENGTH ! = 32 )
throw std : : runtime_error ( " Warning: can't compute Sha1Sum with sum size != 32 " ) ;
2016-10-19 15:30:37 -04:00
2016-11-03 03:50:13 -04:00
SHA256_Init ( & sha_ctx ) ;
SHA256_Update ( & sha_ctx , hash . toByteArray ( ) , hash . SIZE_IN_BYTES ) ;
SHA256_Final ( key , & sha_ctx ) ;
2016-10-19 15:30:37 -04:00
}
2016-10-19 16:49:51 -04:00
static const uint32_t ENCRYPTED_FT_INITIALIZATION_VECTOR_SIZE = 12 ;
static const uint32_t ENCRYPTED_FT_AUTHENTICATION_TAG_SIZE = 16 ;
static const uint32_t ENCRYPTED_FT_HEADER_SIZE = 4 ;
static const uint32_t ENCRYPTED_FT_EDATA_SIZE = 4 ;
2016-10-26 16:05:56 -04:00
static const uint8_t ENCRYPTED_FT_FORMAT_AEAD_CHACHA20_POLY1305 = 0x01 ;
static const uint8_t ENCRYPTED_FT_FORMAT_AEAD_CHACHA20_SHA256 = 0x02 ;
2016-10-19 15:30:37 -04:00
bool ftServer : : encryptItem ( RsTurtleGenericTunnelItem * clear_item , const RsFileHash & hash , RsTurtleGenericDataItem * & encrypted_item )
{
2016-11-03 03:50:13 -04:00
uint8_t initialization_vector [ ENCRYPTED_FT_INITIALIZATION_VECTOR_SIZE ] ;
2016-10-19 15:30:37 -04:00
2016-11-03 03:50:13 -04:00
RSRandom : : random_bytes ( initialization_vector , ENCRYPTED_FT_INITIALIZATION_VECTOR_SIZE ) ;
2016-10-19 15:30:37 -04:00
2016-10-30 10:33:05 -04:00
# ifdef SERVER_DEBUG
2016-11-03 03:50:13 -04:00
FTSERVER_DEBUG ( ) < < " ftServer::Encrypting ft item. " < < std : : endl ;
FTSERVER_DEBUG ( ) < < " random nonce : " < < RsUtil : : BinToHex ( initialization_vector , ENCRYPTED_FT_INITIALIZATION_VECTOR_SIZE ) < < std : : endl ;
2016-10-30 10:33:05 -04:00
# endif
2016-10-19 15:30:37 -04:00
2017-04-15 12:46:44 -04:00
uint32_t item_serialized_size = size ( clear_item ) ;
uint32_t total_data_size = ENCRYPTED_FT_HEADER_SIZE + ENCRYPTED_FT_INITIALIZATION_VECTOR_SIZE + ENCRYPTED_FT_EDATA_SIZE + item_serialized_size + ENCRYPTED_FT_AUTHENTICATION_TAG_SIZE ;
2016-10-19 15:30:37 -04:00
2016-10-30 10:33:05 -04:00
# ifdef SERVER_DEBUG
2016-11-03 03:50:13 -04:00
FTSERVER_DEBUG ( ) < < " clear part size : " < < clear_item - > serial_size ( ) < < std : : endl ;
FTSERVER_DEBUG ( ) < < " total item size : " < < total_data_size < < std : : endl ;
2016-10-30 10:33:05 -04:00
# endif
2016-10-19 15:30:37 -04:00
2016-11-03 03:50:13 -04:00
encrypted_item = new RsTurtleGenericDataItem ;
encrypted_item - > data_bytes = rs_malloc ( total_data_size ) ;
encrypted_item - > data_size = total_data_size ;
2016-10-19 15:30:37 -04:00
2016-11-03 03:50:13 -04:00
if ( encrypted_item - > data_bytes = = NULL )
return false ;
2016-10-19 15:30:37 -04:00
2016-11-03 03:50:13 -04:00
uint8_t * edata = ( uint8_t * ) encrypted_item - > data_bytes ;
2017-04-15 12:46:44 -04:00
uint32_t edata_size = item_serialized_size ;
2016-11-03 03:50:13 -04:00
uint32_t offset = 0 ;
2016-10-19 15:30:37 -04:00
2016-11-03 03:50:13 -04:00
edata [ 0 ] = 0xae ;
edata [ 1 ] = 0xad ;
edata [ 2 ] = ENCRYPTED_FT_FORMAT_AEAD_CHACHA20_SHA256 ; // means AEAD_chacha20_sha256
edata [ 3 ] = 0x01 ;
2016-10-19 15:30:37 -04:00
2016-11-03 03:50:13 -04:00
offset + = ENCRYPTED_FT_HEADER_SIZE ;
uint32_t aad_offset = offset ;
uint32_t aad_size = ENCRYPTED_FT_INITIALIZATION_VECTOR_SIZE + ENCRYPTED_FT_EDATA_SIZE ;
2016-10-19 15:30:37 -04:00
2016-11-03 03:50:13 -04:00
memcpy ( & edata [ offset ] , initialization_vector , ENCRYPTED_FT_INITIALIZATION_VECTOR_SIZE ) ;
offset + = ENCRYPTED_FT_INITIALIZATION_VECTOR_SIZE ;
2016-10-19 15:30:37 -04:00
2016-11-03 03:50:13 -04:00
edata [ offset + 0 ] = ( edata_size > > 0 ) & 0xff ;
edata [ offset + 1 ] = ( edata_size > > 8 ) & 0xff ;
edata [ offset + 2 ] = ( edata_size > > 16 ) & 0xff ;
edata [ offset + 3 ] = ( edata_size > > 24 ) & 0xff ;
2016-10-19 15:30:37 -04:00
2016-11-03 03:50:13 -04:00
offset + = ENCRYPTED_FT_EDATA_SIZE ;
2016-10-19 15:30:37 -04:00
2016-11-03 03:50:13 -04:00
uint32_t ser_size = ( uint32_t ) ( ( int ) total_data_size - ( int ) offset ) ;
2017-04-15 12:46:44 -04:00
serialise ( clear_item , & edata [ offset ] , & ser_size ) ;
2016-10-19 15:30:37 -04:00
2016-10-30 10:33:05 -04:00
# ifdef SERVER_DEBUG
2016-11-03 03:50:13 -04:00
FTSERVER_DEBUG ( ) < < " clear item : " < < RsUtil : : BinToHex ( & edata [ offset ] , std : : min ( 50 , ( int ) total_data_size - ( int ) offset ) ) < < " (...) " < < std : : endl ;
2016-10-30 10:33:05 -04:00
# endif
2016-10-19 15:30:37 -04:00
2016-11-03 03:50:13 -04:00
uint32_t clear_item_offset = offset ;
offset + = edata_size ;
2016-10-19 15:30:37 -04:00
2016-11-03 03:50:13 -04:00
uint32_t authentication_tag_offset = offset ;
assert ( ENCRYPTED_FT_AUTHENTICATION_TAG_SIZE + offset = = total_data_size ) ;
2016-10-19 15:30:37 -04:00
2016-11-03 03:50:13 -04:00
uint8_t encryption_key [ 32 ] ;
deriveEncryptionKey ( hash , encryption_key ) ;
2016-10-19 15:30:37 -04:00
2016-11-03 03:50:13 -04:00
if ( edata [ 2 ] = = ENCRYPTED_FT_FORMAT_AEAD_CHACHA20_POLY1305 )
librs : : crypto : : AEAD_chacha20_poly1305 ( encryption_key , initialization_vector , & edata [ clear_item_offset ] , edata_size , & edata [ aad_offset ] , aad_size , & edata [ authentication_tag_offset ] , true ) ;
else if ( edata [ 2 ] = = ENCRYPTED_FT_FORMAT_AEAD_CHACHA20_SHA256 )
librs : : crypto : : AEAD_chacha20_sha256 ( encryption_key , initialization_vector , & edata [ clear_item_offset ] , edata_size , & edata [ aad_offset ] , aad_size , & edata [ authentication_tag_offset ] , true ) ;
else
return false ;
2016-10-19 15:30:37 -04:00
2016-10-30 10:33:05 -04:00
# ifdef SERVER_DEBUG
2016-11-03 03:50:13 -04:00
FTSERVER_DEBUG ( ) < < " encryption key : " < < RsUtil : : BinToHex ( encryption_key , 32 ) < < std : : endl ;
FTSERVER_DEBUG ( ) < < " authen. tag : " < < RsUtil : : BinToHex ( & edata [ authentication_tag_offset ] , ENCRYPTED_FT_AUTHENTICATION_TAG_SIZE ) < < std : : endl ;
FTSERVER_DEBUG ( ) < < " final item : " < < RsUtil : : BinToHex ( & edata [ 0 ] , std : : min ( 50u , total_data_size ) ) < < " (...) " < < std : : endl ;
2016-10-30 10:33:05 -04:00
# endif
2016-10-19 15:30:37 -04:00
2016-11-03 03:50:13 -04:00
return true ;
2016-10-19 15:30:37 -04:00
}
// Decrypts the given item using aead-chacha20-poly1305
2016-10-19 16:49:51 -04:00
bool ftServer : : decryptItem ( RsTurtleGenericDataItem * encrypted_item , const RsFileHash & hash , RsTurtleGenericTunnelItem * & decrypted_item )
2016-10-19 15:30:37 -04:00
{
2016-11-03 03:50:13 -04:00
uint8_t encryption_key [ 32 ] ;
deriveEncryptionKey ( hash , encryption_key ) ;
2016-10-19 16:49:51 -04:00
2016-11-03 03:50:13 -04:00
uint8_t * edata = ( uint8_t * ) encrypted_item - > data_bytes ;
uint32_t offset = 0 ;
2016-10-19 16:49:51 -04:00
2016-11-03 03:50:13 -04:00
if ( encrypted_item - > data_size < ENCRYPTED_FT_HEADER_SIZE + ENCRYPTED_FT_INITIALIZATION_VECTOR_SIZE + ENCRYPTED_FT_EDATA_SIZE ) return false ;
2016-10-19 16:49:51 -04:00
2016-11-03 03:50:13 -04:00
if ( edata [ 0 ] ! = 0xae ) return false ;
if ( edata [ 1 ] ! = 0xad ) return false ;
if ( edata [ 2 ] ! = ENCRYPTED_FT_FORMAT_AEAD_CHACHA20_POLY1305 & & edata [ 2 ] ! = ENCRYPTED_FT_FORMAT_AEAD_CHACHA20_SHA256 ) return false ;
if ( edata [ 3 ] ! = 0x01 ) return false ;
2016-10-19 16:49:51 -04:00
2016-11-03 03:50:13 -04:00
offset + = ENCRYPTED_FT_HEADER_SIZE ;
uint32_t aad_offset = offset ;
uint32_t aad_size = ENCRYPTED_FT_EDATA_SIZE + ENCRYPTED_FT_INITIALIZATION_VECTOR_SIZE ;
2016-10-19 16:49:51 -04:00
2016-11-03 03:50:13 -04:00
uint8_t * initialization_vector = & edata [ offset ] ;
2016-10-19 16:49:51 -04:00
2016-10-30 10:33:05 -04:00
# ifdef SERVER_DEBUG
2016-11-03 03:50:13 -04:00
FTSERVER_DEBUG ( ) < < " ftServer::decrypting ft item. " < < std : : endl ;
FTSERVER_DEBUG ( ) < < " item data : " < < RsUtil : : BinToHex ( edata , std : : min ( 50u , encrypted_item - > data_size ) ) < < " (...) " < < std : : endl ;
FTSERVER_DEBUG ( ) < < " hash : " < < hash < < std : : endl ;
FTSERVER_DEBUG ( ) < < " encryption key : " < < RsUtil : : BinToHex ( encryption_key , 32 ) < < std : : endl ;
FTSERVER_DEBUG ( ) < < " random nonce : " < < RsUtil : : BinToHex ( initialization_vector , ENCRYPTED_FT_INITIALIZATION_VECTOR_SIZE ) < < std : : endl ;
2016-10-30 10:33:05 -04:00
# endif
2016-10-19 16:49:51 -04:00
2016-11-03 03:50:13 -04:00
offset + = ENCRYPTED_FT_INITIALIZATION_VECTOR_SIZE ;
2016-10-19 16:49:51 -04:00
2016-11-03 03:50:13 -04:00
uint32_t edata_size = 0 ;
edata_size + = ( ( uint32_t ) edata [ offset + 0 ] ) < < 0 ;
edata_size + = ( ( uint32_t ) edata [ offset + 1 ] ) < < 8 ;
edata_size + = ( ( uint32_t ) edata [ offset + 2 ] ) < < 16 ;
edata_size + = ( ( uint32_t ) edata [ offset + 3 ] ) < < 24 ;
2016-10-19 16:49:51 -04:00
2016-11-03 03:50:13 -04:00
if ( edata_size + ENCRYPTED_FT_EDATA_SIZE + ENCRYPTED_FT_AUTHENTICATION_TAG_SIZE + ENCRYPTED_FT_INITIALIZATION_VECTOR_SIZE + ENCRYPTED_FT_HEADER_SIZE ! = encrypted_item - > data_size )
{
FTSERVER_ERROR ( ) < < " ERROR: encrypted data size is " < < edata_size < < " , should be " < < encrypted_item - > data_size - ( ENCRYPTED_FT_EDATA_SIZE + ENCRYPTED_FT_AUTHENTICATION_TAG_SIZE + ENCRYPTED_FT_INITIALIZATION_VECTOR_SIZE + ENCRYPTED_FT_HEADER_SIZE ) < < std : : endl ;
return false ;
}
2016-10-30 10:11:22 -04:00
2016-11-03 03:50:13 -04:00
offset + = ENCRYPTED_FT_EDATA_SIZE ;
uint32_t clear_item_offset = offset ;
2016-10-19 16:49:51 -04:00
2016-11-03 03:50:13 -04:00
uint32_t authentication_tag_offset = offset + edata_size ;
2016-10-30 10:33:05 -04:00
# ifdef SERVER_DEBUG
2016-11-03 03:50:13 -04:00
FTSERVER_DEBUG ( ) < < " authen. tag : " < < RsUtil : : BinToHex ( & edata [ authentication_tag_offset ] , ENCRYPTED_FT_AUTHENTICATION_TAG_SIZE ) < < std : : endl ;
2016-10-30 10:33:05 -04:00
# endif
2016-10-19 16:49:51 -04:00
2016-11-03 03:50:13 -04:00
bool result ;
2016-10-19 16:49:51 -04:00
2016-11-03 03:50:13 -04:00
if ( edata [ 2 ] = = ENCRYPTED_FT_FORMAT_AEAD_CHACHA20_POLY1305 )
result = librs : : crypto : : AEAD_chacha20_poly1305 ( encryption_key , initialization_vector , & edata [ clear_item_offset ] , edata_size , & edata [ aad_offset ] , aad_size , & edata [ authentication_tag_offset ] , false ) ;
else if ( edata [ 2 ] = = ENCRYPTED_FT_FORMAT_AEAD_CHACHA20_SHA256 )
result = librs : : crypto : : AEAD_chacha20_sha256 ( encryption_key , initialization_vector , & edata [ clear_item_offset ] , edata_size , & edata [ aad_offset ] , aad_size , & edata [ authentication_tag_offset ] , false ) ;
else
return false ;
2016-10-26 16:05:56 -04:00
2016-10-30 10:33:05 -04:00
# ifdef SERVER_DEBUG
2016-11-03 03:50:13 -04:00
FTSERVER_DEBUG ( ) < < " authen. result : " < < result < < std : : endl ;
FTSERVER_DEBUG ( ) < < " decrypted daya : " < < RsUtil : : BinToHex ( & edata [ clear_item_offset ] , std : : min ( 50u , edata_size ) ) < < " (...) " < < std : : endl ;
2016-10-30 10:33:05 -04:00
# endif
2016-10-26 16:05:56 -04:00
2016-11-03 03:50:13 -04:00
if ( ! result )
{
FTSERVER_ERROR ( ) < < " (EE) decryption/authentication went wrong. " < < std : : endl ;
return false ;
}
2016-10-19 16:49:51 -04:00
2017-04-15 12:46:44 -04:00
decrypted_item = dynamic_cast < RsTurtleGenericTunnelItem * > ( deserialise ( & edata [ clear_item_offset ] , & edata_size ) ) ;
2016-10-19 16:49:51 -04:00
2016-11-03 03:50:13 -04:00
if ( decrypted_item = = NULL )
return false ;
2016-10-19 16:49:51 -04:00
2016-11-03 03:50:13 -04:00
return true ;
2016-10-19 15:30:37 -04:00
}
2016-10-29 11:59:03 -04:00
bool ftServer : : encryptHash ( const RsFileHash & hash , RsFileHash & hash_of_hash )
{
2016-11-03 03:50:13 -04:00
hash_of_hash = RsDirUtil : : sha1sum ( hash . toByteArray ( ) , hash . SIZE_IN_BYTES ) ;
return true ;
2016-10-29 11:59:03 -04:00
}
2016-10-30 06:36:00 -04:00
bool ftServer : : findEncryptedHash ( const RsPeerId & virtual_peer_id , RsFileHash & encrypted_hash )
{
2016-11-03 03:50:13 -04:00
RS_STACK_MUTEX ( srvMutex ) ;
2016-10-30 06:36:00 -04:00
2016-11-03 03:50:13 -04:00
std : : map < RsPeerId , RsFileHash > : : const_iterator it = mEncryptedPeerIds . find ( virtual_peer_id ) ;
2016-10-30 06:36:00 -04:00
2016-11-03 03:50:13 -04:00
if ( it ! = mEncryptedPeerIds . end ( ) )
{
encrypted_hash = it - > second ;
return true ;
}
else
return false ;
2016-10-30 06:36:00 -04:00
}
2016-10-24 18:08:27 -04:00
bool ftServer : : findRealHash ( const RsFileHash & hash , RsFileHash & real_hash )
{
2016-11-03 03:50:13 -04:00
RS_STACK_MUTEX ( srvMutex ) ;
std : : map < RsFileHash , RsFileHash > : : const_iterator it = mEncryptedHashes . find ( hash ) ;
2016-10-24 18:08:27 -04:00
2016-11-03 03:50:13 -04:00
if ( it ! = mEncryptedHashes . end ( ) )
{
real_hash = it - > second ;
return true ;
}
else
return false ;
2016-10-24 18:08:27 -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 ,
2016-11-03 03:50:13 -04:00
const RsFileHash & hash ,
const RsPeerId & virtual_peer_id ,
RsTurtleGenericTunnelItem : : Direction direction )
2013-04-06 05:21:01 -04:00
{
2016-11-03 03:50:13 -04:00
if ( i - > PacketSubType ( ) = = RS_TURTLE_SUBTYPE_GENERIC_DATA )
{
2016-10-30 10:33:05 -04:00
# ifdef SERVER_DEBUG
2016-11-03 03:50:13 -04:00
FTSERVER_DEBUG ( ) < < " Received encrypted data item. Trying to decrypt " < < std : : endl ;
2016-10-30 10:33:05 -04:00
# endif
2016-10-24 18:08:27 -04:00
2016-11-03 03:50:13 -04:00
RsFileHash real_hash ;
if ( ! findRealHash ( hash , real_hash ) )
{
FTSERVER_ERROR ( ) < < " (EE) Cannot find real hash for encrypted data item with H(H(F))= " < < hash < < " . This is unexpected. " < < std : : endl ;
return ;
}
RsTurtleGenericTunnelItem * decrypted_item ;
if ( ! decryptItem ( dynamic_cast < RsTurtleGenericDataItem * > ( i ) , real_hash , decrypted_item ) )
{
FTSERVER_ERROR ( ) < < " (EE) decryption error. " < < std : : endl ;
return ;
}
receiveTurtleData ( decrypted_item , real_hash , virtual_peer_id , direction ) ;
delete decrypted_item ;
return ;
}
switch ( i - > PacketSubType ( ) )
{
case RS_TURTLE_SUBTYPE_FILE_REQUEST :
{
RsTurtleFileRequestItem * item = dynamic_cast < RsTurtleFileRequestItem * > ( i ) ;
if ( item )
{
2013-10-02 15:56:01 -04:00
# ifdef SERVER_DEBUG
2016-11-03 03:50:13 -04:00
FTSERVER_DEBUG ( ) < < " ftServer::receiveTurtleData(): received file data request for " < < hash < < " from peer " < < virtual_peer_id < < std : : endl ;
2013-10-02 15:56:01 -04:00
# endif
2016-11-03 03:50:13 -04:00
getMultiplexer ( ) - > recvDataRequest ( virtual_peer_id , hash , 0 , item - > chunk_offset , item - > chunk_size ) ;
}
}
break ;
case RS_TURTLE_SUBTYPE_FILE_DATA :
{
RsTurtleFileDataItem * item = dynamic_cast < RsTurtleFileDataItem * > ( i ) ;
if ( item )
{
2013-10-02 15:56:01 -04:00
# ifdef SERVER_DEBUG
2016-11-03 03:50:13 -04:00
FTSERVER_DEBUG ( ) < < " ftServer::receiveTurtleData(): received file data for " < < hash < < " from peer " < < virtual_peer_id < < std : : endl ;
2013-10-02 15:56:01 -04:00
# endif
2016-11-03 03:50:13 -04:00
getMultiplexer ( ) - > recvData ( virtual_peer_id , hash , 0 , item - > chunk_offset , item - > chunk_size , item - > chunk_data ) ;
item - > chunk_data = NULL ; // this prevents deletion in the destructor of RsFileDataItem, because data will be deleted
// down _ft_server->getMultiplexer()->recvData()...in ftTransferModule::recvFileData
}
}
break ;
case RS_TURTLE_SUBTYPE_FILE_MAP :
{
RsTurtleFileMapItem * item = dynamic_cast < RsTurtleFileMapItem * > ( i ) ;
if ( item )
{
2013-10-02 15:56:01 -04:00
# ifdef SERVER_DEBUG
2016-11-03 03:50:13 -04:00
FTSERVER_DEBUG ( ) < < " ftServer::receiveTurtleData(): received chunk map for hash " < < hash < < " from peer " < < virtual_peer_id < < std : : endl ;
2013-10-02 15:56:01 -04:00
# endif
2016-11-03 03:50:13 -04:00
getMultiplexer ( ) - > recvChunkMap ( virtual_peer_id , hash , item - > compressed_map , direction = = RsTurtleGenericTunnelItem : : DIRECTION_CLIENT ) ;
}
}
break ;
case RS_TURTLE_SUBTYPE_FILE_MAP_REQUEST :
{
//RsTurtleFileMapRequestItem *item = dynamic_cast<RsTurtleFileMapRequestItem *>(i) ;
2013-10-02 15:56:01 -04:00
# ifdef SERVER_DEBUG
2016-11-03 03:50:13 -04:00
FTSERVER_DEBUG ( ) < < " ftServer::receiveTurtleData(): received chunkmap request for hash " < < hash < < " from peer " < < virtual_peer_id < < std : : endl ;
2013-10-02 15:56:01 -04:00
# endif
2016-11-03 03:50:13 -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 ) ;
if ( item )
{
2013-10-02 15:56:01 -04:00
# ifdef SERVER_DEBUG
2016-11-03 03:50:13 -04:00
FTSERVER_DEBUG ( ) < < " 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
2016-11-03 03:50:13 -04:00
getMultiplexer ( ) - > recvSingleChunkCRC ( virtual_peer_id , hash , item - > chunk_number , item - > check_sum ) ;
}
}
break ;
case RS_TURTLE_SUBTYPE_CHUNK_CRC_REQUEST :
{
RsTurtleChunkCrcRequestItem * item = dynamic_cast < RsTurtleChunkCrcRequestItem * > ( i ) ;
if ( item )
{
2013-10-02 15:56:01 -04:00
# ifdef SERVER_DEBUG
2016-11-03 03:50:13 -04:00
FTSERVER_DEBUG ( ) < < " 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
2016-11-03 03:50:13 -04:00
getMultiplexer ( ) - > recvSingleChunkCRCRequest ( virtual_peer_id , hash , item - > chunk_number ) ;
}
}
break ;
default :
FTSERVER_ERROR ( ) < < " WARNING: Unknown packet type received: sub_id= " < < reinterpret_cast < void * > ( i - > PacketSubType ( ) ) < < " . Is somebody trying to poison you ? " < < std : : endl ;
}
2013-04-06 05:21:01 -04:00
}
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 ( )
{
2016-11-03 03:50:13 -04:00
bool moreToTick = false ;
2008-08-03 08:45:53 -04:00
2016-11-03 03:50:13 -04:00
if ( handleIncoming ( ) )
moreToTick = true ;
2008-08-17 11:23:11 -04:00
2016-11-03 03:50:13 -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
2016-11-03 03:50:13 -04:00
if ( last_law_priority_tasks_handling_time + FILE_TRANSFER_LOW_PRIORITY_TASKS_PERIOD < now )
{
last_law_priority_tasks_handling_time = now ;
2008-08-03 08:45:53 -04:00
2016-11-03 03:50:13 -04:00
mFtDataplex - > deleteUnusedServers ( ) ;
mFtDataplex - > handlePendingCrcRequests ( ) ;
mFtDataplex - > dispatchReceivedChunkCheckSum ( ) ;
}
2008-08-09 13:03:24 -04:00
2016-11-03 03:50:13 -04:00
return moreToTick ;
2008-08-03 08:45:53 -04:00
}
2017-05-08 16:00:51 -04:00
bool ftServer : : checkUploadLimit ( const RsPeerId & pid , const RsFileHash & hash )
{
// No need for this extra cost if the value means "unlimited"
# ifdef SERVER_DEBUG
std : : cerr < < " Checking upload limit for friend " < < pid < < " and hash " < < hash < < " : " ;
# endif
uint32_t max_ups = mFtController - > getMaxUploadsPerFriend ( ) ;
2017-05-08 17:04:04 -04:00
RS_STACK_MUTEX ( srvMutex ) ;
2017-05-08 16:00:51 -04:00
if ( max_ups = = 0 )
{
# ifdef SERVER_DEBUG
std : : cerr < < " no limit! returning true. " < < std : : endl ;
# endif
return true ;
}
# ifdef SERVER_DEBUG
std : : cerr < < " max= " < < max_ups ;
# endif
// Find the latest records for this pid.
std : : map < RsFileHash , time_t > & tmap ( mUploadLimitMap [ pid ] ) ;
std : : map < RsFileHash , time_t > : : iterator it ;
time_t now = time ( NULL ) ;
// If the limit has been decresed, we arbitrarily drop some ongoing slots.
while ( tmap . size ( ) > max_ups )
tmap . erase ( tmap . begin ( ) ) ;
// Look in the upload record map. If it's not full, directly allocate a slot. If full, re-use an existing slot if a file is already cited.
if ( tmap . size ( ) < max_ups | | ( tmap . size ( ) = = max_ups & & tmap . end ( ) ! = ( it = tmap . find ( hash ) ) ) )
{
# ifdef SERVER_DEBUG
std : : cerr < < " allocated slot for this hash => true " < < std : : endl ;
# endif
tmap [ hash ] = now ;
return true ;
}
// There's no room in the used slots, but maybe some of them are not used anymore, in which case we remove them, which freeze a slot.
uint32_t cleaned = 0 ;
for ( it = tmap . begin ( ) ; it ! = tmap . end ( ) & & cleaned < 2 ; )
if ( it - > second + FILE_TRANSFER_MAX_DELAY_BEFORE_DROP_USAGE_RECORD < now )
{
2017-05-08 17:04:04 -04:00
std : : map < RsFileHash , time_t > : : iterator tmp ( it ) ;
+ + tmp ;
2017-05-08 16:00:51 -04:00
tmap . erase ( it ) ;
2017-05-08 17:04:04 -04:00
it = tmp ;
2017-05-08 16:00:51 -04:00
+ + cleaned ;
}
else
+ + it ;
if ( cleaned > 0 )
{
# ifdef SERVER_DEBUG
std : : cerr < < " cleaned up " < < cleaned < < " old hashes => true " < < std : : endl ;
# endif
tmap [ hash ] = now ;
return true ;
}
# ifdef SERVER_DEBUG
std : : cerr < < " no slot for this hash => false " < < std : : endl ;
# endif
return false ;
}
2013-10-01 04:11:15 -04:00
int ftServer : : handleIncoming ( )
2008-08-03 08:45:53 -04:00
{
2016-11-03 03:50:13 -04:00
// now File Input.
int nhandled = 0 ;
2008-08-03 08:45:53 -04:00
2016-11-03 03:50:13 -04:00
RsItem * item = NULL ;
2008-08-03 08:45:53 -04:00
2016-11-03 03:50:13 -04:00
while ( NULL ! = ( item = recvItem ( ) ) )
{
nhandled + + ;
2008-10-29 16:58:23 -04:00
2016-11-03 03:50:13 -04:00
switch ( item - > PacketSubType ( ) )
{
case RS_PKT_SUBTYPE_FT_DATA_REQUEST :
{
RsFileTransferDataRequestItem * f = dynamic_cast < RsFileTransferDataRequestItem * > ( item ) ;
2017-05-08 16:00:51 -04:00
if ( f & & checkUploadLimit ( f - > PeerId ( ) , f - > file . hash ) )
2016-11-03 03:50:13 -04:00
{
2010-07-25 15:04:31 -04:00
# ifdef SERVER_DEBUG
2016-11-03 03:50:13 -04:00
FTSERVER_DEBUG ( ) < < " 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
2016-11-03 03:50:13 -04:00
mFtDataplex - > recvDataRequest ( f - > PeerId ( ) , f - > file . hash , f - > file . filesize , f - > fileoffset , f - > chunksize ) ;
}
}
break ;
case RS_PKT_SUBTYPE_FT_DATA :
{
RsFileTransferDataItem * f = dynamic_cast < RsFileTransferDataItem * > ( item ) ;
if ( f )
{
2010-07-25 15:04:31 -04:00
# ifdef SERVER_DEBUG
2016-11-03 03:50:13 -04:00
FTSERVER_DEBUG ( ) < < " 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
2016-11-03 03:50:13 -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 ) ;
/* we've stolen the data part -> so blank before delete
*/
f - > fd . binData . TlvShallowClear ( ) ;
}
}
break ;
case RS_PKT_SUBTYPE_FT_CHUNK_MAP_REQUEST :
{
RsFileTransferChunkMapRequestItem * f = dynamic_cast < RsFileTransferChunkMapRequestItem * > ( item ) ;
if ( f )
{
2010-07-29 17:07:07 -04:00
# ifdef SERVER_DEBUG
2016-11-03 03:50:13 -04:00
FTSERVER_DEBUG ( ) < < " ftServer::handleIncoming: received chunkmap request for hash " < < f - > hash < < " , client= " < < f - > is_client < < std : : endl ;
2010-07-29 17:07:07 -04:00
# endif
2016-11-03 03:50:13 -04:00
mFtDataplex - > recvChunkMapRequest ( f - > PeerId ( ) , f - > hash , f - > is_client ) ;
}
}
break ;
case RS_PKT_SUBTYPE_FT_CHUNK_MAP :
{
RsFileTransferChunkMapItem * f = dynamic_cast < RsFileTransferChunkMapItem * > ( item ) ;
if ( f )
{
2010-07-29 17:07:07 -04:00
# ifdef SERVER_DEBUG
2016-11-03 03:50:13 -04:00
FTSERVER_DEBUG ( ) < < " 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
2016-11-03 03:50:13 -04:00
mFtDataplex - > recvChunkMap ( f - > PeerId ( ) , f - > hash , f - > compressed_map , f - > is_client ) ;
}
}
break ;
case RS_PKT_SUBTYPE_FT_CHUNK_CRC_REQUEST :
{
RsFileTransferSingleChunkCrcRequestItem * f = dynamic_cast < RsFileTransferSingleChunkCrcRequestItem * > ( item ) ;
if ( f )
{
2012-03-15 15:55:43 -04:00
# ifdef SERVER_DEBUG
2016-11-03 03:50:13 -04:00
FTSERVER_DEBUG ( ) < < " 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
2016-11-03 03:50:13 -04:00
mFtDataplex - > recvSingleChunkCRCRequest ( f - > PeerId ( ) , f - > hash , f - > chunk_number ) ;
}
}
break ;
case RS_PKT_SUBTYPE_FT_CHUNK_CRC :
{
RsFileTransferSingleChunkCrcItem * f = dynamic_cast < RsFileTransferSingleChunkCrcItem * > ( item ) ;
if ( f )
{
2012-03-15 15:55:43 -04:00
# ifdef SERVER_DEBUG
2016-11-03 03:50:13 -04:00
FTSERVER_DEBUG ( ) < < " 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
2016-11-03 03:50:13 -04:00
mFtDataplex - > recvSingleChunkCRC ( f - > PeerId ( ) , f - > hash , f - > chunk_number , f - > check_sum ) ;
}
}
break ;
}
2012-03-15 15:55:43 -04:00
2016-11-03 03:50:13 -04:00
delete item ;
}
2013-10-01 04:11:15 -04:00
2016-11-03 03:50:13 -04:00
return nhandled ;
2008-08-03 08:45:53 -04:00
}
/**********************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2016-11-03 03:50:13 -04:00
/***************************** CONFIG ****************************/
2008-11-15 15:00:29 -05:00
bool ftServer : : addConfiguration ( p3ConfigMgr * cfgmgr )
{
2016-11-03 03:50:13 -04:00
/* add all the subbits to config mgr */
cfgmgr - > addConfiguration ( " ft_database.cfg " , mFileDatabase ) ;
cfgmgr - > addConfiguration ( " ft_extra.cfg " , mFtExtra ) ;
cfgmgr - > addConfiguration ( " ft_transfers.cfg " , mFtController ) ;
2009-07-12 09:22:31 -04:00
2016-11-03 03:50:13 -04:00
return true ;
2008-11-15 15:00:29 -05:00
}