Vulnerability Development mailing list archives

Re: FreeBSD listen()


From: tkennedy () CYBERPORT COM (Warren Young)
Date: Thu, 28 Oct 1999 17:42:27 -0600


At 04:50 PM 10/27/99 +0400, you wrote:

But:   for  FreeBSD  2.2.* backlog parameter seems doesn't working. At
least, if I use
listen(sock, 1)
and  trying to connect() from 3 different connections all 3 connect()s
succeed  atleast  in  FreeBSD  up  to  2.2.6  (later  versions are not
tested).

Setting the backlog parameter to 1 doesn't limit the number of possible
simultaneous connections to 1, it limits the number of possible
simultaneous connection _attempts_ to 1.

Understanding what that means requires knowing how a TCP connection is
established.  My apologies if you already understand this.

In the header for a TCP packet, there are two flags, called SYN and ACK.
To start a connection attempt, the client sends an empty TCP packet with
the SYN flag set.  If a server is listening on the requested port _and_
there are places left in the connection backlog queue for that port, the
server machine sends back a similar packet with both the SYN and ACK bits
set.  When the client receives that packet, it replies with an ACK packet.
When the server receives it, the connection is marked as established, and
the connection attempt is removed from the connection backlog.

What this means in your case is that while one connection is being
established, no other connections will be allowed: they'll be rejected as
the documentation states.  But, once that connection is established,
another client can try to connect.  If you don't call accept() on that
connection, however, the client will eventually time out.

If that behavior is not acceptable for your application, you'll have to
close the listening socket whenever you have a connected client, so that
all connection attempts will be rejected.  The main problem with this
method is that some network stacks won't let you recreate that listening
socket for 30-120 seconds, because the stack goes into the TIME_WAIT state
on that port, as RFC 1122 says it must.  (The length of the TIME_WAIT state
depends on the stack and on the network type.  Experimentation is the
simplest way of finding the exact value on your setup.)

Another method you might prefer is to have your program _always_ accept
incoming connections.  Then if you already have one other connection, slam
the new connection shut.  The simplest way to do that is to call
setsockopt() to set the SO_LINGER option to 0.  Then call close() on the
accepted socket.  The remote end will receive the ECONNRESET error, which
programs should treat as roughly equivalent to ECONNREFUSED.

Good luck,

= Warren Young, maintainer of the Winsock Programmer's FAQ at:
=     http://www.cyberport.com/~tangent/programming/winsock/
=
= ICBM Address: 36.8274040 N, 108.0204086 W, alt. 1714m


Current thread: