8#include <qplatformdefs.h>
10#include "QtCore/qapplicationstatic.h"
11#include "QtCore/qscopedpointer.h"
25# include <netinet/in.h>
26# if defined(AI_ADDRCONFIG) && !defined(Q_OS_WASM)
27# define Q_ADDRCONFIG AI_ADDRCONFIG
32# define QT_SOCKLEN_T int
44struct ToBeLookedUpEquals {
45 typedef bool result_type;
46 explicit ToBeLookedUpEquals(
const QString &toBeLookedUp) noexcept : m_toBeLookedUp(toBeLookedUp) {}
49 return m_toBeLookedUp == lookup->toBeLookedUp;
55template <
typename InputIt,
typename OutputIt1,
typename OutputIt2,
typename UnaryPredicate>
56std::pair<OutputIt1, OutputIt2> separate_if(InputIt
first, InputIt last, OutputIt1 dest1, OutputIt2 dest2, UnaryPredicate
p)
58 while (
first != last) {
68 return std::make_pair(dest1, dest2);
76 : receiver{receiver ? receiver :
this}, slotObj{
std::move(slot)}
112 &QHostInfoResult::finalizePostResultsReady,
120void QHostInfoResult::finalizePostResultsReady(
const QHostInfo &
info)
194 return 1 +
counter.fetchAndAddRelaxed(1);
231 if (!receiver || !member) {
232 qWarning(
"QHostInfo::lookupHost: both the receiver and the member to invoke must be non-null");
235 return QHostInfo::lookupHostImpl(
name, receiver,
nullptr, member);
322 theHostInfoLookupManager()->abortLookup(
id);
340#if defined QHOSTINFO_DEBUG
341 qDebug(
"QHostInfo::fromName(\"%s\")",
name.toLatin1().constData());
361 sockaddr *sa =
nullptr;
364 sa =
reinterpret_cast<sockaddr *
>(&sa4);
365 saSize =
sizeof(sa4);
366 memset(&sa4, 0,
sizeof(sa4));
367 sa4.sin_family = AF_INET;
368 sa4.sin_addr.s_addr = htonl(
address.toIPv4Address());
370 sa =
reinterpret_cast<sockaddr *
>(&sa6);
371 saSize =
sizeof(sa6);
372 memset(&sa6, 0,
sizeof(sa6));
374 memcpy(&sa6.sin6_addr,
address.toIPv6Address().c,
sizeof(sa6.sin6_addr));
378 if (sa && getnameinfo(sa, saSize, hbuf,
sizeof(hbuf),
nullptr, 0, 0) == 0)
398 if (aceHostname.isEmpty()) {
406 addrinfo *
res =
nullptr;
407 struct addrinfo hints;
408 memset(&hints, 0,
sizeof(hints));
409 hints.ai_family = PF_UNSPEC;
411 hints.ai_flags = Q_ADDRCONFIG;
414 int result = getaddrinfo(aceHostname.constData(),
nullptr, &hints, &
res);
416 if (
result == EAI_BADFLAGS) {
419 result = getaddrinfo(aceHostname.constData(),
nullptr, &hints, &
res);
424 addrinfo *node =
res;
425 QList<QHostAddress> addresses;
427#ifdef QHOSTINFO_DEBUG
428 qDebug() <<
"getaddrinfo node: flags:" << node->ai_flags <<
"family:" << node->ai_family
429 <<
"ai_socktype:" << node->ai_socktype <<
"ai_protocol:" << node->ai_protocol
430 <<
"ai_addrlen:" << node->ai_addrlen;
432 switch (node->ai_family) {
435 addr.
setAddress(ntohl(((sockaddr_in *) node->ai_addr)->sin_addr.s_addr));
436 if (!addresses.contains(
addr))
437 addresses.append(
addr);
442 sockaddr_in6 *sa6 = (sockaddr_in6 *) node->ai_addr;
443 addr.setAddress(sa6->sin6_addr.s6_addr);
444 if (sa6->sin6_scope_id)
446 if (!addresses.contains(
addr))
447 addresses.append(
addr);
454 node = node->ai_next;
456 if (addresses.isEmpty()) {
463 results.setAddresses(addresses);
468 case WSAHOST_NOT_FOUND:
492#if defined(QHOSTINFO_DEBUG)
494 qDebug(
"QHostInfoAgent::fromName(): error #%d %s",
498 QList<QHostAddress> addresses =
results.addresses();
499 for (
int i = 0;
i < addresses.count(); ++
i) {
500 if (
i != 0) tmp +=
", "_L1;
501 tmp += addresses.at(
i).toString();
503 qDebug(
"QHostInfoAgent::fromName(): found %i entries for \"%s\": {%s}",
504 addresses.count(), aceHostname.constData(),
567 *d_ptr = *
other.d_ptr;
743#if defined QHOSTINFO_DEBUG
744 qDebug(
"QHostInfo::lookupHostImpl(\"%s\", %p, %p, %s)",
745 name.toLatin1().constData(), receiver, slotObj.get(), member ? member + 1 : 0);
750 const bool isUsingStringBasedSlot =
static_cast<bool>(member);
753 qWarning(
"QHostInfo::lookupHost() called with no event dispatcher");
757 qRegisterMetaType<QHostInfo>();
767 if (isUsingStringBasedSlot) {
771 result.postResultsReady(hostInfo);
782 hostInfo.setLookupId(
id);
785 if (isUsingStringBasedSlot) {
789 result.postResultsReady(hostInfo);
802 if (isUsingStringBasedSlot) {
813 if (isUsingStringBasedSlot) {
817 manager->scheduleLookup(runnable);
825 : toBeLookedUp{hn},
id{
i}, resultEmitter{receiver,
std::move(slotObj)}
866 hostInfo.setLookupId(
id);
873 const auto partitionBegin = std::stable_partition(
manager->postponedLookups.rbegin(),
manager->postponedLookups.rend(),
875 const auto partitionEnd =
manager->postponedLookups.end();
876 for (
auto it = partitionBegin;
it != partitionEnd; ++
it) {
879 hostInfo.setLookupId(postponed->id);
880 postponed->resultEmitter.postResultsReady(hostInfo);
883 manager->postponedLookups.erase(partitionBegin, partitionEnd);
894 &threadPool, [&](
QObject *) { threadPool.waitForDone(); },
896 threadPool.setMaxThreadCount(20);
918 postponedLookups.clear();
925 threadPool.waitForDone();
931void QHostInfoLookupManager::rescheduleWithMutexHeld()
951 return std::any_of(currentLookups.cbegin(), currentLookups.cend(), ToBeLookedUpEquals(lookup->toBeLookedUp));
955 postponedLookups.erase(separate_if(postponedLookups.begin(),
956 postponedLookups.end(),
957 postponedLookups.begin(),
959 isAlreadyRunning).first,
960 postponedLookups.end());
965 std::back_inserter(postponedLookups),
967 isAlreadyRunning).second,
970 const int availableThreads = std::max(threadPool.maxThreadCount(), 1) - currentLookups.size();
971 if (availableThreads > 0) {
974 while (readyToStartCount--) {
976 threadPool.start(*
it);
977 currentLookups.push_back(std::move(*
it));
997 rescheduleWithMutexHeld();
1011#if QT_CONFIG(thread)
1013 for (
int i = 0;
i < postponedLookups.size();
i++) {
1014 if (postponedLookups.at(
i)->id ==
id) {
1015 delete postponedLookups.takeAt(
i);
1052#if QT_CONFIG(thread)
1053 currentLookups.removeOne(
r);
1056 rescheduleWithMutexHeld();
1075 *
id = QHostInfo::lookupHostImpl(
name, receiver,
nullptr, member);
1089#ifdef QT_BUILD_INTERNAL
1112#ifdef QT_QHOSTINFO_CACHE_DISABLED_BY_DEFAULT
1113 enabled.store(
false, std::memory_order_relaxed);
1122 if (QHostInfoCacheElement *element =
cache.object(
name)) {
1123 if (element->age.elapsed() <
max_age*1000)
1125 return element->info;
1141 QHostInfoCacheElement* element =
new QHostInfoCacheElement();
1142 element->info =
info;
1144 element->age.
start();
1147 cache.insert(name, element);
1158#include "moc_qhostinfo_p.cpp"
static QAbstractEventDispatcher * instance(QThread *thread=nullptr)
Returns a pointer to the event dispatcher object for the specified thread.
static constexpr auto IPv4Protocol
const char * constData() const noexcept
Returns a pointer to the const data stored in the byte array.
static QCoreApplication * instance() noexcept
Returns a pointer to the application's QCoreApplication (or QGuiApplication/QApplication) instance.
static QString translate(const char *context, const char *key, const char *disambiguation=nullptr, int n=-1)
\threadsafe
void start() noexcept
\typealias QElapsedTimer::Duration Synonym for std::chrono::nanoseconds.
The QHostAddress class provides an IP address.
void setAddress(quint32 ip4Addr)
Set the IPv4 address specified by ip4Addr.
static QHostInfo lookup(const QString &hostName)
static QHostInfo reverseLookup(const QHostAddress &address)
static QHostInfo fromName(const QString &hostName)
QHostInfo get(const QString &name, bool *valid)
void put(const QString &name, const QHostInfo &info)
~QHostInfoLookupManager()
QQueue< QHostInfoRunnable * > scheduledLookups
void lookupFinished(QHostInfoRunnable *r)
void scheduleLookup(QHostInfoRunnable *r)
QList< int > abortedLookups
QList< QHostInfoRunnable * > finishedLookups
void resultsReady(const QHostInfo &info)
QHostInfoResult(const QObject *receiver, QtPrivate::SlotObjUniquePtr slot)
void postResultsReady(const QHostInfo &info)
~QHostInfoResult() override
void run() override
Implement this pure virtual function in your subclass.
QHostInfoRunnable(const QString &hn, int i, const QObject *receiver, QtPrivate::SlotObjUniquePtr slotObj)
QHostInfoResult resultEmitter
~QHostInfoRunnable() override
The QHostInfo class provides static functions for host name lookups.
void setHostName(const QString &name)
Sets the host name of this QHostInfo to hostName.
static void abortHostLookup(int lookupId)
Aborts the host lookup with the ID id, as returned by lookupHost().
static int lookupHost(const QString &name, const QObject *receiver, const char *member)
Looks up the IP address(es) associated with host name name, and returns an ID for the lookup.
void setAddresses(const QList< QHostAddress > &addresses)
Sets the list of addresses in this QHostInfo to addresses.
QHostInfo & operator=(const QHostInfo &d)
Assigns the data of the other object to this host info object, and returns a reference to it.
static QString localHostName()
Returns this machine's host name, if one is configured.
HostInfoError
This enum describes the various errors that can occur when trying to resolve a host name.
HostInfoError error() const
Returns the type of error that occurred if the host name lookup failed; otherwise returns NoError.
void setError(HostInfoError error)
Sets the error type of this QHostInfo to error.
QHostInfo(int lookupId=-1)
Constructs an empty host info object with lookup ID id.
QString hostName() const
Returns the name of the host whose IP addresses were looked up.
QString errorString() const
If the lookup failed, this function returns a human readable description of the error; otherwise "Unk...
static QHostInfo fromName(const QString &name)
Looks up the IP address(es) for the given host name.
void setErrorString(const QString &errorString)
Sets the human readable description of the error that occurred to str if the lookup failed.
QList< QHostAddress > addresses() const
Returns the list of IP addresses associated with hostName().
int lookupId() const
Returns the ID of this lookup.
void setLookupId(int id)
Sets the ID of this lookup to id.
~QHostInfo()
Destroys the host info object.
qsizetype size() const noexcept
const_pointer constData() const noexcept
bool isEmpty() const noexcept
iterator erase(const_iterator begin, const_iterator end)
const_reference at(qsizetype i) const noexcept
qsizetype removeAll(const AT &t)
void append(parameter_type t)
void unlock() noexcept
Unlocks this mutex locker.
QAbstractNetworkCache * cache() const
static QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *member, Qt::ConnectionType=Qt::AutoConnection)
\threadsafe
QThread * thread() const
Returns the thread in which the object lives.
bool moveToThread(QThread *thread QT6_DECL_NEW_OVERLOAD_TAIL)
Changes the thread affinity for this object and its children and returns true on success.
void destroyed(QObject *=nullptr)
This signal is emitted immediately before the object obj is destroyed, after any instances of QPointe...
void deleteLater()
\threadsafe
T * data() const noexcept
void enqueue(const T &t)
Adds value t to the tail of the queue.
void setAutoDelete(bool autoDelete)
Enables auto-deletion if autoDelete is true; otherwise auto-deletion is disabled.
\macro QT_RESTRICTED_CAST_FROM_ASCII
QByteArray toLatin1() const &
static QString fromLatin1(QByteArrayView ba)
This is an overloaded member function, provided for convenience. It differs from the above function o...
static QString fromLocal8Bit(QByteArrayView ba)
This is an overloaded member function, provided for convenience. It differs from the above function o...
bool isEmpty() const noexcept
Returns true if the string has no characters; otherwise returns false.
static QString fromWCharArray(const wchar_t *string, qsizetype size=-1)
static QString number(int, int base=10)
This is an overloaded member function, provided for convenience. It differs from the above function o...
static QString machineHostName()
static QThread * currentThread()
static QByteArray toAce(const QString &domain, AceProcessingOptions options={})
qDeleteAll(list.begin(), list.end())
QCache< int, Employee > cache
[0]
QSet< QString >::iterator it
Combined button and popup list for selecting options.
std::unique_ptr< QSlotObjectBase, QSlotObjectBase::Deleter > SlotObjUniquePtr
#define Q_APPLICATION_STATIC(TYPE, NAME,...)
#define Q_BASIC_ATOMIC_INITIALIZER(a)
DBusConnection const char DBusError * error
void qt_qhostinfo_clear_cache()
QHostInfo qt_qhostinfo_lookup(const QString &name, QObject *receiver, const char *member, bool *valid, int *id)
void Q_AUTOTEST_EXPORT qt_qhostinfo_enable_cache(bool e)
void Q_AUTOTEST_EXPORT qt_qhostinfo_cache_inject(const QString &hostname, const QHostInfo &resolution)
constexpr const T & qMin(const T &a, const T &b)
GLenum GLenum GLsizei const GLuint GLboolean enabled
GLuint GLuint64EXT address
QScopeGuard< typename std::decay< F >::type > qScopeGuard(F &&f)
[qScopeGuard]
#define Q_AUTOTEST_EXPORT
Q_CHECK_PTR(a=new int[80])
QNetworkAccessManager manager
bool contains(const AT &t) const noexcept