From e2f43b338360079622a26d28a7b6a79ce764a71c Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sat, 9 Apr 2016 09:19:22 -0700 Subject: [PATCH 1/4] Add option to bind directly to an IP instead of using a network Interface --- src/base/bittorrent/session.cpp | 9 ++++++++- src/base/preferences.cpp | 18 ++++++++++++++---- src/base/preferences.h | 6 ++++-- src/gui/advancedsettings.cpp | 23 ++++++++++++++++++----- src/gui/advancedsettings.h | 1 + 5 files changed, 45 insertions(+), 12 deletions(-) diff --git a/src/base/bittorrent/session.cpp b/src/base/bittorrent/session.cpp index e781b15a6..51136a78f 100644 --- a/src/base/bittorrent/session.cpp +++ b/src/base/bittorrent/session.cpp @@ -633,7 +633,7 @@ void Session::setSessionSettings() // Include overhead in transfer limits sessionSettings.rate_limit_ip_overhead = pref->includeOverheadInLimits(); // IP address to announce to trackers - sessionSettings.announce_ip = Utils::String::toStdString(pref->getNetworkAddress()); + sessionSettings.announce_ip = Utils::String::toStdString(pref->getAnnounceAddress()); // Super seeding sessionSettings.strict_super_seeding = pref->isSuperSeedingEnabled(); // * Max Half-open connections @@ -1658,6 +1658,13 @@ const QStringList Session::getListeningIPs() Logger* const logger = Logger::instance(); QStringList IPs; + //Take the override addresss + const QString networkAddr = pref->getNetworkAddress(); + if ( !networkAddr.isEmpty()) { + IPs.append( networkAddr); + return IPs; + } + const QString ifaceName = pref->getNetworkInterface(); const bool listenIPv6 = pref->getListenIPv6(); diff --git a/src/base/preferences.cpp b/src/base/preferences.cpp index 2fbda9c15..661c56f48 100644 --- a/src/base/preferences.cpp +++ b/src/base/preferences.cpp @@ -1349,6 +1349,16 @@ QString Preferences::getNetworkInterfaceName() const return value("Preferences/Connection/InterfaceName").toString(); } +void Preferences::setNetworkAddress(const QString& iface) +{ + setValue("Preferences/Connection/InterfaceAddress", iface); +} + +QString Preferences::getNetworkAddress() const +{ + return value("Preferences/Connection/InterfaceAddress").toString(); +} + void Preferences::setNetworkInterfaceName(const QString& iface) { setValue("Preferences/Connection/InterfaceName", iface); @@ -1364,14 +1374,14 @@ void Preferences::setListenIPv6(bool enable) setValue("Preferences/Connection/InterfaceListenIPv6", enable); } -QString Preferences::getNetworkAddress() const +QString Preferences::getAnnounceAddress() const { - return value("Preferences/Connection/InetAddress").toString(); + return value("Preferences/Connection/AnnounceAddress").toString(); } -void Preferences::setNetworkAddress(const QString& addr) +void Preferences::setAnnounceAddress(const QString& addr) { - setValue("Preferences/Connection/InetAddress", addr); + setValue("Preferences/Connection/AnnounceAddress", addr); } bool Preferences::isAnonymousModeEnabled() const diff --git a/src/base/preferences.h b/src/base/preferences.h index f9eaec5ff..f2da7ae16 100644 --- a/src/base/preferences.h +++ b/src/base/preferences.h @@ -363,12 +363,14 @@ public: void setMaxHalfOpenConnections(int value); QString getNetworkInterface() const; void setNetworkInterface(const QString& iface); + QString getNetworkAddress() const; + void setNetworkAddress(const QString& iface); QString getNetworkInterfaceName() const; void setNetworkInterfaceName(const QString& iface); bool getListenIPv6() const; void setListenIPv6(bool enable); - QString getNetworkAddress() const; - void setNetworkAddress(const QString& addr); + QString getAnnounceAddress() const; + void setAnnounceAddress(const QString& addr); bool isAnonymousModeEnabled() const; void enableAnonymousMode(bool enabled); bool isSuperSeedingEnabled() const; diff --git a/src/gui/advancedsettings.cpp b/src/gui/advancedsettings.cpp index 1216ed5c3..1dbd9f09d 100644 --- a/src/gui/advancedsettings.cpp +++ b/src/gui/advancedsettings.cpp @@ -45,6 +45,8 @@ enum AdvSettingsRows QBITTORRENT_HEADER, // network interface NETWORK_IFACE, + //Optional bind address + NETWORK_ADDRESS, NETWORK_LISTEN_IPV6, // behavior SAVE_RESUME_DATA_INTERVAL, @@ -80,7 +82,7 @@ enum AdvSettingsRows // tracker TRACKER_EXCHANGE, ANNOUNCE_ALL_TRACKERS, - NETWORK_ADDRESS, + ANNOUNCE_ADDRESS, ROW_COUNT }; @@ -144,11 +146,18 @@ void AdvancedSettings::saveAdvancedSettings() // Listen on IPv6 address pref->setListenIPv6(cb_listen_ipv6.isChecked()); // Network address - QHostAddress addr(txt_network_address.text().trimmed()); - if (addr.isNull()) + QHostAddress networkAddr(txt_network_address.text().trimmed()); + if (networkAddr.isNull()) pref->setNetworkAddress(""); else - pref->setNetworkAddress(addr.toString()); + pref->setNetworkAddress(networkAddr.toString()); + // Announce address + QHostAddress announceAddr(txt_announce_address.text().trimmed()); + if (announceAddr.isNull()) + pref->setAnnounceAddress(""); + else + pref->setAnnounceAddress(announceAddr.toString()); + // Program notification pref->useProgramNotification(cb_program_notifications.isChecked()); // Tracker @@ -276,7 +285,11 @@ void AdvancedSettings::loadAdvancedSettings() addRow(NETWORK_LISTEN_IPV6, tr("Listen on IPv6 address (requires restart)"), &cb_listen_ipv6); // Network address txt_network_address.setText(pref->getNetworkAddress()); - addRow(NETWORK_ADDRESS, tr("IP Address to report to trackers (requires restart)"), &txt_network_address); + addRow(NETWORK_ADDRESS, tr("IP Address to bind to( requires restart))"), &txt_network_address); + // Network address + txt_announce_address.setText(pref->getAnnounceAddress()); + addRow(ANNOUNCE_ADDRESS, tr("IP Address to report to trackers (requires restart)"), &txt_announce_address); + // Program notifications cb_program_notifications.setChecked(pref->useProgramNotification()); addRow(PROGRAM_NOTIFICATIONS, tr("Display program on-screen notifications"), &cb_program_notifications); diff --git a/src/gui/advancedsettings.h b/src/gui/advancedsettings.h index b0d13f8c7..8f132ba39 100644 --- a/src/gui/advancedsettings.h +++ b/src/gui/advancedsettings.h @@ -63,6 +63,7 @@ private: cb_super_seeding, cb_program_notifications, cb_tracker_status, cb_confirm_torrent_recheck, cb_enable_tracker_ext, cb_listen_ipv6, cb_announce_all_trackers; QComboBox combo_iface; + QLineEdit txt_announce_address; QLineEdit txt_network_address; // OS dependent settings From c7c71d3c888d335824891bbec25e0d1f55f72c43 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Wed, 13 Apr 2016 10:51:29 +0200 Subject: [PATCH 2/4] Change back to the original names for the announce address Only allow ip's through that match the currenrly selected network interface and address --- src/base/bittorrent/session.cpp | 20 +++++++++++--------- src/base/preferences.cpp | 14 +++++++------- src/base/preferences.h | 8 ++++---- src/gui/advancedsettings.cpp | 30 +++++++++++++++--------------- src/gui/advancedsettings.h | 3 +-- 5 files changed, 38 insertions(+), 37 deletions(-) diff --git a/src/base/bittorrent/session.cpp b/src/base/bittorrent/session.cpp index 51136a78f..360a8b1c3 100644 --- a/src/base/bittorrent/session.cpp +++ b/src/base/bittorrent/session.cpp @@ -633,7 +633,7 @@ void Session::setSessionSettings() // Include overhead in transfer limits sessionSettings.rate_limit_ip_overhead = pref->includeOverheadInLimits(); // IP address to announce to trackers - sessionSettings.announce_ip = Utils::String::toStdString(pref->getAnnounceAddress()); + sessionSettings.announce_ip = Utils::String::toStdString(pref->getNetworkAddress()); // Super seeding sessionSettings.strict_super_seeding = pref->isSuperSeedingEnabled(); // * Max Half-open connections @@ -1658,17 +1658,12 @@ const QStringList Session::getListeningIPs() Logger* const logger = Logger::instance(); QStringList IPs; - //Take the override addresss - const QString networkAddr = pref->getNetworkAddress(); - if ( !networkAddr.isEmpty()) { - IPs.append( networkAddr); - return IPs; - } - const QString ifaceName = pref->getNetworkInterface(); + const QString ifaceAddr = pref->getNetworkInterfaceAddress(); const bool listenIPv6 = pref->getListenIPv6(); - if (ifaceName.isEmpty()) { + //No interface name or address defined just use an empty list + if (ifaceName.isEmpty() && ifaceAddr.isEmpty()) { IPs.append(QString()); return IPs; } @@ -1695,6 +1690,13 @@ const QStringList Session::getListeningIPs() if ((!listenIPv6 && (protocol == QAbstractSocket::IPv6Protocol)) || (listenIPv6 && (protocol == QAbstractSocket::IPv4Protocol))) continue; + + //If an iface address has been defined only allow ip's that match it to go through + if (!ifaceAddr.isEmpty()) { + if (ipString != ifaceAddr) { + continue; + } + } IPs.append(ipString); } diff --git a/src/base/preferences.cpp b/src/base/preferences.cpp index 661c56f48..d135a5d6d 100644 --- a/src/base/preferences.cpp +++ b/src/base/preferences.cpp @@ -1349,12 +1349,12 @@ QString Preferences::getNetworkInterfaceName() const return value("Preferences/Connection/InterfaceName").toString(); } -void Preferences::setNetworkAddress(const QString& iface) +void Preferences::setNetworkInterfaceAddress(const QString& addr) { - setValue("Preferences/Connection/InterfaceAddress", iface); + setValue("Preferences/Connection/InterfaceAddress", addr); } -QString Preferences::getNetworkAddress() const +QString Preferences::getNetworkInterfaceAddress() const { return value("Preferences/Connection/InterfaceAddress").toString(); } @@ -1374,14 +1374,14 @@ void Preferences::setListenIPv6(bool enable) setValue("Preferences/Connection/InterfaceListenIPv6", enable); } -QString Preferences::getAnnounceAddress() const +QString Preferences::getNetworkAddress() const { - return value("Preferences/Connection/AnnounceAddress").toString(); + return value("Preferences/Connection/InetAddress").toString(); } -void Preferences::setAnnounceAddress(const QString& addr) +void Preferences::setNetworkAddress(const QString& addr) { - setValue("Preferences/Connection/AnnounceAddress", addr); + setValue("Preferences/Connection/InetAddress", addr); } bool Preferences::isAnonymousModeEnabled() const diff --git a/src/base/preferences.h b/src/base/preferences.h index f2da7ae16..52dcb6556 100644 --- a/src/base/preferences.h +++ b/src/base/preferences.h @@ -363,14 +363,14 @@ public: void setMaxHalfOpenConnections(int value); QString getNetworkInterface() const; void setNetworkInterface(const QString& iface); - QString getNetworkAddress() const; - void setNetworkAddress(const QString& iface); + QString getNetworkInterfaceAddress() const; + void setNetworkInterfaceAddress(const QString& addr); QString getNetworkInterfaceName() const; void setNetworkInterfaceName(const QString& iface); bool getListenIPv6() const; void setListenIPv6(bool enable); - QString getAnnounceAddress() const; - void setAnnounceAddress(const QString& addr); + QString getNetworkAddress() const; + void setNetworkAddress(const QString& addr); bool isAnonymousModeEnabled() const; void enableAnonymousMode(bool enabled); bool isSuperSeedingEnabled() const; diff --git a/src/gui/advancedsettings.cpp b/src/gui/advancedsettings.cpp index 1dbd9f09d..5a516c19d 100644 --- a/src/gui/advancedsettings.cpp +++ b/src/gui/advancedsettings.cpp @@ -45,8 +45,8 @@ enum AdvSettingsRows QBITTORRENT_HEADER, // network interface NETWORK_IFACE, - //Optional bind address - NETWORK_ADDRESS, + //Optional network address + NETWORK_IFACE_ADDRESS, NETWORK_LISTEN_IPV6, // behavior SAVE_RESUME_DATA_INTERVAL, @@ -82,7 +82,7 @@ enum AdvSettingsRows // tracker TRACKER_EXCHANGE, ANNOUNCE_ALL_TRACKERS, - ANNOUNCE_ADDRESS, + NETWORK_ADDRESS, ROW_COUNT }; @@ -145,18 +145,18 @@ void AdvancedSettings::saveAdvancedSettings() } // Listen on IPv6 address pref->setListenIPv6(cb_listen_ipv6.isChecked()); - // Network address + // Interface address + QHostAddress ifaceAddr(txt_iface_address.text().trimmed()); + if (ifaceAddr.isNull()) + pref->setNetworkInterfaceAddress(""); + else + pref->setNetworkInterfaceAddress(ifaceAddr.toString()); + // Network Announce address QHostAddress networkAddr(txt_network_address.text().trimmed()); if (networkAddr.isNull()) pref->setNetworkAddress(""); else pref->setNetworkAddress(networkAddr.toString()); - // Announce address - QHostAddress announceAddr(txt_announce_address.text().trimmed()); - if (announceAddr.isNull()) - pref->setAnnounceAddress(""); - else - pref->setAnnounceAddress(announceAddr.toString()); // Program notification pref->useProgramNotification(cb_program_notifications.isChecked()); @@ -283,12 +283,12 @@ void AdvancedSettings::loadAdvancedSettings() // Listen on IPv6 address cb_listen_ipv6.setChecked(pref->getListenIPv6()); addRow(NETWORK_LISTEN_IPV6, tr("Listen on IPv6 address (requires restart)"), &cb_listen_ipv6); - // Network address + // Network interface address + txt_iface_address.setText(pref->getNetworkInterfaceAddress()); + addRow(NETWORK_IFACE_ADDRESS, tr("Optional IP Address to bind to (requires restart)"), &txt_iface_address); + // Announce address txt_network_address.setText(pref->getNetworkAddress()); - addRow(NETWORK_ADDRESS, tr("IP Address to bind to( requires restart))"), &txt_network_address); - // Network address - txt_announce_address.setText(pref->getAnnounceAddress()); - addRow(ANNOUNCE_ADDRESS, tr("IP Address to report to trackers (requires restart)"), &txt_announce_address); + addRow(NETWORK_ADDRESS, tr("IP Address to report to trackers (requires restart)"), &txt_network_address); // Program notifications cb_program_notifications.setChecked(pref->useProgramNotification()); diff --git a/src/gui/advancedsettings.h b/src/gui/advancedsettings.h index 8f132ba39..855475231 100644 --- a/src/gui/advancedsettings.h +++ b/src/gui/advancedsettings.h @@ -63,8 +63,7 @@ private: cb_super_seeding, cb_program_notifications, cb_tracker_status, cb_confirm_torrent_recheck, cb_enable_tracker_ext, cb_listen_ipv6, cb_announce_all_trackers; QComboBox combo_iface; - QLineEdit txt_announce_address; - QLineEdit txt_network_address; + QLineEdit txt_iface_address, network_address; // OS dependent settings #if defined(Q_OS_WIN) || defined(Q_OS_MAC) From 03d1dad2a3f8367aafd37baeef82c7a17abe14ae Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Wed, 13 Apr 2016 11:17:36 +0200 Subject: [PATCH 3/4] Fix variable name --- src/gui/advancedsettings.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/advancedsettings.h b/src/gui/advancedsettings.h index 855475231..ca8945557 100644 --- a/src/gui/advancedsettings.h +++ b/src/gui/advancedsettings.h @@ -63,7 +63,7 @@ private: cb_super_seeding, cb_program_notifications, cb_tracker_status, cb_confirm_torrent_recheck, cb_enable_tracker_ext, cb_listen_ipv6, cb_announce_all_trackers; QComboBox combo_iface; - QLineEdit txt_iface_address, network_address; + QLineEdit txt_iface_address, txt_network_address; // OS dependent settings #if defined(Q_OS_WIN) || defined(Q_OS_MAC) From 220f6b1da2ad7672acd74afae9801e2a380b02d1 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Thu, 21 Apr 2016 18:21:49 +0200 Subject: [PATCH 4/4] Use a combo box to select the IP address you want to listen on for a specific interface --- src/gui/advancedsettings.cpp | 63 +++++++++++++++++++++++++++++++----- src/gui/advancedsettings.h | 6 ++-- 2 files changed, 58 insertions(+), 11 deletions(-) diff --git a/src/gui/advancedsettings.cpp b/src/gui/advancedsettings.cpp index 5a516c19d..ef66633f7 100644 --- a/src/gui/advancedsettings.cpp +++ b/src/gui/advancedsettings.cpp @@ -103,6 +103,7 @@ AdvancedSettings::AdvancedSettings(QWidget *parent) setEditTriggers(QAbstractItemView::NoEditTriggers); // Signals connect(&spin_cache, SIGNAL(valueChanged(int)), SLOT(updateCacheSpinSuffix(int))); + connect(&combo_iface, SIGNAL(currentIndexChanged(int)), SLOT(updateInterfaceAddressCombo(int))); // Load settings loadAdvancedSettings(); resizeColumnToContents(0); @@ -146,11 +147,18 @@ void AdvancedSettings::saveAdvancedSettings() // Listen on IPv6 address pref->setListenIPv6(cb_listen_ipv6.isChecked()); // Interface address - QHostAddress ifaceAddr(txt_iface_address.text().trimmed()); - if (ifaceAddr.isNull()) - pref->setNetworkInterfaceAddress(""); - else - pref->setNetworkInterfaceAddress(ifaceAddr.toString()); + if (combo_iface_address.currentIndex() == 0) { + // All addresses (default) + pref->setNetworkInterfaceAddress(QString::null); + } + else { + QHostAddress ifaceAddr(combo_iface_address.currentText().trimmed()); + if (ifaceAddr.isNull()) { + pref->setNetworkInterfaceAddress(QString::null); + } else { + pref->setNetworkInterfaceAddress(ifaceAddr.toString()); + } + } // Network Announce address QHostAddress networkAddr(txt_network_address.text().trimmed()); if (networkAddr.isNull()) @@ -184,6 +192,45 @@ void AdvancedSettings::updateCacheSpinSuffix(int value) spin_cache.setSuffix(tr(" MiB")); } +void AdvancedSettings::updateInterfaceAddressCombo(int) { + //Try to get the currently selected interface name + QString ifaceName; + if (combo_iface.currentIndex() == 0) { + ifaceName = QString(); + } + else { + ifaceName = combo_iface.itemData(combo_iface.currentIndex()).toString(); + } + const QNetworkInterface iface = QNetworkInterface::interfaceFromName(ifaceName); + + //Clear all items and reinsert them, default to all + combo_iface_address.clear(); + combo_iface_address.addItem(tr("All Addresses")); + combo_iface_address.setCurrentIndex(0); + if (!iface.isValid()) { + return; + } + //Found a valid interface, try to get the addresses + const QList addresses = iface.addressEntries(); + const Preferences* const pref = Preferences::instance(); + const QString currentAddress = pref->getNetworkInterfaceAddress(); + + foreach (const QNetworkAddressEntry &entry, addresses) { + QHostAddress ip = entry.ip(); + QString ipString = ip.toString(); + QAbstractSocket::NetworkLayerProtocol protocol = ip.protocol(); + Q_ASSERT(protocol == QAbstractSocket::IPv4Protocol || protocol == QAbstractSocket::IPv6Protocol); + //Only take ipv4 for now? + if (protocol != QAbstractSocket::IPv4Protocol) + continue; + combo_iface_address.addItem( ipString ); + //Try to select the last added one + if (ipString == currentAddress) { + combo_iface_address.setCurrentIndex(combo_iface_address.count() - 1); + } + } +} + void AdvancedSettings::loadAdvancedSettings() { const Preferences* const pref = Preferences::instance(); @@ -280,12 +327,12 @@ void AdvancedSettings::loadAdvancedSettings() combo_iface.setCurrentIndex(i); } addRow(NETWORK_IFACE, tr("Network Interface (requires restart)"), &combo_iface); + // Network interface address + updateInterfaceAddressCombo(combo_iface.currentIndex()); + addRow(NETWORK_IFACE_ADDRESS, tr("Optional IP Address to bind to (requires restart)"), &combo_iface_address); // Listen on IPv6 address cb_listen_ipv6.setChecked(pref->getListenIPv6()); addRow(NETWORK_LISTEN_IPV6, tr("Listen on IPv6 address (requires restart)"), &cb_listen_ipv6); - // Network interface address - txt_iface_address.setText(pref->getNetworkInterfaceAddress()); - addRow(NETWORK_IFACE_ADDRESS, tr("Optional IP Address to bind to (requires restart)"), &txt_iface_address); // Announce address txt_network_address.setText(pref->getNetworkAddress()); addRow(NETWORK_ADDRESS, tr("IP Address to report to trackers (requires restart)"), &txt_network_address); diff --git a/src/gui/advancedsettings.h b/src/gui/advancedsettings.h index ca8945557..7fd525803 100644 --- a/src/gui/advancedsettings.h +++ b/src/gui/advancedsettings.h @@ -52,7 +52,7 @@ signals: private slots: void updateCacheSpinSuffix(int value); - + void updateInterfaceAddressCombo(int index); private: void loadAdvancedSettings(); template void addRow(int row, const QString &rowText, T* widget); @@ -62,8 +62,8 @@ private: QCheckBox cb_os_cache, cb_recheck_completed, cb_resolve_countries, cb_resolve_hosts, cb_super_seeding, cb_program_notifications, cb_tracker_status, cb_confirm_torrent_recheck, cb_enable_tracker_ext, cb_listen_ipv6, cb_announce_all_trackers; - QComboBox combo_iface; - QLineEdit txt_iface_address, txt_network_address; + QComboBox combo_iface, combo_iface_address; + QLineEdit txt_network_address; // OS dependent settings #if defined(Q_OS_WIN) || defined(Q_OS_MAC)