summaryrefslogtreecommitdiffstats
path: root/src/network
diff options
context:
space:
mode:
Diffstat (limited to 'src/network')
-rw-r--r--src/network/access/qhttpnetworkconnection.cpp178
-rw-r--r--src/network/access/qhttpnetworkconnection_p.h16
-rw-r--r--src/network/access/qhttpnetworkconnectionchannel.cpp31
-rw-r--r--src/network/access/qhttpnetworkconnectionchannel_p.h2
-rw-r--r--src/network/socket/qabstractsocket.cpp20
-rw-r--r--src/network/socket/qabstractsocket.h2
-rw-r--r--src/network/socket/qabstractsocket_p.h2
-rw-r--r--src/network/ssl/qsslsocket.cpp11
-rw-r--r--src/network/ssl/qsslsocket.h4
9 files changed, 238 insertions, 28 deletions
diff --git a/src/network/access/qhttpnetworkconnection.cpp b/src/network/access/qhttpnetworkconnection.cpp
index d950af4ee2..a8a4fd9ae7 100644
--- a/src/network/access/qhttpnetworkconnection.cpp
+++ b/src/network/access/qhttpnetworkconnection.cpp
@@ -46,6 +46,7 @@
#include <private/qnetworkrequest_p.h>
#include <private/qobject_p.h>
#include <private/qauthenticator_p.h>
+#include "private/qhostinfo_p.h"
#include <qnetworkproxy.h>
#include <qauthenticator.h>
@@ -83,7 +84,8 @@ const int QHttpNetworkConnectionPrivate::defaultRePipelineLength = 2;
QHttpNetworkConnectionPrivate::QHttpNetworkConnectionPrivate(const QString &hostName, quint16 port, bool encrypt)
: state(RunningState),
hostName(hostName), port(port), encrypt(encrypt),
- channelCount(defaultChannelCount)
+ channelCount(defaultChannelCount),
+ networkLayerState(Unknown)
#ifndef QT_NO_NETWORKPROXY
, networkProxy(QNetworkProxy::NoProxy)
#endif
@@ -94,7 +96,8 @@ QHttpNetworkConnectionPrivate::QHttpNetworkConnectionPrivate(const QString &host
QHttpNetworkConnectionPrivate::QHttpNetworkConnectionPrivate(quint16 channelCount, const QString &hostName, quint16 port, bool encrypt)
: state(RunningState),
hostName(hostName), port(port), encrypt(encrypt),
- channelCount(channelCount)
+ channelCount(channelCount),
+ networkLayerState(Unknown)
#ifndef QT_NO_NETWORKPROXY
, networkProxy(QNetworkProxy::NoProxy)
#endif
@@ -174,6 +177,45 @@ int QHttpNetworkConnectionPrivate::indexOf(QAbstractSocket *socket) const
return 0;
}
+// If the connection is in the InProgress state channel errors should not always be
+// emitted. This function will check the status of the connection channels if we
+// have not decided the networkLayerState and will return true if the channel error
+// should be emitted by the channel.
+bool QHttpNetworkConnectionPrivate::shouldEmitChannelError(QAbstractSocket *socket)
+{
+ Q_Q(QHttpNetworkConnection);
+
+ bool emitError = true;
+ int i = indexOf(socket);
+ int otherSocket = (i == 0 ? 1 : 0);
+
+ if (networkLayerState == QHttpNetworkConnectionPrivate::InProgress) {
+ if (channels[otherSocket].isSocketBusy() && (channels[otherSocket].state != QHttpNetworkConnectionChannel::ClosingState)) {
+ // this was the first socket to fail.
+ channels[i].close();
+ emitError = false;
+ }
+ else {
+ // Both connection attempts has failed.
+ networkLayerState = QHttpNetworkConnectionPrivate::Unknown;
+ channels[i].close();
+ emitError = true;
+ }
+ } else {
+ if ((networkLayerState == QHttpNetworkConnectionPrivate::IPv4) && (channels[i].networkLayerPreference != QAbstractSocket::IPv4Protocol)
+ || (networkLayerState == QHttpNetworkConnectionPrivate::IPv6) && (channels[i].networkLayerPreference != QAbstractSocket::IPv6Protocol)) {
+ // First connection worked so this is the second one to complete and it failed.
+ channels[i].close();
+ QMetaObject::invokeMethod(q, "_q_startNextRequest", Qt::QueuedConnection);
+ emitError = false;
+ }
+ if (networkLayerState == QHttpNetworkConnectionPrivate::Unknown)
+ qWarning() << "We got a connection error when networkLayerState is Unknown";
+ }
+ return emitError;
+}
+
+
qint64 QHttpNetworkConnectionPrivate::uncompressedBytesAvailable(const QHttpNetworkReply &reply) const
{
return reply.d_func()->responseData.byteAmount();
@@ -469,17 +511,23 @@ QHttpNetworkReply* QHttpNetworkConnectionPrivate::queueRequest(const QHttpNetwor
break;
}
- // 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.
- // This is dangerous because of recursion that might occur when emitting
- // signals as DirectConnection from this code path. Therefore all signal
- // emissions that can come out from this code path need to
- // be QueuedConnection.
- // We are currently trying to fine-tune this.
- _q_startNextRequest();
-
-
+ // For Happy Eyeballs the networkLayerState is set to Unkown
+ // untill we have started the first connection attempt. So no
+ // request will be started untill we know if IPv4 or IPv6
+ // should be used.
+ if (networkLayerState == Unknown) {
+ startHostInfoLookup();
+ } else if ( networkLayerState == IPv4 || networkLayerState == IPv6 ) {
+ // 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.
+ // This is dangerous because of recursion that might occur when emitting
+ // signals as DirectConnection from this code path. Therefore all signal
+ // emissions that can come out from this code path need to
+ // be QueuedConnection.
+ // We are currently trying to fine-tune this.
+ _q_startNextRequest();
+ }
return reply;
}
@@ -781,6 +829,10 @@ void QHttpNetworkConnectionPrivate::removeReply(QHttpNetworkReply *reply)
// although it is called _q_startNextRequest, it will actually start multiple requests when possible
void QHttpNetworkConnectionPrivate::_q_startNextRequest()
{
+ // If there is no network layer state decided we should not start any new requests.
+ if (networkLayerState == Unknown || networkLayerState == InProgress)
+ return;
+
// If the QHttpNetworkConnection is currently paused then bail out immediately
if (state == PausedState)
return;
@@ -830,11 +882,15 @@ void QHttpNetworkConnectionPrivate::_q_startNextRequest()
// connected or not. This is to reuse connected channels before we connect new once.
int queuedRequest = highPriorityQueue.count() + lowPriorityQueue.count();
for (int i = 0; i < channelCount; ++i) {
- if (channels[i].socket->state() == QAbstractSocket::ConnectingState)
+ if ((channels[i].socket->state() == QAbstractSocket::ConnectingState) || (channels[i].socket->state() == QAbstractSocket::HostLookupState))
queuedRequest--;
if ( queuedRequest <=0 )
break;
if (!channels[i].reply && !channels[i].isSocketBusy() && (channels[i].socket->state() == QAbstractSocket::UnconnectedState)) {
+ if (networkLayerState == IPv4)
+ channels[i].networkLayerPreference = QAbstractSocket::IPv4Protocol;
+ else if (networkLayerState == IPv6)
+ channels[i].networkLayerPreference = QAbstractSocket::IPv6Protocol;
channels[i].ensureConnection();
queuedRequest--;
}
@@ -853,6 +909,100 @@ void QHttpNetworkConnectionPrivate::readMoreLater(QHttpNetworkReply *reply)
}
}
+
+
+// The first time we start the connection is used we do not know if we
+// should use IPv4 or IPv6. So we start a hostlookup to figure this out.
+// Later when we do the connection the socket will not need to do another
+// lookup as then the hostinfo will already be in the cache.
+void QHttpNetworkConnectionPrivate::startHostInfoLookup()
+{
+ // At this time all channels should be unconnected.
+ Q_ASSERT(!channels[0].isSocketBusy());
+ Q_ASSERT(!channels[1].isSocketBusy());
+
+ networkLayerState = InProgress;
+
+ // check if we already now can descide if this is IPv4 or IPv6
+ QHostAddress temp;
+ if (temp.setAddress(hostName)) {
+ if (temp.protocol() == QAbstractSocket::IPv4Protocol) {
+ networkLayerState = QHttpNetworkConnectionPrivate::IPv4;
+ QMetaObject::invokeMethod(this->q_func(), "_q_startNextRequest", Qt::QueuedConnection);
+ return;
+ } else if (temp.protocol() == QAbstractSocket::IPv6Protocol) {
+ networkLayerState = QHttpNetworkConnectionPrivate::IPv6;
+ QMetaObject::invokeMethod(this->q_func(), "_q_startNextRequest", Qt::QueuedConnection);
+ return;
+ }
+ } else {
+ int hostLookupId;
+ bool immediateResultValid = false;
+ QHostInfo hostInfo = qt_qhostinfo_lookup(hostName,
+ this->q_func(),
+ SLOT(_q_hostLookupFinished(QHostInfo)),
+ &immediateResultValid,
+ &hostLookupId);
+ if (immediateResultValid) {
+ _q_hostLookupFinished(hostInfo);
+ }
+ }
+}
+
+
+void QHttpNetworkConnectionPrivate::_q_hostLookupFinished(QHostInfo info)
+{
+ bool bIpv4 = false;
+ bool bIpv6 = false;
+
+ foreach (QHostAddress address, info.addresses()) {
+ if (address.protocol() == QAbstractSocket::IPv4Protocol)
+ bIpv4 = true;
+ else if (address.protocol() == QAbstractSocket::IPv6Protocol)
+ bIpv6 = true;
+ }
+
+ if (bIpv4 && bIpv6)
+ startNetworkLayerStateLookup();
+ else if (bIpv4) {
+ networkLayerState = QHttpNetworkConnectionPrivate::IPv4;
+ QMetaObject::invokeMethod(this->q_func(), "_q_startNextRequest", Qt::QueuedConnection);
+ } else if (bIpv6) {
+ networkLayerState = QHttpNetworkConnectionPrivate::IPv6;
+ QMetaObject::invokeMethod(this->q_func(), "_q_startNextRequest", Qt::QueuedConnection);
+ } else {
+ if (dequeueRequest(channels[0].socket)) {
+ emitReplyError(channels[0].socket, channels[0].reply, QNetworkReply::HostNotFoundError);
+ networkLayerState = QHttpNetworkConnectionPrivate::Unknown;
+ } else {
+ // Should not happen
+ qWarning() << "QHttpNetworkConnectionPrivate::_q_hostLookupFinished could not dequeu request";
+ networkLayerState = QHttpNetworkConnectionPrivate::Unknown;
+ }
+ }
+}
+
+
+// This will be used if the host lookup found both and Ipv4 and
+// Ipv6 address. Then we will start up two connections and pick
+// the network layer of the one that finish first. The second
+// connection will then be disconnected.
+void QHttpNetworkConnectionPrivate::startNetworkLayerStateLookup()
+{
+ // At this time all channels should be unconnected.
+ Q_ASSERT(!channels[0].isSocketBusy());
+ Q_ASSERT(!channels[1].isSocketBusy());
+
+ networkLayerState = InProgress;
+
+ channels[0].networkLayerPreference = QAbstractSocket::IPv4Protocol;
+ channels[1].networkLayerPreference = QAbstractSocket::IPv6Protocol;
+
+ channels[0].ensureConnection(); // Possibly delay this one..
+ channels[1].ensureConnection();
+}
+
+
#ifndef QT_NO_BEARERMANAGEMENT
QHttpNetworkConnection::QHttpNetworkConnection(const QString &hostName, quint16 port, bool encrypt, QObject *parent, QSharedPointer<QNetworkSession> networkSession)
: QObject(*(new QHttpNetworkConnectionPrivate(hostName, port, encrypt)), parent)
diff --git a/src/network/access/qhttpnetworkconnection_p.h b/src/network/access/qhttpnetworkconnection_p.h
index 6c953be58d..0c86fd94b9 100644
--- a/src/network/access/qhttpnetworkconnection_p.h
+++ b/src/network/access/qhttpnetworkconnection_p.h
@@ -82,6 +82,7 @@ QT_BEGIN_NAMESPACE
class QHttpNetworkRequest;
class QHttpNetworkReply;
class QByteArray;
+class QHostInfo;
class QHttpNetworkConnectionPrivate;
class Q_AUTOTEST_EXPORT QHttpNetworkConnection : public QObject
@@ -132,6 +133,7 @@ private:
friend class QHttpNetworkConnectionChannel;
Q_PRIVATE_SLOT(d_func(), void _q_startNextRequest())
+ Q_PRIVATE_SLOT(d_func(), void _q_hostLookupFinished(QHostInfo))
};
@@ -152,6 +154,13 @@ public:
PausedState = 1,
};
+ enum NetworkLayerPreferenceState {
+ Unknown,
+ InProgress,
+ IPv4,
+ IPv6
+ };
+
QHttpNetworkConnectionPrivate(const QString &hostName, quint16 port, bool encrypt);
QHttpNetworkConnectionPrivate(quint16 channelCount, const QString &hostName, quint16 port, bool encrypt);
~QHttpNetworkConnectionPrivate();
@@ -160,6 +169,7 @@ public:
void pauseConnection();
void resumeConnection();
ConnectionState state;
+ NetworkLayerPreferenceState networkLayerState;
enum { ChunkSize = 4096 };
@@ -179,9 +189,14 @@ public:
void copyCredentials(int fromChannel, QAuthenticator *auth, bool isProxy);
+ void startHostInfoLookup();
+ void startNetworkLayerStateLookup();
+
// private slots
void _q_startNextRequest(); // send the next request from the queue
+ void _q_hostLookupFinished(QHostInfo info);
+
void createAuthorization(QAbstractSocket *socket, QHttpNetworkRequest &request);
QString errorDetail(QNetworkReply::NetworkError errorCode, QAbstractSocket *socket,
@@ -198,6 +213,7 @@ public:
const int channelCount;
QHttpNetworkConnectionChannel *channels; // parallel connections to the server
+ bool shouldEmitChannelError(QAbstractSocket *socket);
qint64 uncompressedBytesAvailable(const QHttpNetworkReply &reply) const;
qint64 uncompressedBytesAvailableNextBlock(const QHttpNetworkReply &reply) const;
diff --git a/src/network/access/qhttpnetworkconnectionchannel.cpp b/src/network/access/qhttpnetworkconnectionchannel.cpp
index 7c644ad4b9..b8ed8ee567 100644
--- a/src/network/access/qhttpnetworkconnectionchannel.cpp
+++ b/src/network/access/qhttpnetworkconnectionchannel.cpp
@@ -80,6 +80,7 @@ QHttpNetworkConnectionChannel::QHttpNetworkConnectionChannel()
#endif
, pipeliningSupported(PipeliningSupportUnknown)
, connection(0)
+ , networkLayerPreference(QAbstractSocket::AnyIPProtocol)
{
// Inlining this function in the header leads to compiler error on
// release-armv5, on at least timebox 9.2 and 10.1.
@@ -594,7 +595,7 @@ bool QHttpNetworkConnectionChannel::ensureConnection()
if (ssl) {
#ifndef QT_NO_OPENSSL
QSslSocket *sslSocket = qobject_cast<QSslSocket*>(socket);
- sslSocket->connectToHostEncrypted(connectHost, connectPort);
+ sslSocket->connectToHostEncrypted(connectHost, connectPort, QIODevice::ReadWrite, networkLayerPreference);
if (ignoreAllSslErrors)
sslSocket->ignoreSslErrors();
sslSocket->ignoreSslErrors(ignoreSslErrorsList);
@@ -613,12 +614,12 @@ bool QHttpNetworkConnectionChannel::ensureConnection()
&& connection->cacheProxy().type() == QNetworkProxy::NoProxy
&& connection->transparentProxy().type() == QNetworkProxy::NoProxy) {
#endif
- socket->connectToHost(connectHost, connectPort, QIODevice::ReadWrite | QIODevice::Unbuffered);
+ socket->connectToHost(connectHost, connectPort, QIODevice::ReadWrite | QIODevice::Unbuffered, networkLayerPreference);
// For an Unbuffered QTcpSocket, the read buffer size has a special meaning.
socket->setReadBufferSize(1*1024);
#ifndef QT_NO_NETWORKPROXY
} else {
- socket->connectToHost(connectHost, connectPort);
+ socket->connectToHost(connectHost, connectPort, QIODevice::ReadWrite, networkLayerPreference);
// limit the socket read buffer size. we will read everything into
// the QHttpNetworkReply anyway, so let's grow only that and not
@@ -1002,6 +1003,25 @@ void QHttpNetworkConnectionChannel::_q_disconnected()
void QHttpNetworkConnectionChannel::_q_connected()
{
+ // For the Happy Eyeballs we need to check if this is the first channel to connect.
+ if (!pendingEncrypt) {
+ if (connection->d_func()->networkLayerState == QHttpNetworkConnectionPrivate::InProgress) {
+ if (networkLayerPreference == QAbstractSocket::IPv4Protocol)
+ connection->d_func()->networkLayerState = QHttpNetworkConnectionPrivate::IPv4;
+ else if (networkLayerPreference == QAbstractSocket::IPv6Protocol)
+ connection->d_func()->networkLayerState = QHttpNetworkConnectionPrivate::IPv6;
+ } else {
+ if (((connection->d_func()->networkLayerState == QHttpNetworkConnectionPrivate::IPv4) && (networkLayerPreference != QAbstractSocket::IPv4Protocol))
+ || ((connection->d_func()->networkLayerState == QHttpNetworkConnectionPrivate::IPv6) && (networkLayerPreference != QAbstractSocket::IPv6Protocol))) {
+ close();
+ // This is the second connection so it has to be closed and we can schedule it for another request.
+ QMetaObject::invokeMethod(connection, "_q_startNextRequest", Qt::QueuedConnection);
+ return;
+ }
+ //The connections networkLayerState had already been decided.
+ }
+ }
+
// improve performance since we get the request sent by the kernel ASAP
//socket->setSocketOption(QAbstractSocket::LowDelayOption, 1);
// We have this commented out now. It did not have the effect we wanted. If we want to
@@ -1089,6 +1109,11 @@ void QHttpNetworkConnectionChannel::_q_error(QAbstractSocket::SocketError socket
QPointer<QHttpNetworkConnection> that = connection;
QString errorString = connection->d_func()->errorDetail(errorCode, socket, socket->errorString());
+ // In the InProgress state the channel should not emit the error.
+ // This will instead be handled by the connection.
+ if (!connection->d_func()->shouldEmitChannelError(socket))
+ return;
+
// Need to dequeu the request so that we can emit the error.
if (!reply)
connection->d_func()->dequeueRequest(socket);
diff --git a/src/network/access/qhttpnetworkconnectionchannel_p.h b/src/network/access/qhttpnetworkconnectionchannel_p.h
index f635cc9557..8400f62ab9 100644
--- a/src/network/access/qhttpnetworkconnectionchannel_p.h
+++ b/src/network/access/qhttpnetworkconnectionchannel_p.h
@@ -136,6 +136,8 @@ public:
void detectPipeliningSupport();
QHttpNetworkConnectionChannel();
+
+ QAbstractSocket::NetworkLayerProtocol networkLayerPreference;
void setConnection(QHttpNetworkConnection *c);
QPointer<QHttpNetworkConnection> connection;
diff --git a/src/network/socket/qabstractsocket.cpp b/src/network/socket/qabstractsocket.cpp
index 5316626638..9afb21155b 100644
--- a/src/network/socket/qabstractsocket.cpp
+++ b/src/network/socket/qabstractsocket.cpp
@@ -483,7 +483,8 @@ QAbstractSocketPrivate::QAbstractSocketPrivate()
hostLookupId(-1),
socketType(QAbstractSocket::UnknownSocketType),
state(QAbstractSocket::UnconnectedState),
- socketError(QAbstractSocket::UnknownSocketError)
+ socketError(QAbstractSocket::UnknownSocketError),
+ preferredNetworkLayerProtocol(QAbstractSocket::UnknownNetworkLayerProtocol)
{
}
@@ -899,7 +900,16 @@ void QAbstractSocketPrivate::_q_startConnecting(const QHostInfo &hostInfo)
qWarning("QAbstractSocketPrivate::_q_startConnecting() received hostInfo for wrong lookup ID %d expected %d", hostInfo.lookupId(), hostLookupId);
}
- addresses = hostInfo.addresses();
+ // Only add the addresses for the prefered network layer.
+ // Or all if prefered network layer is not set.
+ if (preferredNetworkLayerProtocol == QAbstractSocket::UnknownNetworkLayerProtocol || preferredNetworkLayerProtocol == QAbstractSocket::AnyIPProtocol) {
+ addresses = hostInfo.addresses();
+ } else {
+ foreach (QHostAddress address, hostInfo.addresses())
+ if (address.protocol() == preferredNetworkLayerProtocol)
+ addresses += address;
+ }
+
#if defined(QABSTRACTSOCKET_DEBUG)
QString s = QLatin1String("{");
@@ -1330,8 +1340,12 @@ bool QAbstractSocket::isValid() const
\sa state(), peerName(), peerAddress(), peerPort(), waitForConnected()
*/
void QAbstractSocket::connectToHost(const QString &hostName, quint16 port,
- OpenMode openMode)
+ OpenMode openMode,
+ NetworkLayerProtocol protocol)
{
+ Q_D(QAbstractSocket);
+ d->preferredNetworkLayerProtocol = protocol;
+
QMetaObject::invokeMethod(this, "connectToHostImplementation",
Qt::DirectConnection,
Q_ARG(QString, hostName),
diff --git a/src/network/socket/qabstractsocket.h b/src/network/socket/qabstractsocket.h
index 2717ceb58a..2501df6e3d 100644
--- a/src/network/socket/qabstractsocket.h
+++ b/src/network/socket/qabstractsocket.h
@@ -129,7 +129,7 @@ public:
virtual ~QAbstractSocket();
// ### Qt 5: Make connectToHost() and disconnectFromHost() virtual.
- void connectToHost(const QString &hostName, quint16 port, OpenMode mode = ReadWrite);
+ void connectToHost(const QString &hostName, quint16 port, OpenMode mode = ReadWrite, NetworkLayerProtocol protocol = AnyIPProtocol);
void connectToHost(const QHostAddress &address, quint16 port, OpenMode mode = ReadWrite);
void disconnectFromHost();
diff --git a/src/network/socket/qabstractsocket_p.h b/src/network/socket/qabstractsocket_p.h
index cf7d98895f..978fb1433a 100644
--- a/src/network/socket/qabstractsocket_p.h
+++ b/src/network/socket/qabstractsocket_p.h
@@ -156,6 +156,8 @@ public:
QAbstractSocket::SocketError socketError;
+ QAbstractSocket::NetworkLayerProtocol preferredNetworkLayerProtocol;
+
bool prePauseReadSocketNotifierState;
bool prePauseWriteSocketNotifierState;
bool prePauseExceptionSocketNotifierState;
diff --git a/src/network/ssl/qsslsocket.cpp b/src/network/ssl/qsslsocket.cpp
index df61fb6c18..f191ed9324 100644
--- a/src/network/ssl/qsslsocket.cpp
+++ b/src/network/ssl/qsslsocket.cpp
@@ -405,7 +405,7 @@ QSslSocket::~QSslSocket()
\sa connectToHost(), startClientEncryption(), waitForConnected(), waitForEncrypted()
*/
-void QSslSocket::connectToHostEncrypted(const QString &hostName, quint16 port, OpenMode mode)
+void QSslSocket::connectToHostEncrypted(const QString &hostName, quint16 port, OpenMode mode, NetworkLayerProtocol protocol)
{
Q_D(QSslSocket);
if (d->state == ConnectedState || d->state == ConnectingState) {
@@ -419,7 +419,7 @@ void QSslSocket::connectToHostEncrypted(const QString &hostName, quint16 port, O
// Note: When connecting to localhost, some platforms (e.g., HP-UX and some BSDs)
// establish the connection immediately (i.e., first attempt).
- connectToHost(hostName, port, mode);
+ connectToHost(hostName, port, mode, protocol);
}
/*!
@@ -434,7 +434,8 @@ void QSslSocket::connectToHostEncrypted(const QString &hostName, quint16 port, O
\sa connectToHostEncrypted()
*/
void QSslSocket::connectToHostEncrypted(const QString &hostName, quint16 port,
- const QString &sslPeerName, OpenMode mode)
+ const QString &sslPeerName, OpenMode mode,
+ NetworkLayerProtocol protocol)
{
Q_D(QSslSocket);
if (d->state == ConnectedState || d->state == ConnectingState) {
@@ -449,7 +450,7 @@ void QSslSocket::connectToHostEncrypted(const QString &hostName, quint16 port,
// Note: When connecting to localhost, some platforms (e.g., HP-UX and some BSDs)
// establish the connection immediately (i.e., first attempt).
- connectToHost(hostName, port, mode);
+ connectToHost(hostName, port, mode, protocol);
}
/*!
@@ -1740,7 +1741,7 @@ void QSslSocket::connectToHostImplementation(const QString &hostName, quint16 po
d->plainSocket->setProperty("_q_user-agent", property("_q_user-agent"));
#endif
QIODevice::open(openMode);
- d->plainSocket->connectToHost(hostName, port, openMode);
+ d->plainSocket->connectToHost(hostName, port, openMode, d->preferredNetworkLayerProtocol);
d->cachedSocketDescriptor = d->plainSocket->socketDescriptor();
}
diff --git a/src/network/ssl/qsslsocket.h b/src/network/ssl/qsslsocket.h
index 1e7c67ce91..f175ffd946 100644
--- a/src/network/ssl/qsslsocket.h
+++ b/src/network/ssl/qsslsocket.h
@@ -85,8 +85,8 @@ public:
~QSslSocket();
// Autostarting the SSL client handshake.
- void connectToHostEncrypted(const QString &hostName, quint16 port, OpenMode mode = ReadWrite);
- void connectToHostEncrypted(const QString &hostName, quint16 port, const QString &sslPeerName, OpenMode mode = ReadWrite);
+ void connectToHostEncrypted(const QString &hostName, quint16 port, OpenMode mode = ReadWrite, NetworkLayerProtocol protocol = AnyIPProtocol);
+ void connectToHostEncrypted(const QString &hostName, quint16 port, const QString &sslPeerName, OpenMode mode = ReadWrite, NetworkLayerProtocol protocol = AnyIPProtocol);
bool setSocketDescriptor(int socketDescriptor, SocketState state = ConnectedState,
OpenMode openMode = ReadWrite);