Browse Source

Merge pull request #5096 from Harekiet/kietC

Bind directly to an IP instead of using a network Interface
adaptive-webui-19844
sledgehammer999 9 years ago
parent
commit
1397a951fe
  1. 11
      src/base/bittorrent/session.cpp
  2. 10
      src/base/preferences.cpp
  3. 2
      src/base/preferences.h
  4. 70
      src/gui/advancedsettings.cpp
  5. 4
      src/gui/advancedsettings.h

11
src/base/bittorrent/session.cpp

@ -1735,9 +1735,11 @@ const QStringList Session::getListeningIPs()
QStringList IPs; QStringList IPs;
const QString ifaceName = pref->getNetworkInterface(); const QString ifaceName = pref->getNetworkInterface();
const QString ifaceAddr = pref->getNetworkInterfaceAddress();
const bool listenIPv6 = pref->getListenIPv6(); 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()); IPs.append(QString());
return IPs; return IPs;
} }
@ -1764,6 +1766,13 @@ const QStringList Session::getListeningIPs()
if ((!listenIPv6 && (protocol == QAbstractSocket::IPv6Protocol)) if ((!listenIPv6 && (protocol == QAbstractSocket::IPv6Protocol))
|| (listenIPv6 && (protocol == QAbstractSocket::IPv4Protocol))) || (listenIPv6 && (protocol == QAbstractSocket::IPv4Protocol)))
continue; 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); IPs.append(ipString);
} }

10
src/base/preferences.cpp

@ -1339,6 +1339,16 @@ QString Preferences::getNetworkInterfaceName() const
return value("Preferences/Connection/InterfaceName").toString(); return value("Preferences/Connection/InterfaceName").toString();
} }
void Preferences::setNetworkInterfaceAddress(const QString& addr)
{
setValue("Preferences/Connection/InterfaceAddress", addr);
}
QString Preferences::getNetworkInterfaceAddress() const
{
return value("Preferences/Connection/InterfaceAddress").toString();
}
void Preferences::setNetworkInterfaceName(const QString& iface) void Preferences::setNetworkInterfaceName(const QString& iface)
{ {
setValue("Preferences/Connection/InterfaceName", iface); setValue("Preferences/Connection/InterfaceName", iface);

2
src/base/preferences.h

@ -361,6 +361,8 @@ public:
void setMaxHalfOpenConnections(int value); void setMaxHalfOpenConnections(int value);
QString getNetworkInterface() const; QString getNetworkInterface() const;
void setNetworkInterface(const QString& iface); void setNetworkInterface(const QString& iface);
QString getNetworkInterfaceAddress() const;
void setNetworkInterfaceAddress(const QString& addr);
QString getNetworkInterfaceName() const; QString getNetworkInterfaceName() const;
void setNetworkInterfaceName(const QString& iface); void setNetworkInterfaceName(const QString& iface);
bool getListenIPv6() const; bool getListenIPv6() const;

70
src/gui/advancedsettings.cpp

@ -47,6 +47,8 @@ enum AdvSettingsRows
QBITTORRENT_HEADER, QBITTORRENT_HEADER,
// network interface // network interface
NETWORK_IFACE, NETWORK_IFACE,
//Optional network address
NETWORK_IFACE_ADDRESS,
NETWORK_LISTEN_IPV6, NETWORK_LISTEN_IPV6,
// behavior // behavior
SAVE_RESUME_DATA_INTERVAL, SAVE_RESUME_DATA_INTERVAL,
@ -104,6 +106,7 @@ AdvancedSettings::AdvancedSettings(QWidget *parent)
setEditTriggers(QAbstractItemView::NoEditTriggers); setEditTriggers(QAbstractItemView::NoEditTriggers);
// Signals // Signals
connect(&spin_cache, SIGNAL(valueChanged(int)), SLOT(updateCacheSpinSuffix(int))); connect(&spin_cache, SIGNAL(valueChanged(int)), SLOT(updateCacheSpinSuffix(int)));
connect(&combo_iface, SIGNAL(currentIndexChanged(int)), SLOT(updateInterfaceAddressCombo(int)));
// Load settings // Load settings
loadAdvancedSettings(); loadAdvancedSettings();
resizeColumnToContents(0); resizeColumnToContents(0);
@ -146,12 +149,26 @@ void AdvancedSettings::saveAdvancedSettings()
} }
// Listen on IPv6 address // Listen on IPv6 address
pref->setListenIPv6(cb_listen_ipv6.isChecked()); pref->setListenIPv6(cb_listen_ipv6.isChecked());
// Network address // Interface address
QHostAddress addr(txt_network_address.text().trimmed()); if (combo_iface_address.currentIndex() == 0) {
if (addr.isNull()) // 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())
pref->setNetworkAddress(""); pref->setNetworkAddress("");
else else
pref->setNetworkAddress(addr.toString()); pref->setNetworkAddress(networkAddr.toString());
// Program notification // Program notification
MainWindow * const mainWindow = static_cast<Application*>(QCoreApplication::instance())->mainWindow(); MainWindow * const mainWindow = static_cast<Application*>(QCoreApplication::instance())->mainWindow();
mainWindow->setNotificationsEnabled(cb_program_notifications.isChecked()); mainWindow->setNotificationsEnabled(cb_program_notifications.isChecked());
@ -180,6 +197,45 @@ void AdvancedSettings::updateCacheSpinSuffix(int value)
spin_cache.setSuffix(tr(" MiB")); 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<QNetworkAddressEntry> 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() void AdvancedSettings::loadAdvancedSettings()
{ {
const Preferences* const pref = Preferences::instance(); const Preferences* const pref = Preferences::instance();
@ -282,12 +338,16 @@ void AdvancedSettings::loadAdvancedSettings()
combo_iface.setCurrentIndex(i); combo_iface.setCurrentIndex(i);
} }
addRow(NETWORK_IFACE, tr("Network Interface (requires restart)"), &combo_iface); 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 // Listen on IPv6 address
cb_listen_ipv6.setChecked(pref->getListenIPv6()); cb_listen_ipv6.setChecked(pref->getListenIPv6());
addRow(NETWORK_LISTEN_IPV6, tr("Listen on IPv6 address (requires restart)"), &cb_listen_ipv6); addRow(NETWORK_LISTEN_IPV6, tr("Listen on IPv6 address (requires restart)"), &cb_listen_ipv6);
// Network address // Announce address
txt_network_address.setText(pref->getNetworkAddress()); 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 report to trackers (requires restart)"), &txt_network_address);
// Program notifications // Program notifications
const MainWindow * const mainWindow = static_cast<Application*>(QCoreApplication::instance())->mainWindow(); const MainWindow * const mainWindow = static_cast<Application*>(QCoreApplication::instance())->mainWindow();
cb_program_notifications.setChecked(mainWindow->isNotificationsEnabled()); cb_program_notifications.setChecked(mainWindow->isNotificationsEnabled());

4
src/gui/advancedsettings.h

@ -52,7 +52,7 @@ signals:
private slots: private slots:
void updateCacheSpinSuffix(int value); void updateCacheSpinSuffix(int value);
void updateInterfaceAddressCombo(int index);
private: private:
void loadAdvancedSettings(); void loadAdvancedSettings();
template <typename T> void addRow(int row, const QString &rowText, T* widget); template <typename T> void addRow(int row, const QString &rowText, T* widget);
@ -62,7 +62,7 @@ private:
QCheckBox cb_os_cache, cb_recheck_completed, cb_resolve_countries, cb_resolve_hosts, QCheckBox cb_os_cache, cb_recheck_completed, cb_resolve_countries, cb_resolve_hosts,
cb_super_seeding, cb_program_notifications, cb_torrent_added_notifications, cb_tracker_status, cb_super_seeding, cb_program_notifications, cb_torrent_added_notifications, cb_tracker_status,
cb_confirm_torrent_recheck, cb_enable_tracker_ext, cb_listen_ipv6, cb_announce_all_trackers; cb_confirm_torrent_recheck, cb_enable_tracker_ext, cb_listen_ipv6, cb_announce_all_trackers;
QComboBox combo_iface; QComboBox combo_iface, combo_iface_address;
QLineEdit txt_network_address; QLineEdit txt_network_address;
// OS dependent settings // OS dependent settings

Loading…
Cancel
Save