summaryrefslogtreecommitdiffstats
path: root/src/network
diff options
context:
space:
mode:
authorLiang Qi <liang.qi@qt.io>2017-10-26 15:14:18 +0000
committerThe Qt Project <gerrit-noreply@qt-project.org>2017-10-26 15:14:18 +0000
commitf79e7c07237efcefe27d6ed5090e552cd9722e3d (patch)
tree9a1d1ac6576e882e8a8239b0fbb29fd3ddf2e4ad /src/network
parentea284937eaf27709e7a10a0a7b43e0bc91d4aa36 (diff)
parentfa9d12f4a20d618caedc77880459fa1af75fd50d (diff)
Merge "Merge remote-tracking branch 'origin/5.10' into dev" into refs/staging/dev
Diffstat (limited to 'src/network')
-rw-r--r--src/network/access/qhstsstore.cpp2
-rw-r--r--src/network/access/qhttpmultipart.cpp2
-rw-r--r--src/network/access/qhttpnetworkconnectionchannel.cpp11
-rw-r--r--src/network/access/qhttpnetworkreply.cpp2
-rw-r--r--src/network/access/qnetworkcookiejar.cpp2
-rw-r--r--src/network/access/qnetworkreply.cpp2
-rw-r--r--src/network/access/qnetworkreplyhttpimpl.cpp89
-rw-r--r--src/network/access/qnetworkreplyhttpimpl_p.h4
-rw-r--r--src/network/configure.json32
-rw-r--r--src/network/kernel/kernel.pri2
-rw-r--r--src/network/kernel/qhostaddress.cpp86
-rw-r--r--src/network/kernel/qhostinfo_unix.cpp50
-rw-r--r--src/network/kernel/qhostinfo_win.cpp161
-rw-r--r--src/network/kernel/qnetworkdatagram.cpp4
-rw-r--r--src/network/kernel/qnetworkinterface_win.cpp1
-rw-r--r--src/network/socket/qnet_unix_p.h10
-rw-r--r--src/network/socket/qudpsocket.cpp8
-rw-r--r--src/network/ssl/qsslsocket_mac.cpp2
18 files changed, 180 insertions, 290 deletions
diff --git a/src/network/access/qhstsstore.cpp b/src/network/access/qhstsstore.cpp
index 239a52b7a4..6d7f60ba8d 100644
--- a/src/network/access/qhstsstore.cpp
+++ b/src/network/access/qhstsstore.cpp
@@ -114,7 +114,7 @@ void QHstsStore::synchronize()
if (observedPolicies.size()) {
beginHstsGroups();
- for (const QHstsPolicy &policy : observedPolicies) {
+ for (const QHstsPolicy &policy : qAsConst(observedPolicies)) {
const QString key(host_name_to_settings_key(policy.host()));
// If we fail to write a new, updated policy, we also remove the old one.
if (policy.isExpired() || !serializePolicy(key, policy))
diff --git a/src/network/access/qhttpmultipart.cpp b/src/network/access/qhttpmultipart.cpp
index 303c145394..58d306d5f9 100644
--- a/src/network/access/qhttpmultipart.cpp
+++ b/src/network/access/qhttpmultipart.cpp
@@ -476,6 +476,8 @@ bool QHttpMultiPartIODevice::isSequential() const
bool QHttpMultiPartIODevice::reset()
{
+ // Reset QIODevice's data
+ QIODevice::reset();
for (int a = 0; a < multiPart->parts.count(); a++)
if (!multiPart->parts[a].d->reset())
return false;
diff --git a/src/network/access/qhttpnetworkconnectionchannel.cpp b/src/network/access/qhttpnetworkconnectionchannel.cpp
index f21acc7574..5f75172c90 100644
--- a/src/network/access/qhttpnetworkconnectionchannel.cpp
+++ b/src/network/access/qhttpnetworkconnectionchannel.cpp
@@ -604,14 +604,21 @@ void QHttpNetworkConnectionChannel::handleStatus()
case 302:
case 303:
case 305:
- case 307: {
+ case 307:
+ case 308: {
// Parse the response headers and get the "location" url
QUrl redirectUrl = connection->d_func()->parseRedirectResponse(socket, reply);
if (redirectUrl.isValid())
reply->setRedirectUrl(redirectUrl);
- if (qobject_cast<QHttpNetworkConnection *>(connection))
+ if ((statusCode == 307 || statusCode == 308) && !resetUploadData()) {
+ // Couldn't reset the upload data, which means it will be unable to POST the data -
+ // this would lead to a long wait until it eventually failed and then retried.
+ // Instead of doing that we fail here instead, resetUploadData will already have emitted
+ // a ContentReSendError, so we're done.
+ } else if (qobject_cast<QHttpNetworkConnection *>(connection)) {
QMetaObject::invokeMethod(connection, "_q_startNextRequest", Qt::QueuedConnection);
+ }
break;
}
case 401: // auth required
diff --git a/src/network/access/qhttpnetworkreply.cpp b/src/network/access/qhttpnetworkreply.cpp
index 612abb9044..778ba821e8 100644
--- a/src/network/access/qhttpnetworkreply.cpp
+++ b/src/network/access/qhttpnetworkreply.cpp
@@ -96,7 +96,7 @@ void QHttpNetworkReply::setRedirectUrl(const QUrl &url)
bool QHttpNetworkReply::isHttpRedirect(int statusCode)
{
return (statusCode == 301 || statusCode == 302 || statusCode == 303
- || statusCode == 305 || statusCode == 307);
+ || statusCode == 305 || statusCode == 307 || statusCode == 308);
}
qint64 QHttpNetworkReply::contentLength() const
diff --git a/src/network/access/qnetworkcookiejar.cpp b/src/network/access/qnetworkcookiejar.cpp
index 232c2b47a5..f62a03b11d 100644
--- a/src/network/access/qnetworkcookiejar.cpp
+++ b/src/network/access/qnetworkcookiejar.cpp
@@ -140,7 +140,7 @@ void QNetworkCookieJar::setAllCookies(const QList<QNetworkCookie> &cookieList)
static inline bool isParentPath(const QString &path, const QString &reference)
{
- if (path.startsWith(reference)) {
+ if ((path.isEmpty() && reference == QLatin1String("/")) || path.startsWith(reference)) {
//The cookie-path and the request-path are identical.
if (path.length() == reference.length())
return true;
diff --git a/src/network/access/qnetworkreply.cpp b/src/network/access/qnetworkreply.cpp
index cabea86521..11d8f0e3f7 100644
--- a/src/network/access/qnetworkreply.cpp
+++ b/src/network/access/qnetworkreply.cpp
@@ -297,7 +297,7 @@ QNetworkReplyPrivate::QNetworkReplyPrivate()
This signal is emitted if the QNetworkRequest::FollowRedirectsAttribute was
set in the request and the server responded with a 3xx status (specifically
- 301, 302, 303, 305 or 307 status code) with a valid url in the location
+ 301, 302, 303, 305, 307 or 308 status code) with a valid url in the location
header, indicating a HTTP redirect. The \a url parameter contains the new
redirect url as returned by the server in the location header.
diff --git a/src/network/access/qnetworkreplyhttpimpl.cpp b/src/network/access/qnetworkreplyhttpimpl.cpp
index 684fee610c..4ac046ef58 100644
--- a/src/network/access/qnetworkreplyhttpimpl.cpp
+++ b/src/network/access/qnetworkreplyhttpimpl.cpp
@@ -165,6 +165,16 @@ static QHash<QByteArray, QByteArray> parseHttpOptionHeader(const QByteArray &hea
}
}
+#if QT_CONFIG(bearermanagement)
+static bool isSessionNeeded(const QUrl &url)
+{
+ // Connections to the local machine does not require a session
+ QString host = url.host().toLower();
+ return !QHostAddress(host).isLoopback() && host != QLatin1String("localhost")
+ && host != QSysInfo::machineHostName().toLower();
+}
+#endif // bearer management
+
QNetworkReplyHttpImpl::QNetworkReplyHttpImpl(QNetworkAccessManager* const manager,
const QNetworkRequest& request,
QNetworkAccessManager::Operation& operation,
@@ -1115,10 +1125,15 @@ QNetworkAccessManager::Operation QNetworkReplyHttpImplPrivate::getRedirectOperat
switch (currentOp) {
case QNetworkAccessManager::HeadOperation:
return QNetworkAccessManager::HeadOperation;
+ case QNetworkAccessManager::PostOperation:
+ // We MUST keep using POST when being redirected with 307 or 308.
+ if (statusCode == 307 || statusCode == 308)
+ return QNetworkAccessManager::PostOperation;
+ break;
default:
break;
}
- // For now, we're always returning GET for anything other than HEAD
+ // Use GET for everything else.
return QNetworkAccessManager::GetOperation;
}
@@ -1193,11 +1208,30 @@ void QNetworkReplyHttpImplPrivate::followRedirect()
{
Q_Q(QNetworkReplyHttpImpl);
+ rawHeaders.clear();
cookedHeaders.clear();
if (managerPrivate->thread)
managerPrivate->thread->disconnect();
+#if QT_CONFIG(bearermanagement)
+ // If the original request didn't need a session (i.e. it was to localhost)
+ // then we might not have a session open, to which to redirect, if the
+ // new URL is remote. When this happens, we need to open the session now:
+ if (managerPrivate && isSessionNeeded(url)) {
+ if (auto session = managerPrivate->getNetworkSession()) {
+ if (session->state() != QNetworkSession::State::Connected || !session->isOpen()) {
+ startWaitForSession(session);
+ // Need to set 'request' to the redirectRequest so that when QNAM restarts
+ // the request after the session starts it will not repeat the previous request.
+ request = redirectRequest;
+ // Return now, QNAM will start the request when the session has started.
+ return;
+ }
+ }
+ }
+#endif // bearer management
+
QMetaObject::invokeMethod(q, "start", Qt::QueuedConnection,
Q_ARG(QNetworkRequest, redirectRequest));
}
@@ -1210,6 +1244,7 @@ void QNetworkReplyHttpImplPrivate::checkForRedirect(const int statusCode)
case 302: // Found
case 303: // See Other
case 307: // Temporary Redirect
+ case 308: // Permanent Redirect
// What do we do about the caching of the HTML note?
// The response to a 303 MUST NOT be cached, while the response to
// all of the others is cacheable if the headers indicate it to be
@@ -1783,10 +1818,8 @@ bool QNetworkReplyHttpImplPrivate::start(const QNetworkRequest &newHttpRequest)
}
// This is not ideal.
- const QString host = url.host();
- if (host == QLatin1String("localhost") ||
- QHostAddress(host).isLoopback()) {
- // Don't need an open session for localhost access.
+ if (!isSessionNeeded(url)) {
+ // Don't need to check for an open session if we don't need one.
postRequest(newHttpRequest);
return true;
}
@@ -1810,6 +1843,34 @@ bool QNetworkReplyHttpImplPrivate::start(const QNetworkRequest &newHttpRequest)
#endif
}
+#if QT_CONFIG(bearermanagement)
+bool QNetworkReplyHttpImplPrivate::startWaitForSession(QSharedPointer<QNetworkSession> &session)
+{
+ Q_Q(QNetworkReplyHttpImpl);
+ state = WaitingForSession;
+
+ if (session) {
+ QObject::connect(session.data(), SIGNAL(error(QNetworkSession::SessionError)),
+ q, SLOT(_q_networkSessionFailed()), Qt::QueuedConnection);
+
+ if (!session->isOpen()) {
+ QVariant isBackground = request.attribute(QNetworkRequest::BackgroundRequestAttribute,
+ QVariant::fromValue(false));
+ session->setSessionProperty(QStringLiteral("ConnectInBackground"), isBackground);
+ session->open();
+ }
+ return true;
+ }
+ const Qt::ConnectionType connection = synchronous ? Qt::DirectConnection : Qt::QueuedConnection;
+ qWarning("Backend is waiting for QNetworkSession to connect, but there is none!");
+ QMetaObject::invokeMethod(q, "_q_error", connection,
+ Q_ARG(QNetworkReply::NetworkError, QNetworkReply::NetworkSessionFailedError),
+ Q_ARG(QString, QCoreApplication::translate("QNetworkReply", "Network session error.")));
+ QMetaObject::invokeMethod(q, "_q_finished", connection);
+ return false;
+}
+#endif // QT_CONFIG(bearermanagement)
+
void QNetworkReplyHttpImplPrivate::_q_startOperation()
{
Q_Q(QNetworkReplyHttpImpl);
@@ -1837,24 +1898,8 @@ void QNetworkReplyHttpImplPrivate::_q_startOperation()
// backend failed to start because the session state is not Connected.
// QNetworkAccessManager will call reply->backend->start() again for us when the session
// state changes.
- state = WaitingForSession;
-
- if (session) {
- QObject::connect(session.data(), SIGNAL(error(QNetworkSession::SessionError)),
- q, SLOT(_q_networkSessionFailed()), Qt::QueuedConnection);
-
- if (!session->isOpen()) {
- session->setSessionProperty(QStringLiteral("ConnectInBackground"), isBackground);
- session->open();
- }
- } else {
- qWarning("Backend is waiting for QNetworkSession to connect, but there is none!");
- QMetaObject::invokeMethod(q, "_q_error", synchronous ? Qt::DirectConnection : Qt::QueuedConnection,
- Q_ARG(QNetworkReply::NetworkError, QNetworkReply::NetworkSessionFailedError),
- Q_ARG(QString, QCoreApplication::translate("QNetworkReply", "Network session error.")));
- QMetaObject::invokeMethod(q, "_q_finished", synchronous ? Qt::DirectConnection : Qt::QueuedConnection);
+ if (!startWaitForSession(session))
return;
- }
} else if (session) {
QObject::connect(session.data(), SIGNAL(stateChanged(QNetworkSession::State)),
q, SLOT(_q_networkSessionStateChanged(QNetworkSession::State)),
diff --git a/src/network/access/qnetworkreplyhttpimpl_p.h b/src/network/access/qnetworkreplyhttpimpl_p.h
index 91e9207601..8d2bd132b0 100644
--- a/src/network/access/qnetworkreplyhttpimpl_p.h
+++ b/src/network/access/qnetworkreplyhttpimpl_p.h
@@ -161,6 +161,10 @@ signals:
class QNetworkReplyHttpImplPrivate: public QNetworkReplyPrivate
{
+#if QT_CONFIG(bearermanagement)
+ bool startWaitForSession(QSharedPointer<QNetworkSession> &session);
+#endif
+
public:
static QHttpNetworkRequest::Priority convert(const QNetworkRequest::Priority& prio);
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/kernel.pri b/src/network/kernel/kernel.pri
index 716f745bc9..54b61f3ad3 100644
--- a/src/network/kernel/kernel.pri
+++ b/src/network/kernel/kernel.pri
@@ -49,8 +49,6 @@ win32: {
SOURCES += kernel/qdnslookup_win.cpp \
kernel/qnetworkinterface_win.cpp
LIBS_PRIVATE += -ldnsapi -liphlpapi
- DEFINES += WINVER=0x0600 _WIN32_WINNT=0x0600
-
} else {
SOURCES += kernel/qdnslookup_winrt.cpp \
kernel/qnetworkinterface_winrt.cpp
diff --git a/src/network/kernel/qhostaddress.cpp b/src/network/kernel/qhostaddress.cpp
index 8b380960e6..72b6d2dc70 100644
--- a/src/network/kernel/qhostaddress.cpp
+++ b/src/network/kernel/qhostaddress.cpp
@@ -534,49 +534,6 @@ QHostAddress::QHostAddress(SpecialAddress address)
}
/*!
- \overload
- \since 5.8
-
- Sets the special address specified by \a address.
-*/
-void QHostAddress::setAddress(SpecialAddress address)
-{
- d->clear();
-
- Q_IPV6ADDR ip6;
- memset(&ip6, 0, sizeof ip6);
- quint32 ip4 = INADDR_ANY;
-
- switch (address) {
- case Null:
- return;
-
- case Broadcast:
- ip4 = INADDR_BROADCAST;
- break;
- case LocalHost:
- ip4 = INADDR_LOOPBACK;
- break;
- case AnyIPv4:
- break;
-
- case LocalHostIPv6:
- ip6[15] = 1;
- Q_FALLTHROUGH();
- case AnyIPv6:
- d->setAddress(ip6);
- return;
-
- case Any:
- d->protocol = QAbstractSocket::AnyIPProtocol;
- return;
- }
-
- // common IPv4 part
- d->setAddress(ip4);
-}
-
-/*!
Destroys the host address object.
*/
QHostAddress::~QHostAddress()
@@ -740,6 +697,49 @@ void QHostAddress::setAddress(const struct sockaddr *sockaddr)
}
/*!
+ \overload
+ \since 5.8
+
+ Sets the special address specified by \a address.
+*/
+void QHostAddress::setAddress(SpecialAddress address)
+{
+ clear();
+
+ Q_IPV6ADDR ip6;
+ memset(&ip6, 0, sizeof ip6);
+ quint32 ip4 = INADDR_ANY;
+
+ switch (address) {
+ case Null:
+ return;
+
+ case Broadcast:
+ ip4 = INADDR_BROADCAST;
+ break;
+ case LocalHost:
+ ip4 = INADDR_LOOPBACK;
+ break;
+ case AnyIPv4:
+ break;
+
+ case LocalHostIPv6:
+ ip6[15] = 1;
+ Q_FALLTHROUGH();
+ case AnyIPv6:
+ d->setAddress(ip6);
+ return;
+
+ case Any:
+ d->protocol = QAbstractSocket::AnyIPProtocol;
+ return;
+ }
+
+ // common IPv4 part
+ d->setAddress(ip4);
+}
+
+/*!
Returns the IPv4 address as a number.
For example, if the address is 127.0.0.1, the returned value is
diff --git a/src/network/kernel/qhostinfo_unix.cpp b/src/network/kernel/qhostinfo_unix.cpp
index 91e5d18ae5..d22608e22f 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.
@@ -188,7 +184,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;
@@ -211,12 +206,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());
@@ -235,7 +224,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;
@@ -302,39 +290,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) {
@@ -377,11 +332,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/kernel/qnetworkdatagram.cpp b/src/network/kernel/qnetworkdatagram.cpp
index dd412b69d1..d167190684 100644
--- a/src/network/kernel/qnetworkdatagram.cpp
+++ b/src/network/kernel/qnetworkdatagram.cpp
@@ -124,9 +124,7 @@ QT_BEGIN_NAMESPACE
\row \li Linux \li Supported \li Supported \li Supported
\row \li OS X \li Supported \li Supported \li Only for IPv6
\row \li Other Unix supporting RFC 3542 \li Only for IPv6 \li Only for IPv6 \li Only for IPv6
- \row \li Windows XP and older \li Not supported \li Not supported \li Not supported
- \row \li Windows Vista & up \li Supported \li Supported \li Supported
- \row \li Windows CE \li Not supported \li Not supported \li Not supported
+ \row \li Windows (desktop) \li Supported \li Supported \li Supported
\row \li Windows RT \li Not supported \li Not supported \li Not supported
\endtable
diff --git a/src/network/kernel/qnetworkinterface_win.cpp b/src/network/kernel/qnetworkinterface_win.cpp
index 8344fb04c2..64c3fa6f83 100644
--- a/src/network/kernel/qnetworkinterface_win.cpp
+++ b/src/network/kernel/qnetworkinterface_win.cpp
@@ -56,6 +56,7 @@
// (http://sourceforge.net/p/mingw-w64/mailman/message/32935366/)
#include <winsock2.h>
#include <ws2ipdef.h>
+#include <wincrypt.h>
#include <iphlpapi.h>
#include <ws2tcpip.h>
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/src/network/socket/qudpsocket.cpp b/src/network/socket/qudpsocket.cpp
index 37b385dfb5..79629a07f2 100644
--- a/src/network/socket/qudpsocket.cpp
+++ b/src/network/socket/qudpsocket.cpp
@@ -454,10 +454,12 @@ QNetworkDatagram QUdpSocket::receiveDatagram(qint64 maxSize)
QAbstractSocketEngine::WantAll);
d->hasPendingData = false;
d->socketEngine->setReadNotificationEnabled(true);
- if (readBytes < 0)
+ if (readBytes < 0) {
d->setErrorAndEmit(d->socketEngine->error(), d->socketEngine->errorString());
- else if (readBytes != result.d->data.size())
- result.d->data.truncate(readBytes);
+ readBytes = 0;
+ }
+
+ result.d->data.truncate(readBytes);
return result;
}
diff --git a/src/network/ssl/qsslsocket_mac.cpp b/src/network/ssl/qsslsocket_mac.cpp
index a8d09feb31..e29ebbe028 100644
--- a/src/network/ssl/qsslsocket_mac.cpp
+++ b/src/network/ssl/qsslsocket_mac.cpp
@@ -92,7 +92,7 @@ EphemeralSecKeychain::EphemeralSecKeychain()
{
const auto uuid = QUuid::createUuid();
if (uuid.isNull()) {
- qCWarning(lcSsl) << "Failed to create an unique keychain name";
+ qCWarning(lcSsl) << "Failed to create a unique keychain name";
return;
}