diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/network/access/qhttpnetworkconnection.cpp | 178 | ||||
-rw-r--r-- | src/network/access/qhttpnetworkconnection_p.h | 16 | ||||
-rw-r--r-- | src/network/access/qhttpnetworkconnectionchannel.cpp | 31 | ||||
-rw-r--r-- | src/network/access/qhttpnetworkconnectionchannel_p.h | 2 | ||||
-rw-r--r-- | src/network/socket/qabstractsocket.cpp | 20 | ||||
-rw-r--r-- | src/network/socket/qabstractsocket.h | 2 | ||||
-rw-r--r-- | src/network/socket/qabstractsocket_p.h | 2 | ||||
-rw-r--r-- | src/network/ssl/qsslsocket.cpp | 11 | ||||
-rw-r--r-- | src/network/ssl/qsslsocket.h | 4 |
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); |