diff options
author | pst <pst@FreeBSD.org> | 1996-09-20 21:25:18 +0000 |
---|---|---|
committer | pst <pst@FreeBSD.org> | 1996-09-20 21:25:18 +0000 |
commit | dd5375bf7c0c606b2a6c6e73255d88eb6e1edfd6 (patch) | |
tree | 11f85b992773b9cda81b9ca3502b35400e3e4a5f /sys/netinet | |
parent | 6b0658e42a8a02e0a434e3dcf148253d1087ff57 (diff) | |
download | FreeBSD-src-dd5375bf7c0c606b2a6c6e73255d88eb6e1edfd6.zip FreeBSD-src-dd5375bf7c0c606b2a6c6e73255d88eb6e1edfd6.tar.gz |
If the incomplete listen queue for a given socket is full,
drop the oldest entry in the queue.
There was a fair bit of discussion as to whether or not the
proper action is to drop a random entry in the queue. It's
my conclusion that a random drop is better than a head drop,
however profiling this section of code (done by John Capo)
shows that a head-drop results in a significant performance
increase.
There are scenarios where a random drop is more appropriate.
If I find one in reality, I'll add the random drop code under
a conditional.
Obtained from: discussions and code done by Vernon Schryver (vjs@sgi.com).
Diffstat (limited to 'sys/netinet')
-rw-r--r-- | sys/netinet/tcp_input.c | 23 | ||||
-rw-r--r-- | sys/netinet/tcp_reass.c | 23 |
2 files changed, 36 insertions, 10 deletions
diff --git a/sys/netinet/tcp_input.c b/sys/netinet/tcp_input.c index 75a33e6..d861efe 100644 --- a/sys/netinet/tcp_input.c +++ b/sys/netinet/tcp_input.c @@ -31,7 +31,7 @@ * SUCH DAMAGE. * * @(#)tcp_input.c 8.12 (Berkeley) 5/24/95 - * $Id: tcp_input.c,v 1.47 1996/09/13 18:47:03 pst Exp $ + * $Id: tcp_input.c,v 1.48 1996/09/13 23:51:41 pst Exp $ */ #ifndef TUBA_INCLUDE @@ -410,11 +410,24 @@ findpcb: #endif if (so->so_options & SO_ACCEPTCONN) { register struct tcpcb *tp0 = tp; - so = sonewconn(so, 0); - if (so == 0) { - tcpstat.tcps_listendrop++; - goto drop; + struct socket *so2; + /* + * If the attempt to get onto the socket queue failed, + * drop the oldest queue entry and try again. + */ + so2 = sonewconn(so, 0); + if (!so2) { + so2 = TAILQ_FIRST(&so->so_incom); + if (so2) { + tcp_drop(sototcpcb(so2), ETIMEDOUT); + so2 = sonewconn(so, 0); + } + if (!so2) { + tcpstat.tcps_listendrop++; + goto drop; + } } + so = so2; /* * This is ugly, but .... * diff --git a/sys/netinet/tcp_reass.c b/sys/netinet/tcp_reass.c index 75a33e6..d861efe 100644 --- a/sys/netinet/tcp_reass.c +++ b/sys/netinet/tcp_reass.c @@ -31,7 +31,7 @@ * SUCH DAMAGE. * * @(#)tcp_input.c 8.12 (Berkeley) 5/24/95 - * $Id: tcp_input.c,v 1.47 1996/09/13 18:47:03 pst Exp $ + * $Id: tcp_input.c,v 1.48 1996/09/13 23:51:41 pst Exp $ */ #ifndef TUBA_INCLUDE @@ -410,11 +410,24 @@ findpcb: #endif if (so->so_options & SO_ACCEPTCONN) { register struct tcpcb *tp0 = tp; - so = sonewconn(so, 0); - if (so == 0) { - tcpstat.tcps_listendrop++; - goto drop; + struct socket *so2; + /* + * If the attempt to get onto the socket queue failed, + * drop the oldest queue entry and try again. + */ + so2 = sonewconn(so, 0); + if (!so2) { + so2 = TAILQ_FIRST(&so->so_incom); + if (so2) { + tcp_drop(sototcpcb(so2), ETIMEDOUT); + so2 = sonewconn(so, 0); + } + if (!so2) { + tcpstat.tcps_listendrop++; + goto drop; + } } + so = so2; /* * This is ugly, but .... * |