1 /*
2  * Bittorrent Client using Qt and libtorrent.
3  * Copyright (C) 2015  Vladimir Golovnev <glassez@yandex.ru>
4  * Copyright (C) 2006  Christophe Dumez <chris@qbittorrent.org>
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
19  *
20  * In addition, as a special exception, the copyright holders give permission to
21  * link this program with the OpenSSL project's "OpenSSL" library (or with
22  * modified versions of it that use the same license as the "OpenSSL" library),
23  * and distribute the linked executables. You must obey the GNU General Public
24  * License in all respects for all of the code used other than "OpenSSL".  If you
25  * modify file(s), you may extend this exception to your version of the file(s),
26  * but you are not obligated to do so. If you do not wish to do so, delete this
27  * exception statement from your version.
28  */
29 
30 #pragma once
31 
32 #include <memory>
33 #include <variant>
34 #include <vector>
35 
36 #include <libtorrent/add_torrent_params.hpp>
37 #include <libtorrent/fwd.hpp>
38 #include <libtorrent/torrent_handle.hpp>
39 #include <libtorrent/version.hpp>
40 
41 #include <QHash>
42 #include <QPointer>
43 #include <QSet>
44 #include <QtContainerFwd>
45 #include <QVector>
46 
47 #include "base/settingvalue.h"
48 #include "base/types.h"
49 #include "addtorrentparams.h"
50 #include "cachestatus.h"
51 #include "sessionstatus.h"
52 #include "torrentinfo.h"
53 
54 class QFile;
55 class QNetworkConfiguration;
56 class QNetworkConfigurationManager;
57 class QString;
58 class QThread;
59 class QTimer;
60 class QUrl;
61 
62 class BandwidthScheduler;
63 class FileSearcher;
64 class FilterParserThread;
65 class ResumeDataSavingManager;
66 class Statistics;
67 
68 // These values should remain unchanged when adding new items
69 // so as not to break the existing user settings.
70 enum MaxRatioAction
71 {
72     Pause = 0,
73     Remove = 1,
74     DeleteFiles = 3,
75     EnableSuperSeeding = 2
76 };
77 
78 enum DeleteOption
79 {
80     DeleteTorrent,
81     DeleteTorrentAndFiles
82 };
83 
84 enum TorrentExportFolder
85 {
86     Regular,
87     Finished
88 };
89 
90 namespace Net
91 {
92     struct DownloadResult;
93 }
94 
95 namespace BitTorrent
96 {
97     class InfoHash;
98     class MagnetUri;
99     class Torrent;
100     class TorrentImpl;
101     class Tracker;
102     struct LoadTorrentParams;
103     struct TrackerEntry;
104 
105     enum class MoveStorageMode;
106 
107     // Using `Q_ENUM_NS()` without a wrapper namespace in our case is not advised
108     // since `Q_NAMESPACE` cannot be used when the same namespace resides at different files.
109     // https://www.kdab.com/new-qt-5-8-meta-object-support-namespaces/#comment-143779
110     inline namespace SessionSettingsEnums
111     {
112         Q_NAMESPACE
113 
114         enum class BTProtocol : int
115         {
116             Both = 0,
117             TCP = 1,
118             UTP = 2
119         };
120         Q_ENUM_NS(BTProtocol)
121 
122         enum class ChokingAlgorithm : int
123         {
124             FixedSlots = 0,
125             RateBased = 1
126         };
127         Q_ENUM_NS(ChokingAlgorithm)
128 
129         enum class MixedModeAlgorithm : int
130         {
131             TCP = 0,
132             Proportional = 1
133         };
134         Q_ENUM_NS(MixedModeAlgorithm)
135 
136         enum class SeedChokingAlgorithm : int
137         {
138             RoundRobin = 0,
139             FastestUpload = 1,
140             AntiLeech = 2
141         };
142         Q_ENUM_NS(SeedChokingAlgorithm)
143 
144 #if defined(Q_OS_WIN)
145         enum class OSMemoryPriority : int
146         {
147             Normal = 0,
148             BelowNormal = 1,
149             Medium = 2,
150             Low = 3,
151             VeryLow = 4
152         };
153         Q_ENUM_NS(OSMemoryPriority)
154 #endif
155     }
156 
157     struct SessionMetricIndices
158     {
159         struct
160         {
161             int hasIncomingConnections = -1;
162             int sentPayloadBytes = -1;
163             int recvPayloadBytes = -1;
164             int sentBytes = -1;
165             int recvBytes = -1;
166             int sentIPOverheadBytes = -1;
167             int recvIPOverheadBytes = -1;
168             int sentTrackerBytes = -1;
169             int recvTrackerBytes = -1;
170             int recvRedundantBytes = -1;
171             int recvFailedBytes = -1;
172         } net;
173 
174         struct
175         {
176             int numPeersConnected = -1;
177             int numPeersUpDisk = -1;
178             int numPeersDownDisk = -1;
179         } peer;
180 
181         struct
182         {
183             int dhtBytesIn = -1;
184             int dhtBytesOut = -1;
185             int dhtNodes = -1;
186         } dht;
187 
188         struct
189         {
190             int diskBlocksInUse = -1;
191             int numBlocksRead = -1;
192 #if (LIBTORRENT_VERSION_NUM < 20000)
193             int numBlocksCacheHits = -1;
194 #endif
195             int writeJobs = -1;
196             int readJobs = -1;
197             int hashJobs = -1;
198             int queuedDiskJobs = -1;
199             int diskJobTime = -1;
200         } disk;
201     };
202 
203     class Session : public QObject
204     {
205         Q_OBJECT
206         Q_DISABLE_COPY(Session)
207 
208     public:
209         static void initInstance();
210         static void freeInstance();
211         static Session *instance();
212 
213         QString defaultSavePath() const;
214         void setDefaultSavePath(QString path);
215         QString tempPath() const;
216         void setTempPath(QString path);
217         bool isTempPathEnabled() const;
218         void setTempPathEnabled(bool enabled);
219         QString torrentTempPath(const TorrentInfo &torrentInfo) const;
220 
221         static bool isValidCategoryName(const QString &name);
222         // returns category itself and all top level categories
223         static QStringList expandCategory(const QString &category);
224 
225         QStringMap categories() const;
226         QString categorySavePath(const QString &categoryName) const;
227         bool addCategory(const QString &name, const QString &savePath = "");
228         bool editCategory(const QString &name, const QString &savePath);
229         bool removeCategory(const QString &name);
230         bool isSubcategoriesEnabled() const;
231         void setSubcategoriesEnabled(bool value);
232 
233         static bool isValidTag(const QString &tag);
234         QSet<QString> tags() const;
235         bool hasTag(const QString &tag) const;
236         bool addTag(const QString &tag);
237         bool removeTag(const QString &tag);
238 
239         // Torrent Management Mode subsystem (TMM)
240         //
241         // Each torrent can be either in Manual mode or in Automatic mode
242         // In Manual Mode various torrent properties are set explicitly(eg save path)
243         // In Automatic Mode various torrent properties are set implicitly(eg save path)
244         //     based on the associated category.
245         // In Automatic Mode torrent save path can be changed in following cases:
246         //     1. Default save path changed
247         //     2. Torrent category save path changed
248         //     3. Torrent category changed
249         //     (unless otherwise is specified)
250         bool isAutoTMMDisabledByDefault() const;
251         void setAutoTMMDisabledByDefault(bool value);
252         bool isDisableAutoTMMWhenCategoryChanged() const;
253         void setDisableAutoTMMWhenCategoryChanged(bool value);
254         bool isDisableAutoTMMWhenDefaultSavePathChanged() const;
255         void setDisableAutoTMMWhenDefaultSavePathChanged(bool value);
256         bool isDisableAutoTMMWhenCategorySavePathChanged() const;
257         void setDisableAutoTMMWhenCategorySavePathChanged(bool value);
258 
259         qreal globalMaxRatio() const;
260         void setGlobalMaxRatio(qreal ratio);
261         int globalMaxSeedingMinutes() const;
262         void setGlobalMaxSeedingMinutes(int minutes);
263         bool isDHTEnabled() const;
264         void setDHTEnabled(bool enabled);
265         bool isLSDEnabled() const;
266         void setLSDEnabled(bool enabled);
267         bool isPeXEnabled() const;
268         void setPeXEnabled(bool enabled);
269         bool isAddTorrentPaused() const;
270         void setAddTorrentPaused(bool value);
271         TorrentContentLayout torrentContentLayout() const;
272         void setTorrentContentLayout(TorrentContentLayout value);
273         bool isTrackerEnabled() const;
274         void setTrackerEnabled(bool enabled);
275         bool isAppendExtensionEnabled() const;
276         void setAppendExtensionEnabled(bool enabled);
277         int refreshInterval() const;
278         void setRefreshInterval(int value);
279         bool isPreallocationEnabled() const;
280         void setPreallocationEnabled(bool enabled);
281         QString torrentExportDirectory() const;
282         void setTorrentExportDirectory(QString path);
283         QString finishedTorrentExportDirectory() const;
284         void setFinishedTorrentExportDirectory(QString path);
285 
286         int globalDownloadSpeedLimit() const;
287         void setGlobalDownloadSpeedLimit(int limit);
288         int globalUploadSpeedLimit() const;
289         void setGlobalUploadSpeedLimit(int limit);
290         int altGlobalDownloadSpeedLimit() const;
291         void setAltGlobalDownloadSpeedLimit(int limit);
292         int altGlobalUploadSpeedLimit() const;
293         void setAltGlobalUploadSpeedLimit(int limit);
294         int downloadSpeedLimit() const;
295         void setDownloadSpeedLimit(int limit);
296         int uploadSpeedLimit() const;
297         void setUploadSpeedLimit(int limit);
298         bool isAltGlobalSpeedLimitEnabled() const;
299         void setAltGlobalSpeedLimitEnabled(bool enabled);
300         bool isBandwidthSchedulerEnabled() const;
301         void setBandwidthSchedulerEnabled(bool enabled);
302 
303         int saveResumeDataInterval() const;
304         void setSaveResumeDataInterval(int value);
305         int port() const;
306         void setPort(int port);
307         bool useRandomPort() const;
308         void setUseRandomPort(bool value);
309         QString networkInterface() const;
310         void setNetworkInterface(const QString &iface);
311         QString networkInterfaceName() const;
312         void setNetworkInterfaceName(const QString &name);
313         QString networkInterfaceAddress() const;
314         void setNetworkInterfaceAddress(const QString &address);
315         int encryption() const;
316         void setEncryption(int state);
317         bool isProxyPeerConnectionsEnabled() const;
318         void setProxyPeerConnectionsEnabled(bool enabled);
319         ChokingAlgorithm chokingAlgorithm() const;
320         void setChokingAlgorithm(ChokingAlgorithm mode);
321         SeedChokingAlgorithm seedChokingAlgorithm() const;
322         void setSeedChokingAlgorithm(SeedChokingAlgorithm mode);
323         bool isAddTrackersEnabled() const;
324         void setAddTrackersEnabled(bool enabled);
325         QString additionalTrackers() const;
326         void setAdditionalTrackers(const QString &trackers);
327         bool isIPFilteringEnabled() const;
328         void setIPFilteringEnabled(bool enabled);
329         QString IPFilterFile() const;
330         void setIPFilterFile(QString path);
331         bool announceToAllTrackers() const;
332         void setAnnounceToAllTrackers(bool val);
333         bool announceToAllTiers() const;
334         void setAnnounceToAllTiers(bool val);
335         int peerTurnover() const;
336         void setPeerTurnover(int num);
337         int peerTurnoverCutoff() const;
338         void setPeerTurnoverCutoff(int num);
339         int peerTurnoverInterval() const;
340         void setPeerTurnoverInterval(int num);
341         int asyncIOThreads() const;
342         void setAsyncIOThreads(int num);
343         int hashingThreads() const;
344         void setHashingThreads(int num);
345         int filePoolSize() const;
346         void setFilePoolSize(int size);
347         int checkingMemUsage() const;
348         void setCheckingMemUsage(int size);
349         int diskCacheSize() const;
350         void setDiskCacheSize(int size);
351         int diskCacheTTL() const;
352         void setDiskCacheTTL(int ttl);
353         bool useOSCache() const;
354         void setUseOSCache(bool use);
355         bool isCoalesceReadWriteEnabled() const;
356         void setCoalesceReadWriteEnabled(bool enabled);
357         bool usePieceExtentAffinity() const;
358         void setPieceExtentAffinity(bool enabled);
359         bool isSuggestModeEnabled() const;
360         void setSuggestMode(bool mode);
361         int sendBufferWatermark() const;
362         void setSendBufferWatermark(int value);
363         int sendBufferLowWatermark() const;
364         void setSendBufferLowWatermark(int value);
365         int sendBufferWatermarkFactor() const;
366         void setSendBufferWatermarkFactor(int value);
367         int socketBacklogSize() const;
368         void setSocketBacklogSize(int value);
369         bool isAnonymousModeEnabled() const;
370         void setAnonymousModeEnabled(bool enabled);
371         bool isQueueingSystemEnabled() const;
372         void setQueueingSystemEnabled(bool enabled);
373         bool ignoreSlowTorrentsForQueueing() const;
374         void setIgnoreSlowTorrentsForQueueing(bool ignore);
375         int downloadRateForSlowTorrents() const;
376         void setDownloadRateForSlowTorrents(int rateInKibiBytes);
377         int uploadRateForSlowTorrents() const;
378         void setUploadRateForSlowTorrents(int rateInKibiBytes);
379         int slowTorrentsInactivityTimer() const;
380         void setSlowTorrentsInactivityTimer(int timeInSeconds);
381         int outgoingPortsMin() const;
382         void setOutgoingPortsMin(int min);
383         int outgoingPortsMax() const;
384         void setOutgoingPortsMax(int max);
385         int UPnPLeaseDuration() const;
386         void setUPnPLeaseDuration(int duration);
387         int peerToS() const;
388         void setPeerToS(int value);
389         bool ignoreLimitsOnLAN() const;
390         void setIgnoreLimitsOnLAN(bool ignore);
391         bool includeOverheadInLimits() const;
392         void setIncludeOverheadInLimits(bool include);
393         QString announceIP() const;
394         void setAnnounceIP(const QString &ip);
395         int maxConcurrentHTTPAnnounces() const;
396         void setMaxConcurrentHTTPAnnounces(int value);
397         int stopTrackerTimeout() const;
398         void setStopTrackerTimeout(int value);
399         int maxConnections() const;
400         void setMaxConnections(int max);
401         int maxConnectionsPerTorrent() const;
402         void setMaxConnectionsPerTorrent(int max);
403         int maxUploads() const;
404         void setMaxUploads(int max);
405         int maxUploadsPerTorrent() const;
406         void setMaxUploadsPerTorrent(int max);
407         int maxActiveDownloads() const;
408         void setMaxActiveDownloads(int max);
409         int maxActiveUploads() const;
410         void setMaxActiveUploads(int max);
411         int maxActiveTorrents() const;
412         void setMaxActiveTorrents(int max);
413         BTProtocol btProtocol() const;
414         void setBTProtocol(BTProtocol protocol);
415         bool isUTPRateLimited() const;
416         void setUTPRateLimited(bool limited);
417         MixedModeAlgorithm utpMixedMode() const;
418         void setUtpMixedMode(MixedModeAlgorithm mode);
419         bool isIDNSupportEnabled() const;
420         void setIDNSupportEnabled(bool enabled);
421         bool multiConnectionsPerIpEnabled() const;
422         void setMultiConnectionsPerIpEnabled(bool enabled);
423         bool validateHTTPSTrackerCertificate() const;
424         void setValidateHTTPSTrackerCertificate(bool enabled);
425         bool isSSRFMitigationEnabled() const;
426         void setSSRFMitigationEnabled(bool enabled);
427         bool blockPeersOnPrivilegedPorts() const;
428         void setBlockPeersOnPrivilegedPorts(bool enabled);
429         bool isTrackerFilteringEnabled() const;
430         void setTrackerFilteringEnabled(bool enabled);
431         QStringList bannedIPs() const;
432         void setBannedIPs(const QStringList &newList);
433 #if defined(Q_OS_WIN)
434         OSMemoryPriority getOSMemoryPriority() const;
435         void setOSMemoryPriority(OSMemoryPriority priority);
436 #endif
437 
438         void startUpTorrents();
439         Torrent *findTorrent(const TorrentID &id) const;
440         QVector<Torrent *> torrents() const;
441         bool hasActiveTorrents() const;
442         bool hasUnfinishedTorrents() const;
443         bool hasRunningSeed() const;
444         const SessionStatus &status() const;
445         const CacheStatus &cacheStatus() const;
446         quint64 getAlltimeDL() const;
447         quint64 getAlltimeUL() const;
448         bool isListening() const;
449 
450         MaxRatioAction maxRatioAction() const;
451         void setMaxRatioAction(MaxRatioAction act);
452 
453         void banIP(const QString &ip);
454 
455         bool isKnownTorrent(const TorrentID &id) const;
456         bool addTorrent(const QString &source, const AddTorrentParams &params = AddTorrentParams());
457         bool addTorrent(const MagnetUri &magnetUri, const AddTorrentParams &params = AddTorrentParams());
458         bool addTorrent(const TorrentInfo &torrentInfo, const AddTorrentParams &params = AddTorrentParams());
459         bool deleteTorrent(const TorrentID &id, DeleteOption deleteOption = DeleteTorrent);
460         bool downloadMetadata(const MagnetUri &magnetUri);
461         bool cancelDownloadMetadata(const TorrentID &id);
462 
463         void recursiveTorrentDownload(const TorrentID &id);
464         void increaseTorrentsQueuePos(const QVector<TorrentID> &ids);
465         void decreaseTorrentsQueuePos(const QVector<TorrentID> &ids);
466         void topTorrentsQueuePos(const QVector<TorrentID> &ids);
467         void bottomTorrentsQueuePos(const QVector<TorrentID> &ids);
468 
469         // Torrent interface
470         void handleTorrentNeedSaveResumeData(const TorrentImpl *torrent);
471         void handleTorrentSaveResumeDataRequested(const TorrentImpl *torrent);
472         void handleTorrentShareLimitChanged(TorrentImpl *const torrent);
473         void handleTorrentNameChanged(TorrentImpl *const torrent);
474         void handleTorrentSavePathChanged(TorrentImpl *const torrent);
475         void handleTorrentCategoryChanged(TorrentImpl *const torrent, const QString &oldCategory);
476         void handleTorrentTagAdded(TorrentImpl *const torrent, const QString &tag);
477         void handleTorrentTagRemoved(TorrentImpl *const torrent, const QString &tag);
478         void handleTorrentSavingModeChanged(TorrentImpl *const torrent);
479         void handleTorrentMetadataReceived(TorrentImpl *const torrent);
480         void handleTorrentPaused(TorrentImpl *const torrent);
481         void handleTorrentResumed(TorrentImpl *const torrent);
482         void handleTorrentChecked(TorrentImpl *const torrent);
483         void handleTorrentFinished(TorrentImpl *const torrent);
484         void handleTorrentTrackersAdded(TorrentImpl *const torrent, const QVector<TrackerEntry> &newTrackers);
485         void handleTorrentTrackersRemoved(TorrentImpl *const torrent, const QVector<TrackerEntry> &deletedTrackers);
486         void handleTorrentTrackersChanged(TorrentImpl *const torrent);
487         void handleTorrentUrlSeedsAdded(TorrentImpl *const torrent, const QVector<QUrl> &newUrlSeeds);
488         void handleTorrentUrlSeedsRemoved(TorrentImpl *const torrent, const QVector<QUrl> &urlSeeds);
489         void handleTorrentResumeDataReady(TorrentImpl *const torrent, const LoadTorrentParams &data);
490         void handleTorrentTrackerReply(TorrentImpl *const torrent, const QString &trackerUrl);
491         void handleTorrentTrackerWarning(TorrentImpl *const torrent, const QString &trackerUrl);
492         void handleTorrentTrackerError(TorrentImpl *const torrent, const QString &trackerUrl);
493 
494         bool addMoveTorrentStorageJob(TorrentImpl *torrent, const QString &newPath, MoveStorageMode mode);
495 
496         void findIncompleteFiles(const TorrentInfo &torrentInfo, const QString &savePath) const;
497 
498     signals:
499         void allTorrentsFinished();
500         void categoryAdded(const QString &categoryName);
501         void categoryRemoved(const QString &categoryName);
502         void downloadFromUrlFailed(const QString &url, const QString &reason);
503         void downloadFromUrlFinished(const QString &url);
504         void fullDiskError(Torrent *torrent, const QString &msg);
505         void IPFilterParsed(bool error, int ruleCount);
506         void loadTorrentFailed(const QString &error);
507         void metadataDownloaded(const TorrentInfo &info);
508         void recursiveTorrentDownloadPossible(Torrent *torrent);
509         void speedLimitModeChanged(bool alternative);
510         void statsUpdated();
511         void subcategoriesSupportChanged();
512         void tagAdded(const QString &tag);
513         void tagRemoved(const QString &tag);
514         void torrentAboutToBeRemoved(Torrent *torrent);
515         void torrentAdded(Torrent *torrent);
516         void torrentCategoryChanged(Torrent *torrent, const QString &oldCategory);
517         void torrentFinished(Torrent *torrent);
518         void torrentFinishedChecking(Torrent *torrent);
519         void torrentLoaded(Torrent *torrent);
520         void torrentMetadataReceived(Torrent *torrent);
521         void torrentPaused(Torrent *torrent);
522         void torrentResumed(Torrent *torrent);
523         void torrentSavePathChanged(Torrent *torrent);
524         void torrentSavingModeChanged(Torrent *torrent);
525         void torrentsUpdated(const QVector<Torrent *> &torrents);
526         void torrentTagAdded(Torrent *torrent, const QString &tag);
527         void torrentTagRemoved(Torrent *torrent, const QString &tag);
528         void trackerError(Torrent *torrent, const QString &tracker);
529         void trackerlessStateChanged(Torrent *torrent, bool trackerless);
530         void trackersAdded(Torrent *torrent, const QVector<TrackerEntry> &trackers);
531         void trackersChanged(Torrent *torrent);
532         void trackersRemoved(Torrent *torrent, const QVector<TrackerEntry> &trackers);
533         void trackerSuccess(Torrent *torrent, const QString &tracker);
534         void trackerWarning(Torrent *torrent, const QString &tracker);
535 
536     private slots:
537         void configureDeferred();
538         void readAlerts();
539         void enqueueRefresh();
540         void processShareLimits();
541         void generateResumeData();
542         void handleIPFilterParsed(int ruleCount);
543         void handleIPFilterError();
544         void handleDownloadFinished(const Net::DownloadResult &result);
545         void fileSearchFinished(const TorrentID &id, const QString &savePath, const QStringList &fileNames);
546 
547         // Session reconfiguration triggers
548         void networkOnlineStateChanged(bool online);
549         void networkConfigurationChange(const QNetworkConfiguration &);
550 
551     private:
552         struct MoveStorageJob
553         {
554             lt::torrent_handle torrentHandle;
555             QString path;
556             MoveStorageMode mode;
557         };
558 
559         struct RemovingTorrentData
560         {
561             QString name;
562             QString pathToRemove;
563             DeleteOption deleteOption;
564         };
565 
566         explicit Session(QObject *parent = nullptr);
567         ~Session();
568 
569         bool hasPerTorrentRatioLimit() const;
570         bool hasPerTorrentSeedingTimeLimit() const;
571 
572         void initResumeFolder();
573 
574         // Session configuration
575         Q_INVOKABLE void configure();
576         void configureComponents();
577         void initializeNativeSession();
578         void loadLTSettings(lt::settings_pack &settingsPack);
579         void configureNetworkInterfaces(lt::settings_pack &settingsPack);
580         void configurePeerClasses();
581         void adjustLimits(lt::settings_pack &settingsPack) const;
582         void applyBandwidthLimits(lt::settings_pack &settingsPack) const;
583         void initMetrics();
584         void adjustLimits();
585         void applyBandwidthLimits();
586         void processBannedIPs(lt::ip_filter &filter);
587         QStringList getListeningIPs() const;
588         void configureListeningInterface();
589         void enableTracker(bool enable);
590         void enableBandwidthScheduler();
591         void populateAdditionalTrackers();
592         void enableIPFilter();
593         void disableIPFilter();
594 #if defined(Q_OS_WIN)
595         void applyOSMemoryPriority() const;
596 #endif
597 
598         bool loadTorrentResumeData(const QByteArray &data, const TorrentInfo &metadata, LoadTorrentParams &torrentParams);
599         bool loadTorrent(LoadTorrentParams params);
600         LoadTorrentParams initLoadTorrentParams(const AddTorrentParams &addTorrentParams);
601         bool addTorrent_impl(const std::variant<MagnetUri, TorrentInfo> &source, const AddTorrentParams &addTorrentParams);
602 
603         void updateSeedingLimitTimer();
604         void exportTorrentFile(const Torrent *torrent, TorrentExportFolder folder = TorrentExportFolder::Regular);
605 
606         void handleAlert(const lt::alert *a);
607         void dispatchTorrentAlert(const lt::alert *a);
608         void handleAddTorrentAlert(const lt::add_torrent_alert *p);
609         void handleStateUpdateAlert(const lt::state_update_alert *p);
610         void handleMetadataReceivedAlert(const lt::metadata_received_alert *p);
611         void handleFileErrorAlert(const lt::file_error_alert *p);
612         void handleTorrentRemovedAlert(const lt::torrent_removed_alert *p);
613         void handleTorrentDeletedAlert(const lt::torrent_deleted_alert *p);
614         void handleTorrentDeleteFailedAlert(const lt::torrent_delete_failed_alert *p);
615         void handlePortmapWarningAlert(const lt::portmap_error_alert *p);
616         void handlePortmapAlert(const lt::portmap_alert *p);
617         void handlePeerBlockedAlert(const lt::peer_blocked_alert *p);
618         void handlePeerBanAlert(const lt::peer_ban_alert *p);
619         void handleUrlSeedAlert(const lt::url_seed_alert *p);
620         void handleListenSucceededAlert(const lt::listen_succeeded_alert *p);
621         void handleListenFailedAlert(const lt::listen_failed_alert *p);
622         void handleExternalIPAlert(const lt::external_ip_alert *p);
623         void handleSessionStatsAlert(const lt::session_stats_alert *p);
624         void handleAlertsDroppedAlert(const lt::alerts_dropped_alert *p) const;
625         void handleStorageMovedAlert(const lt::storage_moved_alert *p);
626         void handleStorageMovedFailedAlert(const lt::storage_moved_failed_alert *p);
627         void handleSocks5Alert(const lt::socks5_alert *p) const;
628 
629         void createTorrent(const lt::torrent_handle &nativeHandle);
630 
631         void saveResumeData();
632         void saveTorrentsQueue() const;
633         void removeTorrentsQueue() const;
634 
635         std::vector<lt::alert *> getPendingAlerts(lt::time_duration time = lt::time_duration::zero()) const;
636 
637         void moveTorrentStorage(const MoveStorageJob &job) const;
638         void handleMoveTorrentStorageJobFinished();
639 
640         // BitTorrent
641         lt::session *m_nativeSession = nullptr;
642 
643         bool m_deferredConfigureScheduled = false;
644         bool m_IPFilteringConfigured = false;
645         bool m_listenInterfaceConfigured = false;
646 
647         CachedSettingValue<bool> m_isDHTEnabled;
648         CachedSettingValue<bool> m_isLSDEnabled;
649         CachedSettingValue<bool> m_isPeXEnabled;
650         CachedSettingValue<bool> m_isIPFilteringEnabled;
651         CachedSettingValue<bool> m_isTrackerFilteringEnabled;
652         CachedSettingValue<QString> m_IPFilterFile;
653         CachedSettingValue<bool> m_announceToAllTrackers;
654         CachedSettingValue<bool> m_announceToAllTiers;
655         CachedSettingValue<int> m_asyncIOThreads;
656         CachedSettingValue<int> m_hashingThreads;
657         CachedSettingValue<int> m_filePoolSize;
658         CachedSettingValue<int> m_checkingMemUsage;
659         CachedSettingValue<int> m_diskCacheSize;
660         CachedSettingValue<int> m_diskCacheTTL;
661         CachedSettingValue<bool> m_useOSCache;
662         CachedSettingValue<bool> m_coalesceReadWriteEnabled;
663         CachedSettingValue<bool> m_usePieceExtentAffinity;
664         CachedSettingValue<bool> m_isSuggestMode;
665         CachedSettingValue<int> m_sendBufferWatermark;
666         CachedSettingValue<int> m_sendBufferLowWatermark;
667         CachedSettingValue<int> m_sendBufferWatermarkFactor;
668         CachedSettingValue<int> m_socketBacklogSize;
669         CachedSettingValue<bool> m_isAnonymousModeEnabled;
670         CachedSettingValue<bool> m_isQueueingEnabled;
671         CachedSettingValue<int> m_maxActiveDownloads;
672         CachedSettingValue<int> m_maxActiveUploads;
673         CachedSettingValue<int> m_maxActiveTorrents;
674         CachedSettingValue<bool> m_ignoreSlowTorrentsForQueueing;
675         CachedSettingValue<int> m_downloadRateForSlowTorrents;
676         CachedSettingValue<int> m_uploadRateForSlowTorrents;
677         CachedSettingValue<int> m_slowTorrentsInactivityTimer;
678         CachedSettingValue<int> m_outgoingPortsMin;
679         CachedSettingValue<int> m_outgoingPortsMax;
680         CachedSettingValue<int> m_UPnPLeaseDuration;
681         CachedSettingValue<int> m_peerToS;
682         CachedSettingValue<bool> m_ignoreLimitsOnLAN;
683         CachedSettingValue<bool> m_includeOverheadInLimits;
684         CachedSettingValue<QString> m_announceIP;
685         CachedSettingValue<int> m_maxConcurrentHTTPAnnounces;
686         CachedSettingValue<int> m_stopTrackerTimeout;
687         CachedSettingValue<int> m_maxConnections;
688         CachedSettingValue<int> m_maxUploads;
689         CachedSettingValue<int> m_maxConnectionsPerTorrent;
690         CachedSettingValue<int> m_maxUploadsPerTorrent;
691         CachedSettingValue<BTProtocol> m_btProtocol;
692         CachedSettingValue<bool> m_isUTPRateLimited;
693         CachedSettingValue<MixedModeAlgorithm> m_utpMixedMode;
694         CachedSettingValue<bool> m_IDNSupportEnabled;
695         CachedSettingValue<bool> m_multiConnectionsPerIpEnabled;
696         CachedSettingValue<bool> m_validateHTTPSTrackerCertificate;
697         CachedSettingValue<bool> m_SSRFMitigationEnabled;
698         CachedSettingValue<bool> m_blockPeersOnPrivilegedPorts;
699         CachedSettingValue<bool> m_isAddTrackersEnabled;
700         CachedSettingValue<QString> m_additionalTrackers;
701         CachedSettingValue<qreal> m_globalMaxRatio;
702         CachedSettingValue<int> m_globalMaxSeedingMinutes;
703         CachedSettingValue<bool> m_isAddTorrentPaused;
704         CachedSettingValue<TorrentContentLayout> m_torrentContentLayout;
705         CachedSettingValue<bool> m_isAppendExtensionEnabled;
706         CachedSettingValue<int> m_refreshInterval;
707         CachedSettingValue<bool> m_isPreallocationEnabled;
708         CachedSettingValue<QString> m_torrentExportDirectory;
709         CachedSettingValue<QString> m_finishedTorrentExportDirectory;
710         CachedSettingValue<int> m_globalDownloadSpeedLimit;
711         CachedSettingValue<int> m_globalUploadSpeedLimit;
712         CachedSettingValue<int> m_altGlobalDownloadSpeedLimit;
713         CachedSettingValue<int> m_altGlobalUploadSpeedLimit;
714         CachedSettingValue<bool> m_isAltGlobalSpeedLimitEnabled;
715         CachedSettingValue<bool> m_isBandwidthSchedulerEnabled;
716         CachedSettingValue<int> m_saveResumeDataInterval;
717         CachedSettingValue<int> m_port;
718         CachedSettingValue<bool> m_useRandomPort;
719         CachedSettingValue<QString> m_networkInterface;
720         CachedSettingValue<QString> m_networkInterfaceName;
721         CachedSettingValue<QString> m_networkInterfaceAddress;
722         CachedSettingValue<int> m_encryption;
723         CachedSettingValue<bool> m_isProxyPeerConnectionsEnabled;
724         CachedSettingValue<ChokingAlgorithm> m_chokingAlgorithm;
725         CachedSettingValue<SeedChokingAlgorithm> m_seedChokingAlgorithm;
726         CachedSettingValue<QVariantMap> m_storedCategories;
727         CachedSettingValue<QStringList> m_storedTags;
728         CachedSettingValue<int> m_maxRatioAction;
729         CachedSettingValue<QString> m_defaultSavePath;
730         CachedSettingValue<QString> m_tempPath;
731         CachedSettingValue<bool> m_isSubcategoriesEnabled;
732         CachedSettingValue<bool> m_isTempPathEnabled;
733         CachedSettingValue<bool> m_isAutoTMMDisabledByDefault;
734         CachedSettingValue<bool> m_isDisableAutoTMMWhenCategoryChanged;
735         CachedSettingValue<bool> m_isDisableAutoTMMWhenDefaultSavePathChanged;
736         CachedSettingValue<bool> m_isDisableAutoTMMWhenCategorySavePathChanged;
737         CachedSettingValue<bool> m_isTrackerEnabled;
738         CachedSettingValue<int> m_peerTurnover;
739         CachedSettingValue<int> m_peerTurnoverCutoff;
740         CachedSettingValue<int> m_peerTurnoverInterval;
741         CachedSettingValue<QStringList> m_bannedIPs;
742 #if defined(Q_OS_WIN)
743         CachedSettingValue<OSMemoryPriority> m_OSMemoryPriority;
744 #endif
745 
746         // Order is important. This needs to be declared after its CachedSettingsValue
747         // counterpart, because it uses it for initialization in the constructor
748         // initialization list.
749         const bool m_wasPexEnabled = m_isPeXEnabled;
750 
751         int m_numResumeData = 0;
752         int m_extraLimit = 0;
753         QVector<TrackerEntry> m_additionalTrackerList;
754         QString m_resumeFolderPath;
755         QFile *m_resumeFolderLock = nullptr;
756 
757         bool m_refreshEnqueued = false;
758         QTimer *m_seedingLimitTimer = nullptr;
759         QTimer *m_resumeDataTimer = nullptr;
760         Statistics *m_statistics = nullptr;
761         // IP filtering
762         QPointer<FilterParserThread> m_filterParser;
763         QPointer<BandwidthScheduler> m_bwScheduler;
764         // Tracker
765         QPointer<Tracker> m_tracker;
766         // fastresume data writing thread
767         QThread *m_ioThread = nullptr;
768         ResumeDataSavingManager *m_resumeDataSavingManager = nullptr;
769         FileSearcher *m_fileSearcher = nullptr;
770 
771         QSet<TorrentID> m_downloadedMetadata;
772 
773         QHash<TorrentID, TorrentImpl *> m_torrents;
774         QHash<TorrentID, LoadTorrentParams> m_loadingTorrents;
775         QHash<QString, AddTorrentParams> m_downloadedTorrents;
776         QHash<TorrentID, RemovingTorrentData> m_removingTorrents;
777         QSet<TorrentID> m_needSaveResumeDataTorrents;
778         QStringMap m_categories;
779         QSet<QString> m_tags;
780 
781         // I/O errored torrents
782         QSet<TorrentID> m_recentErroredTorrents;
783         QTimer *m_recentErroredTorrentsTimer = nullptr;
784 
785         SessionMetricIndices m_metricIndices;
786         lt::time_point m_statsLastTimestamp = lt::clock_type::now();
787 
788         SessionStatus m_status;
789         CacheStatus m_cacheStatus;
790 
791         QNetworkConfigurationManager *m_networkManager = nullptr;
792 
793         QList<MoveStorageJob> m_moveStorageQueue;
794 
795         static Session *m_instance;
796     };
797 }
798