summaryrefslogtreecommitdiffstats
path: root/src/network
diff options
context:
space:
mode:
Diffstat (limited to 'src/network')
-rw-r--r--src/network/access/qhttpmultipart.cpp21
-rw-r--r--src/network/access/qhttpnetworkconnection.cpp8
-rw-r--r--src/network/access/qhttpnetworkconnectionchannel.cpp23
-rw-r--r--src/network/access/qhttpnetworkconnectionchannel_p.h4
-rw-r--r--src/network/access/qhttpthreaddelegate.cpp16
-rw-r--r--src/network/access/qhttpthreaddelegate_p.h4
-rw-r--r--src/network/access/qnetworkaccessmanager.cpp2
-rw-r--r--src/network/access/qnetworkreply.cpp6
-rw-r--r--src/network/access/qnetworkreplyhttpimpl.cpp17
-rw-r--r--src/network/access/qnetworkreplyhttpimpl_p.h5
-rw-r--r--src/network/bearer/qnetworkconfiguration.cpp2
-rw-r--r--src/network/configure.json1
-rw-r--r--src/network/kernel/kernel.pri2
-rw-r--r--src/network/kernel/qhostinfo.cpp21
-rw-r--r--src/network/kernel/qhostinfo.h9
-rw-r--r--src/network/socket/qabstractsocket.cpp13
-rw-r--r--src/network/socket/qlocalserver.cpp40
-rw-r--r--src/network/socket/qlocalserver.h2
-rw-r--r--src/network/socket/qlocalsocket.cpp14
-rw-r--r--src/network/socket/qlocalsocket_win.cpp4
-rw-r--r--src/network/socket/qnativesocketengine_unix.cpp3
-rw-r--r--src/network/socket/qnativesocketengine_win.cpp4
-rw-r--r--src/network/ssl/qsslsocket.cpp2
-rw-r--r--src/network/ssl/qsslsocket_mac.cpp24
-rw-r--r--src/network/ssl/qsslsocket_openssl.cpp47
-rw-r--r--src/network/ssl/qsslsocket_openssl_symbols.cpp10
-rw-r--r--src/network/ssl/qsslsocket_openssl_symbols_p.h5
27 files changed, 239 insertions, 70 deletions
diff --git a/src/network/access/qhttpmultipart.cpp b/src/network/access/qhttpmultipart.cpp
index 5c704efeef..303c145394 100644
--- a/src/network/access/qhttpmultipart.cpp
+++ b/src/network/access/qhttpmultipart.cpp
@@ -41,7 +41,7 @@
#include "qhttpmultipart_p.h"
#include "QtCore/qdatetime.h" // for initializing the random number generator with QTime
#include "QtCore/qmutex.h"
-#include "QtCore/qthreadstorage.h"
+#include "QtCore/qrandom.h"
QT_BEGIN_NAMESPACE
@@ -431,23 +431,16 @@ void QHttpPartPrivate::checkHeaderCreated() const
}
}
-Q_GLOBAL_STATIC(QThreadStorage<bool *>, seedCreatedStorage);
-
QHttpMultiPartPrivate::QHttpMultiPartPrivate() : contentType(QHttpMultiPart::MixedType), device(new QHttpMultiPartIODevice(this))
{
- if (!seedCreatedStorage()->hasLocalData()) {
- qsrand(QTime(0,0,0).msecsTo(QTime::currentTime()) ^ reinterpret_cast<quintptr>(this));
- seedCreatedStorage()->setLocalData(new bool(true));
- }
-
- boundary = QByteArray("boundary_.oOo._")
- + QByteArray::number(qrand()).toBase64()
- + QByteArray::number(qrand()).toBase64()
- + QByteArray::number(qrand()).toBase64();
+ // 24 random bytes, becomes 32 characters when encoded to Base64
+ quint32 random[6];
+ QRandomGenerator::fillRange(random);
+ boundary = "boundary_.oOo._"
+ + QByteArray::fromRawData(reinterpret_cast<char *>(random), sizeof(random)).toBase64();
// boundary must not be longer than 70 characters, see RFC 2046, section 5.1.1
- if (boundary.count() > 70)
- boundary = boundary.left(70);
+ Q_ASSERT(boundary.count() <= 70);
}
qint64 QHttpMultiPartIODevice::size() const
diff --git a/src/network/access/qhttpnetworkconnection.cpp b/src/network/access/qhttpnetworkconnection.cpp
index da055de2da..ae30d3a8cf 100644
--- a/src/network/access/qhttpnetworkconnection.cpp
+++ b/src/network/access/qhttpnetworkconnection.cpp
@@ -644,6 +644,7 @@ QHttpNetworkReply* QHttpNetworkConnectionPrivate::queueRequest(const QHttpNetwor
channels[0].spdyRequestsToSend.insertMulti(request.priority(), pair);
}
+#ifndef Q_OS_WINRT
// For Happy Eyeballs the networkLayerState is set to Unknown
// untill we have started the first connection attempt. So no
// request will be started untill we know if IPv4 or IPv6
@@ -651,6 +652,13 @@ QHttpNetworkReply* QHttpNetworkConnectionPrivate::queueRequest(const QHttpNetwor
if (networkLayerState == Unknown || networkLayerState == HostLookupPending) {
startHostInfoLookup();
} else if ( networkLayerState == IPv4 || networkLayerState == IPv6 ) {
+#else // !Q_OS_WINRT
+ {
+ // Skip the host lookup part for winrt. Host lookup and proxy handling are done by Windows
+ // internally and networkLayerPreference is ignored on this platform. Instead of refactoring
+ // the whole approach we just pretend that everything important is known here.
+ networkLayerState = IPv4;
+#endif
// this used to be called via invokeMethod and a QueuedConnection
// It is the only place _q_startNextRequest is called directly without going
// through the event loop using a QueuedConnection.
diff --git a/src/network/access/qhttpnetworkconnectionchannel.cpp b/src/network/access/qhttpnetworkconnectionchannel.cpp
index c86cc9d8c9..84681561f2 100644
--- a/src/network/access/qhttpnetworkconnectionchannel.cpp
+++ b/src/network/access/qhttpnetworkconnectionchannel.cpp
@@ -55,7 +55,6 @@
# include <private/qsslsocket_p.h>
# include <QtNetwork/qsslkey.h>
# include <QtNetwork/qsslcipher.h>
-# include <QtNetwork/qsslconfiguration.h>
#endif
#ifndef QT_NO_BEARERMANAGEMENT
@@ -176,8 +175,8 @@ void QHttpNetworkConnectionChannel::init()
if (!ignoreSslErrorsList.isEmpty())
sslSocket->ignoreSslErrors(ignoreSslErrorsList);
- if (!sslConfiguration.isNull())
- sslSocket->setSslConfiguration(sslConfiguration);
+ if (sslConfiguration.data() && !sslConfiguration->isNull())
+ sslSocket->setSslConfiguration(*sslConfiguration);
} else {
#endif // !QT_NO_SSL
if (connection->connectionType() != QHttpNetworkConnection::ConnectionTypeHTTP2)
@@ -656,7 +655,10 @@ void QHttpNetworkConnectionChannel::setSslConfiguration(const QSslConfiguration
if (socket)
static_cast<QSslSocket *>(socket)->setSslConfiguration(config);
- sslConfiguration = config;
+ if (sslConfiguration.data())
+ *sslConfiguration = config;
+ else
+ sslConfiguration.reset(new QSslConfiguration(config));
}
#endif
@@ -1085,8 +1087,15 @@ void QHttpNetworkConnectionChannel::_q_encrypted()
Q_FALLTHROUGH();
case QSslConfiguration::NextProtocolNegotiationNone: {
protocolHandler.reset(new QHttpProtocolHandler(this));
+ if (!sslConfiguration.data()) {
+ // Our own auto-tests bypass the normal initialization (done by
+ // QHttpThreadDelegate), this means in the past we'd have here
+ // the default constructed QSslConfiguration without any protocols
+ // to negotiate. Let's create it now:
+ sslConfiguration.reset(new QSslConfiguration);
+ }
- QList<QByteArray> protocols = sslConfiguration.allowedNextProtocols();
+ QList<QByteArray> protocols = sslConfiguration->allowedNextProtocols();
const int nProtocols = protocols.size();
// Clear the protocol that we failed to negotiate, so we do not try
// it again on other channels that our connection can create/open.
@@ -1096,10 +1105,10 @@ void QHttpNetworkConnectionChannel::_q_encrypted()
protocols.removeAll(QSslConfiguration::NextProtocolSpdy3_0);
if (nProtocols > protocols.size()) {
- sslConfiguration.setAllowedNextProtocols(protocols);
+ sslConfiguration->setAllowedNextProtocols(protocols);
const int channelCount = connection->d_func()->channelCount;
for (int i = 0; i < channelCount; ++i)
- connection->d_func()->channels[i].setSslConfiguration(sslConfiguration);
+ connection->d_func()->channels[i].setSslConfiguration(*sslConfiguration);
}
connection->setConnectionType(QHttpNetworkConnection::ConnectionTypeHTTP);
diff --git a/src/network/access/qhttpnetworkconnectionchannel_p.h b/src/network/access/qhttpnetworkconnectionchannel_p.h
index 61aea9d35d..584d52ddb7 100644
--- a/src/network/access/qhttpnetworkconnectionchannel_p.h
+++ b/src/network/access/qhttpnetworkconnectionchannel_p.h
@@ -78,6 +78,8 @@
# include <QtNetwork/qtcpsocket.h>
#endif
+#include <QtCore/qscopedpointer.h>
+
QT_BEGIN_NAMESPACE
class QHttpNetworkRequest;
@@ -128,7 +130,7 @@ public:
#ifndef QT_NO_SSL
bool ignoreAllSslErrors;
QList<QSslError> ignoreSslErrorsList;
- QSslConfiguration sslConfiguration;
+ QScopedPointer<QSslConfiguration> sslConfiguration;
void ignoreSslErrors();
void ignoreSslErrors(const QList<QSslError> &errors);
void setSslConfiguration(const QSslConfiguration &config);
diff --git a/src/network/access/qhttpthreaddelegate.cpp b/src/network/access/qhttpthreaddelegate.cpp
index 9d874b4d94..3d17664ed4 100644
--- a/src/network/access/qhttpthreaddelegate.cpp
+++ b/src/network/access/qhttpthreaddelegate.cpp
@@ -44,6 +44,7 @@
#include <QTimer>
#include <QAuthenticator>
#include <QEventLoop>
+#include <QCryptographicHash>
#include "private/qhttpnetworkreply_p.h"
#include "private/qnetworkaccesscache_p.h"
@@ -158,7 +159,10 @@ static QByteArray makeCacheKey(QUrl &url, QNetworkProxy *proxy)
}
if (!key.scheme().isEmpty()) {
+ const QByteArray obfuscatedPassword = QCryptographicHash::hash(proxy->password().toUtf8(),
+ QCryptographicHash::Sha1).toHex();
key.setUserName(proxy->user());
+ key.setPassword(QString::fromUtf8(obfuscatedPassword));
key.setHost(proxy->hostName());
key.setPort(proxy->port());
key.setQuery(result);
@@ -290,18 +294,21 @@ void QHttpThreadDelegate::startRequest()
: QHttpNetworkConnection::ConnectionTypeHTTP;
#ifndef QT_NO_SSL
+ if (ssl && !incomingSslConfiguration.data())
+ incomingSslConfiguration.reset(new QSslConfiguration);
+
if (httpRequest.isHTTP2Allowed() && ssl) {
QList<QByteArray> protocols;
protocols << QSslConfiguration::ALPNProtocolHTTP2
<< QSslConfiguration::NextProtocolHttp1_1;
- incomingSslConfiguration.setAllowedNextProtocols(protocols);
+ incomingSslConfiguration->setAllowedNextProtocols(protocols);
} else if (httpRequest.isSPDYAllowed() && ssl) {
connectionType = QHttpNetworkConnection::ConnectionTypeSPDY;
urlCopy.setScheme(QStringLiteral("spdy")); // to differentiate SPDY requests from HTTPS requests
QList<QByteArray> nextProtocols;
nextProtocols << QSslConfiguration::NextProtocolSpdy3_0
<< QSslConfiguration::NextProtocolHttp1_1;
- incomingSslConfiguration.setAllowedNextProtocols(nextProtocols);
+ incomingSslConfiguration->setAllowedNextProtocols(nextProtocols);
}
#endif // QT_NO_SSL
@@ -330,9 +337,8 @@ void QHttpThreadDelegate::startRequest()
#endif
#ifndef QT_NO_SSL
// Set the QSslConfiguration from this QNetworkRequest.
- if (ssl && incomingSslConfiguration != QSslConfiguration::defaultConfiguration()) {
- httpConnection->setSslConfiguration(incomingSslConfiguration);
- }
+ if (ssl)
+ httpConnection->setSslConfiguration(*incomingSslConfiguration);
#endif
#ifndef QT_NO_NETWORKPROXY
diff --git a/src/network/access/qhttpthreaddelegate_p.h b/src/network/access/qhttpthreaddelegate_p.h
index 6d1ea11f29..2f6954aa3b 100644
--- a/src/network/access/qhttpthreaddelegate_p.h
+++ b/src/network/access/qhttpthreaddelegate_p.h
@@ -63,7 +63,7 @@
#include "qhttpnetworkrequest_p.h"
#include "qhttpnetworkconnection_p.h"
#include <QSharedPointer>
-#include "qsslconfiguration.h"
+#include <QScopedPointer>
#include "private/qnoncontiguousbytedevice_p.h"
#include "qnetworkaccessauthenticationmanager_p.h"
@@ -88,7 +88,7 @@ public:
// incoming
bool ssl;
#ifndef QT_NO_SSL
- QSslConfiguration incomingSslConfiguration;
+ QScopedPointer<QSslConfiguration> incomingSslConfiguration;
#endif
QHttpNetworkRequest httpRequest;
qint64 downloadBufferMaximumSize;
diff --git a/src/network/access/qnetworkaccessmanager.cpp b/src/network/access/qnetworkaccessmanager.cpp
index d57acc2f6b..79f0aa8038 100644
--- a/src/network/access/qnetworkaccessmanager.cpp
+++ b/src/network/access/qnetworkaccessmanager.cpp
@@ -732,7 +732,7 @@ bool QNetworkAccessManager::isStrictTransportSecurityEnabled() const
/*!
\since 5.9
- Adds HTTP Strict Transport Security policies into HSTS cache.
+ Adds HTTP Strict Transport Security policies contained in \a knownHosts into HSTS cache.
\note An expired policy will remove a known host from the cache, if previously
present.
diff --git a/src/network/access/qnetworkreply.cpp b/src/network/access/qnetworkreply.cpp
index 8e7059de0f..cabea86521 100644
--- a/src/network/access/qnetworkreply.cpp
+++ b/src/network/access/qnetworkreply.cpp
@@ -311,9 +311,11 @@ QNetworkReplyPrivate::QNetworkReplyPrivate()
When client code handling the redirected() signal has verified the new URL,
it emits this signal to allow the redirect to go ahead. This protocol applies
to network requests whose redirects policy is set to
- QNetworkRequest::UserVerifiedRedirectsPolicy.
+ QNetworkRequest::UserVerifiedRedirectPolicy
- \sa QNetworkRequest::UserVerifiedRedirectPolicy, QNetworkAccessManager::setRedirectPolicy(), QNetworkRequest::RedirectPolicyAttribute
+ \sa QNetworkRequest::UserVerifiedRedirectPolicy,
+ QNetworkAccessManager::setRedirectPolicy(),
+ QNetworkRequest::RedirectPolicyAttribute
*/
/*!
diff --git a/src/network/access/qnetworkreplyhttpimpl.cpp b/src/network/access/qnetworkreplyhttpimpl.cpp
index fec3b0a100..84b1ddf5ac 100644
--- a/src/network/access/qnetworkreplyhttpimpl.cpp
+++ b/src/network/access/qnetworkreplyhttpimpl.cpp
@@ -180,7 +180,8 @@ QNetworkReplyHttpImpl::QNetworkReplyHttpImpl(QNetworkAccessManager* const manage
d->outgoingData = outgoingData;
d->url = request.url();
#ifndef QT_NO_SSL
- d->sslConfiguration = request.sslConfiguration();
+ if (request.url().scheme() == QLatin1String("https"))
+ d->sslConfiguration.reset(new QSslConfiguration(request.sslConfiguration()));
#endif
// FIXME Later maybe set to Unbuffered, especially if it is zerocopy or from cache?
@@ -419,7 +420,10 @@ void QNetworkReplyHttpImpl::setSslConfigurationImplementation(const QSslConfigur
void QNetworkReplyHttpImpl::sslConfigurationImplementation(QSslConfiguration &configuration) const
{
Q_D(const QNetworkReplyHttpImpl);
- configuration = d->sslConfiguration;
+ if (d->sslConfiguration.data())
+ configuration = *d->sslConfiguration;
+ else
+ configuration = request().sslConfiguration();
}
#endif
@@ -786,7 +790,7 @@ void QNetworkReplyHttpImplPrivate::postRequest(const QNetworkRequest &newHttpReq
delegate->ssl = ssl;
#ifndef QT_NO_SSL
if (ssl)
- delegate->incomingSslConfiguration = newHttpRequest.sslConfiguration();
+ delegate->incomingSslConfiguration.reset(new QSslConfiguration(newHttpRequest.sslConfiguration()));
#endif
// Do we use synchronous HTTP?
@@ -1411,10 +1415,13 @@ void QNetworkReplyHttpImplPrivate::replySslErrors(
*toBeIgnored = pendingIgnoreSslErrorsList;
}
-void QNetworkReplyHttpImplPrivate::replySslConfigurationChanged(const QSslConfiguration &sslConfiguration)
+void QNetworkReplyHttpImplPrivate::replySslConfigurationChanged(const QSslConfiguration &newSslConfiguration)
{
// Receiving the used SSL configuration from the HTTP thread
- this->sslConfiguration = sslConfiguration;
+ if (sslConfiguration.data())
+ *sslConfiguration = newSslConfiguration;
+ else
+ sslConfiguration.reset(new QSslConfiguration(newSslConfiguration));
}
void QNetworkReplyHttpImplPrivate::replyPreSharedKeyAuthenticationRequiredSlot(QSslPreSharedKeyAuthenticator *authenticator)
diff --git a/src/network/access/qnetworkreplyhttpimpl_p.h b/src/network/access/qnetworkreplyhttpimpl_p.h
index 9383149124..26b16e8386 100644
--- a/src/network/access/qnetworkreplyhttpimpl_p.h
+++ b/src/network/access/qnetworkreplyhttpimpl_p.h
@@ -58,6 +58,7 @@
#include "QtCore/qpointer.h"
#include "QtCore/qdatetime.h"
#include "QtCore/qsharedpointer.h"
+#include "QtCore/qscopedpointer.h"
#include "qatomic.h"
#include <QtNetwork/QNetworkCacheMetaData>
@@ -260,7 +261,7 @@ public:
#ifndef QT_NO_SSL
- QSslConfiguration sslConfiguration;
+ QScopedPointer<QSslConfiguration> sslConfiguration;
bool pendingIgnoreAllSslErrors;
QList<QSslError> pendingIgnoreSslErrorsList;
#endif
@@ -290,7 +291,7 @@ public:
#ifndef QT_NO_SSL
void replyEncrypted();
void replySslErrors(const QList<QSslError> &, bool *, QList<QSslError> *);
- void replySslConfigurationChanged(const QSslConfiguration&);
+ void replySslConfigurationChanged(const QSslConfiguration &newSslConfiguration);
void replyPreSharedKeyAuthenticationRequiredSlot(QSslPreSharedKeyAuthenticator *);
#endif
#ifndef QT_NO_NETWORKPROXY
diff --git a/src/network/bearer/qnetworkconfiguration.cpp b/src/network/bearer/qnetworkconfiguration.cpp
index f1619ab7c0..3367de80c8 100644
--- a/src/network/bearer/qnetworkconfiguration.cpp
+++ b/src/network/bearer/qnetworkconfiguration.cpp
@@ -111,7 +111,7 @@ QT_BEGIN_NAMESPACE
Depending on the type of configuration some states are transient in nature. A GPRS/UMTS
connection may almost always be \l Discovered if the GSM/UMTS network is available.
- However if the GSM/UMTS network looses the connection the associated configuration may change its state
+ However if the GSM/UMTS network loses the connection the associated configuration may change its state
from \l Discovered to \l Defined as well. A similar use case might be triggered by
WLAN availability. QNetworkConfigurationManager::updateConfigurations() can be used to
manually trigger updates of states. Note that some platforms do not require such updates
diff --git a/src/network/configure.json b/src/network/configure.json
index d35dda99bc..efb48f7655 100644
--- a/src/network/configure.json
+++ b/src/network/configure.json
@@ -205,7 +205,6 @@
"label": "QNetworkProxy",
"purpose": "Provides network proxy support.",
"section": "Networking",
- "condition": "!config.winrt",
"output": [ "publicFeature", "feature" ]
},
"socks5": {
diff --git a/src/network/kernel/kernel.pri b/src/network/kernel/kernel.pri
index a80b2d387e..c3fcf25233 100644
--- a/src/network/kernel/kernel.pri
+++ b/src/network/kernel/kernel.pri
@@ -60,7 +60,7 @@ mac {
}
osx:SOURCES += kernel/qnetworkproxy_mac.cpp
-else:win32:SOURCES += kernel/qnetworkproxy_win.cpp
+else:win32:!winrt: SOURCES += kernel/qnetworkproxy_win.cpp
else: qtConfig(libproxy) {
SOURCES += kernel/qnetworkproxy_libproxy.cpp
QMAKE_USE_PRIVATE += libproxy
diff --git a/src/network/kernel/qhostinfo.cpp b/src/network/kernel/qhostinfo.cpp
index 46123eb8a7..0156e22d41 100644
--- a/src/network/kernel/qhostinfo.cpp
+++ b/src/network/kernel/qhostinfo.cpp
@@ -279,6 +279,27 @@ int QHostInfo::lookupHost(const QString &name, QObject *receiver,
}
/*!
+ \fn QHostInfo &QHostInfo::operator=(QHostInfo &&other)
+
+ Move-assigns \a other to this QHostInfo instance.
+
+ \note The moved-from object \a other is placed in a
+ partially-formed state, in which the only valid operations are
+ destruction and assignment of a new value.
+
+ \since 5.10
+*/
+
+/*!
+ \fn void QHostInfo::swap(QHostInfo &other)
+
+ Swaps host-info \a other with this host-info. This operation is
+ very fast and never fails.
+
+ \since 5.10
+*/
+
+/*!
\fn int QHostInfo::lookupHost(const QString &name, const QObject *receiver, PointerToMemberFunction function)
\since 5.9
diff --git a/src/network/kernel/qhostinfo.h b/src/network/kernel/qhostinfo.h
index 4484d718bd..c5727bb6eb 100644
--- a/src/network/kernel/qhostinfo.h
+++ b/src/network/kernel/qhostinfo.h
@@ -63,8 +63,11 @@ public:
explicit QHostInfo(int lookupId = -1);
QHostInfo(const QHostInfo &d);
QHostInfo &operator=(const QHostInfo &d);
+ QHostInfo &operator=(QHostInfo &&other) Q_DECL_NOTHROW { swap(other); return *this; }
~QHostInfo();
+ void swap(QHostInfo &other) Q_DECL_NOTHROW { qSwap(d, other.d); }
+
QString hostName() const;
void setHostName(const QString &name);
@@ -125,7 +128,7 @@ public:
!std::is_same<const char *, Func>::value, int>::type
lookupHost(const QString &name, Func slot)
{
- return lookupHost(name, nullptr, slot);
+ return lookupHost(name, nullptr, std::move(slot));
}
// lookupHost to a functor or function pointer (with context)
@@ -141,7 +144,7 @@ public:
auto slotObj = new QtPrivate::QFunctorSlotObject<Func1, 1,
typename QtPrivate::List<QHostInfo>,
- void>(slot);
+ void>(std::move(slot));
return lookupHostImpl(name, context, slotObj);
}
#endif // Q_QDOC
@@ -154,6 +157,8 @@ private:
QtPrivate::QSlotObjectBase *slotObj);
};
+Q_DECLARE_SHARED_NOT_MOVABLE_UNTIL_QT6(QHostInfo)
+
QT_END_NAMESPACE
Q_DECLARE_METATYPE(QHostInfo)
diff --git a/src/network/socket/qabstractsocket.cpp b/src/network/socket/qabstractsocket.cpp
index 7ecbf35489..9cb6c4be57 100644
--- a/src/network/socket/qabstractsocket.cpp
+++ b/src/network/socket/qabstractsocket.cpp
@@ -943,7 +943,9 @@ void QAbstractSocketPrivate::resolveProxy(const QString &hostname, quint16 port)
// DefaultProxy here will raise an error
proxyInUse = QNetworkProxy();
}
+#endif // !QT_NO_NETWORKPROXY
+#if !defined(QT_NO_NETWORKPROXY) || defined(Q_OS_WINRT)
/*!
\internal
@@ -981,7 +983,7 @@ void QAbstractSocketPrivate::startConnectingByName(const QString &host)
emit q->stateChanged(state);
}
-#endif
+#endif // !QT_NO_NETWORKPROXY || Q_OS_WINRT
/*! \internal
@@ -1113,10 +1115,6 @@ void QAbstractSocketPrivate::_q_connectToNextAddress()
// (localhost address on BSD or any UDP connect), emit
// connected() and return.
if (
-#if defined(Q_OS_WINRT) && _MSC_VER >= 1900
- !qEnvironmentVariableIsEmpty("QT_WINRT_USE_THREAD_NETWORK_CONTEXT") ?
- socketEngine->connectToHostByName(hostName, port) :
-#endif
socketEngine->connectToHost(host, port)) {
//_q_testConnection();
fetchConnectionParameters();
@@ -1712,6 +1710,7 @@ void QAbstractSocket::connectToHost(const QString &hostName, quint16 port,
QIODevice::open(openMode);
d->readChannelCount = d->writeChannelCount = 0;
+#ifndef Q_OS_WINRT
d->state = HostLookupState;
emit stateChanged(d->state);
@@ -1749,6 +1748,10 @@ void QAbstractSocket::connectToHost(const QString &hostName, quint16 port,
(d->state == ConnectingState || d->state == HostLookupState)
? " (connection in progress)" : "");
#endif
+#else // !Q_OS_WINRT
+ // On WinRT we should always connect by name. Lookup and proxy handling are done by the API.
+ d->startConnectingByName(hostName);
+#endif
}
/*! \overload
diff --git a/src/network/socket/qlocalserver.cpp b/src/network/socket/qlocalserver.cpp
index 94143c2dc0..219a19f8b1 100644
--- a/src/network/socket/qlocalserver.cpp
+++ b/src/network/socket/qlocalserver.cpp
@@ -41,6 +41,10 @@
#include "qlocalserver_p.h"
#include "qlocalsocket.h"
+#if defined(Q_OS_WIN) && !defined(QT_LOCALSOCKET_TCP)
+#include <QtCore/qt_windows.h>
+#endif
+
QT_BEGIN_NAMESPACE
#ifndef QT_NO_LOCALSERVER
@@ -183,6 +187,42 @@ QLocalServer::SocketOptions QLocalServer::socketOptions() const
}
/*!
+ \since 5.10
+ Returns the native socket descriptor the server uses to listen
+ for incoming instructions, or -1 if the server is not listening.
+
+ The type of the descriptor depends on the platform:
+ \list
+ \li On Windows, the returned value is a
+ \l{https://msdn.microsoft.com/en-us/library/windows/desktop/ms740522(v=vs.85).aspx}
+ {Winsock 2 Socket Handle}.
+
+ \li With WinRT and on INTEGRITY, the returned value is the
+ QTcpServer socket descriptor and the type is defined by
+ \l{QTcpServer::socketDescriptor}{socketDescriptor}.
+
+ \li On all other UNIX-like operating systems, the type is
+ a file descriptor representing a listening socket.
+ \endlist
+
+ \sa listen()
+*/
+qintptr QLocalServer::socketDescriptor() const
+{
+ Q_D(const QLocalServer);
+ if (!isListening())
+ return -1;
+#if defined(QT_LOCALSOCKET_TCP)
+ return d->tcpServer.socketDescriptor();
+#elif defined(Q_OS_WIN)
+ const auto handle = d->connectionEventNotifier->handle();
+ return handle != INVALID_HANDLE_VALUE ? qintptr(handle) : -1;
+#else
+ return d->socketNotifier->socket();
+#endif
+}
+
+/*!
Stop listening for incoming connections. Existing connections are not
affected, but any new connections will be refused.
diff --git a/src/network/socket/qlocalserver.h b/src/network/socket/qlocalserver.h
index 52c533141f..2341fd40d4 100644
--- a/src/network/socket/qlocalserver.h
+++ b/src/network/socket/qlocalserver.h
@@ -93,6 +93,8 @@ public:
void setSocketOptions(SocketOptions options);
SocketOptions socketOptions() const;
+ qintptr socketDescriptor() const;
+
protected:
virtual void incomingConnection(quintptr socketDescriptor);
diff --git a/src/network/socket/qlocalsocket.cpp b/src/network/socket/qlocalsocket.cpp
index 91d2137ce6..4dad5a6eba 100644
--- a/src/network/socket/qlocalsocket.cpp
+++ b/src/network/socket/qlocalsocket.cpp
@@ -128,6 +128,20 @@ QT_BEGIN_NAMESPACE
The socket descriptor is not available when QLocalSocket
is in UnconnectedState.
+ The type of the descriptor depends on the platform:
+
+ \list
+ \li On Windows, the returned value is a
+ \l{https://msdn.microsoft.com/en-us/library/windows/desktop/ms740522(v=vs.85).aspx}
+ {Winsock 2 Socket Handle}.
+
+ \li With WinRT and on INTEGRITY, the returned value is the
+ QTcpSocket socket descriptor and the type is defined by
+ \l{QTcpSocket::socketDescriptor}{socketDescriptor}.
+
+ \li On all other UNIX-like operating systems, the type is
+ a file descriptor representing a socket.
+ \endlist
\sa setSocketDescriptor()
*/
diff --git a/src/network/socket/qlocalsocket_win.cpp b/src/network/socket/qlocalsocket_win.cpp
index 312c934632..ae94cb9d51 100644
--- a/src/network/socket/qlocalsocket_win.cpp
+++ b/src/network/socket/qlocalsocket_win.cpp
@@ -183,10 +183,8 @@ void QLocalSocket::connectToServer(OpenMode openMode)
}
// we have a valid handle
- if (setSocketDescriptor((qintptr)localSocket, ConnectedState, openMode)) {
- d->handle = localSocket;
+ if (setSocketDescriptor((qintptr)localSocket, ConnectedState, openMode))
emit connected();
- }
}
// This is reading from the buffer
diff --git a/src/network/socket/qnativesocketengine_unix.cpp b/src/network/socket/qnativesocketengine_unix.cpp
index 3cf65b3553..13ceb4c612 100644
--- a/src/network/socket/qnativesocketengine_unix.cpp
+++ b/src/network/socket/qnativesocketengine_unix.cpp
@@ -670,8 +670,7 @@ static bool multicastMembershipHelper(QNativeSocketEnginePrivate *d,
Q_IPV6ADDR ip6 = groupAddress.toIPv6Address();
memcpy(&mreq6.ipv6mr_multiaddr, &ip6, sizeof(ip6));
mreq6.ipv6mr_interface = interface.index();
- } else
- if (groupAddress.protocol() == QAbstractSocket::IPv4Protocol) {
+ } else if (groupAddress.protocol() == QAbstractSocket::IPv4Protocol) {
level = IPPROTO_IP;
sockOpt = how4;
sockArg = &mreq4;
diff --git a/src/network/socket/qnativesocketengine_win.cpp b/src/network/socket/qnativesocketengine_win.cpp
index a09d611e89..12c5aa0023 100644
--- a/src/network/socket/qnativesocketengine_win.cpp
+++ b/src/network/socket/qnativesocketengine_win.cpp
@@ -944,9 +944,7 @@ static bool multicastMembershipHelper(QNativeSocketEnginePrivate *d,
Q_IPV6ADDR ip6 = groupAddress.toIPv6Address();
memcpy(&mreq6.ipv6mr_multiaddr, &ip6, sizeof(ip6));
mreq6.ipv6mr_interface = iface.index();
- } else
-
- if (groupAddress.protocol() == QAbstractSocket::IPv4Protocol) {
+ } else if (groupAddress.protocol() == QAbstractSocket::IPv4Protocol) {
level = IPPROTO_IP;
sockOpt = how4;
sockArg = reinterpret_cast<char *>(&mreq4);
diff --git a/src/network/ssl/qsslsocket.cpp b/src/network/ssl/qsslsocket.cpp
index 84b8f3a8d9..0e4b049353 100644
--- a/src/network/ssl/qsslsocket.cpp
+++ b/src/network/ssl/qsslsocket.cpp
@@ -1993,6 +1993,8 @@ qint64 QSslSocket::readData(char *data, qint64 maxlen)
// possibly trigger another transmit() to decrypt more data from the socket
if (d->plainSocket->bytesAvailable())
QMetaObject::invokeMethod(this, "_q_flushReadBuffer", Qt::QueuedConnection);
+ else if (d->state != QAbstractSocket::ConnectedState)
+ return maxlen ? qint64(-1) : qint64(0);
}
return readBytes;
diff --git a/src/network/ssl/qsslsocket_mac.cpp b/src/network/ssl/qsslsocket_mac.cpp
index 10f6fb4e41..4216e2a16a 100644
--- a/src/network/ssl/qsslsocket_mac.cpp
+++ b/src/network/ssl/qsslsocket_mac.cpp
@@ -96,16 +96,14 @@ EphemeralSecKeychain::EphemeralSecKeychain()
return;
}
- QString uuidAsString(uuid.toString());
- Q_ASSERT(uuidAsString.size() > 2);
- Q_ASSERT(uuidAsString.startsWith(QLatin1Char('{'))
- && uuidAsString.endsWith(QLatin1Char('}')));
- uuidAsString = uuidAsString.mid(1, uuidAsString.size() - 2);
-
- QString keychainName(QDir::tempPath());
- keychainName.append(QDir::separator());
- keychainName += uuidAsString;
- keychainName += QLatin1String(".keychain");
+ const QByteArray uuidAsByteArray = uuid.toByteArray();
+ Q_ASSERT(uuidAsByteArray.size() > 2);
+ Q_ASSERT(uuidAsByteArray.startsWith('{'));
+ Q_ASSERT(uuidAsByteArray.endsWith('}'));
+ const auto uuidAsString = QLatin1String(uuidAsByteArray.data(), uuidAsByteArray.size()).mid(1, uuidAsByteArray.size() - 2);
+
+ const QString keychainName
+ = QDir::tempPath() + QDir::separator() + uuidAsString + QLatin1String(".keychain");
// SecKeychainCreate, pathName parameter:
//
// "A constant character string representing the POSIX path indicating where
@@ -1108,6 +1106,12 @@ bool QSslSocketBackendPrivate::verifySessionProtocol() const
protocolOk = (sessionProtocol() >= QSsl::SslV3);
else if (configuration.protocol == QSsl::SecureProtocols)
protocolOk = (sessionProtocol() >= QSsl::TlsV1_0);
+ else if (configuration.protocol == QSsl::TlsV1_0OrLater)
+ protocolOk = (sessionProtocol() >= QSsl::TlsV1_0);
+ else if (configuration.protocol == QSsl::TlsV1_1OrLater)
+ protocolOk = (sessionProtocol() >= QSsl::TlsV1_1);
+ else if (configuration.protocol == QSsl::TlsV1_2OrLater)
+ protocolOk = (sessionProtocol() >= QSsl::TlsV1_2);
else
protocolOk = (sessionProtocol() == configuration.protocol);
diff --git a/src/network/ssl/qsslsocket_openssl.cpp b/src/network/ssl/qsslsocket_openssl.cpp
index 644dfdb6a8..b4bfaca8be 100644
--- a/src/network/ssl/qsslsocket_openssl.cpp
+++ b/src/network/ssl/qsslsocket_openssl.cpp
@@ -212,6 +212,48 @@ static unsigned int q_ssl_psk_server_callback(SSL *ssl,
#endif
} // extern "C"
+static void q_OpenSSL_add_all_algorithms_safe()
+{
+#ifdef Q_OS_WIN
+ // Prior to version 1.0.1m an attempt to call OpenSSL_add_all_algorithms on
+ // Windows could result in 'exit' call from OPENSSL_config (QTBUG-43843).
+ // We can predict this and avoid OPENSSL_add_all_algorithms call.
+ // From OpenSSL docs:
+ // "An application does not need to add algorithms to use them explicitly,
+ // for example by EVP_sha1(). It just needs to add them if it (or any of
+ // the functions it calls) needs to lookup algorithms.
+ // The cipher and digest lookup functions are used in many parts of the
+ // library. If the table is not initialized several functions will
+ // misbehave and complain they cannot find algorithms. This includes the
+ // PEM, PKCS#12, SSL and S/MIME libraries. This is a common query in
+ // the OpenSSL mailing lists."
+ //
+ // Anyway, as a result, we chose not to call this function if it would exit.
+
+ if (q_SSLeay() < 0x100010DFL)
+ {
+ // Now, before we try to call it, check if an attempt to open config file
+ // will result in exit:
+ if (char *confFileName = q_CONF_get1_default_config_file()) {
+ BIO *confFile = q_BIO_new_file(confFileName, "r");
+ const auto lastError = q_ERR_peek_last_error();
+ q_OPENSSL_free(confFileName);
+ if (confFile) {
+ q_BIO_free(confFile);
+ } else {
+ q_ERR_clear_error();
+ if (ERR_GET_REASON(lastError) == ERR_R_SYS_LIB) {
+ qCWarning(lcSsl, "failed to open openssl.conf file");
+ return;
+ }
+ }
+ }
+ }
+#endif // Q_OS_WIN
+
+ q_OpenSSL_add_all_algorithms();
+}
+
QSslSocketBackendPrivate::QSslSocketBackendPrivate()
: ssl(0),
readBio(0),
@@ -269,11 +311,10 @@ QSslCipher QSslSocketBackendPrivate::QSslCipher_from_SSL_CIPHER(SSL_CIPHER *ciph
// static
inline QSslErrorEntry QSslErrorEntry::fromStoreContext(X509_STORE_CTX *ctx) {
- QSslErrorEntry result = {
+ return {
q_X509_STORE_CTX_get_error(ctx),
q_X509_STORE_CTX_get_error_depth(ctx)
};
- return result;
}
// ### This list is shared between all threads, and protected by a
@@ -503,7 +544,7 @@ bool QSslSocketPrivate::ensureLibraryLoaded()
if (q_SSL_library_init() != 1)
return false;
q_SSL_load_error_strings();
- q_OpenSSL_add_all_algorithms();
+ q_OpenSSL_add_all_algorithms_safe();
#if OPENSSL_VERSION_NUMBER >= 0x10001000L
if (q_SSLeay() >= 0x10001000L)
diff --git a/src/network/ssl/qsslsocket_openssl_symbols.cpp b/src/network/ssl/qsslsocket_openssl_symbols.cpp
index c344a94427..12d52fc082 100644
--- a/src/network/ssl/qsslsocket_openssl_symbols.cpp
+++ b/src/network/ssl/qsslsocket_openssl_symbols.cpp
@@ -144,6 +144,9 @@ DEFINEFUNC(unsigned char *, ASN1_STRING_data, ASN1_STRING *a, a, return 0, retur
DEFINEFUNC(int, ASN1_STRING_length, ASN1_STRING *a, a, return 0, return)
DEFINEFUNC2(int, ASN1_STRING_to_UTF8, unsigned char **a, a, ASN1_STRING *b, b, return 0, return);
DEFINEFUNC4(long, BIO_ctrl, BIO *a, a, int b, b, long c, c, void *d, d, return -1, return)
+DEFINEFUNC2(BIO *, BIO_new_file, const char *filename, filename, const char *mode, mode, return 0, return)
+DEFINEFUNC(void, ERR_clear_error, DUMMYARG, DUMMYARG, return, DUMMYARG)
+DEFINEFUNC(void, OPENSSL_free, void *ptr, ptr, return, DUMMYARG)
DEFINEFUNC(int, BIO_free, BIO *a, a, return 0, return)
DEFINEFUNC(BIO *, BIO_new, BIO_METHOD *a, a, return 0, return)
DEFINEFUNC2(BIO *, BIO_new_mem_buf, void *a, a, int b, b, return 0, return)
@@ -168,6 +171,7 @@ DEFINEFUNC(void, DSA_free, DSA *a, a, return, DUMMYARG)
DEFINEFUNC3(X509 *, d2i_X509, X509 **a, a, const unsigned char **b, b, long c, c, return 0, return)
DEFINEFUNC2(char *, ERR_error_string, unsigned long a, a, char *b, b, return 0, return)
DEFINEFUNC(unsigned long, ERR_get_error, DUMMYARG, DUMMYARG, return 0, return)
+DEFINEFUNC(unsigned long, ERR_peek_last_error, DUMMYARG, DUMMYARG, return 0, return)
DEFINEFUNC(void, ERR_free_strings, void, DUMMYARG, return, DUMMYARG)
DEFINEFUNC(void, EVP_CIPHER_CTX_cleanup, EVP_CIPHER_CTX *a, a, return, DUMMYARG)
DEFINEFUNC(void, EVP_CIPHER_CTX_init, EVP_CIPHER_CTX *a, a, return, DUMMYARG)
@@ -407,6 +411,7 @@ DEFINEFUNC3(DSA *, d2i_DSAPrivateKey, DSA **a, a, unsigned char **b, b, long c,
DEFINEFUNC3(EC_KEY *, d2i_ECPrivateKey, EC_KEY **a, a, unsigned char **b, b, long c, c, return 0, return)
#endif
#endif
+DEFINEFUNC(char *, CONF_get1_default_config_file, DUMMYARG, DUMMYARG, return 0, return)
DEFINEFUNC(void, OPENSSL_add_all_algorithms_noconf, void, DUMMYARG, return, DUMMYARG)
DEFINEFUNC(void, OPENSSL_add_all_algorithms_conf, void, DUMMYARG, return, DUMMYARG)
DEFINEFUNC3(int, SSL_CTX_load_verify_locations, SSL_CTX *ctx, ctx, const char *CAfile, CAfile, const char *CApath, CApath, return 0, return)
@@ -779,6 +784,9 @@ bool q_resolveOpenSslSymbols()
RESOLVEFUNC(ASN1_STRING_length)
RESOLVEFUNC(ASN1_STRING_to_UTF8)
RESOLVEFUNC(BIO_ctrl)
+ RESOLVEFUNC(BIO_new_file)
+ RESOLVEFUNC(ERR_clear_error)
+ RESOLVEFUNC(OPENSSL_free)
RESOLVEFUNC(BIO_free)
RESOLVEFUNC(BIO_new)
RESOLVEFUNC(BIO_new_mem_buf)
@@ -802,6 +810,7 @@ bool q_resolveOpenSslSymbols()
RESOLVEFUNC(DSA_free)
RESOLVEFUNC(ERR_error_string)
RESOLVEFUNC(ERR_get_error)
+ RESOLVEFUNC(ERR_peek_last_error)
RESOLVEFUNC(ERR_free_strings)
RESOLVEFUNC(EVP_CIPHER_CTX_cleanup)
RESOLVEFUNC(EVP_CIPHER_CTX_init)
@@ -991,6 +1000,7 @@ bool q_resolveOpenSslSymbols()
RESOLVEFUNC(d2i_DSAPrivateKey)
RESOLVEFUNC(d2i_RSAPrivateKey)
#endif
+ RESOLVEFUNC(CONF_get1_default_config_file)
RESOLVEFUNC(OPENSSL_add_all_algorithms_noconf)
RESOLVEFUNC(OPENSSL_add_all_algorithms_conf)
RESOLVEFUNC(SSL_CTX_load_verify_locations)
diff --git a/src/network/ssl/qsslsocket_openssl_symbols_p.h b/src/network/ssl/qsslsocket_openssl_symbols_p.h
index b35a895d38..68dc6da811 100644
--- a/src/network/ssl/qsslsocket_openssl_symbols_p.h
+++ b/src/network/ssl/qsslsocket_openssl_symbols_p.h
@@ -221,6 +221,9 @@ unsigned char * q_ASN1_STRING_data(ASN1_STRING *a);
int q_ASN1_STRING_length(ASN1_STRING *a);
int q_ASN1_STRING_to_UTF8(unsigned char **a, ASN1_STRING *b);
long q_BIO_ctrl(BIO *a, int b, long c, void *d);
+BIO *q_BIO_new_file(const char *filename, const char *mode);
+void q_ERR_clear_error();
+void q_OPENSSL_free(void *ptr);
Q_AUTOTEST_EXPORT int q_BIO_free(BIO *a);
Q_AUTOTEST_EXPORT BIO *q_BIO_new(BIO_METHOD *a);
BIO *q_BIO_new_mem_buf(void *a, int b);
@@ -256,6 +259,7 @@ void q_DSA_free(DSA *a);
X509 *q_d2i_X509(X509 **a, const unsigned char **b, long c);
char *q_ERR_error_string(unsigned long a, char *b);
unsigned long q_ERR_get_error();
+unsigned long q_ERR_peek_last_error();
void q_ERR_free_strings();
void q_EVP_CIPHER_CTX_cleanup(EVP_CIPHER_CTX *a);
void q_EVP_CIPHER_CTX_init(EVP_CIPHER_CTX *a);
@@ -565,6 +569,7 @@ DSA *q_d2i_DSAPrivateKey(DSA **a, unsigned char **pp, long length);
#define q_EVP_PKEY_assign_DSA(pkey,dsa) q_EVP_PKEY_assign((pkey),EVP_PKEY_DSA,\
(char *)(dsa))
#define q_OpenSSL_add_all_algorithms() q_OPENSSL_add_all_algorithms_conf()
+char *q_CONF_get1_default_config_file();
void q_OPENSSL_add_all_algorithms_noconf();
void q_OPENSSL_add_all_algorithms_conf();
int q_SSL_CTX_load_verify_locations(SSL_CTX *ctx, const char *CAfile, const char *CApath);