2018-05-21 20:50:38 +02:00
/*******************************************************************************
* libretroshare / src / file_sharing : p3filelists . h *
* *
* libretroshare : retroshare core library *
* *
* Copyright 2018 by Mr . Alice < mralice @ users . sourceforge . net > *
* *
* This program is free software : you can redistribute it and / or modify *
2018-05-28 22:03:39 +02:00
* it under the terms of the GNU Lesser General Public License as *
2018-05-21 20:50:38 +02:00
* published by the Free Software Foundation , either version 3 of the *
* License , or ( at your option ) any later version . *
* *
* This program 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 *
2018-05-28 22:03:39 +02:00
* GNU Lesser General Public License for more details . *
2018-05-21 20:50:38 +02:00
* *
2018-05-28 22:03:39 +02:00
* You should have received a copy of the GNU Lesser General Public License *
2018-05-21 20:50:38 +02:00
* along with this program . If not , see < https : //www.gnu.org/licenses/>. *
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2016-09-13 00:01:26 +02:00
//
2016-04-14 18:25:12 -04:00
// This class is responsible for
// - maintaining a list of shared file hierarchies for each known friends
// - talking to the GUI
// - providing handles for the directory tree listing GUI
// - providing search handles for FT
// - keeping these lists up to date
// - sending our own file list to friends depending on the defined access rights
// - serving file search requests from other services such as file transfer
//
// p3FileList does the following micro-tasks:
// - tick the watchers
// - get incoming info from the service layer, which can be:
// - directory content request => the directory content is shared to the friend
// - directory content => the directory watcher is notified
// - keep two queues of update requests:
// - fast queue that is handled in highest priority. This one is used for e.g. updating while browsing.
// - slow queue that is handled slowly. Used in background update of shared directories.
//
// The file lists are not directry updated. A FileListWatcher class is responsible for this
// in every case.
//
2016-07-20 15:28:55 -04:00
# pragma once
2016-07-30 21:52:42 +02:00
# include "ft/ftsearch.h"
2018-09-27 13:42:49 +02:00
# include "ft/ftextralist.h"
2016-07-20 16:10:51 -04:00
# include "retroshare/rsfiles.h"
# include "services/p3service.h"
2018-10-07 01:34:05 +02:00
# include "util/rstime.h"
2016-07-30 21:52:42 +02:00
# include "file_sharing/hash_cache.h"
2016-07-31 15:59:58 +02:00
# include "file_sharing/directory_storage.h"
2016-07-30 21:52:42 +02:00
2016-07-20 16:10:51 -04:00
# include "pqi/p3cfgmgr.h"
# include "pqi/p3linkmgr.h"
2016-07-30 21:52:42 +02:00
class RemoteDirectoryUpdater ;
class LocalDirectoryUpdater ;
2016-07-20 16:10:51 -04:00
class RemoteDirectoryStorage ;
2016-07-30 21:52:42 +02:00
class LocalDirectoryStorage ;
2016-07-20 16:10:51 -04:00
2016-08-23 21:23:58 +02:00
class RsFileListsSyncRequestItem ;
class RsFileListsSyncResponseItem ;
2018-08-20 23:30:05 +02:00
class RsFileListsBannedHashesItem ;
2016-08-20 16:23:11 +02:00
2016-07-30 21:52:42 +02:00
class HashStorage ;
2018-08-19 21:11:17 +02:00
struct PeerBannedFilesEntry
{
std : : set < RsFileHash > mBannedHashOfHash ;
2018-08-20 23:30:05 +02:00
uint32_t mSessionId ; // used for when a friend sends multiple packets in separate items.
2018-10-07 01:34:05 +02:00
rstime_t mLastSent ;
2018-08-19 21:11:17 +02:00
} ;
2016-07-30 21:52:42 +02:00
class p3FileDatabase : public p3Service , public p3Config , public ftSearch //, public RsSharedFileService
2016-04-14 18:25:12 -04:00
{
public :
2016-07-31 15:59:58 +02:00
typedef DirectoryStorage : : EntryIndex EntryIndex ; // this should probably be defined elsewhere
2016-07-18 21:33:54 -04:00
2016-07-30 21:52:42 +02:00
virtual RsServiceInfo getServiceInfo ( ) ;
2016-07-20 16:10:51 -04:00
struct RsFileListSyncRequest
{
RsPeerId peerId ;
EntryIndex index ;
// [...] more to add here
} ;
2018-09-27 13:42:49 +02:00
explicit p3FileDatabase ( p3ServiceControl * mpeers ) ;
2016-07-30 21:52:42 +02:00
~ p3FileDatabase ( ) ;
2018-09-27 13:42:49 +02:00
void setExtraList ( ftExtraList * f ) { mExtraFiles = f ; }
2016-07-30 21:52:42 +02:00
/*!
* \ brief forceSyncWithPeers
*
2016-07-31 15:59:58 +02:00
* Forces the synchronisation of the database with connected peers . This is triggered when e . g . a new group of friend is created , or when
2016-07-30 21:52:42 +02:00
* a friend was added / removed from a group .
*/
2016-07-31 15:59:58 +02:00
void forceSyncWithPeers ( ) { NOT_IMPLEMENTED ( ) ; }
2016-07-18 21:33:54 -04:00
// derived from p3Service
//
virtual int tick ( ) ;
2016-07-30 21:52:42 +02:00
// ftSearch
virtual bool search ( const RsFileHash & hash , FileSearchFlags hintflags , FileInfo & info ) const ;
2016-09-18 21:16:25 +02:00
virtual int SearchKeywords ( const std : : list < std : : string > & keywords , std : : list < DirDetails > & results , FileSearchFlags flags , const RsPeerId & peer_id ) ;
virtual int SearchBoolExp ( RsRegularExpression : : Expression * exp , std : : list < DirDetails > & results , FileSearchFlags flags , const RsPeerId & peer_id ) const ;
2016-07-30 21:52:42 +02:00
2019-08-01 15:20:54 +02:00
// Extra file list
virtual bool removeExtraFile ( const RsFileHash & hash ) ;
2018-09-27 16:53:08 +02:00
2016-07-18 21:33:54 -04:00
// Interface for browsing dir hierarchy
//
2016-07-30 21:52:42 +02:00
void stopThreads ( ) ;
void startThreads ( ) ;
2016-09-15 10:41:40 +02:00
bool findChildPointer ( void * ref , int row , void * & result , FileSearchFlags flags ) const ;
2016-07-18 21:33:54 -04:00
2016-07-30 21:52:42 +02:00
// void * here is the type expected by the abstract model index from Qt. It gets turned into a DirectoryStorage::EntryIndex internally.
2016-09-11 17:52:12 +02:00
void requestDirUpdate ( void * ref ) ; // triggers an update. Used when browsing.
2016-07-30 21:52:42 +02:00
int RequestDirDetails ( void * , DirDetails & , FileSearchFlags ) const ;
2018-09-27 16:53:08 +02:00
uint32_t getType ( void * , FileSearchFlags flags ) const ;
2016-07-30 21:52:42 +02:00
2016-09-22 21:47:58 +02:00
// proxy method used by the web UI. Dont't delete!
2016-09-18 21:16:25 +02:00
int RequestDirDetails ( const RsPeerId & uid , const std : : string & path , DirDetails & details ) const ;
2016-07-30 21:52:42 +02:00
// set/update shared directories
2016-07-31 15:59:58 +02:00
2016-07-30 21:52:42 +02:00
void setSharedDirectories ( const std : : list < SharedDirInfo > & dirs ) ;
void getSharedDirectories ( std : : list < SharedDirInfo > & dirs ) ;
void updateShareFlags ( const SharedDirInfo & info ) ;
bool convertSharedFilePath ( const std : : string & path , std : : string & fullpath ) ;
2017-09-10 19:58:57 +02:00
void setIgnoreLists ( const std : : list < std : : string > & ignored_prefixes , const std : : list < std : : string > & ignored_suffixes , uint32_t ignore_flags ) ;
bool getIgnoreLists ( std : : list < std : : string > & ignored_prefixes , std : : list < std : : string > & ignored_suffixes , uint32_t & ignore_flags ) ;
2017-09-24 17:53:06 +02:00
void setIgnoreDuplicates ( bool i ) ;
bool ignoreDuplicates ( ) const ;
void setMaxShareDepth ( int i ) ;
int maxShareDepth ( ) const ;
2018-08-16 18:49:36 +02:00
bool banFile ( const RsFileHash & real_file_hash , const std : : string & filename , uint64_t file_size ) ;
bool unbanFile ( const RsFileHash & real_file_hash ) ;
2018-08-22 21:57:56 +02:00
bool isFileBanned ( const RsFileHash & hash ) ;
2018-08-16 18:49:36 +02:00
bool getPrimaryBannedFilesList ( std : : map < RsFileHash , BannedFileEntry > & banned_files ) ;
2018-08-19 15:52:35 +02:00
bool trustFriendNodesForBannedFiles ( ) const ;
void setTrustFriendNodesForBannedFiles ( bool b ) ;
2018-08-16 18:49:36 +02:00
2016-11-11 20:25:11 +01:00
// computes/gathers statistics about shared directories
int getSharedDirStatistics ( const RsPeerId & pid , SharedDirStats & stats ) ;
2016-07-30 21:52:42 +02:00
// interface for hash caching
void setWatchPeriod ( uint32_t seconds ) ;
uint32_t watchPeriod ( ) ;
2016-09-18 18:34:39 +02:00
void setWatchEnabled ( bool b ) ;
bool watchEnabled ( ) ;
2016-07-30 21:52:42 +02:00
2016-11-24 23:42:56 +01:00
bool followSymLinks ( ) const ;
void setFollowSymLinks ( bool b ) ;
2016-07-30 21:52:42 +02:00
// interfact for directory parsing
2016-07-18 21:33:54 -04:00
2020-01-29 22:04:29 +01:00
void forceDirectoryCheck ( bool add_safe_delay ) ; // Force re-sweep the directories and see what's changed
2016-07-18 21:33:54 -04:00
bool inDirectoryCheck ( ) ;
2017-09-10 22:07:36 +02:00
void togglePauseHashingProcess ( ) ;
bool hashingProcessPaused ( ) ;
2016-07-18 21:33:54 -04:00
2016-07-20 16:10:51 -04:00
protected :
2018-09-27 13:42:49 +02:00
void getExtraFilesDirDetails ( void * ref , DirectoryStorage : : EntryIndex e , DirDetails & d ) const ;
2016-07-31 15:59:58 +02:00
2018-01-23 22:18:02 +01:00
int filterResults ( const std : : list < void * > & firesults , std : : list < DirDetails > & results , FileSearchFlags flags , const RsPeerId & peer_id ) const ;
2016-07-31 15:59:58 +02:00
std : : string makeRemoteFileName ( const RsPeerId & pid ) const ;
2016-07-30 21:52:42 +02:00
// Derived from p3Config
//
2016-07-20 16:10:51 -04:00
virtual bool loadList ( std : : list < RsItem * > & items ) ;
2016-07-30 21:52:42 +02:00
virtual bool saveList ( bool & cleanup , std : : list < RsItem * > & ) ;
2016-08-27 16:38:15 +02:00
virtual RsSerialiser * setupSerialiser ( ) ;
2016-07-30 21:52:42 +02:00
2016-07-20 16:10:51 -04:00
void cleanup ( ) ;
void tickRecv ( ) ;
void tickSend ( ) ;
2018-08-19 21:11:17 +02:00
void checkSendBannedFilesInfo ( ) ;
2016-07-20 16:10:51 -04:00
private :
2016-07-30 21:52:42 +02:00
p3ServiceControl * mServCtrl ;
2016-08-20 16:23:11 +02:00
RsPeerId mOwnId ;
typedef uint64_t DirSyncRequestId ;
2016-09-11 17:52:12 +02:00
static DirSyncRequestId makeDirSyncReqId ( const RsPeerId & peer_id , const RsFileHash & hash ) ;
2016-09-15 23:51:46 +02:00
// utility functions to send items with some maximum size.
void splitAndSendItem ( RsFileListsSyncResponseItem * ritem ) ;
RsFileListsSyncResponseItem * recvAndRebuildItem ( RsFileListsSyncResponseItem * ritem ) ;
2016-09-11 17:52:12 +02:00
/*!
* \ brief generateAndSendSyncRequest
* \ param rds Remote directory storage for the request
* \ param e Entry index to update
* \ return true if the request is correctly sent .
*/
2016-09-22 21:47:58 +02:00
bool locked_generateAndSendSyncRequest ( RemoteDirectoryStorage * rds , const DirectoryStorage : : EntryIndex & e ) ;
2016-07-18 21:33:54 -04:00
// File sync request queues. The fast one is used for online browsing when friends are connected.
// The slow one is used for background update of file lists.
//
2016-08-20 16:23:11 +02:00
std : : map < DirSyncRequestId , RsFileListSyncRequest > mFastRequestQueue ;
std : : map < DirSyncRequestId , RsFileListSyncRequest > mSlowRequestQueue ;
2016-07-18 21:33:54 -04:00
// Directory storage hierarchies
//
2016-08-05 22:00:25 +02:00
// The remote one is the reference for the PeerId index below:
// RemoteDirectories[ getFriendIndex(pid) - 1] = RemoteDirectoryStorage(pid)
2016-08-20 16:23:11 +02:00
std : : vector < RemoteDirectoryStorage * > mRemoteDirectories ;
2016-07-30 21:52:42 +02:00
LocalDirectoryStorage * mLocalSharedDirs ;
LocalDirectoryUpdater * mLocalDirWatcher ;
2018-09-27 13:42:49 +02:00
ftExtraList * mExtraFiles ;
2016-04-14 18:25:12 -04:00
2016-08-05 22:00:25 +02:00
// utility functions to make/get a pointer out of an (EntryIndex,PeerId) pair. This is further documented in the .cc
2017-09-20 22:57:32 +02:00
template < int BYTES > static bool convertEntryIndexToPointer ( const EntryIndex & e , uint32_t friend_index , void * & p ) ;
template < int BYTES > static bool convertPointerToEntryIndex ( const void * p , EntryIndex & e , uint32_t & friend_index ) ;
2016-08-17 14:48:54 +02:00
uint32_t locked_getFriendIndex ( const RsPeerId & pid ) ;
2016-08-05 22:00:25 +02:00
2016-08-23 21:23:58 +02:00
void handleDirSyncRequest ( RsFileListsSyncRequestItem * ) ;
2017-03-09 22:05:06 +01:00
void handleDirSyncResponse ( RsFileListsSyncResponseItem * & ) ;
2016-08-20 16:23:11 +02:00
2016-08-05 22:00:25 +02:00
std : : map < RsPeerId , uint32_t > mFriendIndexMap ;
std : : vector < RsPeerId > mFriendIndexTab ;
2016-08-22 07:49:45 +02:00
// Directory synchronization
//
struct DirSyncRequestData
{
2016-08-27 16:38:15 +02:00
RsPeerId peer_id ;
2018-10-07 01:34:05 +02:00
rstime_t request_TS ;
2016-08-22 07:49:45 +02:00
uint32_t flags ;
} ;
2018-10-07 01:34:05 +02:00
rstime_t mLastRemoteDirSweepTS ; // TS for friend list update
2016-08-22 07:49:45 +02:00
std : : map < DirSyncRequestId , DirSyncRequestData > mPendingSyncRequests ; // pending requests, waiting for an answer
2016-09-15 23:51:46 +02:00
std : : map < DirSyncRequestId , RsFileListsSyncResponseItem * > mPartialResponseItems ;
2016-08-20 16:23:11 +02:00
2016-09-11 17:52:12 +02:00
void locked_recursSweepRemoteDirectory ( RemoteDirectoryStorage * rds , DirectoryStorage : : EntryIndex e , int depth ) ;
2016-08-20 16:23:11 +02:00
2016-08-05 22:00:25 +02:00
// We use a shared file cache as well, to avoid re-hashing files with known modification TS and equal name.
2016-07-18 21:33:54 -04:00
//
2016-07-30 21:52:42 +02:00
HashStorage * mHashCache ;
2016-04-14 18:25:12 -04:00
2016-07-20 16:10:51 -04:00
// Local flags and mutexes
2016-08-17 14:48:54 +02:00
mutable RsMutex mFLSMtx ;
2016-07-20 16:10:51 -04:00
uint32_t mUpdateFlags ;
2016-09-02 21:49:43 +02:00
std : : string mFileSharingDir ;
2018-10-07 01:34:05 +02:00
rstime_t mLastCleanupTime ;
rstime_t mLastDataRecvTS ;
2018-08-16 18:49:36 +02:00
2018-08-21 11:20:02 +02:00
// File filtering. Not explicitly related to shared files, but has its place here
2018-08-16 18:49:36 +02:00
//
std : : map < RsFileHash , BannedFileEntry > mPrimaryBanList ; // primary list (user controlled) of files banned from FT search and forwarding. map<real hash, BannedFileEntry>
2018-08-19 21:11:17 +02:00
std : : map < RsPeerId , PeerBannedFilesEntry > mPeerBannedFiles ; // records of which files other peers ban, stored as H(H(f))
2018-08-16 18:49:36 +02:00
std : : set < RsFileHash > mBannedFileList ; // list of banned hashes. This include original hashs and H(H(f)) when coming from friends.
2018-09-27 13:42:49 +02:00
mutable std : : vector < FileInfo > mExtraFilesCache ; // cache for extra files, to avoid requesting them too often.
2018-10-07 01:34:05 +02:00
mutable rstime_t mLastExtraFilesCacheUpdate ;
2018-08-19 15:52:35 +02:00
bool mTrustFriendNodesForBannedFiles ;
2018-08-25 20:52:06 +02:00
bool mBannedFileListNeedsUpdate ;
2018-10-07 01:34:05 +02:00
rstime_t mLastPrimaryBanListChangeTimeStamp ;
2018-08-19 21:11:17 +02:00
void locked_sendBanInfo ( const RsPeerId & pid ) ;
2018-08-20 23:30:05 +02:00
void handleBannedFilesInfo ( RsFileListsBannedHashesItem * item ) ;
2016-04-14 18:25:12 -04:00
} ;