Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 28 Feb 2002 13:21:42 -0800 (PST)
From:      rfg@monkeys.com
To:        FreeBSD-gnats-submit@freebsd.org
Subject:   kern/35429: select(2)/poll(2)/kevent(2) can't/don't notice lost connections
Message-ID:  <20020228212142.1E168660C@segfault.monkeys.com>

next in thread | raw e-mail | index | archive | help


>Number:         35429
>Category:       kern
>Synopsis:       select(2)/poll(2)/kevent(2) can't/don't notice lost connections
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          change-request
>Submitter-Id:   current-users
>Arrival-Date:   Thu Feb 28 13:30:00 PST 2002
>Closed-Date:
>Last-Modified:
>Originator:     Ronald F. Guilmette
>Release:        FreeBSD 4.3-RELEASE i386
>Organization:
Infinite Monkeys & Co.
>Environment:

FreeBSD 4.3-RELEASE #0

>Description:

Certain server processes that accept input from multiple TCP stream sockets
(but which do not customarily write to those sockets) and which use the
select(2), poll(2), or kevent(2) kernel calls to monitor the state of their
own ends of these stream sockets may find it desirable to optimize usage
of both socket descriptors and file descriptors (either of which may be in
short supply) by closing sockets / file descriptors as soon as possible
when and if the connections associated with those sockets have been lost
or broken.

In cases where connections are broken, voluntarily, by the relevant peers
performing normal socket close operations, the select(2), poll(2), and
kevent(2) kernel functions can and do signal these events back to user-
level processes immediately.  However in cases where connections to peers
are simply lost (e.g. due to network lossage or unexpected power failures
on the peers) there currently appears to be no mechanism whereby user-level
processes (in particular server processes that do not customarily write to
their client peers) may be made aware of these connection losses, either
in near-real-time (which would be optimal) or at all.

Intutively, the SO_KEEPALIVE option for sockets would seem to provide at
least a low-level mechanism via which the kernel can become aware of the
sudden loss of any socket connection for which this option has been set.
However the man page for setsockopt(2) says:

     SO_KEEPALIVE enables
     the periodic transmission of messages on a connected socket.  Should the
     connected party fail to respond to these messages, the connection is con-
     sidered broken and processes using the socket are notified via a SIGPIPE
     signal when attempting to send data.

It is clear from this description of the semantics of SO_KEEPALIVE that
unless and until an attempt is made, by the user-level process, to write
to a socket for which the connection has been lost (and for which the
SO_KEEPALIVE option has been set) the user-level process will not be made
aware... either in near-real-time, or at all...  that a given socket
connection which it has opened has lost its connection to the relevant
peer, even if the kernel already has that information.  This is clearly
unfortunate, given that a user-level process which is attempting to
optimize its use of socket descriptors and/or file descriptors could
clearly benefit from being informed, by the kernel, of cases of dropped
socket connections, ideally in near-real-time, and without the need to
attempt a write to each socket for which this information is desired.
(Note that certain protocols may even prohibit the server process from
performing any writes to its ends of the socket connections.)

It would seem to make a great deal of sense to alter the current behavior
of the select(2), poll(2), and kevent(2) kernel calls in cases involving
sockets for which the SO_KEEPALIVE option has been set and for which the
kernel's keepalive mechanism has already determined that the socket con-
nection has indeed been lost.  Such cases could be, and should be treated
as being functionally equivalent to the remote peer having performed a
normal close of its end of the socket connection... at least with respect
to the select(2), poll(2), and kevent(2) kernel calls.

Note:  Concerns about the effects on backward compatability of this change
could be avoided by defining a new socket option code and associated symbol
to be used where either the new behavior or, alternatively, the old behavior
is desired.  For example, a symbol like `SO_KEEPALIVE_ORIG' might be created
for use when the original behavior is desired.  Alternatively, a new symbol
(e.g. `SO_KEEPWATCH') and an associated new socket option code could be
defined and used when the new and more useful behavior is desired.


>How-To-Repeat:

This is an enhancement request.  There is nothing to repeat.

>Fix:

See above.  This is an enhancement request.
>Release-Note:
>Audit-Trail:
>Unformatted:

To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-bugs" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20020228212142.1E168660C>