QtNetwork: Better detection of connection failures on Windows
If the error code from WSAConnect is WSAEWOULDBLOCK, then the operation proceeds but the outcome is not known at that time. We then check SO_ERROR's value to detect errors. But if that call returns 0 this could indicate that the value is still not know. In this case we try one more time to increase the chance of getting the correct value. This fixed the tst_QNetworkReply::getFromUnreachableIp auto test on Windows. Change-Id: I25008aca062b2f823e3d93ebb0ae456d7e4a6ecc Reviewed-by: Shane Kearns <shane.kearns@accenture.com>
This commit is contained in:
parent
ada38c75cc
commit
4d38a3b2da
@ -683,28 +683,48 @@ bool QNativeSocketEnginePrivate::nativeConnect(const QHostAddress &address, quin
|
||||
// unfinished operation.
|
||||
int value = 0;
|
||||
QT_SOCKLEN_T valueSize = sizeof(value);
|
||||
if (::getsockopt(socketDescriptor, SOL_SOCKET, SO_ERROR, (char *) &value, &valueSize) == 0) {
|
||||
if (value == WSAECONNREFUSED) {
|
||||
setError(QAbstractSocket::ConnectionRefusedError, ConnectionRefusedErrorString);
|
||||
socketState = QAbstractSocket::UnconnectedState;
|
||||
break;
|
||||
bool tryAgain = false;
|
||||
bool errorDetected = false;
|
||||
int tries = 0;
|
||||
do {
|
||||
if (::getsockopt(socketDescriptor, SOL_SOCKET, SO_ERROR, (char *) &value, &valueSize) == 0) {
|
||||
if (value == WSAECONNREFUSED) {
|
||||
setError(QAbstractSocket::ConnectionRefusedError, ConnectionRefusedErrorString);
|
||||
socketState = QAbstractSocket::UnconnectedState;
|
||||
errorDetected = true;
|
||||
break;
|
||||
}
|
||||
if (value == WSAETIMEDOUT) {
|
||||
setError(QAbstractSocket::NetworkError, ConnectionTimeOutErrorString);
|
||||
socketState = QAbstractSocket::UnconnectedState;
|
||||
errorDetected = true;
|
||||
break;
|
||||
}
|
||||
if (value == WSAEHOSTUNREACH) {
|
||||
setError(QAbstractSocket::NetworkError, HostUnreachableErrorString);
|
||||
socketState = QAbstractSocket::UnconnectedState;
|
||||
errorDetected = true;
|
||||
break;
|
||||
}
|
||||
if (value == WSAEADDRNOTAVAIL) {
|
||||
setError(QAbstractSocket::NetworkError, AddressNotAvailableErrorString);
|
||||
socketState = QAbstractSocket::UnconnectedState;
|
||||
errorDetected = true;
|
||||
break;
|
||||
}
|
||||
if (value == NOERROR) {
|
||||
// When we get WSAEWOULDBLOCK the outcome was not known, so a
|
||||
// NOERROR might indicate that the result of the operation
|
||||
// is still unknown. We try again to increase the chance that we did
|
||||
// get the correct result.
|
||||
tryAgain = !tryAgain;
|
||||
}
|
||||
}
|
||||
if (value == WSAETIMEDOUT) {
|
||||
setError(QAbstractSocket::NetworkError, ConnectionTimeOutErrorString);
|
||||
socketState = QAbstractSocket::UnconnectedState;
|
||||
break;
|
||||
}
|
||||
if (value == WSAEHOSTUNREACH) {
|
||||
setError(QAbstractSocket::NetworkError, HostUnreachableErrorString);
|
||||
socketState = QAbstractSocket::UnconnectedState;
|
||||
break;
|
||||
}
|
||||
if (value == WSAEADDRNOTAVAIL) {
|
||||
setError(QAbstractSocket::NetworkError, AddressNotAvailableErrorString);
|
||||
socketState = QAbstractSocket::UnconnectedState;
|
||||
break;
|
||||
}
|
||||
}
|
||||
tries++;
|
||||
} while (tryAgain && (tries < 2));
|
||||
|
||||
if (errorDetected)
|
||||
break;
|
||||
// fall through
|
||||
}
|
||||
case WSAEINPROGRESS:
|
||||
|
Loading…
Reference in New Issue
Block a user