You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@apr.apache.org by Mladen Turk <mt...@apache.org> on 2006/08/02 13:42:52 UTC

How to detect is the socket is still open

Hi,

We have a problem with mod_proxy and
the way how we detect if the connection is
still opened.

Right now, the algorithm for that is as follows:
1. Remember socket timeout
2. Set timeout to 0
3. Try to read one byte
4. Restore timeout
6. If read is APR_STATUS_IS_EOF return False
5. Else return True

Now, this works most of the time on unixes,
but it fails for windows if connection goes
to the localhost.

We have that resolved for mod_jk by using
select on windows and nonblocking read on
other platforms.
See:
jk_connect.c inside jk/native/common

My question is, if someone is aware of the
smarter mechanism for checking the socket
connection, and if we could add the function
for that inside APR.


Regards,
Mladen.

Re: How to detect is the socket is still open

Posted by Gonzalo Paniagua Javier <go...@gmail.com>.
On 8/2/06, Mladen Turk <mt...@apache.org> wrote:
> Hi,
>
> We have a problem with mod_proxy and
> the way how we detect if the connection is
> still opened.
>
> Right now, the algorithm for that is as follows:
> 1. Remember socket timeout
> 2. Set timeout to 0
> 3. Try to read one byte
> 4. Restore timeout
> 6. If read is APR_STATUS_IS_EOF return False
> 5. Else return True
>
> Now, this works most of the time on unixes,
> but it fails for windows if connection goes
> to the localhost.
>
> We have that resolved for mod_jk by using
> select on windows and nonblocking read on
> other platforms.
> See:
> jk_connect.c inside jk/native/common

May be I'm pointing out something that you already know but...:

   -select/poll on the socket.
   -if the socket is readable AND after
       (windows) result = ioctlsocket (handle, FIONREAD, &nbytes);
       (unix) result = ioctl (sock_fd, FIONREAD, &nbytes);

   nbytes is 0, that means that the connection has been closed on the other end.

-Gonzalo

Re: How to detect is the socket is still open

Posted by "William A. Rowe, Jr." <wr...@rowe-clan.net>.
Mladen Turk wrote:
> The point is that read with 0 timeout can return data,
> and that breaks any attempt to check the status of the socket
> without duplicating code for each protocol (http, ajp, ftp, etc...).

-1 because that tweaks the socket stack's behavior.  Don't pull anything
off the socket until we are ready to process it.  Certainly not as a 'poll'
for disconnection.

> Now, this works most of the time on unixes, but it fails for windows
> if connection goes to the localhost.

Trying to work around winsock loopback drivers is an exercise in futility,
and certainly not worth changing any standardized socket behavior.

MS's loopback driver authors clearly don't know what they are doing, just
review the MSKB problem tickets if you doubt this.

Bill

Re: How to detect is the socket is still open

Posted by Mladen Turk <mt...@apache.org>.
Joe Orton wrote:
 > On Wed, Aug 02, 2006 at 01:42:52PM +0200, Mladen Turk wrote:
 >> We have a problem with mod_proxy and the way how we detect if the
 >> connection is still opened.
 >
 > Polling the socket is all you can do, but all that tells you is whether
 > the local end of the TCP socket has already received a FIN/RST.
 >

Right. I'm aware of that, and all the problems. However it really
works only on windows.
The solution I had in my mind was to add a small
(1 byte should be enough) read-ahead buffer to the
socket. This way the next read would first use that buffer if
filled by apr_socket_is_connected call.
The point is that read with 0 timeout can return data,
and that breaks any attempt to check the status of the socket
without duplicating code for each protocol (http, ajp, ftp, etc...).

Regards,
Mladen.


Re: How to detect is the socket is still open

Posted by Joe Orton <jo...@redhat.com>.
On Wed, Aug 02, 2006 at 01:42:52PM +0200, Mladen Turk wrote:
> We have a problem with mod_proxy and the way how we detect if the 
> connection is still opened.

Polling the socket is all you can do, but all that tells you is whether 
the local end of the TCP socket has already received a FIN/RST.

If you are in a situation where the connection can be closed 
asynchronously (as with HTTP) it is ultimately pointless to attempt 
this.  There will always be a race between when you check the socket and 
when you use it in which time the server may close the connection; so 
you need to be able to cope with that anyway.

(if you are indeed talking about HTTP then see the discussion around the 
r378032 commit on dev@httpd)

joe