10#include <QFutureWatcher>
20#include <QtConcurrentRun>
24#include <arpa/nameser.h>
25#include <netinet/in.h>
28#define _PATH_RESCONF "/etc/resolv.conf"
32static constexpr int TTL = 300;
36class HostInfoAgentPrivate :
public QObject
43 explicit HostInfoAgentPrivate(
int cacheSize = 100);
44 ~HostInfoAgentPrivate()
override
47 void lookupHost(
const QString &hostName,
QObject *receiver,
const char *member);
57 struct HostCacheInfo {
65class HostInfoAgentPrivate::Result :
public QObject
72 friend class HostInfoAgentPrivate;
75class HostInfoAgentPrivate::Query :
public QObject
87 m_hostName = hostName;
108class NameLookupThreadRequest
111 NameLookupThreadRequest(
const QString &hostName)
112 : m_hostName(hostName)
126 void setResult(
const QHostInfo &hostInfo)
128 m_hostInfo = hostInfo;
141 void setLookupId(
int id)
147 Q_DISABLE_COPY(NameLookupThreadRequest)
155Q_DECLARE_METATYPE(std::shared_ptr<KIO::NameLookupThreadRequest>)
159class NameLookUpThreadWorker :
public QObject
163 void lookupHost(
const std::shared_ptr<KIO::NameLookupThreadRequest> &request)
165 const QString hostName = request->hostName();
167 request->setLookupId(lookupId);
168 m_lookups.
insert(lookupId, request);
171 void abortLookup(
const std::shared_ptr<KIO::NameLookupThreadRequest> &request)
174 m_lookups.
remove(request->lookupId());
177 void lookupFinished(
const QHostInfo &hostInfo)
180 if (it != m_lookups.
end()) {
181 (*it)->setResult(hostInfo);
182 (*it)->semaphore()->release();
191class NameLookUpThread :
public QThread
198 qRegisterMetaType<std::shared_ptr<NameLookupThreadRequest>>();
202 ~NameLookUpThread()
override
208 NameLookUpThreadWorker *worker()
220 NameLookUpThreadWorker worker;
227 NameLookUpThreadWorker *m_worker;
234Q_GLOBAL_STATIC(HostInfoAgentPrivate, hostInfoAgentPrivate)
235Q_GLOBAL_STATIC(NameLookUpThread, nameLookUpThread)
237void HostInfo::lookupHost(const
QString &hostName,
QObject *receiver, const
char *member)
239 hostInfoAgentPrivate()->lookupHost(hostName, receiver, member);
247 if (!address.isNull()) {
249 addressList << address;
261 std::shared_ptr<NameLookupThreadRequest> request = std::make_shared<NameLookupThreadRequest>(hostName);
262 nameLookUpThread()->semaphore()->acquire();
263 nameLookUpThread()->semaphore()->release();
264 NameLookUpThreadWorker *worker = nameLookUpThread()->worker();
265 auto lookupFunc = [worker, request]() {
266 worker->lookupHost(request);
269 if (request->semaphore()->tryAcquire(1, timeout)) {
270 hostInfo = request->result();
275 auto abortFunc = [worker, request]() {
276 worker->abortLookup(request);
287 return hostInfoAgentPrivate()->lookupCachedHostInfoFor(hostName);
292 hostInfoAgentPrivate()->cacheLookup(info);
295HostInfoAgentPrivate::HostInfoAgentPrivate(
int cacheSize)
297 , dnsCache(cacheSize)
299 qRegisterMetaType<QHostInfo>();
302void HostInfoAgentPrivate::lookupHost(
const QString &hostName,
QObject *receiver,
const char *member)
306 QDateTime currentMTime = resolvConf.lastModified();
307 if (resolvConf.exists() && currentMTime != resolvConfMTime) {
310 resolvConfMTime = currentMTime;
315 if (HostCacheInfo *info = dnsCache.
object(hostName)) {
320 Q_EMIT result.result(info->hostInfo);
324 dnsCache.
remove(hostName);
327 if (Query *query = openQueries.
value(hostName)) {
334 Query *
query =
new Query();
335 openQueries.
insert(hostName, query);
337 queryFinished(info, query);
342 query->start(hostName);
345QHostInfo HostInfoAgentPrivate::lookupCachedHostInfoFor(
const QString &hostName)
347 HostCacheInfo *info = dnsCache.
object(hostName);
349 return info->hostInfo;
358void HostInfoAgentPrivate::cacheLookup(
const QHostInfo &info)
368 dnsCache.
insert(info.
hostName(),
new HostCacheInfo{info, QTime::currentTime()});
371void HostInfoAgentPrivate::queryFinished(
const QHostInfo &info, Query *sender)
373 const auto host =
sender->hostName();
381#include "hostinfo.moc"
Q_SCRIPTABLE Q_NOREPLY void start()
KSERVICE_EXPORT KService::List query(FilterFunc filterFunc)
KIOCORE_EXPORT QHostInfo lookupCachedHostInfoFor(const QString &hostName)
KIOCORE_EXPORT void cacheLookup(const QHostInfo &info)
void lookupHost(const QString &hostName, QObject *receiver, const char *member)
A namespace for KIO globals.
bool insert(const Key &key, T *object, qsizetype cost)
T * object(const Key &key) const const
bool remove(const Key &key)
QString decodeName(const QByteArray &localFileName)
void setFuture(const QFuture< T > &future)
iterator insert(const Key &key, const T &value)
bool remove(const Key &key)
T value(const Key &key) const const
void abortHostLookup(int id)
HostInfoError error() const const
QHostInfo fromName(const QString &name)
QString hostName() const const
int lookupHost(const QString &name, Functor &&functor)
int lookupId() const const
void setAddresses(const QList< QHostAddress > &addresses)
void setError(HostInfoError error)
iterator erase(const_iterator first, const_iterator last)
iterator find(const Key &key)
iterator insert(const Key &key, const T &value)
size_type remove(const Key &key)
QMetaObject::Connection connect(const QObject *sender, PointerToMemberFunction signal, Functor functor)
QObject * sender() const const
bool isEmpty() const const
QFuture< T > run(Function function,...)
bool wait(QDeadlineTimer deadline)
QTime addSecs(int s) const const