Summary: | cannot specify which network interface to use | ||
---|---|---|---|
Product: | [Applications] ktorrent | Reporter: | Aggelos Economopoulos <aoiko> |
Component: | general | Assignee: | Joris Guisson <joris.guisson> |
Status: | RESOLVED FIXED | ||
Severity: | wishlist | ||
Priority: | NOR | ||
Version: | unspecified | ||
Target Milestone: | --- | ||
Platform: | Debian testing | ||
OS: | Linux | ||
Latest Commit: | Version Fixed In: | ||
Sentry Crash Report: |
Description
Aggelos Economopoulos
2007-03-08 15:37:56 UTC
True, don't know when we can add this, but this sounds reasonable. Note, we are using KDE code to do http announces, so I'm not quite sure if we can force those on one particular interface. SVN commit 689109 by guisson: Changes : - Added ChangeLog - Added first part of advanced pref page - Added new feature to select which network interface to use BUG: 142684 A ChangeLog M +1 -1 ktorrent/CMakeLists.txt A ktorrent/advancedpref.ui M +2 -1 ktorrent/gui.cpp M +46 -1 ktorrent/prefdialog.cpp M +3 -0 ktorrent/view.cpp M +1 -1 libktorrent/CMakeLists.txt M +2 -1 libktorrent/dht/rpcserver.cpp M +33 -0 libktorrent/interfaces/functions.cpp M +6 -0 libktorrent/interfaces/functions.h M +6 -1 libktorrent/ktorrent.kcfg M +5 -3 libktorrent/net/socket.cpp M +1 -1 libktorrent/net/socket.h M +3 -2 libktorrent/torrent/server.cpp --- branches/ktorrent/kde4port/ktorrent/CMakeLists.txt #689108:689109 @@ -20,7 +20,7 @@ scandlg.cpp trayicon.cpp) -kde4_add_ui_files(ktorrent_SRC fileselectdlg.ui globalpref.ui scandlg.ui generalpref.ui) +kde4_add_ui_files(ktorrent_SRC fileselectdlg.ui globalpref.ui scandlg.ui generalpref.ui advancedpref.ui) kde4_add_executable(ktorrent ${ktorrent_SRC}) target_link_libraries(ktorrent ktideal ktcore ${KDE4_KDEUI_LIBS}) --- branches/ktorrent/kde4port/ktorrent/gui.cpp #689108:689109 @@ -86,7 +86,6 @@ rc->setIcon(KIcon("tab-remove")); connect(rc,SIGNAL(clicked()),this,SLOT(closeTab())); - loadState(KGlobal::config()); applySettings(); connect(core,SIGNAL(settingsChanged()),this,SLOT(applySettings())); @@ -99,6 +98,8 @@ } else tray_icon->hide(); + + loadState(KGlobal::config()); } GUI:: ~GUI() --- branches/ktorrent/kde4port/ktorrent/prefdialog.cpp #689108:689109 @@ -20,13 +20,19 @@ ***************************************************************************/ #include <klocale.h> #include <kconfigdialogmanager.h> + +#include <solid/device.h> +#include <solid/networkinterface.h> + #include <interfaces/functions.h> #include <interfaces/prefpageinterface.h> + #include "settings.h" #include "prefdialog.h" #include "core.h" #include "ui_globalpref.h" #include "ui_generalpref.h" +#include "ui_advancedpref.h" namespace kt { @@ -44,7 +50,7 @@ class GeneralPref : public PrefPageInterface,public Ui_GeneralPref { public: - GeneralPref(QWidget* parent) : PrefPageInterface(Settings::self(),i18n("General"),"settings",parent) + GeneralPref(QWidget* parent) : PrefPageInterface(Settings::self(),i18n("General"),"configure",parent) { setupUi(this); kcfg_tempDir->setMode(KFile::Directory|KFile::ExistingOnly|KFile::LocalOnly); @@ -94,6 +100,44 @@ } }; + class AdvancedPref : public PrefPageInterface,public Ui_AdvancedPref + { + public: + AdvancedPref(QWidget* parent) : PrefPageInterface(Settings::self(),i18n("Advanced"),"configure",parent) + { + setupUi(this); + } + + virtual ~AdvancedPref() + { + } + + void loadSettings() + { + kcfg_httpTrackerProxy->setEnabled(Settings::doNotUseKDEProxy()); + + kcfg_networkInterface->addItem(KIcon("network-wired"),i18n("All interfaces")); + + // get all the network devices and add them to the combo box + QList<Solid::Device> netlist = Solid::Device::listFromType(Solid::DeviceInterface::NetworkInterface); + foreach (Solid::Device device,netlist) + { + Solid::NetworkInterface* netdev = device.as<Solid::NetworkInterface>(); + if (netdev) + kcfg_networkInterface->addItem( + KIcon(netdev->isWireless() ? "network-wireless" : "network-wired"), + netdev->ifaceName()); + } + } + + void loadDefaults() + { + loadSettings(); + } + + }; + + PrefDialog::PrefDialog(QWidget* parent,Core* core) : KConfigDialog(parent,"settings",Settings::self()) { KConfigDialogManager::propertyMap()->insert("KUrlRequester","url"); @@ -101,6 +145,7 @@ connect(this,SIGNAL(settingsChanged(const QString &)),core,SLOT(applySettings())); addPrefPage(new GlobalPref(this)); addPrefPage(new GeneralPref(this)); + addPrefPage(new AdvancedPref(this)); } PrefDialog::~PrefDialog() --- branches/ktorrent/kde4port/ktorrent/view.cpp #689108:689109 @@ -44,6 +44,9 @@ setContextMenuPolicy(Qt::CustomContextMenu); setRootIsDecorated(false); setSortingEnabled(true); + setAlternatingRowColors(true); + setSelectionMode(QAbstractItemView::ExtendedSelection); + setSelectionBehavior(QAbstractItemView::SelectRows); QStringList columns; columns << i18n("Name") --- branches/ktorrent/kde4port/libktorrent/CMakeLists.txt #689108:689109 @@ -164,7 +164,7 @@ kde4_add_library(ktcore SHARED ${libktorrent_SRC}) # target_link_libraries(ktorrent ${KDE4_KPARTS_LIBS} -lgmp) -target_link_libraries(ktcore ${KDE4_KDEUI_LIBS} -lkio -lkparts -lgmp) +target_link_libraries(ktcore ${KDE4_KDEUI_LIBS} -lkio -lkparts -lsolid -lgmp) set_target_properties(ktcore PROPERTIES VERSION 1.0.0 SOVERSION 1 ) install(TARGETS ktcore DESTINATION ${LIB_INSTALL_DIR} ) --- branches/ktorrent/kde4port/libktorrent/dht/rpcserver.cpp #689108:689109 @@ -26,6 +26,7 @@ #include <bcodec/bnode.h> #include <bcodec/bdecoder.h> #include <bcodec/bencoder.h> +#include <interfaces/functions.h> #include <k3socketdevice.h> #include "rpcserver.h" #include "rpccall.h" @@ -63,7 +64,7 @@ void RPCServer::start() { sock->setBlocking(true); - if (!sock->bind(QString::null,QString::number(port))) + if (!sock->bind(kt::NetworkInterfaceIPAddress(kt::NetworkInterface()),QString::number(port))) { Out(SYS_DHT|LOG_IMPORTANT) << "DHT: Failed to bind to UDP port " << port << " for DHT" << endl; } --- branches/ktorrent/kde4port/libktorrent/interfaces/functions.cpp #689108:689109 @@ -18,9 +18,12 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ***************************************************************************/ #include <qdatetime.h> +#include <QNetworkInterface> #include <klocale.h> #include <kglobal.h> #include <kstandarddirs.h> +#include <solid/device.h> +#include <solid/networkinterface.h> #include <util/functions.h> #include <torrent/downloader.h> #include <torrent/choker.h> @@ -134,4 +137,34 @@ Tracker::setCustomIP(QString::null); } + QString NetworkInterface() + { + if (Settings::networkInterface() == 0) + return QString::null; + + QList<Solid::Device> netlist = Solid::Device::listFromType(Solid::DeviceInterface::NetworkInterface); + if (Settings::networkInterface() - 1 > netlist.count()) + return QString::null; + + + Solid::NetworkInterface* netdev = netlist[Settings::networkInterface() - 1].as<Solid::NetworkInterface>(); + if (!netdev) + return QString::null; + + return netdev->ifaceName(); + } + + QString NetworkInterfaceIPAddress(const QString & iface) + { + QNetworkInterface ni = QNetworkInterface::interfaceFromName(iface); + if (!ni.isValid()) + return QString::null; + + QList<QNetworkAddressEntry> addr_list = ni.addressEntries(); + if (addr_list.count() == 0) + return QString::null; + else + return addr_list.front().ip().toString(); + } + } --- branches/ktorrent/kde4port/libktorrent/interfaces/functions.h #689108:689109 @@ -32,6 +32,12 @@ KTORRENT_EXPORT QString DurationToString(bt::Uint32 nsecs); KTORRENT_EXPORT QString DataDir(); KTORRENT_EXPORT void ApplySettings(); + + /// Get the network interface which needs to be used (this will return the name e.g. eth0, wlan0 ...) + KTORRENT_EXPORT QString NetworkInterface(); + + /// Get the IP address of the network interface + KTORRENT_EXPORT QString NetworkInterfaceIPAddress(const QString & iface); template<class T> int CompareVal(T a,T b) { --- branches/ktorrent/kde4port/libktorrent/ktorrent.kcfg #689108:689109 @@ -177,7 +177,7 @@ <default code="true">QString::null</default> </entry> <entry name="eta" type="Int"> - <label>ET algorithm</label> + <label>Algorithm to estimate the time when a torrent is finished</label> <default>0</default> </entry> <entry name="diskPrealloc" type="Bool"> @@ -212,5 +212,10 @@ <default>0</default> <min>0</min> </entry> + <entry name="networkInterface" type="Int"> + <default>0</default> + <min>0</min> + <max>255</max> + </entry> </group> </kcfg> --- branches/ktorrent/kde4port/libktorrent/net/socket.cpp #689108:689109 @@ -131,22 +131,24 @@ return true; } - bool Socket::bind(Uint16 port,bool also_listen) + bool Socket::bind(const QString & ip,Uint16 port,bool also_listen) { struct sockaddr_in addr; memset(&addr,0,sizeof(struct sockaddr_in)); addr.sin_family = AF_INET; addr.sin_port = htons(port); + if (!ip.isNull()) + inet_aton(ip.toAscii(),&addr.sin_addr); if (::bind(m_fd,(struct sockaddr*)&addr,sizeof(struct sockaddr)) < 0) { - Out(SYS_CON|LOG_IMPORTANT) << QString("Cannot bind to port %1 : %2").arg(port).arg(strerror(errno)) << endl; + Out(SYS_CON|LOG_IMPORTANT) << QString("Cannot bind to port %1:%2 : %3").arg(ip).arg(port).arg(strerror(errno)) << endl; return false; } if (also_listen && listen(m_fd,5) < 0) { - Out(SYS_CON|LOG_IMPORTANT) << QString("Cannot listen to port %1 : %2").arg(port).arg(strerror(errno)) << endl; + Out(SYS_CON|LOG_IMPORTANT) << QString("Cannot listen to port %1:%2 : %3").arg(ip).arg(port).arg(strerror(errno)) << endl; return false; } --- branches/ktorrent/kde4port/libktorrent/net/socket.h #689108:689109 @@ -49,7 +49,7 @@ bool connectTo(const Address & addr); /// See if a connectTo was succesfull in non blocking mode bool connectSuccesFull(); - bool bind(Uint16 port,bool also_listen); + bool bind(const QString & ip,Uint16 port,bool also_listen); int send(const bt::Uint8* buf,int len); int recv(bt::Uint8* buf,int max_len); int sendTo(const bt::Uint8* buf,int size,const Address & addr); --- branches/ktorrent/kde4port/libktorrent/torrent/server.cpp #689108:689109 @@ -27,6 +27,7 @@ #include <peer/peermanager.h> #include <peer/serverauthenticate.h> #include <peer/authenticationmonitor.h> +#include <interfaces/functions.h> #include "globals.h" #include "torrent.h" @@ -72,8 +73,8 @@ delete sn; sn = 0; sock = new net::Socket(true); - - if (sock->bind(port,true)) + QString ip = kt::NetworkInterfaceIPAddress(kt::NetworkInterface()); + if (sock->bind(ip,port,true)) { sock->setNonBlocking(); sn = new QSocketNotifier(sock->fd(),QSocketNotifier::Read,this); Hi, I have just configured a virtual adapter from eth0 for torrents, so i can apply a static address to just that but leave dhcp running everything else. I noticed afterwards that KTorrent only lists the physical adapters ALL, lo, eth0 and eth1 3 times, but not my new virtual interface eth0:one. It does appear to be seeding whilst set to All Interfaces, but it would be preferable to target just this adapter. Also for reference, I have confirmed with ifconfig that eth0:one exists and has an ip, it is also reachable externally. Thanks in advance Phill Upson The multiple listings is a bug which is already fixed. As for the virtual adaptor, I had no problem with a tunnel adaptor when I was testing IPv6, it got picked up. Maybe you should try restarting ktorrent, and see if it is then found. |