- From: Hans Maurer <maurer@amasol.de>
- Date: Mon, 05 Nov 2001 00:31:02 +0100
- To: www-lib@w3.org
Hi, I'm using libwww in a software project on Solaris, HP-UX and Windows NT. I'm came across a problem on Windows NT (4.0 with SP6a right now) with WWW_WIN_AYSNC mode, when a host refuses the connection on a given port. I using a simple HTLoadToChunk to load some data from a web site into memory. If the web server on the other side isn't running, the connection is refused by the OS. Unfortunately, my client goes into an endless loop then. The reason can be found in HTDoConnect() (HTTCP.c) and AsyncWindowProc() (HTEvtLst.c). Within it's TCP_NEED_CONNECT case, HTDoConnect calls connect(). On Windows NT, this call returns with SOCKET_ERROR and sets LastError to WSAEWOULDBLOCK, which causes HTDoConnect to return, and my clients returns to the event loop. When Winsock receives the "connection refused" from the destination host, it creates an FD_CONNECT event, that includes an WSAECONNREFUSED error code in its lParam parameter. Unfortunately, AsyncWindowProc ignores the error portion of lParam, but assumes, that the operation was successful. After several callbacks, HTDoConnect is called again. The host's tcpstate is still TCP_NEED_CONNECT, so HTDoConnect tries a connect again. Since the last connect attempt failed, the socket is not bound/locked/whatever, so this looks like a fresh connect attempt to Winsock. It returns WSAEWOULDBLOCK again and the circle starts again. Instead, AsyncWindowProc must retrieve the error code - which can be retrieved with WSAGETSELECTERROR(lParam), WSAGetLastError doesn't work here. This information must be passed to HTDoConnect (through those several callbacks). HTDoConnect then must not try a new connect, but filter the error code through the rest of its TCP_NEED_CONNECT case to figure out the appropriate action. In case of WSAECONNREFUSED, this would result in a state change to TCP_ERROR. For my own project, I've patched libwww to WSASetLastError lParam's error code - including a private flag - in AsyncWindowProc, trigger on that flag in HTDoConnect, skip the connect portition and go directly to the error handling routines in TCP_NEED_CONNECT. IMHO, that's to big a hack to publish, so somebody (else) should implement a clean solution. :-} One other problem, that I found: In the TCP_ERROR case of HTDoConnect, the error message is created (with HTRequest_addSystemError) after the socket has been closed (with NETCLOSE). Unfortunately, closesocket resets LastError, so the error message shows 0 as error code (instead of e.g. 10061 for WSAECONNREFUSED). Thanks a lot for libwww! Hans -- Hans Maurer EMail: maurer@amasol.de amasol AG, Gotthardstraße 42, 80689 München, Germany Phone: ++49 89 58 93 903-13 Fax: ++49 89 58 93 903-01
Received on Sunday, 4 November 2001 19:05:37 UTC