1 /*
2     SPDX-FileCopyrightText: 2005 Joris Guisson <joris.guisson@gmail.com>
3     SPDX-License-Identifier: GPL-2.0-or-later
4 */
5 
6 #include "functions.h"
7 
8 #include <QDateTime>
9 #include <QDir>
10 #include <QFileInfo>
11 #include <QNetworkInterface>
12 #include <QRandomGenerator>
13 #include <QStandardPaths>
14 
15 #include <KLocalizedString>
16 #include <Solid/Device>
17 
18 #include "settings.h"
19 #include <dht/dhtbase.h>
20 #include <diskio/cache.h>
21 #include <diskio/chunkmanager.h>
22 #include <download/downloader.h>
23 #include <download/webseed.h>
24 #include <interfaces/queuemanagerinterface.h>
25 #include <mse/encryptedpacketsocket.h>
26 #include <net/socketmonitor.h>
27 #include <net/socks.h>
28 #include <peer/authenticationmonitor.h>
29 #include <peer/connectionlimit.h>
30 #include <peer/peerconnector.h>
31 #include <peer/peermanager.h>
32 #include <peer/utpex.h>
33 #include <torrent/choker.h>
34 #include <torrent/server.h>
35 #include <torrent/timeestimator.h>
36 #include <torrent/torrentcontrol.h>
37 #include <tracker/httptracker.h>
38 #include <tracker/udptrackersocket.h>
39 #include <util/functions.h>
40 #include <util/log.h>
41 
42 using namespace bt;
43 
44 namespace kt
45 {
DataDir(CreationMode mode)46 QString DataDir(CreationMode mode)
47 {
48     QString dataDirPath = QStandardPaths::writableLocation(QStandardPaths::DataLocation);
49     if (mode == CreateIfNotExists) {
50         QFileInfo fileInfo(dataDirPath);
51         if (!fileInfo.exists()) {
52             QString ktorrent4DataFolder = QDir::homePath() + QLatin1String("/.kde/share/apps/ktorrent");
53             if (!QFile::exists(ktorrent4DataFolder)) {
54                 ktorrent4DataFolder = QDir::homePath() + QLatin1String("/.kde4/share/apps/ktorrent");
55                 if (!QFile::exists(ktorrent4DataFolder))
56                     ktorrent4DataFolder.clear();
57             }
58             if (ktorrent4DataFolder.isEmpty() || !QFile::rename(ktorrent4DataFolder, dataDirPath))
59                 fileInfo.dir().mkpath(fileInfo.fileName());
60         }
61     }
62     // if (!str.endsWith(bt::DirSeparator()))
63     return dataDirPath + bt::DirSeparator();
64     // else
65     //    return str;
66 }
67 
RandomGoodPort()68 Uint16 RandomGoodPort()
69 {
70     Uint16 start = 50000;
71     while (true) {
72         Uint16 port = start + QRandomGenerator::global()->bounded(10000);
73         if (port != Settings::port() && port != Settings::dhtPort() && port != Settings::udpTrackerPort())
74             return port;
75     }
76 }
77 
ApplySettings()78 void ApplySettings()
79 {
80     PeerManager::connectionLimits().setLimits(Settings::maxTotalConnections(), Settings::maxConnections());
81     net::SocketMonitor::setDownloadCap(Settings::maxDownloadRate() * 1024);
82     net::SocketMonitor::setUploadCap(Settings::maxUploadRate() * 1024);
83     net::SocketMonitor::setSleepTime(Settings::cpuUsage());
84     mse::EncryptedPacketSocket::setTOS(Settings::dscp() << 2);
85     bt::PeerConnector::setMaxActive(Settings::maxConnectingSockets());
86 
87     // Check for port conflicts
88     if (Settings::port() == Settings::udpTrackerPort())
89         Settings::setUdpTrackerPort(RandomGoodPort());
90 
91     if (Settings::port() == Settings::dhtPort())
92         Settings::setDhtPort(RandomGoodPort());
93 
94     UDPTrackerSocket::setPort(Settings::udpTrackerPort());
95     Choker::setNumUploadSlots(Settings::numUploadSlots());
96 
97     dht::DHTBase &ht = Globals::instance().getDHT();
98     if (Settings::dhtSupport() && !ht.isRunning()) {
99         ht.start(kt::DataDir() + QLatin1String("dht_table"), kt::DataDir() + QLatin1String("dht_key"), Settings::dhtPort());
100     } else if (!Settings::dhtSupport() && ht.isRunning()) {
101         ht.stop();
102     } else if (Settings::dhtSupport() && ht.getPort() != Settings::dhtPort()) {
103         Out(SYS_GEN | LOG_NOTICE) << "Restarting DHT with new port " << Settings::dhtPort() << endl;
104         ht.stop();
105         ht.start(kt::DataDir() + QLatin1String("dht_table"), kt::DataDir() + QLatin1String("dht_key"), Settings::dhtPort());
106     }
107 
108     UTPex::setEnabled(Settings::pexEnabled());
109 
110     if (Settings::useEncryption()) {
111         ServerInterface::enableEncryption(Settings::allowUnencryptedConnections());
112     } else {
113         ServerInterface::disableEncryption();
114     }
115 
116     if (Settings::useCustomIP())
117         Tracker::setCustomIP(Settings::customIP());
118     else
119         Tracker::setCustomIP(QString());
120 
121     QString proxy = Settings::httpProxy();
122 
123     bt::HTTPTracker::setProxyEnabled(!Settings::useKDEProxySettings() && Settings::useProxyForTracker());
124     bt::HTTPTracker::setProxy(proxy, Settings::httpProxyPort());
125     bt::WebSeed::setProxy(proxy, Settings::httpProxyPort());
126     bt::WebSeed::setProxyEnabled(!Settings::useKDEProxySettings() && Settings::useProxyForWebSeeds());
127     bt::Cache::setPreallocationEnabled(Settings::diskPrealloc());
128     bt::Cache::setPreallocateFully(Settings::fullDiskPrealloc());
129 
130     bt::TorrentControl::setDataCheckWhenCompleted(Settings::checkWhenFinished());
131     bt::TorrentControl::setMinimumDiskSpace(Settings::minDiskSpace());
132     bt::SetNetworkInterface(Settings::networkInterface());
133     net::Socks::setSocksEnabled(Settings::socksEnabled());
134     net::Socks::setSocksVersion(Settings::socksVersion());
135     net::Socks::setSocksServerAddress(Settings::socksProxy(), Settings::socksPort());
136     if (Settings::socksUsePassword())
137         net::Socks::setSocksAuthentication(Settings::socksUsername(), Settings::socksPassword());
138     else
139         net::Socks::setSocksAuthentication(QString(), QString());
140 
141     bt::ChunkManager::setPreviewSizes(Settings::previewSizeAudio() * 1024, Settings::previewSizeVideo() * 1024);
142     bt::QueueManagerInterface::setQueueManagerEnabled(!Settings::manuallyControlTorrents());
143     bt::Downloader::setUseWebSeeds(Settings::webseedsEnabled());
144     bt::Peer::setResolveHostnames(Settings::lookUpHostnameOfPeers());
145 }
146 
TorrentFileFilter(bool all_files_included)147 QString TorrentFileFilter(bool all_files_included)
148 {
149     QString ret = i18nc("*.torrent", "Torrents") + QLatin1String(" (*.torrent)");
150     if (all_files_included)
151         ret += QLatin1String(";;") + i18n("All files") + QLatin1String(" (*)");
152     return ret;
153 }
154 
155 }
156