I've left the QT_NO_ macros because they were public. No one should be
using them (and they are now 1 on Linux, so you had better not be using
them), but just in case.
Change-Id: Ifbf974a4d10745b099b1fffd177758a7a26e4244
Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
Reviewed-by: Timur Pocheptsov <timur.pocheptsov@qt.io>
Reviewed-by: Alexandru Croitor <alexandru.croitor@qt.io>
Create QBA only when it's needed
While touching code, use std::move more
Change-Id: I5f014822a47d41fa1fca46a85a7921c70d1d9a55
Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
As part of creating the QML binding, add
Q_CLASSINFO("RegisterEnumClassesUnscoped", "false")
to QNetworkInformation.
Task-number: QTBUG-113813
Change-Id: Ib5d3b2356986c565b9786bc2d925cc4199bae6c9
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
Clean up after all users are ported to the SlotObjUniquePtr overloads.
Pick-to: 6.6 6.5
Change-Id: I3e58249296ea9674c45fb412463ae3201518de72
Reviewed-by: Ivan Solovev <ivan.solovev@qt.io>
Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
... and use them around the code.
Avoids the impedance mismatch between users, which .release() their
SlotObjUniquePtr's into the ctors, and the ctor, which constructs its
member SlotObjUniquePtr from that.
The old constructors are left in on purpose and removed in a follow-up
commit to facilitate cherry-picking into branches that might have
additional callers.
Pick-to: 6.6 6.5
Change-Id: I6f8bce317d5116296973a3a2e3f97db1451f579d
Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
We've known for a long time that this is producing worse code with GCC
because of how we implemented in Q_ASSUME_IMPL(). So bite the bullet and
actually deprecate the macro, replacing all extant Q_ASSUME() with
Q_ASSERT().
The replacement is in C++23. Backporting the support onto Q_ASSUME_IMPL
was previously rejected by reviewers.
[ChangeLog][Deprecation Notice] The Q_ASSUME() macro is deprecated. This
macro has different side-effects depending on the compiler used (GCC
compared to Clang and MSVC), and there are certain conditions under
which GCC is known to produce worse code than if the macro was absent.
To give a hint to the compiler for optimizations, use the C++23
[[assume]] attribute.
Change-Id: I80612a7d275c41f1baf0fffd177a3a4ad819fb2d
Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
The current implementation is not thread safe - it is possible
to update and query the network information without any locking.
Protect the internals of the backend with a lock and move the
object to the main thread.
Task-number: QTBUG-115748
Change-Id: I9511fc3522ae82cffca42abc54eb79cb156397c4
Reviewed-by: Juha Vuolle <juha.vuolle@qt.io>
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
Move the SlotObjUniquePtr directly into the QMetaCallEvent, without
having to up and down the ref-count.
Pick-to: 6.6 6.5
Change-Id: I029f71c60defce71ac8778547efe999ce0cf7b4b
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
These classes are not exported, so we don't run into duplicate vtables
here, but the header is included in a few TUs other than qhostinfo.cpp
(all, when building with PCH), so make sure we compile dtors only once.
Pick-to: 6.6 6.5
Change-Id: I51f6a6d27fc084ad469f82dc7aef3327bdd9a906
Reviewed-by: Ivan Solovev <ivan.solovev@qt.io>
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
It's a free function, because a) it rhymes with move(ptr) and, of
course, SlotObjUniquePtr being a std::unique_ptr, b) we can't add
member functions to it (and no, inheriting from a type whose dtor is
neither protected nor virtual is nothing you will catch yours truly
doing).
Pick-to: 6.6 6.5
Change-Id: I2026126857a7bba204d683bad118e8a2c5cb2924
Reviewed-by: Ivan Solovev <ivan.solovev@qt.io>
Drops the direct deref'ing.
Pick-to: 6.6 6.5
Change-Id: I9f159244d50572659fa8e9cabfbef47e769ac54e
Reviewed-by: Timur Pocheptsov <timur.pocheptsov@qt.io>
Reviewed-by: Marc Mutz <marc.mutz@qt.io>
We failed to delete the slot object when lookUpHost() was called in
these (exceptional) circumstances:
- on a thread with no event dispatcher
- after application shut-down, when the QHostInfoLookupManager
Q_APPLICATION_STATIC was destroyed already
Fix by adding the missing destroyIfLastRef() calls into these code
paths, too.
Amends ad5eb297e1.
This would be so much easier if we had SlotObjUniquePtr...
Pick-to: 6.6 6.5 6.2 5.15
Task-number: QTBUG-115263
Change-Id: Ief8bf125bc196742c0ce59c1fd87ab93242fc0da
Reviewed-by: Ivan Solovev <ivan.solovev@qt.io>
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
We were not ref'ing or deref'ing the slot object in the various places
that owned it. So, if, in the end, the QHostInfoResult object didn't
call the slot we would leak the slot object.
Pick-to: 6.6 6.5 6.2 5.15
Fixes: QTBUG-115263
Change-Id: I45f43756c7589470045d97b59257ccfd85a325b7
Reviewed-by: Marc Mutz <marc.mutz@qt.io>
Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
It was hard to see the problem because of the lambda, combined with
reinterpret_cast on the output of non-typesafe C macro. NLMSG_DATA
returns a void*, so use static_cast to be sure not to do something
wrong.
This only affected the code that dealt with unexpected replies from the
Linux kernel, which it doesn't send. So I don't expect this fixes any
improper QNetworkInterface behavior.
Found by CodeChecker.
Pick-to: 6.5 6.6
Change-Id: I61b74deaf2514644a24efffd1770d75e5a4f2636
Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
Avoid decoding multiple times the domain name when it comes in
sequence. This happens when a given domain label either has multiple
entries in its record set or when it's a CNAME (or both), such as in:
;; ANSWER SECTION:
cname-cname.test.qt-project.org. 3600 IN CNAME cname.test.qt-project.org.
cname.test.qt-project.org. 1614 IN CNAME multi.test.qt-project.org.
multi.test.qt-project.org. 1614 IN A 198.51.100.2
multi.test.qt-project.org. 1614 IN A 198.51.100.3
multi.test.qt-project.org. 1614 IN A 198.51.100.1
Label targets from other records such as MX and SRV usually do show up
again, in the Additional section, but the chance that they are
sequential isn't very good, so we don't cache those.
;; ANSWER SECTION:
mx-multi.test.qt-project.org. 3354 IN MX 10 multi.test.qt-project.org.
mx-multi.test.qt-project.org. 3354 IN MX 20 a-single.test.qt-project.org.
;; ADDITIONAL SECTION:
multi.test.qt-project.org. 1145 IN A 198.51.100.3
multi.test.qt-project.org. 1145 IN A 198.51.100.1
multi.test.qt-project.org. 1145 IN A 198.51.100.2
a-single.test.qt-project.org. 3364 IN A 192.0.2.1
Change-Id: I5f7f427ded124479baa6fffd175f5cf88939ee73
Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
[ChangeLog][QtNetwork][QDnsLookup] It is now possible to look up the
root DNS domain, by setting the name property to an empty string. This
query is usually done while setting the query type to NS.
Change-Id: I5f7f427ded124479baa6fffd175f688395941610
Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
Use qt_ACE_do directly from QtCore, to avoid going through Latin1
(US-ASCII) multiple times.
Drive-by reduce the size of the buffers from PACKETSZ (512) to the
maximum name a label can be (255 plus 1 for the null, just in case).
Drive-by replace the last QString::fromWCharArray with QStringView,
saving an unnecessary memory allocation before calling
QtPrivate::convertToLatin1().
Change-Id: I3e3bfef633af4130a03afffd175d8be1feb5d74b
Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
Testing for "res_ninit" when WrapResolv.cmake has already checked for
far more complex functions was pointless. Instead, just accept the
library that was found by find_package() as good enough and rename the
feature as "libresolv".
Amends 4a46ba1209 and
68b625901f.
Change-Id: Ib5ce7a497e034ebabb2cfffd1762c0afa2fac6e0
Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
We were getting InvalidReplyError because it was simply unknown, which
is not very useful. Previously, the Unix code used res_nquery(), which
does not return timeouts as a condition. It returns -1 if a timeout did
happen, but the content in errno could be a left-over from a previous
timeout (see the "Not a typewriter"[1] problem).
With the rewrite to using res_nmkquery() and res_nsend() from the
previous commits, we can rely on errno being set properly by
res_nsend().
$ $objdir/tests/manual/qdnslookup/qdnslookup @0.0.0.1
; <<>> QDnsLookup 6.6.0 <<>> qdnslookup @0.0.0.1
;; status: TimeoutError (Request timed out)
;; QUESTION:
;qt-project.org IN A
;; Query time: 10008 ms
;; SERVER: 0.0.0.1#53
Tested on FreeBSD, Linux, macOS, and Windows.
[1] https://en.wikipedia.org/wiki/Not_a_typewriter
Change-Id: I3e3bfef633af4130a03afffd175e31958247f9b1
Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
The current code was inefficient when replies exceeded the initial
buffer size because the res_nsend() function switched to VC to get the
full reply, but that wouldn't fit our buffer before we enlarged it. This
commit tells res_nsend() to only use UDP or only use TCP, avoiding the
two unnecessary transactions in the lookup.
Since we don't get that second TCP reply now that would tell us the size
of the reply, we must allocate the largest possible buffer for a DNS
reply.
Change-Id: I3e3bfef633af4130a03afffd175e73d2e9fa9bf1
Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
The current code is inefficient when dealing with replies exceeding the
PACKETSZ default size. This commit adds an EDNS0 footer to the DNS query
informing the DNS server how big our buffer is. We choose a larger
buffer than the old PACKETSZ so more will fit before a Virtual Circuit
(TCP socket) is required.
The choice is based on IPv6 requirements for the minimum MTU. Any
network incapable of transmitting frames with that big a payload must
support fragmenting and reassembly at the Layer 2 level, below IP.
Ethernet MTU is usually 1500, so we leave a bit on the table, but this
avoids having to discover our Path MTU to the DNS server.
This is incomplete: DNS queries above the 1232-byte limit still perform
the same query four times.
Change-Id: I3e3bfef633af4130a03afffd175e72f7fbc9265d
Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
The current code is inefficient when dealing with replies exceeding the
PACKETSZ default size and especially those that require the use of a
Virtual Circuit (TCP socket). When the TC (Truncated) bit is set in the
DNS reply header, res_nquery() automatically switches to VC so it is
able to return the full size of the reply to us. This means we make the
same request four times:
1) over UDP, getting ~512 bytes of data
2) over TCP, getting the full reply but returning ~512 to us
3) over UDP again, getting (maybe) 1400 bytes of data
4) over TCP again, getting all the data
This commit splits res_nquery() into its two component functions,
res_nmkquery() and res_nsend(). This is incomplete: the four queries
above still happen.
Change-Id: I3e3bfef633af4130a03afffd175e728d96d6a604
Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
Any resolution error that is caused by an invalid request, invalid reply
(only happens on Unix), or a system error can be printed as a warning,
using category "qt.network.dnslookup". Those warnings are disabled by
default.
Change-Id: I5f7f427ded124479baa6fffd175fc40b3e21c969
Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
I couldn't make my Windows 10 or 11 query a non-standard port. It kept
complaining about "The parameter is incorrect.", so as a result the unit
test doesn't actually test the new feature there. I can't find a single
example of this on the Internet; my speculation is that the backend API
that DnsQueryEx uses does not support setting port numbers
(DnsQuery_{A,W} didn't offer that option).
[ChangeLog][QtNetwork][QDnsLookup] Added setNameserverPort().
Change-Id: I3e3bfef633af4130a03afffd175d60a581cc0a9c
Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
This also updates a few messages and transfers the translation context
from QDnsLookupRunnable to QDnsLookup.
Change-Id: I3e3bfef633af4130a03afffd175e86715e4a25e3
Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
Amend 9a73bc5f3d with more typedefs
missing from older mingw headers:
| src/network/kernel/qdnslookup_win.cpp:40:3: error: 'PDNS_QUERY_COMPLETION_ROUTINE' does not name a type; did you mean 'LPOVERLAPPED_COMPLETION_ROUTINE'?
| 40 | PDNS_QUERY_COMPLETION_ROUTINE pQueryCompletionCallback;
| | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
| src/network/kernel/qdnslookup_win.cpp:47:9: error: 'PDNS_QUERY_RESULT' has not been declared
| 47 | PDNS_QUERY_RESULT pQueryResults,
| | ^~~~~~~~~~~~~~~~~
| src/network/kernel/qdnslookup_win.cpp:77:5: error: 'DNS_QUERY_RESULT' was not declared in this scope; did you mean 'DNS_QUERY_REQUEST'?
| 77 | DNS_QUERY_RESULT results = {};
| | ^~~~~~~~~~~~~~~~
Change-Id: I812525aaa938764d337923820d0eb8b3e24a0004
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Both the libresolv and the Win32 API operate in 32-bit quantities, so we
could be aliasing with low values. In any case, RFC 1035 limits to 255.
Various objects and parameters in the DNS have size limits. They are
listed below. Some could be easily changed, others are more
fundamental.
labels 63 octets or less
names 255 octets or less
Pick-to: 6.5
Change-Id: I3e3bfef633af4130a03afffd175e8957cd860bef
Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
Simplifies arguments and will allow me to add stateful helper methods.
Change-Id: I3e3bfef633af4130a03afffd175d6044829a96f2
Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
The Unix code doesn't do that.
[ChangeLog][Important Behavior Changes] QDnsLookup on Windows will no
longer append the system's configured domain name for look ups that
contained only a single label (that is, no dots). This matches the Unix
behavior.
Change-Id: I5f7f427ded124479baa6fffd175f69e537cf9ca2
Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
This is neater with a simple offset and avoids the potential UB code this
was carrying in:
p += size;
(p < response + responseLength)
It's UB to add to a pointer a size that moves it past the end of its
array. In practice we don't expect this to happen because of
construction (p is always pointing to a heap or auxiliary-thread stack
buffer), but in theory it could happen that said buffer is too close to
the end of the virtual address space and adding `size` causes it to
overflow back to small values.
Change-Id: I5f7f427ded124479baa6fffd175f59939c15c666
Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
There's nothing saying the server can't supply those to us, so let's
explicitly skip them. The Windows version already does this because the
windns.h API only supports records of class IN.
Test for this after setNameserverPort() is added.
Pick-to: 6.5
Change-Id: I3e3bfef633af4130a03afffd175e6ddc756c91c5
Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
Similar test with link-local server on the same network:
$ $objdir/tests/manual/qdnslookup/qdnslookup.exe @fe80::1e1b:dff:fee2:49e6%Ethernet
; <<>> QDnsLookup 6.6.0 <<>> qdnslookup @fe80::1e1b:dff:fee2:49e6%Ethernet
;; status: NoError
;; QUESTION:
;qt-project.org IN A
;; ANSWER:
qt-project.org 3532 IN A 52.18.144.254
;; Query time: 17 ms
;; SERVER: fe80::1e1b:dff:fee2:49e6%Ethernet#53
Server's dnsmasq log shows it was queried.
We don't know why we must set the port to 0. It works for me the regular
way, but not for everyone who tested this patch.
[ChangeLog][QtNetwork][QDnsLookup] setNameserver() now supports IPv6
servers with on Apple systems, AIX, FreeBSD, NetBSD, Solaris, and
Windows.
(AIX, NetBSD and Solaris not directly tested, but their docs online show
they have res_setservers())
Change-Id: I3e3bfef633af4130a03afffd175d5bfd4e7922b9
Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
This API is found on FreeBSD, Darwin, Solaris, AIX, and Android Bionic.
That means we complement IPv6 support for most platforms.
Test on macOS:
$ $objdir/tests/manual/qdnslookup/qdnslookup @fe80::1e1b:dff:fee2:49e6%en0
; <<>> QDnsLookup 6.6.0
;; status: NoError
;; QUESTION:
;qt-project.org IN A
;; ANSWER:
qt-project.org 3336 IN A 52.18.144.254
;; Query time: 2 ms
;; SERVER: fe80::1e1b:dff:fee2:49e6%en0#53
Dnsmasq log on the server confirms it was queried.
Change-Id: I3e3bfef633af4130a03afffd175d59c67faa463f
Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
Instead of using #if, this now uses SFINAE to detect the presence of the
glibc extensions to set IPv6 nameserver addresses. It's also possible
that this fixes some bugs that have always been there, but never checked
because we don't have a way to unit-test explicit name servers.
To that effect, this commit adds a manual unit test that mimics the BIND
tool "dig". When running:
./qdnslookup qt-project.org any @dns.google
it printed for me:
; <<>> QDnsLookup 6.6.0
;; status: NoError
;; QUESTION:
;qt-project.org IN ANY
;; ANSWER:
qt-project.org 3600 IN MX 10 mx.qt-project.org
qt-project.org 3600 IN NS ns14.cloudns.net
qt-project.org 3600 IN NS ns11.cloudns.net
qt-project.org 3600 IN NS ns12.cloudns.net
qt-project.org 3600 IN NS ns13.cloudns.net
qt-project.org 3600 IN A 52.18.144.254
qt-project.org 3600 IN TXT "v=spf1 mx ip4:193.209.87.4 include:spf.protection.outlook.com ~all"
;; Query time: 241 ms
;; SERVER: 2001:4860:4860::8844#53
strace confirms the DNS queries were sent to the correct address.
Change-Id: I3e3bfef633af4130a03afffd175d56a92371ed16
Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
The DNS Records are variable length and encode their size in 16 bits
before the Record Data (RDATA). Ensure that both the RDATA and the
Record header fields before it fall inside the buffer we have.
Additionally reject any replies containing more than one query records.
[ChangeLog][QtNetwork][QDnsLookup] Fixed a bug that could cause a buffer
overflow in Unix systems while parsing corrupt, malicious, or truncated
replies.
Pick-to: 5.15 6.2 6.5 6.5.1
Change-Id: I3e3bfef633af4130a03afffd175e4b9547654b95
Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
Reviewed-by: Jani Heikkinen <jani.heikkinen@qt.io>
There's no fallback anywhere, so this class simply doesn't work if
threading isn't supported. Writing it is an exercise left for whoever
cares for that configuration.
Change-Id: I3e3bfef633af4130a03afffd175e6f68a3f4673f
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
It's unnecessary in Qt 6 if we use the new-style connect or if the type
was fully defined in the compilation of the unit containing the moc
output.
Change-Id: I3e3bfef633af4130a03afffd175e6f4e87adf5e1
Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
These were added in commit 20e6a049fe as a
massive sweep of all Q_DECLARE_METATYPE, without thought as to whether
they were actually needed or not. If they are used as a metatype in a
single .cpp file, they don't need to be.
Incidentally removes the entirely incorrect Q_NETWORK_EXPORT of
QDnsLookupReply.
Pick-to: 6.5
Change-Id: I3e3bfef633af4130a03afffd175e6f378f09a3aa
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
There's little need for us to dynamically load it. The reasons why that
was necessary aren't in the public history (Qt 4.5 already had it[1]). I
remember writing the code in 2007-2008, I just don't remember why.
On modern Linux and FreeBSD, there's no libresolv.so any more and those
symbols have been rolled up into libc.so. It's still necessary on Darwin
systems, so this commit introduces WrapResolv.
It also resolves the unity build issues relating to libresolv symbols.
[1] https://code.qt.io/cgit/qt/qt.git/tree/src/network/kernel/qhostinfo_unix.cpp?h=v4.5.1
Task-number: QTBUG-109394
Change-Id: Ic5799e4d000b6c9395109e008780643bac52122b
Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
After the recent changes we only have a single implementation of
QSlotObjectBase, which can handle free functions, member functions,
functors, and lambdas. Rename it to callable, and explicitly hide
the static implementation function so that it doesn't become a symbol
of static libraries using Qt.
Also rename makeSlotObject to makeCallableObject, and polish coding
style and comments in the qobjectdefs_impl header a bit.
Change-Id: Id19107cedfe9c624f807cd8089beb80e9eb99f50
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>