File indexing completed on 2025-01-05 04:37:19

0001 /*
0002     SPDX-FileCopyrightText: 2009 Joris Guisson <joris.guisson@gmail.com>
0003 
0004     SPDX-License-Identifier: GPL-2.0-or-later
0005 */
0006 
0007 #include "reverseresolver.h"
0008 #include <netdb.h>
0009 #include <sys/socket.h>
0010 
0011 namespace net
0012 {
0013 ReverseResolverThread *ReverseResolver::worker = nullptr;
0014 
0015 ReverseResolver::ReverseResolver(QObject *parent)
0016     : QObject(parent)
0017 {
0018 }
0019 
0020 ReverseResolver::~ReverseResolver()
0021 {
0022 }
0023 
0024 void ReverseResolver::resolveAsync(const net::Address &addr)
0025 {
0026     addr_to_resolve = addr;
0027     if (!worker) {
0028         worker = new ReverseResolverThread();
0029         worker->add(this);
0030         worker->start();
0031     } else {
0032         worker->add(this);
0033     }
0034 }
0035 
0036 QString ReverseResolver::resolve(const net::Address &addr)
0037 {
0038     struct sockaddr_storage ss;
0039     int slen = 0;
0040     addr.toSocketAddress(&ss, slen);
0041 
0042     char host[200];
0043     char service[200];
0044     memset(host, 0, 200);
0045     memset(service, 0, 200);
0046     if (getnameinfo((struct sockaddr *)&ss, slen, host, 199, service, 199, NI_NAMEREQD) == 0)
0047         return QString::fromUtf8(host);
0048     else
0049         return QString();
0050 }
0051 
0052 void ReverseResolver::run()
0053 {
0054     QString res = resolve(addr_to_resolve);
0055     Q_EMIT resolved(res);
0056 }
0057 
0058 void ReverseResolver::shutdown()
0059 {
0060     if (worker) {
0061         worker->stop();
0062         worker->wait();
0063         delete worker;
0064         worker = nullptr;
0065     }
0066 }
0067 
0068 ReverseResolverThread::ReverseResolverThread()
0069     : stopped(false)
0070 {
0071 }
0072 
0073 ReverseResolverThread::~ReverseResolverThread()
0074 {
0075 }
0076 
0077 void ReverseResolverThread::add(ReverseResolver *rr)
0078 {
0079     mutex.lock();
0080     todo_list.append(rr);
0081     mutex.unlock();
0082     more_data.wakeOne();
0083 }
0084 
0085 void ReverseResolverThread::run()
0086 {
0087     while (!stopped) {
0088         mutex.lock();
0089         if (!todo_list.empty()) {
0090             ReverseResolver *rr = todo_list.first();
0091             todo_list.pop_front();
0092             mutex.unlock();
0093             rr->run();
0094             rr->deleteLater();
0095         } else {
0096             more_data.wait(&mutex);
0097             mutex.unlock();
0098         }
0099     }
0100 
0101     // cleanup if necessary
0102     for (ReverseResolver *rr : std::as_const(todo_list))
0103         rr->deleteLater();
0104     todo_list.clear();
0105 }
0106 
0107 void ReverseResolverThread::stop()
0108 {
0109     stopped = true;
0110     // wake up the thread if it is sleeping
0111     more_data.wakeOne();
0112 }
0113 
0114 }
0115 
0116 #include "moc_reverseresolver.cpp"