summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThiago Macieira <thiago.macieira@intel.com>2017-08-07 20:52:11 -0700
committerEdward Welbourne <edward.welbourne@qt.io>2017-10-18 09:26:43 +0000
commit3fe74b76fd0eaf39d4c6681e2edca5adbf107883 (patch)
treeb49225508f84dec0a755d6f2f8a7be0f4edd68b7
parent3760bc759045c58c548b8f6b8a0a9c1efaa90cd4 (diff)
QHostInfo: Make getaddrinfo() mandatory
All systems must implement it by now. If there's any system still without it, that means it has no IPv6 support, so they can disable QtNetwork entirely. [ChangeLog][Deprecation Notice] Starting with Qt 5.10, IPv6 support is mandatory for all platforms. Systems without proper IPv6 support, such as the getaddrinfo() function or the proper socket address structures, will not be able to build QtNetwork anymore. Change-Id: I3868166e5efc45538544fffd14d8c28046f9191b Reviewed-by: Edward Welbourne <edward.welbourne@qt.io>
-rw-r--r--src/network/configure.json32
-rw-r--r--src/network/kernel/qhostinfo_unix.cpp50
-rw-r--r--src/network/kernel/qhostinfo_win.cpp161
-rw-r--r--src/network/socket/qnet_unix_p.h10
-rw-r--r--tests/auto/network/kernel/qhostinfo/BLACKLIST6
-rw-r--r--tests/auto/network/kernel/qhostinfo/tst_qhostinfo.cpp15
-rw-r--r--tests/manual/network_remote_stresstest/tst_network_remote_stresstest.cpp2
-rw-r--r--tests/manual/network_stresstest/tst_network_stresstest.cpp2
8 files changed, 55 insertions, 223 deletions
diff --git a/src/network/configure.json b/src/network/configure.json
index b1c943de6f..d46fbfc101 100644
--- a/src/network/configure.json
+++ b/src/network/configure.json
@@ -89,31 +89,6 @@
},
"tests": {
- "getaddrinfo": {
- "label": "getaddrinfo()",
- "type": "compile",
- "test": {
- "head": [
- "#include <stdio.h>",
- "#include <stdlib.h>",
- "#ifdef __MINGW32__",
- "# include <winsock2.h>",
- "# include <ws2tcpip.h>",
- "#else",
- "# include <sys/types.h>",
- "# include <sys/socket.h>",
- "# include <netdb.h>",
- "#endif"
- ],
- "main": [
- "addrinfo *res = 0;",
- "(void) getaddrinfo(\"foo\", 0, 0, &res);",
- "freeaddrinfo(res);",
- "gai_strerror(0);"
- ]
- },
- "use": "network"
- },
"getifaddrs": {
"label": "getifaddrs()",
"type": "compile",
@@ -170,11 +145,6 @@
"emitIf": "config.darwin",
"output": [ "feature", "privateFeature" ]
},
- "getaddrinfo": {
- "label": "getaddrinfo()",
- "condition": "tests.getaddrinfo",
- "output": [ "feature" ]
- },
"getifaddrs": {
"label": "getifaddrs()",
"condition": "tests.getifaddrs",
@@ -337,7 +307,7 @@ For example:
"args": "corewlan",
"condition": "config.darwin"
},
- "getaddrinfo", "getifaddrs", "ipv6ifname", "libproxy",
+ "getifaddrs", "ipv6ifname", "libproxy",
{
"type": "feature",
"args": "securetransport",
diff --git a/src/network/kernel/qhostinfo_unix.cpp b/src/network/kernel/qhostinfo_unix.cpp
index 9a24938284..8d2cffc304 100644
--- a/src/network/kernel/qhostinfo_unix.cpp
+++ b/src/network/kernel/qhostinfo_unix.cpp
@@ -66,10 +66,6 @@
# include <gnu/lib-names.h>
#endif
-#if defined (QT_NO_GETADDRINFO)
-static QBasicMutex getHostByNameMutex;
-#endif
-
QT_BEGIN_NAMESPACE
// Almost always the same. If not, specify in qplatformdefs.h.
@@ -150,7 +146,6 @@ QHostInfo QHostInfoAgent::fromName(const QString &hostName)
QHostAddress address;
if (address.setAddress(hostName)) {
// Reverse lookup
-#if !defined (QT_NO_GETADDRINFO)
sockaddr_in sa4;
sockaddr_in6 sa6;
sockaddr *sa = 0;
@@ -173,12 +168,6 @@ QHostInfo QHostInfoAgent::fromName(const QString &hostName)
char hbuf[NI_MAXHOST];
if (sa && getnameinfo(sa, saSize, hbuf, sizeof(hbuf), 0, 0, 0) == 0)
results.setHostName(QString::fromLatin1(hbuf));
-#else
- in_addr_t inetaddr = qt_safe_inet_addr(hostName.toLatin1().constData());
- struct hostent *ent = gethostbyaddr((const char *)&inetaddr, sizeof(inetaddr), AF_INET);
- if (ent)
- results.setHostName(QString::fromLatin1(ent->h_name));
-#endif
if (results.hostName().isEmpty())
results.setHostName(address.toString());
@@ -197,7 +186,6 @@ QHostInfo QHostInfoAgent::fromName(const QString &hostName)
return results;
}
-#if !defined (QT_NO_GETADDRINFO)
// Call getaddrinfo, and place all IPv4 addresses at the start and
// the IPv6 addresses at the end of the address list in results.
addrinfo *res = 0;
@@ -264,39 +252,6 @@ QHostInfo QHostInfoAgent::fromName(const QString &hostName)
results.setErrorString(QString::fromLocal8Bit(gai_strerror(result)));
}
-#else
- // Fall back to gethostbyname for platforms that don't define
- // getaddrinfo. gethostbyname does not support IPv6, and it's not
- // reentrant on all platforms. For now this is okay since we only
- // use one QHostInfoAgent, but if more agents are introduced, locking
- // must be provided.
- QMutexLocker locker(&getHostByNameMutex);
- hostent *result = gethostbyname(aceHostname.constData());
- if (result) {
- if (result->h_addrtype == AF_INET) {
- QList<QHostAddress> addresses;
- for (char **p = result->h_addr_list; *p != 0; p++) {
- QHostAddress addr;
- addr.setAddress(ntohl(*((quint32 *)*p)));
- if (!addresses.contains(addr))
- addresses.prepend(addr);
- }
- results.setAddresses(addresses);
- } else {
- results.setError(QHostInfo::UnknownError);
- results.setErrorString(tr("Unknown address type"));
- }
-#if !defined(Q_OS_VXWORKS)
- } else if (h_errno == HOST_NOT_FOUND || h_errno == NO_DATA
- || h_errno == NO_ADDRESS) {
- results.setError(QHostInfo::HostNotFound);
- results.setErrorString(tr("Host not found"));
-#endif
- } else {
- results.setError(QHostInfo::UnknownError);
- results.setErrorString(tr("Unknown error"));
- }
-#endif // !defined (QT_NO_GETADDRINFO)
#if defined(QHOSTINFO_DEBUG)
if (results.error() != QHostInfo::NoError) {
@@ -339,11 +294,6 @@ QString QHostInfo::localDomainName()
if (local_res_init && local_res) {
// using thread-unsafe version
-#if defined(QT_NO_GETADDRINFO)
- // We have to call res_init to be sure that _res was initialized
- // So, for systems without getaddrinfo (which is thread-safe), we lock the mutex too
- QMutexLocker locker(&getHostByNameMutex);
-#endif
local_res_init();
QString domainName = QUrl::fromAce(local_res->defdname);
if (domainName.isEmpty())
diff --git a/src/network/kernel/qhostinfo_win.cpp b/src/network/kernel/qhostinfo_win.cpp
index 9e5d556f2b..bea24b0af2 100644
--- a/src/network/kernel/qhostinfo_win.cpp
+++ b/src/network/kernel/qhostinfo_win.cpp
@@ -50,50 +50,12 @@ QT_BEGIN_NAMESPACE
//#define QHOSTINFO_DEBUG
-// Older SDKs do not include the addrinfo struct declaration, so we
-// include a copy of it here.
-struct qt_addrinfo
-{
- int ai_flags;
- int ai_family;
- int ai_socktype;
- int ai_protocol;
- size_t ai_addrlen;
- char *ai_canonname;
- sockaddr *ai_addr;
- qt_addrinfo *ai_next;
-};
-
//###
#define QT_SOCKLEN_T int
#ifndef NI_MAXHOST // already defined to 1025 in ws2tcpip.h?
#define NI_MAXHOST 1024
#endif
-typedef int (__stdcall *getnameinfoProto)(const sockaddr *, QT_SOCKLEN_T, const char *, DWORD, const char *, DWORD, int);
-typedef int (__stdcall *getaddrinfoProto)(const char *, const char *, const qt_addrinfo *, qt_addrinfo **);
-typedef int (__stdcall *freeaddrinfoProto)(qt_addrinfo *);
-static getnameinfoProto local_getnameinfo = 0;
-static getaddrinfoProto local_getaddrinfo = 0;
-static freeaddrinfoProto local_freeaddrinfo = 0;
-
-static bool resolveLibraryInternal()
-{
- // Attempt to resolve getaddrinfo(); without it we'll have to fall
- // back to gethostbyname(), which has no IPv6 support.
-#if defined (Q_OS_WINRT)
- local_getaddrinfo = (getaddrinfoProto) &getaddrinfo;
- local_freeaddrinfo = (freeaddrinfoProto) &freeaddrinfo;
- local_getnameinfo = (getnameinfoProto) getnameinfo;
-#else
- local_getaddrinfo = (getaddrinfoProto) QSystemLibrary::resolve(QLatin1String("ws2_32"), "getaddrinfo");
- local_freeaddrinfo = (freeaddrinfoProto) QSystemLibrary::resolve(QLatin1String("ws2_32"), "freeaddrinfo");
- local_getnameinfo = (getnameinfoProto) QSystemLibrary::resolve(QLatin1String("ws2_32"), "getnameinfo");
-#endif
- return true;
-}
-Q_GLOBAL_STATIC_WITH_ARGS(bool, resolveLibrary, (resolveLibraryInternal()))
-
static void translateWSAError(int error, QHostInfo *results)
{
switch (error) {
@@ -114,49 +76,39 @@ QHostInfo QHostInfoAgent::fromName(const QString &hostName)
{
QSysInfo::machineHostName(); // this initializes ws2_32.dll
- // Load res_init on demand.
- resolveLibrary();
-
QHostInfo results;
#if defined(QHOSTINFO_DEBUG)
qDebug("QHostInfoAgent::fromName(): looking up \"%s\" (IPv6 support is %s)",
hostName.toLatin1().constData(),
- (local_getaddrinfo && local_freeaddrinfo) ? "enabled" : "disabled");
+ (getaddrinfo && freeaddrinfo) ? "enabled" : "disabled");
#endif
QHostAddress address;
if (address.setAddress(hostName)) {
// Reverse lookup
- if (local_getnameinfo) {
- sockaddr_in sa4;
- sockaddr_in6 sa6;
- sockaddr *sa;
- QT_SOCKLEN_T saSize;
- if (address.protocol() == QAbstractSocket::IPv4Protocol) {
- sa = (sockaddr *)&sa4;
- saSize = sizeof(sa4);
- memset(&sa4, 0, sizeof(sa4));
- sa4.sin_family = AF_INET;
- sa4.sin_addr.s_addr = htonl(address.toIPv4Address());
- } else {
- sa = (sockaddr *)&sa6;
- saSize = sizeof(sa6);
- memset(&sa6, 0, sizeof(sa6));
- sa6.sin6_family = AF_INET6;
- memcpy(&sa6.sin6_addr, address.toIPv6Address().c, sizeof(sa6.sin6_addr));
- }
-
- char hbuf[NI_MAXHOST];
- if (local_getnameinfo(sa, saSize, hbuf, sizeof(hbuf), 0, 0, 0) == 0)
- results.setHostName(QString::fromLatin1(hbuf));
+ sockaddr_in sa4;
+ sockaddr_in6 sa6;
+ sockaddr *sa;
+ QT_SOCKLEN_T saSize;
+ if (address.protocol() == QAbstractSocket::IPv4Protocol) {
+ sa = (sockaddr *)&sa4;
+ saSize = sizeof(sa4);
+ memset(&sa4, 0, sizeof(sa4));
+ sa4.sin_family = AF_INET;
+ sa4.sin_addr.s_addr = htonl(address.toIPv4Address());
} else {
- unsigned long addr = inet_addr(hostName.toLatin1().constData());
- struct hostent *ent = gethostbyaddr((const char*)&addr, sizeof(addr), AF_INET);
- if (ent)
- results.setHostName(QString::fromLatin1(ent->h_name));
+ sa = (sockaddr *)&sa6;
+ saSize = sizeof(sa6);
+ memset(&sa6, 0, sizeof(sa6));
+ sa6.sin6_family = AF_INET6;
+ memcpy(&sa6.sin6_addr, address.toIPv6Address().c, sizeof(sa6.sin6_addr));
}
+ char hbuf[NI_MAXHOST];
+ if (getnameinfo(sa, saSize, hbuf, sizeof(hbuf), 0, 0, 0) == 0)
+ results.setHostName(QString::fromLatin1(hbuf));
+
if (results.hostName().isEmpty())
results.setHostName(address.toString());
results.setAddresses(QList<QHostAddress>() << address);
@@ -172,64 +124,35 @@ QHostInfo QHostInfoAgent::fromName(const QString &hostName)
return results;
}
- if (local_getaddrinfo && local_freeaddrinfo) {
- // Call getaddrinfo, and place all IPv4 addresses at the start
- // and the IPv6 addresses at the end of the address list in
- // results.
- qt_addrinfo *res;
- int err = local_getaddrinfo(aceHostname.constData(), 0, 0, &res);
- if (err == 0) {
- QList<QHostAddress> addresses;
- for (qt_addrinfo *p = res; p != 0; p = p->ai_next) {
- switch (p->ai_family) {
- case AF_INET: {
- QHostAddress addr;
- addr.setAddress(ntohl(((sockaddr_in *) p->ai_addr)->sin_addr.s_addr));
- if (!addresses.contains(addr))
- addresses.append(addr);
- }
- break;
- case AF_INET6: {
- QHostAddress addr;
- addr.setAddress(((sockaddr_in6 *) p->ai_addr)->sin6_addr.s6_addr);
- if (!addresses.contains(addr))
- addresses.append(addr);
- }
- break;
- default:
- results.setError(QHostInfo::UnknownError);
- results.setErrorString(tr("Unknown address type"));
- }
+ addrinfo *res;
+ int err = getaddrinfo(aceHostname.constData(), 0, 0, &res);
+ if (err == 0) {
+ QList<QHostAddress> addresses;
+ for (addrinfo *p = res; p != 0; p = p->ai_next) {
+ switch (p->ai_family) {
+ case AF_INET: {
+ QHostAddress addr;
+ addr.setAddress(ntohl(((sockaddr_in *) p->ai_addr)->sin_addr.s_addr));
+ if (!addresses.contains(addr))
+ addresses.append(addr);
+ }
+ break;
+ case AF_INET6: {
+ QHostAddress addr;
+ addr.setAddress(((sockaddr_in6 *) p->ai_addr)->sin6_addr.s6_addr);
+ if (!addresses.contains(addr))
+ addresses.append(addr);
}
- results.setAddresses(addresses);
- local_freeaddrinfo(res);
- } else {
- translateWSAError(WSAGetLastError(), &results);
- }
- } else {
- // Fall back to gethostbyname, which only supports IPv4.
- hostent *ent = gethostbyname(aceHostname.constData());
- if (ent) {
- char **p;
- QList<QHostAddress> addresses;
- switch (ent->h_addrtype) {
- case AF_INET:
- for (p = ent->h_addr_list; *p != 0; p++) {
- long *ip4Addr = (long *) *p;
- QHostAddress temp;
- temp.setAddress(ntohl(*ip4Addr));
- addresses << temp;
- }
break;
default:
results.setError(QHostInfo::UnknownError);
results.setErrorString(tr("Unknown address type"));
- break;
}
- results.setAddresses(addresses);
- } else {
- translateWSAError(WSAGetLastError(), &results);
}
+ results.setAddresses(addresses);
+ freeaddrinfo(res);
+ } else {
+ translateWSAError(WSAGetLastError(), &results);
}
#if defined(QHOSTINFO_DEBUG)
diff --git a/src/network/socket/qnet_unix_p.h b/src/network/socket/qnet_unix_p.h
index 73d7ec2e77..5359872f96 100644
--- a/src/network/socket/qnet_unix_p.h
+++ b/src/network/socket/qnet_unix_p.h
@@ -174,16 +174,6 @@ static inline int qt_safe_ioctl(int sockfd, unsigned long request, T arg)
#endif
}
-// VxWorks' headers do not specify any const modifiers
-static inline in_addr_t qt_safe_inet_addr(const char *cp)
-{
-#ifdef Q_OS_VXWORKS
- return ::inet_addr((char *) cp);
-#else
- return ::inet_addr(cp);
-#endif
-}
-
static inline int qt_safe_sendmsg(int sockfd, const struct msghdr *msg, int flags)
{
#ifdef MSG_NOSIGNAL
diff --git a/tests/auto/network/kernel/qhostinfo/BLACKLIST b/tests/auto/network/kernel/qhostinfo/BLACKLIST
new file mode 100644
index 0000000000..87c5fe991f
--- /dev/null
+++ b/tests/auto/network/kernel/qhostinfo/BLACKLIST
@@ -0,0 +1,6 @@
+# These tests fail due to a DNS server issue
+# (this is not a Qt bug)
+[lookupIPv6:a-plus-aaaa]
+windows ci
+[blockingLookup:a-plus-aaaa]
+windows ci
diff --git a/tests/auto/network/kernel/qhostinfo/tst_qhostinfo.cpp b/tests/auto/network/kernel/qhostinfo/tst_qhostinfo.cpp
index cb7e66bad4..caf8145c19 100644
--- a/tests/auto/network/kernel/qhostinfo/tst_qhostinfo.cpp
+++ b/tests/auto/network/kernel/qhostinfo/tst_qhostinfo.cpp
@@ -64,14 +64,10 @@
#include <qhostinfo.h>
#include "private/qhostinfo_p.h"
-#if !defined(QT_NO_GETADDRINFO)
-# include <sys/types.h>
-# if defined(Q_OS_UNIX)
+#include <sys/types.h>
+#if defined(Q_OS_UNIX)
# include <sys/socket.h>
-# endif
-# if !defined(Q_OS_WIN)
# include <netdb.h>
-# endif
#endif
#include "../../../network-settings.h"
@@ -204,15 +200,13 @@ void tst_QHostInfo::initTestCase()
ipv6Available = true;
}
-// HP-UX 11i does not support IPv6 reverse lookups.
-#if !defined(QT_NO_GETADDRINFO) && !(defined(Q_OS_HPUX) && defined(__ia64))
// check if the system getaddrinfo can do IPv6 lookups
struct addrinfo hint, *result = 0;
memset(&hint, 0, sizeof hint);
hint.ai_family = AF_UNSPEC;
-# ifdef AI_ADDRCONFIG
+#ifdef AI_ADDRCONFIG
hint.ai_flags = AI_ADDRCONFIG;
-# endif
+#endif
int res = getaddrinfo("::1", "80", &hint, &result);
if (res == 0) {
@@ -224,7 +218,6 @@ void tst_QHostInfo::initTestCase()
ipv6LookupsAvailable = true;
}
}
-#endif
// run each testcase with and without test enabled
QTest::addColumn<bool>("cache");
diff --git a/tests/manual/network_remote_stresstest/tst_network_remote_stresstest.cpp b/tests/manual/network_remote_stresstest/tst_network_remote_stresstest.cpp
index 99e3d148df..f5c3bfde34 100644
--- a/tests/manual/network_remote_stresstest/tst_network_remote_stresstest.cpp
+++ b/tests/manual/network_remote_stresstest/tst_network_remote_stresstest.cpp
@@ -156,7 +156,7 @@ void tst_NetworkRemoteStressTest::clearManager()
bool nativeLookup(const char *hostname, int port, QByteArray &buf)
{
-#if !defined(QT_NO_GETADDRINFO) && 0
+#if 0
addrinfo *res = 0;
struct addrinfo hints;
memset(&hints, 0, sizeof(hints));
diff --git a/tests/manual/network_stresstest/tst_network_stresstest.cpp b/tests/manual/network_stresstest/tst_network_stresstest.cpp
index d46703c671..03df1633d5 100644
--- a/tests/manual/network_stresstest/tst_network_stresstest.cpp
+++ b/tests/manual/network_stresstest/tst_network_stresstest.cpp
@@ -147,7 +147,7 @@ void tst_NetworkStressTest::clearManager()
bool nativeLookup(const char *hostname, int port, QByteArray &buf)
{
-#if !defined(QT_NO_GETADDRINFO) && 0
+#if 0
addrinfo *res = 0;
struct addrinfo hints;
memset(&hints, 0, sizeof(hints));