/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 |