libwww on WinNT and connection refused

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