Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Toggle main menu visibility
Loading...
Searching...
No Matches
qhostinfo_unix.cpp
Go to the documentation of this file.
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:trusted-data
4
5
//#define QHOSTINFO_DEBUG
6
7
#
include
"qhostinfo_p.h"
8
9
#
include
<
qbytearray
.
h
>
10
#
include
<
qfile
.
h
>
11
#
include
<
qplatformdefs
.
h
>
12
#
include
<
qurl
.
h
>
13
14
#
include
<
sys
/
types
.
h
>
15
#
include
<
netdb
.
h
>
16
#
include
<
netinet
/
in
.
h
>
17
18
#
if
QT_CONFIG
(
libresolv
)
19
#
include
<
resolv
.
h
>
20
#
endif
21
22
#
ifndef
_PATH_RESCONF
23
#
define
_PATH_RESCONF
"/etc/resolv.conf"
24
#
endif
25
26
QT_BEGIN_NAMESPACE
27
28
using
namespace
Qt::StringLiterals;
29
30
static
void
maybeRefreshResolver
()
31
{
32
#
if
defined
(
RES_NORELOAD
)
33
// If RES_NORELOAD is defined, then the libc is capable of watching
34
// /etc/resolv.conf for changes and reloading as necessary. So accept
35
// whatever is configured.
36
return
;
37
#
elif
defined
(
Q_OS_DARWIN
)
38
// Apple's libsystem_info.dylib:getaddrinfo() uses the
39
// libsystem_dnssd.dylib to resolve hostnames. Using res_init() has no
40
// effect on it and is thread-unsafe.
41
return
;
42
#
elif
defined
(
Q_OS_FREEBSD
)
43
// FreeBSD automatically refreshes:
44
// https://github.com/freebsd/freebsd-src/blob/b3fe5d932264445cbf9a1c4eab01afb6179b499b/lib/libc/resolv/res_state.c#L69
45
return
;
46
#
elif
defined
(
Q_OS_OPENBSD
)
47
// OpenBSD automatically refreshes:
48
// https://github.com/ligurio/openbsd-src/blob/b1ce0da17da254cc15b8aff25b3d55d3c7a82cec/lib/libc/asr/asr.c#L367
49
return
;
50
#
elif
defined
(
Q_OS_QNX
)
51
// res_init() is not thread-safe; executing it leads to state corruption.
52
// Whether it reloads resolv.conf on its own is unknown.
53
return
;
54
#
endif
55
56
#
if
QT_CONFIG
(
libresolv
)
57
// OSes known or thought to reach here: AIX, NetBSD, Solaris,
58
// Linux with MUSL (though res_init() does nothing and is unnecessary)
59
60
Q_CONSTINIT
static
QT_STATBUF lastStat = {};
61
Q_CONSTINIT
static
QBasicMutex mutex = {};
62
if
(QT_STATBUF st; QT_STAT(_PATH_RESCONF, &st) == 0) {
63
QMutexLocker locker(&mutex);
64
bool
refresh =
false
;
65
if
((_res.options & RES_INIT) == 0)
66
refresh =
true
;
67
else
if
(lastStat.st_ctime != st.st_ctime)
68
refresh =
true
;
// file was updated
69
else
if
(lastStat.st_dev != st.st_dev || lastStat.st_ino != st.st_ino)
70
refresh =
true
;
// file was replaced
71
if
(refresh) {
72
lastStat = st;
73
res_init();
74
}
75
}
76
#
endif
77
}
78
79
QHostInfo
QHostInfoAgent
::fromName(
const
QString &hostName)
80
{
81
QHostInfo results;
82
83
#
if
defined
(
QHOSTINFO_DEBUG
)
84
qDebug(
"QHostInfoAgent::fromName(%s) looking up..."
,
85
hostName.toLatin1().constData());
86
#
endif
87
88
maybeRefreshResolver
(
)
;
89
90
QHostAddress address;
91
if
(address.setAddress(hostName))
92
return
reverseLookup(address);
93
94
return
lookup(hostName);
95
}
96
97
QString QHostInfo::localDomainName()
98
{
99
#
if
QT_CONFIG
(
libresolv
)
100
auto
domainNameFromRes = [](res_state r) {
101
QString domainName;
102
if
(r->defdname[0])
103
domainName = QUrl::fromAce(r->defdname);
104
if
(domainName.isEmpty())
105
domainName = QUrl::fromAce(r->dnsrch[0]);
106
return
domainName;
107
};
108
std::remove_pointer_t<res_state> state = {};
109
if
(res_ninit(&state) == 0) {
110
// using thread-safe version
111
auto
guard = qScopeGuard([&] { res_nclose(&state); });
112
return
domainNameFromRes(&state);
113
}
114
115
// using thread-unsafe version
116
maybeRefreshResolver();
117
return
domainNameFromRes(&_res);
118
#
endif
// !QT_CONFIG(libresolv)
119
120
// nothing worked, try doing it by ourselves:
121
QFile resolvconf;
122
resolvconf.setFileName(
_PATH_RESCONF
""_L1
);
123
if
(!resolvconf.open(QIODevice::ReadOnly))
124
return
QString();
// failure
125
126
QString domainName;
127
QByteArray lineArray;
128
while
(resolvconf.readLineInto(&lineArray)) {
129
QByteArrayView line = QByteArrayView(lineArray).trimmed();
130
constexpr
QByteArrayView domainWithSpace =
"domain "
;
131
if
(line.startsWith(domainWithSpace))
132
return
QUrl::fromAce(line.mid(domainWithSpace.size()).trimmed().toByteArray());
133
134
// in case there's no "domain" line, fall back to the first "search" entry
135
constexpr
QByteArrayView searchWithSpace =
"search "
;
136
if
(domainName.isEmpty() && line.startsWith(searchWithSpace)) {
137
QByteArrayView searchDomain = line.mid(searchWithSpace.size()).trimmed();
138
int
pos = searchDomain.indexOf(
' '
);
139
if
(pos != -1)
140
searchDomain.truncate(pos);
141
domainName = QUrl::fromAce(searchDomain.toByteArray());
142
}
143
}
144
145
// return the fallen-back-to searched domain
146
return
domainName;
147
}
148
149
QT_END_NAMESPACE
QHostInfoAgent
Definition
qhostinfo_p.h:78
maybeRefreshResolver
static void maybeRefreshResolver()
Definition
qhostinfo_unix.cpp:30
_PATH_RESCONF
#define _PATH_RESCONF
Definition
qhostinfo_unix.cpp:23
qtbase
src
network
kernel
qhostinfo_unix.cpp
Generated on
for Qt by
1.18.0