From f6735401f4738bac6dce92ed569e49873edbf5f9 Mon Sep 17 00:00:00 2001 From: Chocobo1 Date: Mon, 7 Nov 2022 11:32:11 +0800 Subject: [PATCH] Add port forwarding option for embedded tracker Closes #17781. PR #17981. --- src/base/bittorrent/sessionimpl.cpp | 21 ++++++++++++++++---- src/base/bittorrent/tracker.cpp | 8 ++++---- src/base/preferences.cpp | 10 ++++++++++ src/base/preferences.h | 2 ++ src/gui/advancedsettings.cpp | 6 ++++++ src/gui/advancedsettings.h | 2 +- src/webui/api/appcontroller.cpp | 3 +++ src/webui/webapplication.h | 2 +- src/webui/www/private/views/preferences.html | 10 ++++++++++ 9 files changed, 54 insertions(+), 10 deletions(-) diff --git a/src/base/bittorrent/sessionimpl.cpp b/src/base/bittorrent/sessionimpl.cpp index 6495a8fcf..f640d26ad 100644 --- a/src/base/bittorrent/sessionimpl.cpp +++ b/src/base/bittorrent/sessionimpl.cpp @@ -80,6 +80,7 @@ #include "base/logger.h" #include "base/net/downloadmanager.h" #include "base/net/proxyconfigurationmanager.h" +#include "base/preferences.h" #include "base/profile.h" #include "base/torrentfileguard.h" #include "base/torrentfilter.h" @@ -548,8 +549,6 @@ SessionImpl::SessionImpl(QObject *parent) if (isExcludedFileNamesEnabled()) populateExcludedFileNamesRegExpList(); - enableTracker(isTrackerEnabled()); - connect(Net::ProxyConfigurationManager::instance() , &Net::ProxyConfigurationManager::proxyConfigurationChanged , this, &SessionImpl::configureDeferred); @@ -569,11 +568,14 @@ SessionImpl::SessionImpl(QObject *parent) m_ioThread->start(); + initMetrics(); + loadStatistics(); + // initialize PortForwarder instance new PortForwarderImpl(m_nativeSession); - initMetrics(); - loadStatistics(); + // start embedded tracker + enableTracker(isTrackerEnabled()); prepareStartup(); } @@ -1980,16 +1982,27 @@ void SessionImpl::configurePeerClasses() void SessionImpl::enableTracker(const bool enable) { + const QString profile = u"embeddedTracker"_qs; + auto *portForwarder = Net::PortForwarder::instance(); + if (enable) { if (!m_tracker) m_tracker = new Tracker(this); m_tracker->start(); + + const auto *pref = Preferences::instance(); + if (pref->isTrackerPortForwardingEnabled()) + portForwarder->setPorts(profile, {static_cast(pref->getTrackerPort())}); + else + portForwarder->removePorts(profile); } else { delete m_tracker; + + portForwarder->removePorts(profile); } } diff --git a/src/base/bittorrent/tracker.cpp b/src/base/bittorrent/tracker.cpp index a811502ec..583c01743 100644 --- a/src/base/bittorrent/tracker.cpp +++ b/src/base/bittorrent/tracker.cpp @@ -203,12 +203,12 @@ Tracker::Tracker(QObject *parent) bool Tracker::start() { - const QHostAddress ip = QHostAddress::Any; const int port = Preferences::instance()->getTrackerPort(); if (m_server->isListening()) { - if (m_server->serverPort() == port) + if (const int oldPort = m_server->serverPort() + ; oldPort == port) { // Already listening on the right port, just return return true; @@ -218,9 +218,9 @@ bool Tracker::start() m_server->close(); } - // Listen on the predefined port + // Listen on port + const QHostAddress ip = QHostAddress::Any; const bool listenSuccess = m_server->listen(ip, port); - if (listenSuccess) { LogMsg(tr("Embedded Tracker: Now listening on IP: %1, port: %2") diff --git a/src/base/preferences.cpp b/src/base/preferences.cpp index 59a601118..4cc99227c 100644 --- a/src/base/preferences.cpp +++ b/src/base/preferences.cpp @@ -1164,6 +1164,16 @@ void Preferences::setTrackerPort(const int port) setValue(u"Preferences/Advanced/trackerPort"_qs, port); } +bool Preferences::isTrackerPortForwardingEnabled() const +{ + return value(u"Preferences/Advanced/trackerPortForwarding"_qs, false); +} + +void Preferences::setTrackerPortForwardingEnabled(const bool enabled) +{ + setValue(u"Preferences/Advanced/trackerPortForwarding"_qs, enabled); +} + #if defined(Q_OS_WIN) || defined(Q_OS_MACOS) bool Preferences::isUpdateCheckEnabled() const { diff --git a/src/base/preferences.h b/src/base/preferences.h index 534755b77..d22db8df5 100644 --- a/src/base/preferences.h +++ b/src/base/preferences.h @@ -299,6 +299,8 @@ public: #endif int getTrackerPort() const; void setTrackerPort(int port); + bool isTrackerPortForwardingEnabled() const; + void setTrackerPortForwardingEnabled(bool enabled); #if defined(Q_OS_WIN) || defined(Q_OS_MACOS) bool isUpdateCheckEnabled() const; void setUpdateCheckEnabled(bool enabled); diff --git a/src/gui/advancedsettings.cpp b/src/gui/advancedsettings.cpp index 1f2dda5f5..fb8618f6d 100644 --- a/src/gui/advancedsettings.cpp +++ b/src/gui/advancedsettings.cpp @@ -97,6 +97,7 @@ namespace // embedded tracker TRACKER_STATUS, TRACKER_PORT, + TRACKER_PORT_FORWARDING, // libtorrent section LIBTORRENT_HEADER, ASYNC_IO_THREADS, @@ -292,7 +293,9 @@ void AdvancedSettings::saveAdvancedSettings() const // Tracker pref->setTrackerPort(m_spinBoxTrackerPort.value()); + pref->setTrackerPortForwardingEnabled(m_checkBoxTrackerPortForwarding.isChecked()); session->setTrackerEnabled(m_checkBoxTrackerStatus.isChecked()); + // Choking algorithm session->setChokingAlgorithm(m_comboBoxChokingAlgorithm.currentData().value()); // Seed choking algorithm @@ -732,6 +735,9 @@ void AdvancedSettings::loadAdvancedSettings() m_spinBoxTrackerPort.setMaximum(65535); m_spinBoxTrackerPort.setValue(pref->getTrackerPort()); addRow(TRACKER_PORT, tr("Embedded tracker port"), &m_spinBoxTrackerPort); + // Tracker port forwarding + m_checkBoxTrackerPortForwarding.setChecked(pref->isTrackerPortForwardingEnabled()); + addRow(TRACKER_PORT_FORWARDING, tr("Enable port forwarding for embedded tracker"), &m_checkBoxTrackerPortForwarding); // Choking algorithm m_comboBoxChokingAlgorithm.addItem(tr("Fixed slots"), QVariant::fromValue(BitTorrent::ChokingAlgorithm::FixedSlots)); m_comboBoxChokingAlgorithm.addItem(tr("Upload rate based"), QVariant::fromValue(BitTorrent::ChokingAlgorithm::RateBased)); diff --git a/src/gui/advancedsettings.h b/src/gui/advancedsettings.h index 7846ca5c6..79e3146b2 100644 --- a/src/gui/advancedsettings.h +++ b/src/gui/advancedsettings.h @@ -68,7 +68,7 @@ private: m_spinBoxSavePathHistoryLength, m_spinBoxPeerTurnover, m_spinBoxPeerTurnoverCutoff, m_spinBoxPeerTurnoverInterval, m_spinBoxRequestQueueSize; QCheckBox m_checkBoxOsCache, m_checkBoxRecheckCompleted, m_checkBoxResolveCountries, m_checkBoxResolveHosts, m_checkBoxProgramNotifications, m_checkBoxTorrentAddedNotifications, m_checkBoxReannounceWhenAddressChanged, m_checkBoxTrackerFavicon, m_checkBoxTrackerStatus, - m_checkBoxConfirmTorrentRecheck, m_checkBoxConfirmRemoveAllTags, m_checkBoxAnnounceAllTrackers, m_checkBoxAnnounceAllTiers, + m_checkBoxTrackerPortForwarding, m_checkBoxConfirmTorrentRecheck, m_checkBoxConfirmRemoveAllTags, m_checkBoxAnnounceAllTrackers, m_checkBoxAnnounceAllTiers, m_checkBoxMultiConnectionsPerIp, m_checkBoxValidateHTTPSTrackerCertificate, m_checkBoxSSRFMitigation, m_checkBoxBlockPeersOnPrivilegedPorts, m_checkBoxPieceExtentAffinity, m_checkBoxSuggestMode, m_checkBoxSpeedWidgetEnabled, m_checkBoxIDNSupport; QComboBox m_comboBoxInterface, m_comboBoxInterfaceAddress, m_comboBoxDiskIOReadMode, m_comboBoxDiskIOWriteMode, m_comboBoxUtpMixedMode, m_comboBoxChokingAlgorithm, diff --git a/src/webui/api/appcontroller.cpp b/src/webui/api/appcontroller.cpp index c8d66ea64..0b82613c7 100644 --- a/src/webui/api/appcontroller.cpp +++ b/src/webui/api/appcontroller.cpp @@ -372,6 +372,7 @@ void AppController::preferencesAction() // Embedded tracker data[u"enable_embedded_tracker"_qs] = session->isTrackerEnabled(); data[u"embedded_tracker_port"_qs] = pref->getTrackerPort(); + data[u"embedded_tracker_port_forwarding"_qs] = pref->isTrackerPortForwardingEnabled(); // Choking algorithm data[u"upload_slots_behavior"_qs] = static_cast(session->chokingAlgorithm()); // Seed choking algorithm @@ -899,6 +900,8 @@ void AppController::setPreferencesAction() // Embedded tracker if (hasKey(u"embedded_tracker_port"_qs)) pref->setTrackerPort(it.value().toInt()); + if (hasKey(u"embedded_tracker_port_forwarding"_qs)) + pref->setTrackerPortForwardingEnabled(it.value().toBool()); if (hasKey(u"enable_embedded_tracker"_qs)) session->setTrackerEnabled(it.value().toBool()); // Choking algorithm diff --git a/src/webui/webapplication.h b/src/webui/webapplication.h index df58992ba..54a3f3c4e 100644 --- a/src/webui/webapplication.h +++ b/src/webui/webapplication.h @@ -52,7 +52,7 @@ #include "base/utils/version.h" #include "api/isessionmanager.h" -inline const Utils::Version<3, 2> API_VERSION {2, 8, 17}; +inline const Utils::Version<3, 2> API_VERSION {2, 8, 18}; class APIController; class AuthController; diff --git a/src/webui/www/private/views/preferences.html b/src/webui/www/private/views/preferences.html index fbc237828..78f1b42c5 100644 --- a/src/webui/www/private/views/preferences.html +++ b/src/webui/www/private/views/preferences.html @@ -1016,6 +1016,14 @@ Use ';' to split multiple entries. Can use wildcard '*'.)QBT_TR[CONTEXT=OptionsD + + + + + + + +
@@ -2099,6 +2107,7 @@ Use ';' to split multiple entries. Can use wildcard '*'.)QBT_TR[CONTEXT=OptionsD $('blockPeersOnPrivilegedPorts').setProperty('checked', pref.block_peers_on_privileged_ports); $('enableEmbeddedTracker').setProperty('checked', pref.enable_embedded_tracker); $('embeddedTrackerPort').setProperty('value', pref.embedded_tracker_port); + $('embeddedTrackerPortForwarding').setProperty('checked', pref.embedded_tracker_port_forwarding); $('uploadSlotsBehavior').setProperty('value', pref.upload_slots_behavior); $('uploadChokingAlgorithm').setProperty('value', pref.upload_choking_algorithm); $('announceAllTrackers').setProperty('checked', pref.announce_to_all_trackers); @@ -2526,6 +2535,7 @@ Use ';' to split multiple entries. Can use wildcard '*'.)QBT_TR[CONTEXT=OptionsD settings.set('block_peers_on_privileged_ports', $('blockPeersOnPrivilegedPorts').getProperty('checked')); settings.set('enable_embedded_tracker', $('enableEmbeddedTracker').getProperty('checked')); settings.set('embedded_tracker_port', $('embeddedTrackerPort').getProperty('value')); + settings.set('embedded_tracker_port_forwarding', $('embeddedTrackerPortForwarding').getProperty('checked')); settings.set('upload_slots_behavior', $('uploadSlotsBehavior').getProperty('value')); settings.set('upload_choking_algorithm', $('uploadChokingAlgorithm').getProperty('value')); settings.set('announce_to_all_trackers', $('announceAllTrackers').getProperty('checked'));