Details
-
Bug
-
Resolution: Out of scope
-
P3: Somewhat important
-
4.4.0
-
None
Description
Because of the wrong use of winsock2 function "WSASocket()" inside the Qt network library, Qt applications using QHttp become unstable after HTTP/HTTPS communication.
The details:
1. Application becomes unresponsive while CPU usage climbs to 100% after starting the HTTP communication.
2. Application crashes from memory access violations or exceptions.
The code in the following source files causes this problem.
$QTDIR/src/network/qnativesocketengine_win.cpp (in Qt 4.3.4)
$QTDIR/src/network/socket/qnativesocketengine_win.cpp (in Qt 4.4.0)
bool QNativeSocketEnginePrivate::createNewSocket(QAbstractSocket::SocketType socketType,
QAbstractSocket::NetworkLayerProtocol socketProtocol)
0 is passed as the third argument of the function "WSASocket()" in the above function.
SOCKET socket = ::WSASocket(protocol, type, 0, NULL, 0, WSA_FLAG_OVERLAPPED);
In MSDN, it is stated that if a value of 0 is specified, the caller does not wish to specify a protocol and the service provider will choose the protocol to use.
If any non-IFS layered service provider installed on WinNT/Win2k/WinXP, in this case WSASocket() call selects the non-IFS LSP because Service Provider is not specified. However, it's not possible to use overlapped IO unless service provider is IFS-compatible.
As a result, application hangs.
It is possible to get sample LSP from MS Platform SDK and the details of WSASocket() are available from the following MSDN.
http://msdn.microsoft.com/en-us/library/ms742212(VS.85).aspx
A similar case has been found in ActivePerl. This bug(id 24269) is found in v5.8.1 and fixed in v5.8.6.
- 24269 socket() call uses non-IFS providers causing subsequent print/read to hang or misbehave
http://www.nntp.perl.org/group/perl.perl5.porters/2003/12/msg86717.html
http://rt.perl.org/rt3/Public/Bug/Display.html?id=24269
The following function is added to fix this problem in ActivePerl.
-------------------------------------------------------------------------------------------------
SOCKET
open_ifs_socket(int af, int type, int protocol)
{
unsigned long proto_buffers_len = 0;
int error_code;
SOCKET out = INVALID_SOCKET;
if (WSCEnumProtocols(NULL, NULL, &proto_buffers_len, &error_code) == SOCKET_ERROR &&
error_code == WSAENOBUFS) {
WSAPROTOCOL_INFOW *proto_buffers = (WSAPROTOCOL_INFOW *) malloc(proto_buffers_len);
int protocols_available = 0;
if ((protocols_available = WSCEnumProtocols(NULL, proto_buffers,
&proto_buffers_len, &error_code)) != SOCKET_ERROR) {
int i;
for (i = 0; i < protocols_available; i++)
}
if (proto_buffers)
free(proto_buffers);
}
return out;
}
--------------------------------------------------------------------------------------------------
"QNativeSocketEnginePrivate::createNewSocket()" should be fixed in a similar way