From 4ec1fd396888c030a777b0d07ef776b17b3c6f5f Mon Sep 17 00:00:00 2001 From: Christophe Dumez Date: Tue, 11 May 2010 15:53:14 +0000 Subject: [PATCH] The user can force listening on a particular network interface --- Changelog | 1 + src/advancedsettings.h | 30 ++++++++++++++++++++++++++++-- src/bittorrent.cpp | 20 +++++++++++++++++++- src/preferences.h | 10 ++++++++++ 4 files changed, 58 insertions(+), 3 deletions(-) diff --git a/Changelog b/Changelog index f7e760561..12462b929 100644 --- a/Changelog +++ b/Changelog @@ -2,6 +2,7 @@ - FEATURE: Simplified torrent root folder renaming/truncating (< v2.3.0 is no longer forward compatible) - FEATURE: Max number of half-open connections can now be edited - FEATURE: Added support for strict super seeding + - FEATURE: The user can force listening on a particular network interface - COSMETIC: Display peers country name in tooltip * Sun Mar 14 2010 - Christophe Dumez - v2.2.0 diff --git a/src/advancedsettings.h b/src/advancedsettings.h index c90e9f330..3d952fc32 100644 --- a/src/advancedsettings.h +++ b/src/advancedsettings.h @@ -5,11 +5,13 @@ #include #include #include +#include +#include #include "preferences.h" enum AdvSettingsCols {PROPERTY, VALUE}; -enum AdvSettingsRows {DISK_CACHE, OUTGOING_PORT_MIN, OUTGOING_PORT_MAX, IGNORE_LIMIT_LAN, COUNT_OVERHEAD, RECHECK_COMPLETED, LIST_REFRESH, RESOLVE_COUNTRIES, RESOLVE_HOSTS, MAX_HALF_OPEN, SUPER_SEEDING }; -#define ROW_COUNT 11 +enum AdvSettingsRows {DISK_CACHE, OUTGOING_PORT_MIN, OUTGOING_PORT_MAX, IGNORE_LIMIT_LAN, COUNT_OVERHEAD, RECHECK_COMPLETED, LIST_REFRESH, RESOLVE_COUNTRIES, RESOLVE_HOSTS, MAX_HALF_OPEN, SUPER_SEEDING, NETWORK_IFACE }; +#define ROW_COUNT 12 class AdvancedSettings: public QTableWidget { Q_OBJECT @@ -17,6 +19,7 @@ class AdvancedSettings: public QTableWidget { private: QSpinBox *spin_cache, *outgoing_ports_min, *outgoing_ports_max, *spin_list_refresh, *spin_maxhalfopen; QCheckBox *cb_ignore_limits_lan, *cb_count_overhead, *cb_recheck_completed, *cb_resolve_countries, *cb_resolve_hosts, *cb_super_seeding; + QComboBox *combo_iface; public: AdvancedSettings(QWidget *parent=0): QTableWidget(parent) { @@ -47,6 +50,7 @@ public: delete cb_resolve_hosts; delete spin_maxhalfopen; delete cb_super_seeding; + delete combo_iface; } public slots: @@ -73,6 +77,13 @@ public slots: // Super seeding Preferences::enableSuperSeeding(cb_super_seeding->isChecked()); #endif + // Network interface + if(combo_iface->currentIndex() == 0) { + // All interfaces (default) + Preferences::setNetworkInterface(QString::null); + } else { + Preferences::setNetworkInterface(combo_iface->currentText()); + } } protected slots: @@ -159,6 +170,21 @@ protected slots: cb_super_seeding->setEnabled(false); #endif setCellWidget(SUPER_SEEDING, VALUE, cb_super_seeding); + // Network interface + setItem(NETWORK_IFACE, PROPERTY, new QTableWidgetItem(tr("Network Interface (requires restart)"))); + combo_iface = new QComboBox; + combo_iface->addItem(tr("Any interface", "i.e. Any network interface")); + const QString ¤t_iface = Preferences::getNetworkInterface(); + int i = 1; + foreach(const QNetworkInterface& iface, QNetworkInterface::allInterfaces()) { + if(iface.name() == "lo") continue; + combo_iface->addItem(iface.name()); + if(!current_iface.isEmpty() && iface.name() == current_iface) + combo_iface->setCurrentIndex(i); + ++i; + } + connect(combo_iface, SIGNAL(currentIndexChanged(int)), this, SLOT(emitSettingsChanged())); + setCellWidget(NETWORK_IFACE, VALUE, combo_iface); } void emitSettingsChanged() { diff --git a/src/bittorrent.cpp b/src/bittorrent.cpp index e38ed2c68..5b4d840a8 100644 --- a/src/bittorrent.cpp +++ b/src/bittorrent.cpp @@ -32,6 +32,9 @@ #include #include #include +#include +#include +#include #include #include "filesystemwatcher.h" @@ -1696,7 +1699,22 @@ void Bittorrent::addConsoleMessage(QString msg, QString) { // session will listen to void Bittorrent::setListeningPort(int port) { std::pair ports(port, port); - s->listen_on(ports); + const QString& iface_name = Preferences::getNetworkInterface(); + if(iface_name.isEmpty()) { + s->listen_on(ports); + return; + } + QNetworkInterface network_iface = QNetworkInterface::interfaceFromName(iface_name); + if(!network_iface.isValid()) { + s->listen_on(ports); + return; + } + QString ip = "127.0.0.1"; + if(!network_iface.addressEntries().isEmpty()) { + ip = network_iface.addressEntries().first().ip().toString(); + } + qDebug("Listening on interface %s with ip %s", qPrintable(iface_name), qPrintable(ip)); + s->listen_on(ports, ip.toLocal8Bit().constData()); } // Set download rate limit diff --git a/src/preferences.h b/src/preferences.h index e9ad47b0f..48c99d0cd 100644 --- a/src/preferences.h +++ b/src/preferences.h @@ -929,6 +929,16 @@ public: settings.setValue(QString::fromUtf8("Preferences/Connection/MaxHalfOpenConnec"), value); } + static void setNetworkInterface(QString iface) { + QSettings settings("qBittorrent", "qBittorrent"); + settings.setValue(QString::fromUtf8("Preferences/Connection/Interface"), iface); + } + + static QString getNetworkInterface() { + QSettings settings("qBittorrent", "qBittorrent"); + return settings.value(QString::fromUtf8("Preferences/Connection/Interface"), QString()).toString(); + } + #ifdef LIBTORRENT_0_15 static bool isSuperSeedingEnabled() { QSettings settings("qBittorrent", "qBittorrent");