Coverage Report

Created: 2026-01-25 07:18

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/qtbase/src/network/kernel/qhostinfo_p.h
Line
Count
Source
1
// Copyright (C) 2016 The Qt Company Ltd.
2
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
// Qt-Security score:significant reason:default
4
5
#ifndef QHOSTINFO_P_H
6
#define QHOSTINFO_P_H
7
8
//
9
//  W A R N I N G
10
//  -------------
11
//
12
// This file is not part of the Qt API.  It exists for the convenience
13
// of the QHostInfo class.  This header file may change from
14
// version to version without notice, or even be removed.
15
//
16
// We mean it.
17
//
18
19
#include <QtNetwork/private/qtnetworkglobal_p.h>
20
#include "QtCore/qcoreapplication.h"
21
#include "private/qcoreapplication_p.h"
22
#include "private/qmetaobject_p.h"
23
#include "QtNetwork/qhostinfo.h"
24
#include "QtCore/qmutex.h"
25
#include "QtCore/qwaitcondition.h"
26
#include "QtCore/qobject.h"
27
#include "QtCore/qpointer.h"
28
#include "QtCore/qthread.h"
29
#if QT_CONFIG(thread)
30
#include "QtCore/qthreadpool.h"
31
#endif
32
#include "QtCore/qrunnable.h"
33
#include "QtCore/qlist.h"
34
#include "QtCore/qqueue.h"
35
#include <QElapsedTimer>
36
#include <QCache>
37
38
#include <atomic>
39
40
QT_BEGIN_NAMESPACE
41
42
43
class QHostInfoResult : public QObject
44
{
45
0
    Q_OBJECT
46
0
public:
47
0
    explicit QHostInfoResult(const QObject *receiver, QtPrivate::SlotObjUniquePtr slot);
48
0
    ~QHostInfoResult() override;
49
0
50
0
    void postResultsReady(const QHostInfo &info);
51
0
52
0
Q_SIGNALS:
53
0
    void resultsReady(const QHostInfo &info);
54
0
55
0
private Q_SLOTS:
56
0
    void finalizePostResultsReady(const QHostInfo &info);
57
0
58
0
private:
59
0
    QHostInfoResult(QHostInfoResult *other)
60
0
        : receiver(other->receiver.get() != other ? other->receiver.get() : this),
61
0
          slotObj{std::move(other->slotObj)}
62
0
    {
63
        // cleanup if the application terminates before results are delivered
64
0
        connect(QCoreApplication::instance(), &QCoreApplication::aboutToQuit,
65
0
                this, &QObject::deleteLater);
66
        // maintain thread affinity
67
0
        moveToThread(other->thread());
68
0
    }
69
70
    // receiver is either a QObject provided by the user,
71
    // or it's set to `this` (to emulate the behavior of the contextless connect())
72
    QPointer<const QObject> receiver = nullptr;
73
    QtPrivate::SlotObjUniquePtr slotObj;
74
};
75
76
class QHostInfoAgent
77
{
78
public:
79
    static QHostInfo fromName(const QString &hostName);
80
    static QHostInfo lookup(const QString &hostName);
81
    static QHostInfo reverseLookup(const QHostAddress &address);
82
};
83
84
class QHostInfoPrivate
85
{
86
public:
87
    inline QHostInfoPrivate()
88
0
        : err(QHostInfo::NoError),
89
0
          errorStr(QLatin1StringView(QT_TRANSLATE_NOOP("QHostInfo", "Unknown error"))),
90
0
          lookupId(0)
91
0
    {
92
0
    }
93
    static int lookupHostImpl(const QString &name,
94
                              const QObject *receiver,
95
                              QtPrivate::QSlotObjectBase *slotObj,
96
                              const char *member);
97
98
    QHostInfo::HostInfoError err;
99
    QString errorStr;
100
    QList<QHostAddress> addrs;
101
    QString hostName;
102
    int lookupId;
103
};
104
105
// These functions are outside of the QHostInfo class and strictly internal.
106
// Do NOT use them outside of QAbstractSocket.
107
QHostInfo Q_NETWORK_EXPORT qt_qhostinfo_lookup(const QString &name, QObject *receiver, const char *member, bool *valid, int *id);
108
void Q_AUTOTEST_EXPORT qt_qhostinfo_clear_cache();
109
void Q_AUTOTEST_EXPORT qt_qhostinfo_enable_cache(bool e);
110
void Q_AUTOTEST_EXPORT qt_qhostinfo_cache_inject(const QString &hostname, const QHostInfo &resolution);
111
112
class QHostInfoCache
113
{
114
public:
115
    QHostInfoCache();
116
    const int max_age; // seconds
117
118
    QHostInfo get(const QString &name, bool *valid);
119
    void put(const QString &name, const QHostInfo &info);
120
    void clear();
121
122
0
    bool isEnabled() { return enabled.load(std::memory_order_relaxed); }
123
    // this function is currently only used for the auto tests
124
    // and not usable by public API
125
0
    void setEnabled(bool e) { enabled.store(e, std::memory_order_relaxed); }
126
private:
127
    std::atomic<bool> enabled;
128
    struct QHostInfoCacheElement {
129
        QHostInfo info;
130
        QElapsedTimer age;
131
    };
132
    QCache<QString,QHostInfoCacheElement> cache;
133
    QMutex mutex;
134
};
135
136
// the following classes are used for the (normal) case: We use multiple threads to lookup DNS
137
138
class QHostInfoRunnable : public QRunnable
139
{
140
public:
141
    explicit QHostInfoRunnable(const QString &hn, int i, const QObject *receiver,
142
                               QtPrivate::SlotObjUniquePtr slotObj);
143
    ~QHostInfoRunnable() override;
144
145
    void run() override;
146
147
    QString toBeLookedUp;
148
    int id;
149
    QHostInfoResult resultEmitter;
150
};
151
152
153
class QHostInfoLookupManager
154
{
155
public:
156
    QHostInfoLookupManager();
157
    ~QHostInfoLookupManager();
158
159
    void clear();
160
161
    // called from QHostInfo
162
    void scheduleLookup(QHostInfoRunnable *r);
163
    void abortLookup(int id);
164
165
    // called from QHostInfoRunnable
166
    void lookupFinished(QHostInfoRunnable *r);
167
    bool wasAborted(int id);
168
169
    QHostInfoCache cache;
170
171
    friend class QHostInfoRunnable;
172
protected:
173
#if QT_CONFIG(thread)
174
    QList<QHostInfoRunnable*> currentLookups; // in progress
175
    QList<QHostInfoRunnable*> postponedLookups; // postponed because in progress for same host
176
#endif
177
    QQueue<QHostInfoRunnable*> scheduledLookups; // not yet started
178
    QList<QHostInfoRunnable*> finishedLookups; // recently finished
179
    QList<int> abortedLookups; // ids of aborted lookups
180
181
#if QT_CONFIG(thread)
182
    QThreadPool threadPool;
183
#endif
184
    QMutex mutex;
185
186
    bool wasDeleted;
187
188
private:
189
    void rescheduleWithMutexHeld();
190
};
191
192
QT_END_NAMESPACE
193
194
#endif // QHOSTINFO_P_H