1 /*************************************************************************** 2 cdownloadmanager.h - description 3 ------------------- 4 begin : Don Mai 16 2002 5 copyright : (C) 2002-2004 by Mathias Küster 6 email : mathen@users.berlios.de 7 ***************************************************************************/ 8 9 /*************************************************************************** 10 * * 11 * This program is free software; you can redistribute it and/or modify * 12 * it under the terms of the GNU General Public License as published by * 13 * the Free Software Foundation; either version 2 of the License, or * 14 * (at your option) any later version. * 15 * * 16 ***************************************************************************/ 17 18 #ifndef CDOWNLOADMANAGER_H 19 #define CDOWNLOADMANAGER_H 20 21 /** 22 *@author Mathias Küster 23 * 24 * This handles the queue of files and sources, the list of running 25 * transfers, and starting auto searches. 26 * 27 * The download manager is lacking multi threading, also segment size 28 * is fixed, and the number of download slots is not normally limited. 29 * 30 * Upload bandwith limiting is present, although not present in 31 * mainline DC++ at the time of writing this. 32 * 33 * Calculating the MD5 checksum of the first 10KiB is mostly 34 * useless and completely obsolete, but basically very little 35 * was ever done to dclib's downloading ability between 0.3.7 and 0.3.22. 36 */ 37 38 #include <dclib/dcos.h> 39 #include <dclib/core/cmutex.h> 40 #include <dclib/core/csingleton.h> 41 #include <dclib/ctransfer.h> 42 43 /* 44 * eCloseType has moved to here so 45 * that cconfig.h does not need to include cdownloadmanager.h 46 */ 47 #include <dclib/core/types.h> 48 49 #include <dclib/core/cstringlist.h> 50 51 #define MAX_FILE_PRIORITY 5 52 53 enum eShutdownState { 54 essNONE, 55 essSHUTDOWN, 56 essSHUTDOWNREADY 57 }; 58 59 class CUserFileInfo { 60 public: 61 /** */ CUserFileInfo()62 CUserFileInfo() 63 { 64 bMulti = false; 65 }; 66 /** */ ~CUserFileInfo()67 ~CUserFileInfo() {}; 68 /** */ 69 eTransferWaitState eWaitState; 70 /** */ 71 eTransferFileState eFileState; 72 /** */ 73 CString sLocalFile; 74 /** */ 75 bool bMulti; 76 }; 77 78 class CExtraUserSlot { 79 public: 80 /** */ CExtraUserSlot()81 CExtraUserSlot() 82 { 83 iSlots = 1; 84 bPermanent = false; 85 }; 86 /** */ ~CExtraUserSlot()87 ~CExtraUserSlot() {}; 88 /** */ 89 CString sNick; 90 /** */ 91 CString sHubName; 92 /** */ 93 int iSlots; 94 /** */ 95 bool bPermanent; 96 }; 97 98 class DCTransferBanObject { 99 public: 100 /** */ DCTransferBanObject()101 DCTransferBanObject() { 102 m_nRequestCount = 0; 103 m_tTime = 0; 104 }; 105 /** */ ~DCTransferBanObject()106 ~DCTransferBanObject() {}; 107 /** */ 108 CString m_sIP; 109 /** */ 110 unsigned int m_nRequestCount; 111 /** */ 112 time_t m_tTime; 113 }; 114 115 class CDownloadManagerInfo : public CDCMessage { 116 public: 117 /** */ CDownloadManagerInfo()118 CDownloadManagerInfo() : CDCMessage(DC_MESSAGE_DM_INFO) { 119 rate_ul_settings = 0; 120 rate_ul_operator = 0; 121 rate_ul_user = 0; 122 rate_ul_special = 0; 123 rate_ul_rate_extra = 0; 124 rate_dl = 0; 125 slot_max = 0; 126 slot_use_settings = 0; 127 slot_use_operator = 0; 128 slot_use_user = 0; 129 slot_use_special = 0; 130 slot_use_rate_extra = 0; 131 }; 132 /** */ ~CDownloadManagerInfo()133 virtual ~CDownloadManagerInfo() {}; 134 /** */ Rate()135 ulonglong Rate() { 136 return rate_ul_settings + rate_ul_operator + rate_ul_user + rate_ul_special + rate_ul_rate_extra; 137 } 138 /** */ 139 ulonglong rate_ul_settings; 140 /** */ 141 ulonglong rate_ul_operator; 142 /** */ 143 ulonglong rate_ul_user; 144 /** */ 145 ulonglong rate_ul_special; 146 /** */ 147 ulonglong rate_ul_rate_extra; 148 /** */ 149 ulonglong rate_dl; 150 /** */ 151 int slot_max; 152 /** the number of normal slots from main config settings used */ 153 int slot_use_settings; 154 /** slot usage for operators (after all other slots used up) */ 155 int slot_use_operator; 156 /** slot usage for users (extra normal slots granted to users, only used if normal slots used up) */ 157 int slot_use_user; 158 /** slot usage for special transfers e.g. minimum filelength (after all normal used up) */ 159 int slot_use_special; 160 /** the number of extra slots that have been given because total upload rate is below a limit */ 161 int slot_use_rate_extra; 162 163 CDownloadManagerInfo & operator = (const CDownloadManagerInfo & s) 164 { 165 rate_ul_settings = s.rate_ul_settings; 166 rate_ul_operator = s.rate_ul_operator; 167 rate_ul_user = s.rate_ul_user; 168 rate_ul_special = s.rate_ul_special; 169 rate_ul_rate_extra = s.rate_ul_rate_extra; 170 171 rate_dl = s.rate_dl; 172 slot_max = s.slot_max; 173 174 slot_use_settings = s.slot_use_settings; 175 slot_use_operator = s.slot_use_operator; 176 slot_use_user = s.slot_use_user; 177 slot_use_special = s.slot_use_special; 178 slot_use_rate_extra = s.slot_use_rate_extra; 179 180 return *this; 181 }; 182 }; 183 184 enum eFileManagerStatus { 185 efmsNONE=0, 186 efmsIDLE, 187 efmsCREATESHARELIST, 188 efmsCREATESEARCHINDEX, 189 efmsCREATEHASHLIST, 190 efmsREBUILDLISTS, 191 efmsVALIDATELEAVES 192 }; 193 194 class CFileManagerInfo : public CDCMessage { 195 public: 196 /** */ CFileManagerInfo()197 CFileManagerInfo() : CDCMessage(DC_MESSAGE_FM_INFO) { 198 m_eFileManagerStatus = efmsNONE; 199 m_nProgress = 0; 200 }; 201 /** */ ~CFileManagerInfo()202 virtual ~CFileManagerInfo() {}; 203 /** */ 204 enum eFileManagerStatus m_eFileManagerStatus; 205 /** */ 206 double m_nProgress; 207 208 CFileManagerInfo & operator = (const CFileManagerInfo & s) 209 { 210 m_eFileManagerStatus = s.m_eFileManagerStatus; 211 m_nProgress = s.m_nProgress; 212 return *this; 213 }; 214 }; 215 216 class CDCMessage; 217 class CListen; 218 class CDownloadQueue; 219 class DCFileChunkObject; 220 class DCTransferQueueObject; 221 class DCTransferFileObject; 222 class DCTransferWait; 223 class _CCallback0; 224 225 class CTransferObject { 226 public: 227 /** */ CTransferObject()228 CTransferObject() { 229 m_pTransfer = 0; 230 m_UserDisconnectTimeout = time(0); 231 } 232 /** */ ~CTransferObject()233 ~CTransferObject() { 234 delete m_pTransfer; 235 m_pTransfer = 0; 236 } 237 238 /** */ 239 CTransfer * m_pTransfer; 240 /** */ 241 time_t m_UserDisconnectTimeout; 242 }; 243 244 class CDownloadManager : public CSingleton<CDownloadManager> { 245 public: 246 /** */ 247 CDownloadManager(); 248 /** */ 249 virtual ~CDownloadManager(); 250 251 /** load the queue */ 252 int DLM_LoadQueue(); 253 /** save the queue */ 254 int DLM_SaveQueue(); 255 /** disconnect all transfers for a clean shutdown */ 256 void DLM_Shutdown(); 257 /** return the current shutdownstate */ DLM_ShutdownState()258 eShutdownState DLM_ShutdownState() const { return m_eShutdownState; } 259 /** add a extra slot to the user */ 260 void DLM_AddUserSlot( CString nick, CString hubname, int slot, bool permanent = false ); 261 /** return current used upload slots */ DLM_UsedSlots()262 int DLM_UsedSlots() const { return DownloadManagerInfo.slot_use_settings; } 263 /** */ 264 bool DLM_TransferConnect( CString nick, CString hubname ); 265 /** */ 266 bool DLM_TransferClose( ulonglong transferid ); 267 /** */ 268 bool DLM_TransferSetRate( ulonglong transferid, ulonglong rate ); 269 /** */ 270 bool DLM_TransferGetRate( ulonglong transferid, ulonglong & rate ); 271 /** */ 272 CList<CMessageDMTransferObject> * DLM_TransferGetList(); 273 274 /** */ 275 eDirection DLM_TransferDirection( ulonglong transferid ); 276 277 /** 278 * For filelists, localpath is abused to set the file/folder to 279 * open the list at (when downloaded from search) and localrootpath 280 * is abused to download a directory. 281 */ 282 void DLM_QueueAdd( CString nick, CString hubname, CString hubhost, 283 CString remotename, CString localname, 284 CString localpath, CString localrootpath, 285 eltMedium medium, ulonglong size, 286 ulonglong startposition, 287 ulonglong endposition, 288 CString hash, 289 bool multi = false ); 290 /** */ 291 int DLM_QueueCheck( CString nick, CString hubname, CString hubhost, 292 CString remotename, CString localname, 293 CString localpath, CString localrootpath, 294 eltMedium medium, ulonglong size, CString tth ); 295 /** change the src-nick/hubname to dst-nick/hubname in the queue */ 296 bool DLM_QueueEdit( CString srcnick, CString srchubname, CString dstnick, CString dsthubname, CString dsthubhost ); 297 /** */ 298 bool DLM_QueuePause( CString nick, CString hubname, CString remotefile, bool pause ); 299 /** */ 300 bool DLM_QueueRemove( CString nick, CString hubname, CString remotefile ); 301 /** */ 302 bool DLM_QueueRemove( CString localfile ); 303 /** 304 * 0 = directory removed 305 * 1 = user/hub not found 306 * 2 = no directories queued 307 * 3 = that directory not queued 308 */ 309 int DLM_QueueRemoveDirectory( CString nick, CString hubname, CString directory ); 310 /** */ 311 bool DLM_QueueSetFilePriority( CString nick, CString hubname, CString remotefile, int priority ); 312 /** */ 313 bool DLM_QueueGetFileInfo( CString nick, CString hubname, CString hubhost, CString file, CUserFileInfo * UserFileInfo ); 314 /** */ 315 DCFileChunkObject * DLM_QueueGetFileChunk( CString file ); 316 /** */ 317 bool DLM_QueueUpdateHub( CString nick, CString hubname ); 318 /** */ 319 void DLM_QueueGetHub( CString nick, CString hubname, CList<DCHubObject> * list ); 320 321 /** */ 322 bool DLM_AddTransferRequest( CString nick, CString userhost, CString hubname, CString hubhost ); 323 /** */ 324 void DLM_AddTransferRequest( CString host, int port, bool crypto, CString hubname, CString hubhost ); 325 326 /** */ 327 bool DLM_GetDownloadManagerInfo( CDownloadManagerInfo * pinfo ); 328 /** handle search */ 329 bool DLM_HandleSearch( CMessageSearchResult * MessageSearchResult ); 330 331 /** callback function - Called by CManager */ 332 int Callback(); 333 /** callback function */ DC_DownloadManagerCallBack(CDCMessage *)334 virtual int DC_DownloadManagerCallBack( CDCMessage * ) { return -1; }; 335 336 /** 337 * It's not given to a CCallback it's just directly called by the 338 * listen managers so it can take whatever parameters are necessary. 339 */ 340 int ListenCallbackHandler( int fd, bool crypto ); 341 342 protected: 343 /** */ 344 int DM_TransferCallBack( CTransfer * Transfer, CDCMessage * DCMessage ); 345 346 /** */ 347 void SendFileManagerInfo( CFileManagerInfo * info ); 348 349 private: 350 /** */ 351 friend class CFileManager; 352 353 /** */ 354 void SendFileInfo( DCTransferQueueObject * TransferObject, DCTransferFileObject * TransferFileItem = 0, bool bRemoveFile = false ); 355 /** */ 356 void SendTransferInfo( CTransfer * Transfer, bool remove = false ); 357 /** */ 358 void SendSlotInfo( CExtraUserSlot * Object ); 359 /** */ 360 void SendLogInfo( CString message, CTransfer * Transfer = 0 ); 361 /** */ 362 void SendDownloadManagerInfo( CDownloadManagerInfo * dminfo ); 363 /** */ 364 void SendTrafficInfo(); 365 366 /** create a messagedmtransferobject from a transfer */ 367 CMessageDMTransferObject * CreateDMTransferObject( CTransfer * Transfer ); 368 /** */ 369 void FileListDone( CTransfer * Transfer, DCTransferFileObject * TransferFileObject ); 370 371 /** */ 372 bool CheckUserSlot( CString nick, CString hubname ); 373 /** */ 374 void OptimizeChunks( DCFileChunkObject * FileChunkObject ); 375 /** */ 376 bool GetNextChunk( CString file, ulonglong * lstart, ulonglong * lend ); 377 /** */ 378 int UpdateChunk( CString file, ulonglong lstart, ulonglong lend, ulonglong lcurrent ); 379 /** */ 380 bool GetNewChunkEnd( CString file, ulonglong lstart, ulonglong lend, ulonglong lcurrent, ulonglong * lnstart, ulonglong *lnend ); 381 382 /** */ 383 void UpdateQueueList( time_t ttimeout ); 384 /** */ 385 void UpdateTransferList( time_t ttimeout ); 386 /** */ 387 void UpdateBanList( time_t ttimeout ); 388 389 /** */ 390 eDirection CheckWaitTransfer( CTransfer * Transfer ); 391 /** */ 392 bool UpdateWaitTransfer( CTransfer * Transfer, bool rem = false ); 393 /** */ 394 bool ChangeDirection( CTransfer * Transfer ); 395 /** */ 396 bool SetNextFile( CTransfer * Transfer ); 397 /** */ 398 bool SetDirection( CTransfer * Transfer ); 399 /** */ 400 bool SetFile( CTransfer * Transfer ); 401 /** */ 402 void UpdateFileState( CTransfer * Transfer, eTransferFileState eState ); 403 /** */ 404 bool CheckHash( CTransfer * Transfer ); 405 406 /** */ 407 bool RemoveQueueFile( CString nick, CString hubname, CString remotefile ); 408 /** */ 409 bool RemoveQueueFile( CString localfile ); 410 411 /** */ 412 bool InitSearch( time_t ttimeout ); 413 414 /** */ 415 ulonglong GetNewID(); 416 417 /** */ 418 eShutdownState m_eShutdownState; 419 420 /** mutex for extra slots list */ 421 CMutex * m_pExtraSlotsMutex; 422 /** */ 423 CList<CExtraUserSlot> * m_pExtraUserSlotList; 424 425 /** */ 426 _CCallback0 * m_pCallback; 427 428 /** */ 429 CDownloadManagerInfo DownloadManagerInfo; 430 /** */ 431 CMutex TransferCallBackMutex; 432 /** */ 433 CMutex LogMutex; 434 /** */ 435 ulonglong m_nID; 436 437 /** */ 438 time_t m_tDownloadQueueTimeout; 439 /** */ 440 time_t m_tUpdateTransferTimeout; 441 /** timeout for a new hubsearch */ 442 time_t m_tHubSearchTimeout; 443 /** timeout for a single search */ 444 time_t m_tSearchTimeout; 445 /** 446 * The last time an additional upload slot was given because 447 * total upload rate was below a limit. This is needed so that 448 * these slots are only given max 1 per minute so that there 449 * is enough time for the new transfer to be included in 450 * the total upload rate. 451 */ 452 time_t m_tLastRateExtra; 453 /** 454 * The time old entries were removed from m_pTransferWaitList. 455 */ 456 time_t m_tWaitListCleaned; 457 458 /** */ 459 CDownloadQueue * m_pDownloadQueue; 460 /** mutex for transfers list */ 461 CMutex * m_pTransfersMutex; 462 /** */ 463 CStringList<CTransferObject> * m_pTransferList; 464 /** mutex for transfer wait list */ 465 CMutex * m_pWaitListMutex; 466 /** */ 467 CList<DCTransferWait> * m_pTransferWaitList; 468 /** mutex for transfer ban list */ 469 CMutex * m_pBanListMutex; 470 /** */ 471 CStringList<DCTransferBanObject> * m_pTransferBanList; 472 /** 473 * The search result list was never locked/unlocked. 474 */ 475 CList<CMessageSearchResult> * m_pSearchList; 476 /** */ 477 CList<CDCMessage> * m_pSearchQueryList; 478 }; 479 480 #endif 481