mirror of
https://github.com/d47081/qBittorrent.git
synced 2025-01-22 20:44:15 +00:00
Improved hostname resolution code
This commit is contained in:
parent
51bc67042e
commit
844bd52c67
@ -100,12 +100,12 @@ void PeerListWidget::updatePeerHostNameResolutionState() {
|
|||||||
if(!resolver) {
|
if(!resolver) {
|
||||||
resolver = new ReverseResolution(this);
|
resolver = new ReverseResolution(this);
|
||||||
connect(resolver, SIGNAL(ip_resolved(QString,QString)), this, SLOT(handleResolved(QString,QString)));
|
connect(resolver, SIGNAL(ip_resolved(QString,QString)), this, SLOT(handleResolved(QString,QString)));
|
||||||
resolver->start();
|
|
||||||
loadPeers(properties->getCurrentTorrent(), true);
|
loadPeers(properties->getCurrentTorrent(), true);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if(resolver)
|
if(resolver) {
|
||||||
resolver->asyncDelete();
|
delete resolver;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -315,7 +315,7 @@ void PeerListWidget::loadPeers(const QTorrentHandle &h, bool force_hostname_reso
|
|||||||
old_peers_set.remove(peer_ip);
|
old_peers_set.remove(peer_ip);
|
||||||
if(force_hostname_resolution) {
|
if(force_hostname_resolution) {
|
||||||
if(resolver) {
|
if(resolver) {
|
||||||
QString host = resolver->getHostFromCache(peer.ip);
|
const QString host = resolver->getHostFromCache(peer.ip);
|
||||||
if(host.isNull()) {
|
if(host.isNull()) {
|
||||||
resolver->resolve(peer.ip);
|
resolver->resolve(peer.ip);
|
||||||
} else {
|
} else {
|
||||||
@ -396,12 +396,12 @@ void PeerListWidget::updatePeer(QString ip, peer_info peer) {
|
|||||||
listModel->setData(listModel->index(row, TOT_UP), (qulonglong)peer.total_upload);
|
listModel->setData(listModel->index(row, TOT_UP), (qulonglong)peer.total_upload);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PeerListWidget::handleResolved(QString ip, QString hostname) {
|
void PeerListWidget::handleResolved(const QString &ip, const QString &hostname) {
|
||||||
QStandardItem *item = peerItems.value(ip, 0);
|
QStandardItem *item = peerItems.value(ip, 0);
|
||||||
if(item) {
|
if(item) {
|
||||||
qDebug("Resolved %s -> %s", qPrintable(ip), qPrintable(hostname));
|
qDebug("Resolved %s -> %s", qPrintable(ip), qPrintable(hostname));
|
||||||
item->setData(hostname);
|
item->setData(hostname, Qt::DisplayRole);
|
||||||
//listModel->setData(listModel->index(item->row(), IP), hostname);
|
//listModel->setData(listModel->index(item->row(), IP), hostname, Qt::DisplayRole);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -65,7 +65,7 @@ public slots:
|
|||||||
void loadPeers(const QTorrentHandle &h, bool force_hostname_resolution=false);
|
void loadPeers(const QTorrentHandle &h, bool force_hostname_resolution=false);
|
||||||
QStandardItem* addPeer(QString ip, libtorrent::peer_info peer);
|
QStandardItem* addPeer(QString ip, libtorrent::peer_info peer);
|
||||||
void updatePeer(QString ip, libtorrent::peer_info peer);
|
void updatePeer(QString ip, libtorrent::peer_info peer);
|
||||||
void handleResolved(QString ip, QString hostname);
|
void handleResolved(const QString &ip, const QString &hostname);
|
||||||
void updatePeerHostNameResolutionState();
|
void updatePeerHostNameResolutionState();
|
||||||
void updatePeerCountryResolutionState();
|
void updatePeerCountryResolutionState();
|
||||||
void clear();
|
void clear();
|
||||||
|
@ -31,12 +31,10 @@
|
|||||||
#ifndef REVERSERESOLUTION_H
|
#ifndef REVERSERESOLUTION_H
|
||||||
#define REVERSERESOLUTION_H
|
#define REVERSERESOLUTION_H
|
||||||
|
|
||||||
#include <QQueue>
|
|
||||||
#include <QThread>
|
|
||||||
#include <QWaitCondition>
|
|
||||||
#include <QMutex>
|
|
||||||
#include <QList>
|
#include <QList>
|
||||||
#include <QCache>
|
#include <QCache>
|
||||||
|
#include <QDebug>
|
||||||
|
#include <QHostInfo>
|
||||||
#include "misc.h"
|
#include "misc.h"
|
||||||
|
|
||||||
#include <boost/version.hpp>
|
#include <boost/version.hpp>
|
||||||
@ -46,160 +44,63 @@
|
|||||||
#include <boost/asio/ip/tcp.hpp>
|
#include <boost/asio/ip/tcp.hpp>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
const int MAX_THREADS = 20;
|
|
||||||
const int CACHE_SIZE = 500;
|
const int CACHE_SIZE = 500;
|
||||||
|
|
||||||
class ReverseResolutionST: public QThread {
|
class ReverseResolution: public QObject {
|
||||||
Q_OBJECT
|
|
||||||
|
|
||||||
private:
|
|
||||||
libtorrent::asio::ip::tcp::endpoint ip;
|
|
||||||
libtorrent::asio::ip::tcp::resolver resolver;
|
|
||||||
bool stopped;
|
|
||||||
|
|
||||||
public:
|
|
||||||
ReverseResolutionST(libtorrent::asio::io_service &ios, QObject *parent=0):
|
|
||||||
QThread(parent), resolver(ios), stopped(false) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
~ReverseResolutionST() {
|
|
||||||
stopped = true;
|
|
||||||
if(isRunning()) {
|
|
||||||
resolver.cancel();
|
|
||||||
wait();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void setIP(libtorrent::asio::ip::tcp::endpoint &_ip) {
|
|
||||||
ip = _ip;
|
|
||||||
}
|
|
||||||
|
|
||||||
signals:
|
|
||||||
void ip_resolved(QString ip, QString hostname);
|
|
||||||
|
|
||||||
protected:
|
|
||||||
void run() {
|
|
||||||
try {
|
|
||||||
boost::system::error_code ec;
|
|
||||||
libtorrent::asio::ip::tcp::resolver::iterator it = resolver.resolve(ip, ec);
|
|
||||||
if(ec || stopped) return;
|
|
||||||
const std::string ip_str = ip.address().to_string(ec);
|
|
||||||
if(ec) return;
|
|
||||||
const QString host_name = misc::toQString(it->host_name());
|
|
||||||
const QString ip_qstr = misc::toQString(ip_str);
|
|
||||||
if(host_name != ip_qstr) {
|
|
||||||
emit ip_resolved(ip_qstr, host_name);
|
|
||||||
}
|
|
||||||
} catch(std::exception/* &e*/) {
|
|
||||||
/*std::cerr << "Hostname resolution failed, reason: " << e.what() << std::endl;*/
|
|
||||||
std::cerr << "Hostname resolution error." << std::endl;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
class ReverseResolution: public QThread {
|
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
Q_DISABLE_COPY(ReverseResolution)
|
Q_DISABLE_COPY(ReverseResolution)
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit ReverseResolution(QObject* parent): QThread(parent), stopped(false) {
|
explicit ReverseResolution(QObject* parent): QObject(parent) {
|
||||||
cache = new QCache<QString, QString>(CACHE_SIZE);
|
m_cache.setMaxCost(CACHE_SIZE);
|
||||||
}
|
}
|
||||||
|
|
||||||
~ReverseResolution() {
|
~ReverseResolution() {
|
||||||
qDebug("Deleting host name resolver...");
|
qDebug("Deleting host name resolver...");
|
||||||
if(!stopped) {
|
|
||||||
stopped = true;
|
|
||||||
cond.wakeOne();
|
|
||||||
}
|
|
||||||
delete cache;
|
|
||||||
wait();
|
|
||||||
qDebug("Host name resolver was deleted");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void asyncDelete() {
|
QString getHostFromCache(const libtorrent::asio::ip::tcp::endpoint &ip) {
|
||||||
connect(this, SIGNAL(finished()), this, SLOT(deleteLater()));
|
const QString ip_str = misc::toQString(ip.address().to_string());
|
||||||
qDebug("Deleting async host name resolver...");
|
|
||||||
stopped = true;
|
|
||||||
cond.wakeOne();
|
|
||||||
}
|
|
||||||
|
|
||||||
QString getHostFromCache(libtorrent::asio::ip::tcp::endpoint ip) {
|
|
||||||
mut.lock();
|
|
||||||
QString ip_str = misc::toQString(ip.address().to_string());
|
|
||||||
QString ret;
|
QString ret;
|
||||||
if(cache->contains(ip_str)) {
|
if(m_cache.contains(ip_str)) {
|
||||||
qDebug("Got host name from cache");
|
qDebug("Got host name from cache");
|
||||||
ret = *cache->object(ip_str);
|
ret = *m_cache.object(ip_str);
|
||||||
} else {
|
} else {
|
||||||
ret = QString::null;
|
ret = QString::null;
|
||||||
}
|
}
|
||||||
mut.unlock();
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
void resolve(libtorrent::asio::ip::tcp::endpoint ip) {
|
void resolve(const libtorrent::asio::ip::tcp::endpoint &ip) {
|
||||||
mut.lock();
|
const QString ip_str = misc::toQString(ip.address().to_string());
|
||||||
QString ip_str = misc::toQString(ip.address().to_string());
|
if(m_cache.contains(ip_str)) {
|
||||||
if(cache->contains(ip_str)) {
|
|
||||||
qDebug("Resolved host name using cache");
|
qDebug("Resolved host name using cache");
|
||||||
emit ip_resolved(ip_str, *cache->object(ip_str));
|
emit ip_resolved(ip_str, *m_cache.object(ip_str));
|
||||||
mut.unlock();
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
ips.enqueue(ip);
|
// Actually resolve the ip
|
||||||
if(subThreads.size() < MAX_THREADS)
|
QHostInfo::lookupHost(ip_str, this, SLOT(hostResolved(QHostInfo)));
|
||||||
cond.wakeOne();
|
|
||||||
mut.unlock();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void ip_resolved(QString ip, QString hostname);
|
void ip_resolved(const QString &ip, const QString &hostname);
|
||||||
|
|
||||||
protected slots:
|
private slots:
|
||||||
void forwardSignal(QString ip, QString hostname) {
|
void hostResolved(const QHostInfo& host) {
|
||||||
emit ip_resolved(ip, hostname);
|
if (host.error() == QHostInfo::NoError) {
|
||||||
mut.lock();
|
const QString hostname = host.hostName();
|
||||||
cache->insert(ip, new QString(hostname));
|
if(host.addresses().isEmpty() || hostname.isEmpty()) return;
|
||||||
subThreads.removeOne(static_cast<ReverseResolutionST*>(sender()));
|
const QString ip = host.addresses().first().toString();
|
||||||
if(!ips.empty())
|
if(hostname != ip) {
|
||||||
cond.wakeOne();
|
//qDebug() << Q_FUNC_INFO << ip << QString("->") << hostname;
|
||||||
mut.unlock();
|
m_cache.insert(ip, new QString(hostname));
|
||||||
delete sender();
|
emit ip_resolved(ip, hostname);
|
||||||
//sender()->deleteLater();
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
|
||||||
void run() {
|
|
||||||
do {
|
|
||||||
mut.lock();
|
|
||||||
cond.wait(&mut);
|
|
||||||
if(stopped) {
|
|
||||||
mut.unlock();
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
libtorrent::asio::ip::tcp::endpoint ip = ips.dequeue();
|
}
|
||||||
ReverseResolutionST *st = new ReverseResolutionST(ios);
|
|
||||||
subThreads.append(st);
|
|
||||||
mut.unlock();
|
|
||||||
connect(st, SIGNAL(ip_resolved(QString,QString)), this, SLOT(forwardSignal(QString,QString)));
|
|
||||||
st->setIP(ip);
|
|
||||||
st->start();
|
|
||||||
}while(!stopped);
|
|
||||||
mut.lock();
|
|
||||||
qDeleteAll(subThreads);
|
|
||||||
mut.unlock();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QQueue<libtorrent::asio::ip::tcp::endpoint> ips;
|
QCache<QString, QString> m_cache;
|
||||||
QMutex mut;
|
|
||||||
QWaitCondition cond;
|
|
||||||
bool stopped;
|
|
||||||
libtorrent::asio::io_service ios;
|
|
||||||
QCache<QString, QString> *cache;
|
|
||||||
QList<ReverseResolutionST*> subThreads;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user