From ffa7b050a19ef0169566dd7faf4625c9c6c0763d Mon Sep 17 00:00:00 2001 From: Oliver Wolff Date: Wed, 14 Oct 2015 08:11:04 +0200 Subject: winrt: Properly handle when a remote host closes a tcp connection. Task-number: QTBUG-48476 Change-Id: I1933dfe7e73330a8f0d5ac8d3d7a834e0d77270a Reviewed-by: Andrew Knight Reviewed-by: Samuel Nevala Reviewed-by: Maurice Kalinowski --- src/network/socket/qnativesocketengine_winrt.cpp | 35 ++++++++++++++++++++++-- 1 file changed, 33 insertions(+), 2 deletions(-) (limited to 'src/network') diff --git a/src/network/socket/qnativesocketengine_winrt.cpp b/src/network/socket/qnativesocketengine_winrt.cpp index 44de7f8526..d41bd4d313 100644 --- a/src/network/socket/qnativesocketengine_winrt.cpp +++ b/src/network/socket/qnativesocketengine_winrt.cpp @@ -420,6 +420,16 @@ void QNativeSocketEngine::close() { Q_D(QNativeSocketEngine); + if (d->closingDown) + return; + + d->closingDown = true; + + + d->notifyOnRead = false; + d->notifyOnWrite = false; + d->notifyOnException = false; + if (d->connectOp) { ComPtr info; d->connectOp.As(&info); @@ -440,7 +450,6 @@ void QNativeSocketEngine::close() } if (socket) { - d->closingDown = true; socket->Close(); d->socketDescriptor = -1; } @@ -498,6 +507,14 @@ qint64 QNativeSocketEngine::read(char *data, qint64 maxlen) if (d->socketType != QAbstractSocket::TcpSocket) return -1; + // There will be a read notification when the socket was closed by the remote host. If that + // happens and there isn't anything left in the buffer, we have to return -1 in order to signal + // the closing of the socket. + if (d->readBytes.pos() == d->readBytes.size() && d->socketState != QAbstractSocket::ConnectedState) { + close(); + return -1; + } + QMutexLocker mutexLocker(&d->readMutex); return d->readBytes.read(data, maxlen); } @@ -1184,8 +1201,16 @@ HRESULT QNativeSocketEnginePrivate::handleReadyRead(IAsyncBufferOperation *async if (wasDeleted || isDeletingChildren) return S_OK; - if (status == Error || status == Canceled) + // A read in UnconnectedState will close the socket and return -1 and thus tell the caller, + // that the connection was closed. The socket cannot be closed here, as the subsequent read + // might fail then. + if (status == Error || status == Canceled) { + setError(QAbstractSocket::NetworkError, RemoteHostClosedErrorString); + socketState = QAbstractSocket::UnconnectedState; + if (notifyOnRead) + emit q->readReady(); return S_OK; + } ComPtr buffer; HRESULT hr = asyncInfo->GetResults(&buffer); @@ -1194,7 +1219,13 @@ HRESULT QNativeSocketEnginePrivate::handleReadyRead(IAsyncBufferOperation *async UINT32 bufferLength; hr = buffer->get_Length(&bufferLength); Q_ASSERT_SUCCEEDED(hr); + // A zero sized buffer length signals, that the remote host closed the connection. The socket + // cannot be closed though, as the following read might have socket descriptor -1 and thus and + // the closing of the socket won't be communicated to the caller. So only the error is set. The + // actual socket close happens inside of read. if (!bufferLength) { + setError(QAbstractSocket::NetworkError, RemoteHostClosedErrorString); + socketState = QAbstractSocket::UnconnectedState; if (notifyOnRead) emit q->readReady(); return S_OK; -- cgit v1.2.3 From d159fe199fd50845fd20b00da0962c060479fe4c Mon Sep 17 00:00:00 2001 From: Topi Reinio Date: Tue, 13 Oct 2015 12:20:37 +0200 Subject: Doc: Update examplesinstallpath to include the repository name The examplesinstallpath variable in .qdocconf files defines the path under QT_INSTALL_EXAMPLES where examples are found. To match the way examples are packaged in Qt 5.6, prefix each install path with the repository name. Task-number: QTBUG-48736 Change-Id: I6a35c94fdacaad21cd044411aba02027b9019300 Reviewed-by: Venugopal Shivashankar --- src/network/doc/qtnetwork.qdocconf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/network') diff --git a/src/network/doc/qtnetwork.qdocconf b/src/network/doc/qtnetwork.qdocconf index 2a8e577dda..87e322d6c0 100644 --- a/src/network/doc/qtnetwork.qdocconf +++ b/src/network/doc/qtnetwork.qdocconf @@ -4,7 +4,7 @@ project = QtNetwork description = Qt Network Reference Documentation version = $QT_VERSION -examplesinstallpath = network +examplesinstallpath = qtbase/network qhp.projects = QtNetwork -- cgit v1.2.3 From e1d4c16aef954fe75fdfaf3156e78c3d62d9febd Mon Sep 17 00:00:00 2001 From: Alex Trotsenko Date: Wed, 21 Oct 2015 19:52:05 +0300 Subject: QNativeSocketEngine: allocate more space for the ancillary data As a corner case on BSD systems, we use IP_RECVIF control message to retrieve an interface index of the received datagram. Take care about sockaddr_dl structure, while calculating a size of the ancillary data buffer. Change-Id: I1c113d390a4929489c4c5858847b6262f1baa204 Reviewed-by: Thiago Macieira --- src/network/socket/qnativesocketengine_unix.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'src/network') diff --git a/src/network/socket/qnativesocketengine_unix.cpp b/src/network/socket/qnativesocketengine_unix.cpp index c40eef769e..f1845f31f3 100644 --- a/src/network/socket/qnativesocketengine_unix.cpp +++ b/src/network/socket/qnativesocketengine_unix.cpp @@ -828,7 +828,11 @@ qint64 QNativeSocketEnginePrivate::nativeReceiveDatagram(char *data, qint64 maxS QAbstractSocketEngine::PacketHeaderOptions options) { // we use quintptr to force the alignment - quintptr cbuf[(CMSG_SPACE(sizeof(struct in6_pktinfo)) + CMSG_SPACE(sizeof(int)) + sizeof(quintptr) - 1) / sizeof(quintptr)]; + quintptr cbuf[(CMSG_SPACE(sizeof(struct in6_pktinfo)) + CMSG_SPACE(sizeof(int)) +#if !defined(IP_PKTINFO) && defined(IP_RECVIF) && defined(Q_OS_BSD4) + + CMSG_SPACE(sizeof(sockaddr_dl)) +#endif + + sizeof(quintptr) - 1) / sizeof(quintptr)]; struct msghdr msg; struct iovec vec; -- cgit v1.2.3