From b5fe749f0b3dc8244d8e2ac998313ddf8064a39c Mon Sep 17 00:00:00 2001 From: "Vladimir Golovnev (Glassez)" Date: Fri, 3 Jun 2016 17:03:17 +0300 Subject: [PATCH] Use new libtorrent-1.1 settings API --- src/app/upgrade.h | 29 +- .../bittorrent/private/filterparserthread.cpp | 16 - .../bittorrent/private/filterparserthread.h | 1 - src/base/bittorrent/session.cpp | 668 ++++++++++++------ src/base/bittorrent/session.h | 26 +- src/base/net/portforwarder.cpp | 52 +- src/base/net/portforwarder.h | 6 +- src/base/preferences.cpp | 11 - src/base/preferences.h | 2 - src/base/settingsstorage.cpp | 1 + src/gui/optionsdlg.cpp | 5 +- src/webui/prefjson.cpp | 5 +- 12 files changed, 536 insertions(+), 286 deletions(-) diff --git a/src/app/upgrade.h b/src/app/upgrade.h index 42928c2c5..3538eda9c 100644 --- a/src/app/upgrade.h +++ b/src/app/upgrade.h @@ -29,24 +29,31 @@ #ifndef UPGRADE_H #define UPGRADE_H -#include -#include +#include +#if LIBTORRENT_VERSION_NUM >= 10100 +#include +#endif #include +#include +#if LIBTORRENT_VERSION_NUM < 10100 +#include +#endif + -#include #include #include -#include #ifndef DISABLE_GUI #include #endif +#include +#include #include "base/logger.h" #include "base/utils/fs.h" #include "base/utils/misc.h" #include "base/utils/string.h" -#include "base/qinisettings.h" #include "base/preferences.h" +#include "base/qinisettings.h" bool userAcceptsUpgrade() { @@ -86,10 +93,16 @@ bool upgradeResumeFile(const QString &filepath, const QVariantHash &oldTorrent = QByteArray data = file1.readAll(); file1.close(); - libtorrent::lazy_entry fastOld; libtorrent::error_code ec; - libtorrent::lazy_bdecode(data.constData(), data.constData() + data.size(), fastOld, ec); - if (ec || (fastOld.type() != libtorrent::lazy_entry::dict_t)) return false; +#if LIBTORRENT_VERSION_NUM < 10100 + libtorrent::lazy_entry fastOld; + libtorrent::lazy_bdecode(data.constData(), data.constData() + data.size(), fastOld, ec); + if (ec || (fastOld.type() != libtorrent::lazy_entry::dict_t)) return false; +#else + libtorrent::bdecode_node fastOld; + libtorrent::bdecode(data.constData(), data.constData() + data.size(), fastOld, ec); + if (ec || (fastOld.type() != libtorrent::bdecode_node::dict_t)) return false; +#endif libtorrent::entry fastNew; fastNew = fastOld; diff --git a/src/base/bittorrent/private/filterparserthread.cpp b/src/base/bittorrent/private/filterparserthread.cpp index cbe008c45..21e188706 100644 --- a/src/base/bittorrent/private/filterparserthread.cpp +++ b/src/base/bittorrent/private/filterparserthread.cpp @@ -383,22 +383,6 @@ void FilterParserThread::processFilterFile(QString _filePath) start(); } -void FilterParserThread::processFilterList(libt::session *s, const QStringList &IPs) -{ - // First, import current filter - libt::ip_filter filter = s->get_ip_filter(); - foreach (const QString &ip, IPs) { - qDebug("Manual ban of peer %s", ip.toLocal8Bit().constData()); - boost::system::error_code ec; - libt::address addr = libt::address::from_string(ip.toLocal8Bit().constData(), ec); - Q_ASSERT(!ec); - if (!ec) - filter.add_rule(addr, addr, libt::ip_filter::blocked); - } - - s->set_ip_filter(filter); -} - QString FilterParserThread::cleanupIPAddress(QString _ip) { _ip = _ip.trimmed(); diff --git a/src/base/bittorrent/private/filterparserthread.h b/src/base/bittorrent/private/filterparserthread.h index b54520b0d..9e3bdb6be 100644 --- a/src/base/bittorrent/private/filterparserthread.h +++ b/src/base/bittorrent/private/filterparserthread.h @@ -55,7 +55,6 @@ public: int getlineInStream(QDataStream &stream, std::string &name, char delim); int parseP2BFilterFile(QString filePath, libtorrent::ip_filter &filter); void processFilterFile(QString _filePath); - static void processFilterList(libtorrent::session *s, const QStringList &IPs); signals: void IPFilterParsed(int ruleCount); diff --git a/src/base/bittorrent/session.cpp b/src/base/bittorrent/session.cpp index a1c020f20..9f9ae84e9 100644 --- a/src/base/bittorrent/session.cpp +++ b/src/base/bittorrent/session.cpp @@ -45,10 +45,14 @@ #include #include +#include #include #include #include +#if LIBTORRENT_VERSION_NUM >= 10100 +#include +#endif #include #include #include @@ -57,7 +61,9 @@ #include #include #include +#if LIBTORRENT_VERSION_NUM < 10100 #include +#endif #include #include #include @@ -84,15 +90,9 @@ #include "tracker.h" #include "trackerentry.h" -#if LIBTORRENT_VERSION_NUM >= 10100 -namespace libtorrent -{ - using proxy_settings = aux::proxy_settings; -} -#endif - -static const char PEER_ID[] = "qB"; -static const char RESUME_FOLDER[] = "BT_backup"; +const char PEER_ID[] = "qB"; +const char RESUME_FOLDER[] = "BT_backup"; +const char USER_AGENT[] = "qBittorrent " VERSION; namespace libt = libtorrent; using namespace BitTorrent; @@ -195,6 +195,36 @@ namespace template LowerLimited lowerLimited(T limit, T ret) { return LowerLimited(limit, ret); } + +#if LIBTORRENT_VERSION_NUM >= 10100 + std::string makeFingerprint(const char* peerId, int major, int minor, int revision, int tag) + { + Q_ASSERT(peerId); + Q_ASSERT(major >= 0); + Q_ASSERT(minor >= 0); + Q_ASSERT(revision >= 0); + Q_ASSERT(tag >= 0); + Q_ASSERT(std::strlen(peerId) == 2); + + auto versionToChar = [](int v) -> char + { + if (v >= 0 && v < 10) return static_cast('0' + v); + if (v >= 10) return static_cast('A' + (v - 10)); + Q_ASSERT(false); + return '0'; + }; + + std::ostringstream buf; + buf << '-' + << peerId + << versionToChar(major) + << versionToChar(minor) + << versionToChar(revision) + << versionToChar(tag) + << '-'; + return buf.str(); + } +#endif } // Session @@ -207,6 +237,10 @@ Session *Session::m_instance = nullptr; Session::Session(QObject *parent) : QObject(parent) , m_deferredConfigureScheduled(false) + , m_IPFilteringChanged(false) +#if LIBTORRENT_VERSION_NUM >= 10100 + , m_listenInterfaceChanged(true) +#endif , m_isDHTEnabled(BITTORRENT_SESSION_KEY("DHTEnabled"), true) , m_isLSDEnabled(BITTORRENT_SESSION_KEY("LSDEnabled"), true) , m_isPeXEnabled(BITTORRENT_SESSION_KEY("PeXEnabled"), true) @@ -273,7 +307,6 @@ Session::Session(QObject *parent) , m_isDisableAutoTMMWhenCategorySavePathChanged(BITTORRENT_SESSION_KEY("DisableAutoTMMTriggers/CategorySavePathChanged"), true) , m_isTrackerEnabled(BITTORRENT_KEY("TrackerEnabled"), false) , m_bannedIPs("State/BannedIPs") - , m_numResumeData(0) , m_extraLimit(0) , m_useProxy(false) @@ -286,13 +319,6 @@ Session::Session(QObject *parent) m_bigRatioTimer->setInterval(10000); connect(m_bigRatioTimer, SIGNAL(timeout()), SLOT(processBigRatios())); - // Creating BitTorrent session - - // Construct session - libt::fingerprint fingerprint(PEER_ID, VERSION_MAJOR, VERSION_MINOR, VERSION_BUGFIX, VERSION_BUILD); - const ushort port = this->port(); - std::pair ports(port, port); - const QString ip = getListeningIPs().first(); // Set severity level of libtorrent session int alertMask = libt::alert::error_notification | libt::alert::peer_notification @@ -305,43 +331,97 @@ Session::Session(QObject *parent) | libt::alert::stats_notification ; - if (ip.isEmpty()) { - logger->addMessage(tr("qBittorrent is trying to listen on any interface port: %1", "e.g: qBittorrent is trying to listen on any interface port: TCP/6881").arg(QString::number(port)), Log::INFO); - m_nativeSession = new libt::session(fingerprint, ports, 0, 0, alertMask); - } - else { - logger->addMessage(tr("qBittorrent is trying to listen on interface %1 port: %2", "e.g: qBittorrent is trying to listen on interface 192.168.0.1 port: TCP/6881").arg(ip).arg(port), Log::INFO); - m_nativeSession = new libt::session(fingerprint, ports, ip.toLatin1().constData(), 0, alertMask); - } - - logger->addMessage(tr("Peer ID: ") + Utils::String::fromStdString(fingerprint.to_string())); - #if LIBTORRENT_VERSION_NUM < 10100 + libt::fingerprint fingerprint(PEER_ID, VERSION_MAJOR, VERSION_MINOR, VERSION_BUGFIX, VERSION_BUILD); + std::string peerId = fingerprint.to_string(); + const ushort port = this->port(); + std::pair ports(port, port); + const QString ip = getListeningIPs().first(); + m_nativeSession = new libt::session(fingerprint, ports, ip.isEmpty() ? 0 : ip.toLatin1().constData(), 0, alertMask); + + libt::session_settings sessionSettings = m_nativeSession->settings(); + sessionSettings.user_agent = USER_AGENT; + sessionSettings.upnp_ignore_nonrouters = true; + sessionSettings.use_dht_as_fallback = false; + // Disable support for SSL torrents for now + sessionSettings.ssl_listen = 0; + // To prevent ISPs from blocking seeding + sessionSettings.lazy_bitfields = true; + // Speed up exit + sessionSettings.stop_tracker_timeout = 1; + sessionSettings.auto_scrape_interval = 1200; // 20 minutes + sessionSettings.auto_scrape_min_interval = 900; // 15 minutes + sessionSettings.connection_speed = 20; // default is 10 + sessionSettings.no_connect_privileged_ports = false; + sessionSettings.seed_choking_algorithm = libt::session_settings::fastest_upload; + configure(sessionSettings); + m_nativeSession->set_settings(sessionSettings); + configureListeningInterface(); m_nativeSession->set_alert_dispatch([this](std::auto_ptr alertPtr) { dispatchAlerts(alertPtr); }); #else + std::string peerId = makeFingerprint(PEER_ID, VERSION_MAJOR, VERSION_MINOR, VERSION_BUGFIX, VERSION_BUILD); + libt::settings_pack pack; + pack.set_int(libt::settings_pack::alert_mask, alertMask); + pack.set_str(libt::settings_pack::peer_fingerprint, peerId); + pack.set_bool(libt::settings_pack::listen_system_port_fallback, false); + pack.set_str(libt::settings_pack::user_agent, USER_AGENT); + pack.set_bool(libt::settings_pack::upnp_ignore_nonrouters, true); + pack.set_bool(libt::settings_pack::use_dht_as_fallback, false); + // Disable support for SSL torrents for now + pack.set_int(libt::settings_pack::ssl_listen, 0); + // To prevent ISPs from blocking seeding + pack.set_bool(libt::settings_pack::lazy_bitfields, true); + // Speed up exit + pack.set_int(libt::settings_pack::stop_tracker_timeout, 1); + pack.set_int(libt::settings_pack::auto_scrape_interval, 1200); // 20 minutes + pack.set_int(libt::settings_pack::auto_scrape_min_interval, 900); // 15 minutes + pack.set_int(libt::settings_pack::connection_speed, 20); // default is 10 + pack.set_bool(libt::settings_pack::no_connect_privileged_ports, false); + pack.set_int(libt::settings_pack::seed_choking_algorithm, libt::settings_pack::fastest_upload); + configure(pack); + + m_nativeSession = new libt::session(pack, 0); m_nativeSession->set_alert_notify([this]() { QMetaObject::invokeMethod(this, "readAlerts", Qt::QueuedConnection); }); #endif + if (isDHTEnabled()) { + m_nativeSession->add_dht_router(std::make_pair(std::string("router.bittorrent.com"), 6881)); + m_nativeSession->add_dht_router(std::make_pair(std::string("router.utorrent.com"), 6881)); + m_nativeSession->add_dht_router(std::make_pair(std::string("dht.transmissionbt.com"), 6881)); + m_nativeSession->add_dht_router(std::make_pair(std::string("dht.aelitis.com"), 6881)); // Vuze + } + // Enabling plugins //m_nativeSession->add_extension(&libt::create_metadata_plugin); m_nativeSession->add_extension(&libt::create_ut_metadata_plugin); if (isTrackerExchangeEnabled()) m_nativeSession->add_extension(&libt::create_lt_trackers_plugin); - if (isPeXEnabled()) { + if (isPeXEnabled()) m_nativeSession->add_extension(&libt::create_ut_pex_plugin); - logger->addMessage(tr("PeX support [ON]"), Log::INFO); - } - else { - logger->addMessage(tr("PeX support [OFF]"), Log::INFO); - } m_nativeSession->add_extension(&libt::create_smart_ban_plugin); + logger->addMessage(tr("Peer ID: ") + Utils::String::fromStdString(peerId)); + logger->addMessage(tr("HTTP User-Agent is '%1'").arg(USER_AGENT)); + logger->addMessage(tr("DHT support [%1]").arg(isDHTEnabled() ? tr("ON") : tr("OFF")), Log::INFO); + logger->addMessage(tr("Local Peer Discovery support [%1]").arg(isLSDEnabled() ? tr("ON") : tr("OFF")), Log::INFO); + logger->addMessage(tr("PeX support [%1]").arg(isPeXEnabled() ? tr("ON") : tr("OFF")), Log::INFO); + logger->addMessage(tr("Anonymous mode [%1]").arg(isAnonymousModeEnabled() ? tr("ON") : tr("OFF")), Log::INFO); + logger->addMessage(tr("Encryption support [%1]") + .arg(encryption() == 0 ? tr("ON") : encryption() == 1 ? tr("FORCED") : tr("OFF")) + , Log::INFO); + + m_nativeSession->set_ip_filter({}); + if (isFilteringEnabled()) + enableIPFilter(); + // Add the banned IPs + processBannedIPs(); + m_categories = map_cast(m_storedCategories); if (isSubcategoriesEnabled()) { // if subcategories support changed manually @@ -361,10 +441,6 @@ Session::Session(QObject *parent) m_statistics = new Statistics(this); - // Apply user settings to BitTorrent session - configure(); - - configureListeningInterface(); updateRatioTimer(); populateAdditionalTrackers(); @@ -410,6 +486,14 @@ void Session::setDHTEnabled(bool enabled) if (enabled != m_isDHTEnabled) { m_isDHTEnabled = enabled; configureDeferred(); + Logger::instance()->addMessage( + tr("DHT support [%1]").arg(enabled ? tr("ON") : tr("OFF")), Log::INFO); + if (enabled) { + m_nativeSession->add_dht_router(std::make_pair(std::string("router.bittorrent.com"), 6881)); + m_nativeSession->add_dht_router(std::make_pair(std::string("router.utorrent.com"), 6881)); + m_nativeSession->add_dht_router(std::make_pair(std::string("dht.transmissionbt.com"), 6881)); + m_nativeSession->add_dht_router(std::make_pair(std::string("dht.aelitis.com"), 6881)); // Vuze + } } } @@ -423,6 +507,9 @@ void Session::setLSDEnabled(bool enabled) if (enabled != m_isLSDEnabled) { m_isLSDEnabled = enabled; configureDeferred(); + Logger::instance()->addMessage( + tr("Local Peer Discovery support [%1]").arg(enabled ? tr("ON") : tr("OFF")) + , Log::INFO); } } @@ -823,12 +910,236 @@ Session *Session::instance() void Session::adjustLimits() { if (isQueueingSystemEnabled()) { +#if LIBTORRENT_VERSION_NUM < 10100 libt::session_settings sessionSettings(m_nativeSession->settings()); adjustLimits(sessionSettings); m_nativeSession->set_settings(sessionSettings); +#else + libt::settings_pack settingsPack; + adjustLimits(settingsPack); + m_nativeSession->apply_settings(settingsPack); +#endif } } +// Set BitTorrent session configuration +void Session::configure() +{ + qDebug("Configuring session"); +#if LIBTORRENT_VERSION_NUM < 10100 + libt::session_settings sessionSettings = m_nativeSession->settings(); + configure(sessionSettings); + m_nativeSession->set_settings(sessionSettings); +#else + libt::settings_pack settingsPack; + configure(settingsPack); + m_nativeSession->apply_settings(settingsPack); +#endif + + if (m_IPFilteringChanged) { + if (isFilteringEnabled()) + enableIPFilter(); + else + disableIPFilter(); + m_IPFilteringChanged = false; + } + + m_deferredConfigureScheduled = false; + qDebug("Session configured"); +} + +void Session::processBannedIPs() +{ + // First, import current filter + libt::ip_filter filter = m_nativeSession->get_ip_filter(); + foreach (const QString &ip, m_bannedIPs.value()) { + boost::system::error_code ec; + libt::address addr = libt::address::from_string(ip.toLatin1().constData(), ec); + Q_ASSERT(!ec); + filter.add_rule(addr, addr, libt::ip_filter::blocked); + } + + m_nativeSession->set_ip_filter(filter); +} + +#if LIBTORRENT_VERSION_NUM >= 10100 +void Session::adjustLimits(libt::settings_pack &settingsPack) +{ + //Internally increase the queue limits to ensure that the magnet is started + int maxDownloads = maxActiveDownloads(); + int maxActive = maxActiveTorrents(); + + settingsPack.set_int(libt::settings_pack::active_downloads + , maxDownloads > -1 ? maxDownloads + m_extraLimit : maxDownloads); + settingsPack.set_int(libt::settings_pack::active_limit + , maxActive > -1 ? maxActive + m_extraLimit : maxActive); +} + +void Session::configure(libtorrent::settings_pack &settingsPack) +{ + Logger* const logger = Logger::instance(); + + if (m_listenInterfaceChanged) { + const ushort port = this->port(); + std::pair ports(port, port); + settingsPack.set_int(libt::settings_pack::max_retry_port_bind, ports.second - ports.first); + foreach (QString ip, getListeningIPs()) { + libt::error_code ec; + std::string interfacesStr; + + if (ip.isEmpty()) { + ip = QLatin1String("0.0.0.0"); + interfacesStr = std::string((QString("%1:%2").arg(ip).arg(port)).toLatin1().constData()); + logger->addMessage(tr("qBittorrent is trying to listen on any interface port: %1" + , "e.g: qBittorrent is trying to listen on any interface port: TCP/6881") + .arg(QString::number(port)) + , Log::INFO); + + settingsPack.set_str(libt::settings_pack::listen_interfaces, interfacesStr); + break; + } + + libt::address addr = libt::address::from_string(ip.toLatin1().constData(), ec); + if (!ec) { + interfacesStr = std::string((addr.is_v6() ? QString("[%1]:%2") : QString("%1:%2")) + .arg(ip).arg(port).toLatin1().constData()); + logger->addMessage(tr("qBittorrent is trying to listen on interface %1 port: %2" + , "e.g: qBittorrent is trying to listen on interface 192.168.0.1 port: TCP/6881") + .arg(ip).arg(port) + , Log::INFO); + settingsPack.set_str(libt::settings_pack::listen_interfaces, interfacesStr); + break; + } + } + + m_listenInterfaceChanged = false; + } + + const bool altSpeedLimitEnabled = isAltGlobalSpeedLimitEnabled(); + settingsPack.set_int(libt::settings_pack::download_rate_limit, altSpeedLimitEnabled ? altGlobalDownloadSpeedLimit() : globalDownloadSpeedLimit()); + settingsPack.set_int(libt::settings_pack::upload_rate_limit, altSpeedLimitEnabled ? altGlobalUploadSpeedLimit() : globalUploadSpeedLimit()); + + // The most secure, rc4 only so that all streams are encrypted + settingsPack.set_int(libt::settings_pack::allowed_enc_level, libt::settings_pack::pe_rc4); + settingsPack.set_bool(libt::settings_pack::prefer_rc4, true); + switch (encryption()) { + case 0: //Enabled + settingsPack.set_int(libt::settings_pack::out_enc_policy, libt::settings_pack::pe_enabled); + settingsPack.set_int(libt::settings_pack::in_enc_policy, libt::settings_pack::pe_enabled); + break; + case 1: // Forced + settingsPack.set_int(libt::settings_pack::out_enc_policy, libt::settings_pack::pe_forced); + settingsPack.set_int(libt::settings_pack::in_enc_policy, libt::settings_pack::pe_forced); + break; + default: // Disabled + settingsPack.set_int(libt::settings_pack::out_enc_policy, libt::settings_pack::pe_disabled); + settingsPack.set_int(libt::settings_pack::in_enc_policy, libt::settings_pack::pe_disabled); + } + + auto proxyManager = Net::ProxyConfigurationManager::instance(); + Net::ProxyConfiguration proxyConfig = proxyManager->proxyConfiguration(); + if (m_useProxy || (proxyConfig.type != Net::ProxyType::None)) { + if (proxyConfig.type != Net::ProxyType::None) { + settingsPack.set_str(libt::settings_pack::proxy_hostname, Utils::String::toStdString(proxyConfig.ip)); + settingsPack.set_int(libt::settings_pack::proxy_port, proxyConfig.port); + if (proxyManager->isAuthenticationRequired()) { + settingsPack.set_str(libt::settings_pack::proxy_username, Utils::String::toStdString(proxyConfig.username)); + settingsPack.set_str(libt::settings_pack::proxy_password, Utils::String::toStdString(proxyConfig.password)); + } + settingsPack.set_bool(libt::settings_pack::proxy_peer_connections, isProxyPeerConnectionsEnabled()); + } + + switch (proxyConfig.type) { + case Net::ProxyType::HTTP: + settingsPack.set_int(libt::settings_pack::proxy_type, libt::settings_pack::http); + break; + case Net::ProxyType::HTTP_PW: + settingsPack.set_int(libt::settings_pack::proxy_type, libt::settings_pack::http_pw); + break; + case Net::ProxyType::SOCKS4: + settingsPack.set_int(libt::settings_pack::proxy_type, libt::settings_pack::socks4); + break; + case Net::ProxyType::SOCKS5: + settingsPack.set_int(libt::settings_pack::proxy_type, libt::settings_pack::socks5); + break; + case Net::ProxyType::SOCKS5_PW: + settingsPack.set_int(libt::settings_pack::proxy_type, libt::settings_pack::socks5_pw); + break; + default: + settingsPack.set_int(libt::settings_pack::proxy_type, libt::settings_pack::none); + } + + m_useProxy = (proxyConfig.type != Net::ProxyType::None); + } + settingsPack.set_bool(libt::settings_pack::force_proxy, m_useProxy ? isForceProxyEnabled() : false); + + const bool announceToAll = announceToAllTrackers(); + settingsPack.set_bool(libt::settings_pack::announce_to_all_trackers, announceToAll); + settingsPack.set_bool(libt::settings_pack::announce_to_all_tiers, announceToAll); + + const int cacheSize = diskCacheSize(); + settingsPack.set_int(libt::settings_pack::cache_size, (cacheSize > 0) ? cacheSize * 64 : -1); + settingsPack.set_int(libt::settings_pack::cache_expiry, diskCacheTTL()); + qDebug() << "Using a disk cache size of" << cacheSize << "MiB"; + + libt::settings_pack::io_buffer_mode_t mode = useOSCache() ? libt::settings_pack::enable_os_cache + : libt::settings_pack::disable_os_cache; + settingsPack.set_int(libt::settings_pack::disk_io_read_mode, mode); + settingsPack.set_int(libt::settings_pack::disk_io_write_mode, mode); + + settingsPack.set_bool(libt::settings_pack::anonymous_mode, isAnonymousModeEnabled()); + + // Queueing System + if (isQueueingSystemEnabled()) { + adjustLimits(settingsPack); + + settingsPack.set_int(libt::settings_pack::active_seeds, maxActiveUploads()); + settingsPack.set_bool(libt::settings_pack::dont_count_slow_torrents, ignoreSlowTorrentsForQueueing()); + } + else { + settingsPack.set_int(libt::settings_pack::active_downloads, -1); + settingsPack.set_int(libt::settings_pack::active_seeds, -1); + settingsPack.set_int(libt::settings_pack::active_limit, -1); + } + settingsPack.set_int(libt::settings_pack::active_tracker_limit, -1); + settingsPack.set_int(libt::settings_pack::active_dht_limit, -1); + settingsPack.set_int(libt::settings_pack::active_lsd_limit, -1); + + // Outgoing ports + settingsPack.set_int(libt::settings_pack::outgoing_port, outgoingPortsMin()); + settingsPack.set_int(libt::settings_pack::num_outgoing_ports, outgoingPortsMax() - outgoingPortsMin() + 1); + + // Ignore limits on LAN + settingsPack.set_bool(libt::settings_pack::ignore_limits_on_local_network, ignoreLimitsOnLAN()); + // Include overhead in transfer limits + settingsPack.set_bool(libt::settings_pack::rate_limit_ip_overhead, includeOverheadInLimits()); + // IP address to announce to trackers + settingsPack.set_str(libt::settings_pack::announce_ip, Utils::String::toStdString(networkAddress())); + // Super seeding + settingsPack.set_bool(libt::settings_pack::strict_super_seeding, isSuperSeedingEnabled()); + // * Max Half-open connections + settingsPack.set_int(libt::settings_pack::half_open_limit, maxHalfOpenConnections()); + // * Max connections limit + settingsPack.set_int(libt::settings_pack::connections_limit, maxConnections()); + // * Global max upload slots + settingsPack.set_int(libt::settings_pack::unchoke_slots_limit, maxUploads()); + // uTP + settingsPack.set_bool(libt::settings_pack::enable_incoming_utp, isUTPEnabled()); + settingsPack.set_bool(libt::settings_pack::enable_outgoing_utp, isUTPEnabled()); + // uTP rate limiting + settingsPack.set_bool(libt::settings_pack::rate_limit_utp, isUTPRateLimited()); + settingsPack.set_int(libt::settings_pack::mixed_mode_algorithm, isUTPRateLimited() + ? libt::settings_pack::prefer_tcp + : libt::settings_pack::peer_proportional); + + settingsPack.set_bool(libt::settings_pack::apply_ip_filter_to_trackers, isTrackerFilteringEnabled()); + + settingsPack.set_bool(libt::settings_pack::enable_dht, isDHTEnabled()); + settingsPack.set_bool(libt::settings_pack::enable_lsd, isLSDEnabled()); +} + +#else + void Session::adjustLimits(libt::session_settings &sessionSettings) { //Internally increase the queue limits to ensure that the magnet is started @@ -846,40 +1157,70 @@ void Session::adjustLimits(libt::session_settings &sessionSettings) sessionSettings.active_limit = maxActive; } -// Set BitTorrent session configuration -void Session::configure() +void Session::configure(libtorrent::session_settings &sessionSettings) { - qDebug("Configuring session"); Logger* const logger = Logger::instance(); - // * Session settings - libt::session_settings sessionSettings = m_nativeSession->settings(); - - sessionSettings.user_agent = "qBittorrent " VERSION; - logger->addMessage(tr("HTTP User-Agent is '%1'").arg(Utils::String::fromStdString(sessionSettings.user_agent))); - - sessionSettings.upnp_ignore_nonrouters = true; - sessionSettings.use_dht_as_fallback = false; - // Disable support for SSL torrents for now - sessionSettings.ssl_listen = 0; - // To prevent ISPs from blocking seeding - sessionSettings.lazy_bitfields = true; - // Speed up exit - sessionSettings.stop_tracker_timeout = 1; - sessionSettings.auto_scrape_interval = 1200; // 20 minutes - sessionSettings.auto_scrape_min_interval = 900; // 15 minutes - sessionSettings.connection_speed = 20; // default is 10 - sessionSettings.no_connect_privileged_ports = false; - sessionSettings.seed_choking_algorithm = libt::session_settings::fastest_upload; - const bool altSpeedLimitEnabled = isAltGlobalSpeedLimitEnabled(); sessionSettings.download_rate_limit = altSpeedLimitEnabled ? altGlobalDownloadSpeedLimit() : globalDownloadSpeedLimit(); sessionSettings.upload_rate_limit = altSpeedLimitEnabled ? altGlobalUploadSpeedLimit() : globalUploadSpeedLimit(); - // TODO: Use same settings struct with above - configureEncryption(); - configureProxy(); + // The most secure, rc4 only so that all streams are encrypted + libt::pe_settings encryptionSettings; + encryptionSettings.allowed_enc_level = libt::pe_settings::rc4; + encryptionSettings.prefer_rc4 = true; + switch (encryption()) { + case 0: //Enabled + encryptionSettings.out_enc_policy = libt::pe_settings::enabled; + encryptionSettings.in_enc_policy = libt::pe_settings::enabled; + break; + case 1: // Forced + encryptionSettings.out_enc_policy = libt::pe_settings::forced; + encryptionSettings.in_enc_policy = libt::pe_settings::forced; + break; + default: // Disabled + encryptionSettings.out_enc_policy = libt::pe_settings::disabled; + encryptionSettings.in_enc_policy = libt::pe_settings::disabled; + } + m_nativeSession->set_pe_settings(encryptionSettings); + auto proxyManager = Net::ProxyConfigurationManager::instance(); + Net::ProxyConfiguration proxyConfig = proxyManager->proxyConfiguration(); + if (m_useProxy || (proxyConfig.type != Net::ProxyType::None)) { + libt::proxy_settings proxySettings; + if (proxyConfig.type != Net::ProxyType::None) { + proxySettings.hostname = Utils::String::toStdString(proxyConfig.ip); + proxySettings.port = proxyConfig.port; + if (proxyManager->isAuthenticationRequired()) { + proxySettings.username = Utils::String::toStdString(proxyConfig.username); + proxySettings.password = Utils::String::toStdString(proxyConfig.password); + } + proxySettings.proxy_peer_connections = isProxyPeerConnectionsEnabled(); + } + + switch (proxyConfig.type) { + case Net::ProxyType::HTTP: + proxySettings.type = libt::proxy_settings::http; + break; + case Net::ProxyType::HTTP_PW: + proxySettings.type = libt::proxy_settings::http_pw; + break; + case Net::ProxyType::SOCKS4: + proxySettings.type = libt::proxy_settings::socks4; + break; + case Net::ProxyType::SOCKS5: + proxySettings.type = libt::proxy_settings::socks5; + break; + case Net::ProxyType::SOCKS5_PW: + proxySettings.type = libt::proxy_settings::socks5_pw; + break; + default: + proxySettings.type = libt::proxy_settings::none; + } + + m_nativeSession->set_proxy(proxySettings); + m_useProxy = (proxyConfig.type != Net::ProxyType::None); + } sessionSettings.force_proxy = m_useProxy ? isForceProxyEnabled() : false; bool announceToAll = announceToAllTrackers(); @@ -895,10 +1236,6 @@ void Session::configure() sessionSettings.disk_io_write_mode = mode; sessionSettings.anonymous_mode = isAnonymousModeEnabled(); - if (sessionSettings.anonymous_mode) - logger->addMessage(tr("Anonymous mode [ON]"), Log::INFO); - else - logger->addMessage(tr("Anonymous mode [OFF]"), Log::INFO); // Queueing System if (isQueueingSystemEnabled()) { @@ -917,12 +1254,7 @@ void Session::configure() sessionSettings.active_lsd_limit = -1; // Outgoing ports -#if LIBTORRENT_VERSION_NUM < 10100 sessionSettings.outgoing_ports = std::make_pair(outgoingPortsMin(), outgoingPortsMax()); -#else - sessionSettings.outgoing_port = outgoingPortsMin(); - sessionSettings.num_outgoing_ports = outgoingPortsMax() - outgoingPortsMin(); -#endif // Ignore limits on LAN sessionSettings.ignore_limits_on_local_network = ignoreLimitsOnLAN(); @@ -950,24 +1282,17 @@ void Session::configure() sessionSettings.apply_ip_filter_to_trackers = isTrackerFilteringEnabled(); - m_nativeSession->set_settings(sessionSettings); - - enableDHT(isDHTEnabled()); - enableLSD(isLSDEnabled()); - - if (isFilteringEnabled()) - enableIPFilter(IPFilterFile()); + if (isDHTEnabled()) + m_nativeSession->start_dht(); else - disableIPFilter(); + m_nativeSession->stop_dht(); - // Add the banned IPs after the possibly disabled IPFilter - // which creates an empty filter and overrides all previously - // applied bans. - FilterParserThread::processFilterList(m_nativeSession, m_bannedIPs); - - m_deferredConfigureScheduled = false; - qDebug("Session configured"); + if (isLSDEnabled()) + m_nativeSession->start_lsd(); + else + m_nativeSession->stop_lsd(); } +#endif void Session::enableTracker(bool enable) { @@ -1092,9 +1417,15 @@ bool Session::hasUnfinishedTorrents() const void Session::banIP(const QString &ip) { - FilterParserThread::processFilterList(m_nativeSession, QStringList(ip)); QStringList bannedIPs = m_bannedIPs; if (!bannedIPs.contains(ip)) { + libt::ip_filter filter = m_nativeSession->get_ip_filter(); + boost::system::error_code ec; + libt::address addr = libt::address::from_string(ip.toLatin1().constData(), ec); + Q_ASSERT(!ec); + filter.add_rule(addr, addr, libt::ip_filter::blocked); + m_nativeSession->set_ip_filter(filter); + bannedIPs << ip; m_bannedIPs = bannedIPs; } @@ -1556,47 +1887,6 @@ void Session::exportTorrentFile(TorrentHandle *const torrent, TorrentExportFolde } } -void Session::enableLSD(bool enable) -{ - if (enable) { - m_nativeSession->start_lsd(); - Logger::instance()->addMessage(tr("Local Peer Discovery support [ON]"), Log::INFO); - } - else { - m_nativeSession->stop_lsd(); - Logger::instance()->addMessage(tr("Local Peer Discovery support [OFF]"), Log::INFO); - } -} - -// Enable DHT -void Session::enableDHT(bool enable) -{ - Logger* const logger = Logger::instance(); - - if (enable) { - if (!m_nativeSession->is_dht_running()) { - try { - m_nativeSession->start_dht(); - m_nativeSession->add_dht_router(std::make_pair(std::string("router.bittorrent.com"), 6881)); - m_nativeSession->add_dht_router(std::make_pair(std::string("router.utorrent.com"), 6881)); - m_nativeSession->add_dht_router(std::make_pair(std::string("dht.transmissionbt.com"), 6881)); - m_nativeSession->add_dht_router(std::make_pair(std::string("dht.aelitis.com"), 6881)); // Vuze - logger->addMessage(tr("DHT support [ON]"), Log::INFO); - } - catch (std::exception &e) { - qDebug("Could not enable DHT, reason: %s", e.what()); - logger->addMessage(tr("DHT support [FAILED]. Reason: %1").arg(Utils::String::fromStdString(e.what())), Log::CRITICAL); - } - } - } - else { - if (m_nativeSession->is_dht_running()) { - m_nativeSession->stop_dht(); - logger->addMessage(tr("DHT support [OFF]"), Log::INFO); - } - } -} - void Session::changeSpeedLimitMode_impl(bool alternative) { qDebug() << Q_FUNC_INFO << alternative; @@ -1780,6 +2070,7 @@ const QStringList Session::getListeningIPs() // the BitTorrent session will listen to void Session::configureListeningInterface() { +#if LIBTORRENT_VERSION_NUM < 10100 const ushort port = this->port(); qDebug() << Q_FUNC_INFO << port; @@ -1806,6 +2097,10 @@ void Session::configureListeningInterface() return; } } +#else + m_listenInterfaceChanged = true; + configureDeferred(); +#endif } int Session::globalDownloadSpeedLimit() const @@ -2015,7 +2310,11 @@ void Session::setEncryption(int state) { if (state != encryption()) { m_encryption = state; - configureEncryption(); + configureDeferred(); + Logger::instance()->addMessage( + tr("Encryption support [%1]") + .arg(state == 0 ? tr("ON") : state == 1 ? tr("FORCED") : tr("OFF")) + , Log::INFO); } } @@ -2077,6 +2376,7 @@ void Session::setFilteringEnabled(bool enabled) { if (enabled != m_isFilteringEnabled) { m_isFilteringEnabled = enabled; + m_IPFilteringChanged = true; configureDeferred(); } } @@ -2091,6 +2391,7 @@ void Session::setIPFilterFile(QString path) path = Utils::Fs::fromNativePath(path); if (path != IPFilterFile()) { m_IPFilterFile = path; + m_IPFilteringChanged = true; configureDeferred(); } } @@ -2216,6 +2517,9 @@ void Session::setAnonymousModeEnabled(bool enabled) if (enabled != m_isAnonymousModeEnabled) { m_isAnonymousModeEnabled = enabled; configureDeferred(); + Logger::instance()->addMessage( + tr("Anonymous mode [%1]").arg(isAnonymousModeEnabled() ? tr("ON") : tr("OFF")) + , Log::INFO); } } @@ -2446,34 +2750,6 @@ void Session::setTrackerFilteringEnabled(bool enabled) } } -void Session::configureEncryption() -{ - Logger *const logger = Logger::instance(); - - // The most secure, rc4 only so that all streams and encrypted - libt::pe_settings encryptionSettings; - encryptionSettings.allowed_enc_level = libt::pe_settings::rc4; - encryptionSettings.prefer_rc4 = true; - switch (encryption()) { - case 0: //Enabled - encryptionSettings.out_enc_policy = libt::pe_settings::enabled; - encryptionSettings.in_enc_policy = libt::pe_settings::enabled; - logger->addMessage(tr("Encryption support [ON]"), Log::INFO); - break; - case 1: // Forced - encryptionSettings.out_enc_policy = libt::pe_settings::forced; - encryptionSettings.in_enc_policy = libt::pe_settings::forced; - logger->addMessage(tr("Encryption support [FORCED]"), Log::INFO); - break; - default: // Disabled - encryptionSettings.out_enc_policy = libt::pe_settings::disabled; - encryptionSettings.in_enc_policy = libt::pe_settings::disabled; - logger->addMessage(tr("Encryption support [OFF]"), Log::INFO); - } - - m_nativeSession->set_pe_settings(encryptionSettings); -} - bool Session::isListening() const { return m_nativeSession->is_listening(); @@ -2715,7 +2991,7 @@ void Session::configureDeferred() } // Enable IP Filtering -void Session::enableIPFilter(const QString &filterPath, bool force) +void Session::enableIPFilter() { qDebug("Enabling IPFilter"); if (!m_filterParser) { @@ -2723,10 +2999,8 @@ void Session::enableIPFilter(const QString &filterPath, bool force) connect(m_filterParser.data(), SIGNAL(IPFilterParsed(int)), SLOT(handleIPFilterParsed(int))); connect(m_filterParser.data(), SIGNAL(IPFilterError()), SLOT(handleIPFilterError())); } - if (m_filterPath.isEmpty() || m_filterPath != Utils::Fs::fromNativePath(filterPath) || force) { - m_filterPath = Utils::Fs::fromNativePath(filterPath); - m_filterParser->processFilterFile(Utils::Fs::fromNativePath(filterPath)); - } + + m_filterParser->processFilterFile(IPFilterFile()); } // Disable IP Filtering @@ -2738,7 +3012,11 @@ void Session::disableIPFilter() disconnect(m_filterParser.data(), 0, this, 0); delete m_filterParser; } - m_filterPath = ""; + + // Add the banned IPs after the IPFilter disabling + // which creates an empty filter and overrides all previously + // applied bans. + processBannedIPs(); } void Session::recursiveTorrentDownload(const InfoHash &hash) @@ -2773,58 +3051,6 @@ CacheStatus Session::cacheStatus() const return m_nativeSession->get_cache_status(); } -// Set Proxy -void Session::configureProxy() -{ - auto proxyManager = Net::ProxyConfigurationManager::instance(); - Net::ProxyConfiguration config = proxyManager->proxyConfiguration(); - if (!m_useProxy && (config.type == Net::ProxyType::None)) return; - - libt::proxy_settings proxySettings; - - if (config.type != Net::ProxyType::None) { - qDebug("Enabling P2P proxy"); - proxySettings.hostname = Utils::String::toStdString(config.ip); - qDebug("hostname is %s", proxySettings.hostname.c_str()); - proxySettings.port = config.port; - qDebug("port is %d", proxySettings.port); - if (proxyManager->isAuthenticationRequired()) { - proxySettings.username = Utils::String::toStdString(config.username); - proxySettings.password = Utils::String::toStdString(config.password); - qDebug("username is %s", proxySettings.username.c_str()); - qDebug("password is %s", proxySettings.password.c_str()); - } - proxySettings.proxy_peer_connections = isProxyPeerConnectionsEnabled(); - } - - switch (config.type) { - case Net::ProxyType::HTTP: - qDebug("type: http"); - proxySettings.type = libt::proxy_settings::http; - break; - case Net::ProxyType::HTTP_PW: - qDebug("type: http_pw"); - proxySettings.type = libt::proxy_settings::http_pw; - break; - case Net::ProxyType::SOCKS4: - proxySettings.type = libt::proxy_settings::socks4; - break; - case Net::ProxyType::SOCKS5: - qDebug("type: socks5"); - proxySettings.type = libt::proxy_settings::socks5; - break; - case Net::ProxyType::SOCKS5_PW: - qDebug("type: socks5_pw"); - proxySettings.type = libt::proxy_settings::socks5_pw; - break; - default: - proxySettings.type = libt::proxy_settings::none; - } - - m_nativeSession->set_proxy(proxySettings); - m_useProxy = (config.type != Net::ProxyType::None); -} - // Will resume torrents in backup directory void Session::startUpTorrents() { @@ -3326,10 +3552,16 @@ namespace torrentData.resumed = true; torrentData.skipChecking = false; - libt::lazy_entry fast; libt::error_code ec; +#if LIBTORRENT_VERSION_NUM < 10100 + libt::lazy_entry fast; libt::lazy_bdecode(data.constData(), data.constData() + data.size(), fast, ec); if (ec || (fast.type() != libt::lazy_entry::dict_t)) return false; +#else + libt::bdecode_node fast; + libt::bdecode(data.constData(), data.constData() + data.size(), fast, ec); + if (ec || (fast.type() != libt::bdecode_node::dict_t)) return false; +#endif torrentData.savePath = Utils::Fs::fromNativePath(Utils::String::fromStdString(fast.dict_find_string_value("qBt-savePath"))); torrentData.ratioLimit = Utils::String::fromStdString(fast.dict_find_string_value("qBt-ratioLimit")).toDouble(); diff --git a/src/base/bittorrent/session.h b/src/base/bittorrent/session.h index 073d5958b..998e62dc3 100644 --- a/src/base/bittorrent/session.h +++ b/src/base/bittorrent/session.h @@ -57,7 +57,11 @@ namespace libtorrent class entry; struct add_torrent_params; struct pe_settings; +#if LIBTORRENT_VERSION_NUM < 10100 struct session_settings; +#else + struct settings_pack; +#endif struct session_status; class alert; @@ -336,8 +340,6 @@ namespace BitTorrent MaxRatioAction maxRatioAction() const; void setMaxRatioAction(MaxRatioAction act); - void enableIPFilter(const QString &filterPath, bool force = false); - void disableIPFilter(); void banIP(const QString &ip); bool isKnownTorrent(const InfoHash &hash) const; @@ -436,18 +438,23 @@ namespace BitTorrent // Session configuration Q_INVOKABLE void configure(); - void adjustLimits(); +#if LIBTORRENT_VERSION_NUM < 10100 + void configure(libtorrent::session_settings &sessionSettings); void adjustLimits(libtorrent::session_settings &sessionSettings); +#else + void configure(libtorrent::settings_pack &settingsPack); + void adjustLimits(libtorrent::settings_pack &settingsPack); +#endif + void adjustLimits(); + void processBannedIPs(); const QStringList getListeningIPs(); void configureListeningInterface(); - void enableLSD(bool enable); - void enableDHT(bool enable); void changeSpeedLimitMode_impl(bool alternative); void enableTracker(bool enable); void enableBandwidthScheduler(); void populateAdditionalTrackers(); - void configureEncryption(); - void configureProxy(); + void enableIPFilter(); + void disableIPFilter(); void startUpTorrents(); bool addTorrent_impl(AddTorrentData addData, const MagnetUri &magnetUri, @@ -490,6 +497,10 @@ namespace BitTorrent libtorrent::session *m_nativeSession; bool m_deferredConfigureScheduled; + bool m_IPFilteringChanged; +#if LIBTORRENT_VERSION_NUM >= 10100 + bool m_listenInterfaceChanged; // optimization +#endif CachedSettingValue m_isDHTEnabled; CachedSettingValue m_isLSDEnabled; CachedSettingValue m_isPeXEnabled; @@ -560,7 +571,6 @@ namespace BitTorrent int m_numResumeData; int m_extraLimit; QList m_additionalTrackerList; - QString m_filterPath; QString m_resumeFolderPath; QFile m_resumeFolderLock; QHash m_savePathsToRemove; diff --git a/src/base/net/portforwarder.cpp b/src/base/net/portforwarder.cpp index 456b794b1..7fce6b933 100644 --- a/src/base/net/portforwarder.cpp +++ b/src/base/net/portforwarder.cpp @@ -26,13 +26,17 @@ * exception statement from your version. */ +#include "portforwarder.h" + #include #include +#include #include "base/logger.h" -#include "base/preferences.h" -#include "portforwarder.h" +#include "base/settingsstorage.h" + +const QString KEY_ENABLED = QLatin1String("Network/PortForwardingEnabled"); namespace libt = libtorrent; using namespace Net; @@ -42,8 +46,8 @@ PortForwarder::PortForwarder(libtorrent::session *provider, QObject *parent) , m_active(false) , m_provider(provider) { - configure(); - connect(Preferences::instance(), SIGNAL(changed()), SLOT(configure())); + if (SettingsStorage::instance()->loadValue(KEY_ENABLED, true).toBool()) + start(); } PortForwarder::~PortForwarder() @@ -70,6 +74,21 @@ PortForwarder *PortForwarder::instance() return m_instance; } +bool PortForwarder::isEnabled() const +{ + return m_active; +} + +void PortForwarder::setEnabled(bool enabled) +{ + if (m_active != enabled) { + if (enabled) + start(); + else + stop(); + } +} + void PortForwarder::addPort(qint16 port) { if (!m_mappedPorts.contains(port)) { @@ -88,22 +107,18 @@ void PortForwarder::deletePort(qint16 port) } } -void PortForwarder::configure() -{ - bool enable = Preferences::instance()->isUPnPEnabled(); - if (m_active != enable) { - if (enable) - start(); - else - stop(); - } -} - void PortForwarder::start() { qDebug("Enabling UPnP / NAT-PMP"); +#if LIBTORRENT_VERSION_NUM < 10100 m_provider->start_upnp(); m_provider->start_natpmp(); +#else + libt::settings_pack settingsPack = m_provider->get_settings(); + settingsPack.set_bool(libt::settings_pack::enable_upnp, true); + settingsPack.set_bool(libt::settings_pack::enable_natpmp, true); + m_provider->apply_settings(settingsPack); +#endif foreach (qint16 port, m_mappedPorts.keys()) m_mappedPorts[port] = m_provider->add_port_mapping(libt::session::tcp, port, port); m_active = true; @@ -113,8 +128,15 @@ void PortForwarder::start() void PortForwarder::stop() { qDebug("Disabling UPnP / NAT-PMP"); +#if LIBTORRENT_VERSION_NUM < 10100 m_provider->stop_upnp(); m_provider->stop_natpmp(); +#else + libt::settings_pack settingsPack = m_provider->get_settings(); + settingsPack.set_bool(libt::settings_pack::enable_upnp, false); + settingsPack.set_bool(libt::settings_pack::enable_natpmp, false); + m_provider->apply_settings(settingsPack); +#endif m_active = false; Logger::instance()->addMessage(tr("UPnP / NAT-PMP support [OFF]"), Log::INFO); } diff --git a/src/base/net/portforwarder.h b/src/base/net/portforwarder.h index 6980baaa5..8e3c1ebf5 100644 --- a/src/base/net/portforwarder.h +++ b/src/base/net/portforwarder.h @@ -49,12 +49,12 @@ namespace Net static void freeInstance(); static PortForwarder *instance(); + bool isEnabled() const; + void setEnabled(bool enabled); + void addPort(qint16 port); void deletePort(qint16 port); - private slots: - void configure(); - private: explicit PortForwarder(libtorrent::session *const provider, QObject *parent = 0); ~PortForwarder(); diff --git a/src/base/preferences.cpp b/src/base/preferences.cpp index b47295f4a..40c83f9c3 100644 --- a/src/base/preferences.cpp +++ b/src/base/preferences.cpp @@ -373,17 +373,6 @@ void Preferences::setActionOnDblClOnTorrentFn(int act) setValue("Preferences/Downloads/DblClOnTorFn", act); } -// Connection options -bool Preferences::isUPnPEnabled() const -{ - return value("Preferences/Connection/UPnP", true).toBool(); -} - -void Preferences::setUPnPEnabled(bool enabled) -{ - setValue("Preferences/Connection/UPnP", enabled); -} - QTime Preferences::getSchedulerStartTime() const { return value("Preferences/Scheduler/start_time", QTime(8,0)).toTime(); diff --git a/src/base/preferences.h b/src/base/preferences.h index 83d56209f..72e06b0b4 100644 --- a/src/base/preferences.h +++ b/src/base/preferences.h @@ -160,8 +160,6 @@ public: void setActionOnDblClOnTorrentFn(int act); // Connection options - bool isUPnPEnabled() const; - void setUPnPEnabled(bool enabled); QTime getSchedulerStartTime() const; void setSchedulerStartTime(const QTime &time); QTime getSchedulerEndTime() const; diff --git a/src/base/settingsstorage.cpp b/src/base/settingsstorage.cpp index 1b62aef5d..9eb12723e 100644 --- a/src/base/settingsstorage.cpp +++ b/src/base/settingsstorage.cpp @@ -163,6 +163,7 @@ namespace {"Network/Proxy/Password", "Preferences/Connection/Proxy/Password"}, {"Network/Proxy/IP", "Preferences/Connection/Proxy/IP"}, {"Network/Proxy/Port", "Preferences/Connection/Proxy/Port"}, + {"Network/PortForwardingEnabled", "Preferences/Connection/UPnP"}, #ifdef QBT_USES_QT5 {"AddNewTorrentDialog/TreeHeaderState", "AddNewTorrentDialog/qt5/treeHeaderState"}, #else diff --git a/src/gui/optionsdlg.cpp b/src/gui/optionsdlg.cpp index e688e4d1c..a97111280 100644 --- a/src/gui/optionsdlg.cpp +++ b/src/gui/optionsdlg.cpp @@ -51,6 +51,7 @@ #include "app/application.h" #include "base/bittorrent/session.h" #include "base/net/dnsupdater.h" +#include "base/net/portforwarder.h" #include "base/net/proxyconfigurationmanager.h" #include "base/preferences.h" #include "base/scanfoldersmodel.h" @@ -538,7 +539,7 @@ void OptionsDialog::saveOptions() // Connection preferences session->setPort(getPort()); session->setUseRandomPort(m_ui->checkRandomPort->isChecked()); - pref->setUPnPEnabled(isUPnPEnabled()); + Net::PortForwarder::instance()->setEnabled(isUPnPEnabled()); const QPair down_up_limit = getGlobalBandwidthLimits(); session->setGlobalDownloadSpeedLimit(down_up_limit.first); session->setGlobalUploadSpeedLimit(down_up_limit.second); @@ -781,7 +782,7 @@ void OptionsDialog::loadOptions() // End Downloads preferences // Connection preferences - m_ui->checkUPnP->setChecked(pref->isUPnPEnabled()); + m_ui->checkUPnP->setChecked(Net::PortForwarder::instance()->isEnabled()); m_ui->checkRandomPort->setChecked(session->useRandomPort()); m_ui->spinPort->setValue(session->port()); m_ui->spinPort->setDisabled(m_ui->checkRandomPort->isChecked()); diff --git a/src/webui/prefjson.cpp b/src/webui/prefjson.cpp index 875b526cf..8fa2a4ea9 100644 --- a/src/webui/prefjson.cpp +++ b/src/webui/prefjson.cpp @@ -39,6 +39,7 @@ #include #include "base/bittorrent/session.h" +#include "base/net/portforwarder.h" #include "base/net/proxyconfigurationmanager.h" #include "base/preferences.h" #include "base/scanfoldersmodel.h" @@ -88,7 +89,7 @@ QByteArray prefjson::getPreferences() // Connection // Listening Port data["listen_port"] = session->port(); - data["upnp"] = pref->isUPnPEnabled(); + data["upnp"] = Net::PortForwarder::instance()->isEnabled(); data["random_port"] = session->useRandomPort(); // Connections Limits data["max_connec"] = session->maxConnections(); @@ -268,7 +269,7 @@ void prefjson::setPreferences(const QString& json) if (m.contains("listen_port")) session->setPort(m["listen_port"].toInt()); if (m.contains("upnp")) - pref->setUPnPEnabled(m["upnp"].toBool()); + Net::PortForwarder::instance()->setEnabled(m["upnp"].toBool()); if (m.contains("random_port")) session->setUseRandomPort(m["random_port"].toBool()); // Connections Limits