From f2dd1e645601e7b836aed28490a4f783eb046bc2 Mon Sep 17 00:00:00 2001 From: Nathan Lewis Date: Sun, 23 Oct 2022 02:31:02 -0500 Subject: [PATCH] Add a "Use proxy for hostname lookup" option Add a UI option for "Use proxy for hostname lookup" option and plumb it into libtorrent's settings_pack.proxy_hostnames option. This is available for SOCKS5 and HTTP proxies, and defaults to true, which is the previous functionality. Hostname lookups can be forced to be local by unchecking this option, which can aid compatibility with certain non-compliant proxy servers. Closes #17902. PR #17904. Co-authored-by: Nathan Lewis --- src/base/bittorrent/session.h | 2 ++ src/base/bittorrent/sessionimpl.cpp | 16 ++++++++++++++++ src/base/bittorrent/sessionimpl.h | 3 +++ src/gui/optionsdialog.cpp | 9 +++++++++ src/gui/optionsdialog.ui | 14 ++++++++++++++ src/webui/api/appcontroller.cpp | 3 +++ src/webui/webapplication.h | 2 +- src/webui/www/private/views/preferences.html | 12 +++++++++++- 8 files changed, 59 insertions(+), 2 deletions(-) diff --git a/src/base/bittorrent/session.h b/src/base/bittorrent/session.h index c0dd788fd..981917dd4 100644 --- a/src/base/bittorrent/session.h +++ b/src/base/bittorrent/session.h @@ -260,6 +260,8 @@ namespace BitTorrent virtual void setMaxActiveCheckingTorrents(int val) = 0; virtual bool isProxyPeerConnectionsEnabled() const = 0; virtual void setProxyPeerConnectionsEnabled(bool enabled) = 0; + virtual bool isProxyHostnameLookupEnabled() const = 0; + virtual void setProxyHostnameLookupEnabled(bool enabled) = 0; virtual ChokingAlgorithm chokingAlgorithm() const = 0; virtual void setChokingAlgorithm(ChokingAlgorithm mode) = 0; virtual SeedChokingAlgorithm seedChokingAlgorithm() const = 0; diff --git a/src/base/bittorrent/sessionimpl.cpp b/src/base/bittorrent/sessionimpl.cpp index 9d85c7944..9316e9621 100644 --- a/src/base/bittorrent/sessionimpl.cpp +++ b/src/base/bittorrent/sessionimpl.cpp @@ -475,6 +475,7 @@ SessionImpl::SessionImpl(QObject *parent) , m_encryption(BITTORRENT_SESSION_KEY(u"Encryption"_qs), 0) , m_maxActiveCheckingTorrents(BITTORRENT_SESSION_KEY(u"MaxActiveCheckingTorrents"_qs), 1) , m_isProxyPeerConnectionsEnabled(BITTORRENT_SESSION_KEY(u"ProxyPeerConnections"_qs), false) + , m_isProxyHostnameLookupEnabled(BITTORRENT_SESSION_KEY(u"ProxyHostnameLookup"_qs), true) , m_chokingAlgorithm(BITTORRENT_SESSION_KEY(u"ChokingAlgorithm"_qs), ChokingAlgorithm::FixedSlots , clampValue(ChokingAlgorithm::FixedSlots, ChokingAlgorithm::RateBased)) , m_seedChokingAlgorithm(BITTORRENT_SESSION_KEY(u"SeedChokingAlgorithm"_qs), SeedChokingAlgorithm::FastestUpload @@ -1644,6 +1645,7 @@ void SessionImpl::loadLTSettings(lt::settings_pack &settingsPack) } settingsPack.set_bool(lt::settings_pack::proxy_peer_connections, isProxyPeerConnectionsEnabled()); + settingsPack.set_bool(lt::settings_pack::proxy_hostnames, isProxyHostnameLookupEnabled()); } settingsPack.set_bool(lt::settings_pack::announce_to_all_trackers, announceToAllTrackers()); @@ -3442,6 +3444,20 @@ void SessionImpl::setProxyPeerConnectionsEnabled(const bool enabled) } } +bool SessionImpl::isProxyHostnameLookupEnabled() const +{ + return m_isProxyHostnameLookupEnabled; +} + +void SessionImpl::setProxyHostnameLookupEnabled(const bool enabled) +{ + if (enabled != isProxyHostnameLookupEnabled()) + { + m_isProxyHostnameLookupEnabled = enabled; + configureDeferred(); + } +} + ChokingAlgorithm SessionImpl::chokingAlgorithm() const { return m_chokingAlgorithm; diff --git a/src/base/bittorrent/sessionimpl.h b/src/base/bittorrent/sessionimpl.h index c09ef72fe..6d4f26eb2 100644 --- a/src/base/bittorrent/sessionimpl.h +++ b/src/base/bittorrent/sessionimpl.h @@ -240,6 +240,8 @@ namespace BitTorrent void setMaxActiveCheckingTorrents(int val) override; bool isProxyPeerConnectionsEnabled() const override; void setProxyPeerConnectionsEnabled(bool enabled) override; + bool isProxyHostnameLookupEnabled() const override; + void setProxyHostnameLookupEnabled(bool enabled) override; ChokingAlgorithm chokingAlgorithm() const override; void setChokingAlgorithm(ChokingAlgorithm mode) override; SeedChokingAlgorithm seedChokingAlgorithm() const override; @@ -645,6 +647,7 @@ namespace BitTorrent CachedSettingValue m_encryption; CachedSettingValue m_maxActiveCheckingTorrents; CachedSettingValue m_isProxyPeerConnectionsEnabled; + CachedSettingValue m_isProxyHostnameLookupEnabled; CachedSettingValue m_chokingAlgorithm; CachedSettingValue m_seedChokingAlgorithm; CachedSettingValue m_storedTags; diff --git a/src/gui/optionsdialog.cpp b/src/gui/optionsdialog.cpp index ea6befb74..d4068e26a 100644 --- a/src/gui/optionsdialog.cpp +++ b/src/gui/optionsdialog.cpp @@ -858,6 +858,7 @@ void OptionsDialog::loadConnectionTabOptions() m_ui->checkProxyPeerConnections->setChecked(session->isProxyPeerConnectionsEnabled()); m_ui->isProxyOnlyForTorrents->setChecked(proxyConfigManager->isProxyOnlyForTorrents()); + m_ui->checkProxyHostnameLookup->setChecked(session->isProxyHostnameLookupEnabled()); enableProxy(m_ui->comboProxyType->currentIndex()); m_ui->checkIPFilter->setChecked(session->isIPFilteringEnabled()); @@ -887,8 +888,11 @@ void OptionsDialog::loadConnectionTabOptions() connect(m_ui->comboProxyType, qComboBoxCurrentIndexChanged, this, &ThisType::enableApplyButton); connect(m_ui->textProxyIP, &QLineEdit::textChanged, this, &ThisType::enableApplyButton); connect(m_ui->spinProxyPort, qSpinBoxValueChanged, this, &ThisType::enableApplyButton); + connect(m_ui->checkProxyPeerConnections, &QAbstractButton::toggled, this, &ThisType::enableApplyButton); connect(m_ui->isProxyOnlyForTorrents, &QAbstractButton::toggled, this, &ThisType::enableApplyButton); + connect(m_ui->checkProxyHostnameLookup, &QAbstractButton::toggled, this, &ThisType::enableApplyButton); + connect(m_ui->checkProxyAuth, &QGroupBox::toggled, this, &ThisType::enableApplyButton); connect(m_ui->textProxyUsername, &QLineEdit::textChanged, this, &ThisType::enableApplyButton); connect(m_ui->textProxyPassword, &QLineEdit::textChanged, this, &ThisType::enableApplyButton); @@ -922,7 +926,9 @@ void OptionsDialog::saveConnectionTabOptions() const proxyConf.password = getProxyPassword(); proxyConfigManager->setProxyOnlyForTorrents(m_ui->isProxyOnlyForTorrents->isChecked()); proxyConfigManager->setProxyConfiguration(proxyConf); + session->setProxyPeerConnectionsEnabled(m_ui->checkProxyPeerConnections->isChecked()); + session->setProxyHostnameLookupEnabled(m_ui->checkProxyHostnameLookup->isChecked()); // IPFilter session->setIPFilteringEnabled(isIPFilteringEnabled()); @@ -1596,12 +1602,14 @@ void OptionsDialog::enableProxy(const int index) { // SOCKS5 or HTTP m_ui->checkProxyAuth->setEnabled(true); m_ui->isProxyOnlyForTorrents->setEnabled(true); + m_ui->checkProxyHostnameLookup->setEnabled(true); } else { m_ui->checkProxyAuth->setEnabled(false); m_ui->isProxyOnlyForTorrents->setEnabled(false); m_ui->isProxyOnlyForTorrents->setChecked(true); + m_ui->checkProxyHostnameLookup->setEnabled(false); } } else @@ -1613,6 +1621,7 @@ void OptionsDialog::enableProxy(const int index) m_ui->spinProxyPort->setEnabled(false); m_ui->checkProxyPeerConnections->setEnabled(false); m_ui->isProxyOnlyForTorrents->setEnabled(false); + m_ui->checkProxyHostnameLookup->setEnabled(false); m_ui->checkProxyAuth->setEnabled(false); } } diff --git a/src/gui/optionsdialog.ui b/src/gui/optionsdialog.ui index e85f0e1cc..ea4c73d7f 100644 --- a/src/gui/optionsdialog.ui +++ b/src/gui/optionsdialog.ui @@ -1856,6 +1856,19 @@ readme[0-9].txt: filter 'readme1.txt', 'readme2.txt' but not 'readme10.txt'. + + + + true + + + If checked, hostname lookups are done via the proxy. + + + Use proxy for hostname lookups + + + @@ -3667,6 +3680,7 @@ Use ';' to split multiple entries. Can use wildcard '*'. spinProxyPort checkProxyPeerConnections isProxyOnlyForTorrents + checkProxyHostnameLookup checkProxyAuth textProxyUsername textProxyPassword diff --git a/src/webui/api/appcontroller.cpp b/src/webui/api/appcontroller.cpp index 8e23949c2..c8d66ea64 100644 --- a/src/webui/api/appcontroller.cpp +++ b/src/webui/api/appcontroller.cpp @@ -189,6 +189,7 @@ void AppController::preferencesAction() data[u"proxy_peer_connections"_qs] = session->isProxyPeerConnectionsEnabled(); data[u"proxy_torrents_only"_qs] = proxyManager->isProxyOnlyForTorrents(); + data[u"proxy_hostname_lookup"_qs] = session->isProxyHostnameLookupEnabled(); // IP Filtering data[u"ip_filter_enabled"_qs] = session->isIPFilteringEnabled(); @@ -569,6 +570,8 @@ void AppController::setPreferencesAction() session->setProxyPeerConnectionsEnabled(it.value().toBool()); if (hasKey(u"proxy_torrents_only"_qs)) proxyManager->setProxyOnlyForTorrents(it.value().toBool()); + if (hasKey(u"proxy_hostname_lookup"_qs)) + session->setProxyHostnameLookupEnabled(it.value().toBool()); // IP Filtering if (hasKey(u"ip_filter_enabled"_qs)) diff --git a/src/webui/webapplication.h b/src/webui/webapplication.h index cd89f6011..79b5f9c69 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, 15}; +inline const Utils::Version<3, 2> API_VERSION {2, 8, 16}; class APIController; class AuthController; diff --git a/src/webui/www/private/views/preferences.html b/src/webui/www/private/views/preferences.html index 3b126cda5..fbc237828 100644 --- a/src/webui/www/private/views/preferences.html +++ b/src/webui/www/private/views/preferences.html @@ -333,6 +333,10 @@ +
+ + +
@@ -1541,12 +1545,16 @@ Use ';' to split multiple entries. Can use wildcard '*'.)QBT_TR[CONTEXT=OptionsD $('peer_proxy_host_text').setProperty('disabled', !isPeerProxyTypeSelected); $('peer_proxy_port_value').setProperty('disabled', !isPeerProxyTypeSelected); $('use_peer_proxy_checkbox').setProperty('disabled', !isPeerProxyTypeSelected); - const isPeerProxyAuthenticatable = ($('peer_proxy_type_select').getProperty('value') === "socks5" || $('peer_proxy_type_select').getProperty('value') === "http"); + const proxyType = $('peer_proxy_type_select').getProperty('value'); + const isPeerProxyAuthenticatable = (proxyType === "socks5") || (proxyType === "http"); $('proxy_only_for_torrents_checkbox').setProperty('disabled', !isPeerProxyAuthenticatable); if ($('peer_proxy_type_select').getProperty('value') === "socks4") $('proxy_only_for_torrents_checkbox').setProperty('checked', true); + const canPeerProxyResolveHostnames = (proxyType === "socks5") || (proxyType === "http"); + $('proxyHostnameLookupCheckbox').setProperty('disabled', !canPeerProxyResolveHostnames); + $('peer_proxy_auth_checkbox').setProperty('disabled', !isPeerProxyAuthenticatable); updatePeerProxyAuthSettings(); @@ -1901,6 +1909,7 @@ Use ';' to split multiple entries. Can use wildcard '*'.)QBT_TR[CONTEXT=OptionsD $('peer_proxy_port_value').setProperty('value', pref.proxy_port); $('use_peer_proxy_checkbox').setProperty('checked', pref.proxy_peer_connections); $('proxy_only_for_torrents_checkbox').setProperty('checked', pref.proxy_torrents_only); + $('proxyHostnameLookupCheckbox').setProperty('checked', pref.proxy_hostname_lookup); $('peer_proxy_auth_checkbox').setProperty('checked', pref.proxy_auth_enabled); updatePeerProxyAuthSettings(); $('peer_proxy_username_text').setProperty('value', pref.proxy_username); @@ -2243,6 +2252,7 @@ Use ';' to split multiple entries. Can use wildcard '*'.)QBT_TR[CONTEXT=OptionsD settings.set('proxy_port', $('peer_proxy_port_value').getProperty('value').toInt()); settings.set('proxy_peer_connections', $('use_peer_proxy_checkbox').getProperty('checked')); settings.set('proxy_torrents_only', $('proxy_only_for_torrents_checkbox').getProperty('checked')); + settings.set('proxy_hostname_lookup', $('proxyHostnameLookupCheckbox').getProperty('checked')); settings.set('proxy_username', $('peer_proxy_username_text').getProperty('value')); settings.set('proxy_password', $('peer_proxy_password_text').getProperty('value'));