summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
Diffstat (limited to 'sys')
-rw-r--r--sys/kern/uipc_sockbuf.c52
-rw-r--r--sys/kern/uipc_socket.c3
-rw-r--r--sys/kern/uipc_socket2.c52
-rw-r--r--sys/netinet/tcp_input.c36
-rw-r--r--sys/netinet/tcp_reass.c36
-rw-r--r--sys/sys/socketvar.h6
-rw-r--r--sys/sys/sysctl.h6
7 files changed, 147 insertions, 44 deletions
diff --git a/sys/kern/uipc_sockbuf.c b/sys/kern/uipc_sockbuf.c
index 0590034..59c8ff1 100644
--- a/sys/kern/uipc_sockbuf.c
+++ b/sys/kern/uipc_sockbuf.c
@@ -31,7 +31,7 @@
* SUCH DAMAGE.
*
* @(#)uipc_socket2.c 8.1 (Berkeley) 6/10/93
- * $Id: uipc_socket2.c,v 1.13 1996/08/19 19:22:26 julian Exp $
+ * $Id: uipc_socket2.c,v 1.14 1996/09/19 00:54:36 pst Exp $
*/
#include <sys/param.h>
@@ -60,9 +60,6 @@ static u_long sb_efficiency = 8; /* parameter for sbreserve() */
SYSCTL_INT(_kern, OID_AUTO, sockbuf_waste_factor, CTLFLAG_RW, &sb_efficiency,
0, "");
-static int sominqueue = 0;
-SYSCTL_INT(_kern, KERN_SOMINQUEUE, sominqueue, CTLFLAG_RW, &sominqueue, 0, "");
-
/*
* Procedures to manipulate state flags of socket
* and do appropriate wakeups. Normal sequence from the
@@ -113,6 +110,7 @@ soisconnected(so)
if (head && (so->so_state & SS_INCOMP)) {
TAILQ_REMOVE(&head->so_incomp, so, so_list);
so->so_state &= ~SS_INCOMP;
+ so->so_incqlen--;
TAILQ_INSERT_TAIL(&head->so_comp, so, so_list);
so->so_state |= SS_COMP;
sorwakeup(head);
@@ -149,6 +147,47 @@ soisdisconnected(so)
}
/*
+ * Return a random connection that hasn't been serviced yet and
+ * is eligible for discard.
+ *
+ * This may be used in conjunction with protocol specific queue
+ * congestion routines.
+ */
+struct socket *
+sodropablereq(head)
+ register struct socket *head;
+{
+ register struct socket *so;
+ unsigned int i, j, qlen;
+
+ static int rnd;
+ static long old_mono_secs;
+ static unsigned int cur_cnt, old_cnt;
+
+ so = TAILQ_FIRST(&head->so_incomp);
+ if (!so)
+ return (so);
+
+ qlen = head->so_incqlen;
+
+ if ((i = (mono_time.tv_sec - old_mono_secs)) != 0) {
+ old_mono_secs = mono_time.tv_sec;
+ old_cnt = cur_cnt / i;
+ cur_cnt = 0;
+ }
+
+ if (++cur_cnt > qlen || old_cnt > qlen) {
+ rnd = (314159 * rnd + 66329) & 0xffff;
+ j = ((qlen + 1) * rnd) >> 16;
+
+ while (j-- && so)
+ so = TAILQ_NEXT(so, so_list);
+ }
+
+ return (so);
+}
+
+/*
* When an attempt at a new connection is noted on a socket
* which accepts connections, sonewconn is called. If the
* connection is possible (subject to space constraints, etc.)
@@ -166,8 +205,7 @@ sonewconn1(head, connstatus)
{
register struct socket *so;
- if ((head->so_qlen > 3 * head->so_qlimit / 2) &&
- (head->so_qlen > sominqueue))
+ if (head->so_qlen > 3 * head->so_qlimit / 2)
return ((struct socket *)0);
MALLOC(so, struct socket *, sizeof(*so), M_SOCKET, M_DONTWAIT);
if (so == NULL)
@@ -188,6 +226,7 @@ sonewconn1(head, connstatus)
} else {
TAILQ_INSERT_TAIL(&head->so_incomp, so, so_list);
so->so_state |= SS_INCOMP;
+ head->so_incqlen++;
}
head->so_qlen++;
if ((*so->so_proto->pr_usrreqs->pru_attach)(so, 0)) {
@@ -195,6 +234,7 @@ sonewconn1(head, connstatus)
TAILQ_REMOVE(&head->so_comp, so, so_list);
} else {
TAILQ_REMOVE(&head->so_incomp, so, so_list);
+ head->so_incqlen--;
}
head->so_qlen--;
(void) free((caddr_t)so, M_SOCKET);
diff --git a/sys/kern/uipc_socket.c b/sys/kern/uipc_socket.c
index 462191f..da9e331 100644
--- a/sys/kern/uipc_socket.c
+++ b/sys/kern/uipc_socket.c
@@ -31,7 +31,7 @@
* SUCH DAMAGE.
*
* @(#)uipc_socket.c 8.3 (Berkeley) 4/15/94
- * $Id: uipc_socket.c,v 1.18 1996/05/09 20:14:57 wollman Exp $
+ * $Id: uipc_socket.c,v 1.19 1996/07/11 16:31:56 wollman Exp $
*/
#include <sys/param.h>
@@ -144,6 +144,7 @@ sofree(so)
if (head != NULL) {
if (so->so_state & SS_INCOMP) {
TAILQ_REMOVE(&head->so_incomp, so, so_list);
+ head->so_incqlen--;
} else if (so->so_state & SS_COMP) {
TAILQ_REMOVE(&head->so_comp, so, so_list);
} else {
diff --git a/sys/kern/uipc_socket2.c b/sys/kern/uipc_socket2.c
index 0590034..59c8ff1 100644
--- a/sys/kern/uipc_socket2.c
+++ b/sys/kern/uipc_socket2.c
@@ -31,7 +31,7 @@
* SUCH DAMAGE.
*
* @(#)uipc_socket2.c 8.1 (Berkeley) 6/10/93
- * $Id: uipc_socket2.c,v 1.13 1996/08/19 19:22:26 julian Exp $
+ * $Id: uipc_socket2.c,v 1.14 1996/09/19 00:54:36 pst Exp $
*/
#include <sys/param.h>
@@ -60,9 +60,6 @@ static u_long sb_efficiency = 8; /* parameter for sbreserve() */
SYSCTL_INT(_kern, OID_AUTO, sockbuf_waste_factor, CTLFLAG_RW, &sb_efficiency,
0, "");
-static int sominqueue = 0;
-SYSCTL_INT(_kern, KERN_SOMINQUEUE, sominqueue, CTLFLAG_RW, &sominqueue, 0, "");
-
/*
* Procedures to manipulate state flags of socket
* and do appropriate wakeups. Normal sequence from the
@@ -113,6 +110,7 @@ soisconnected(so)
if (head && (so->so_state & SS_INCOMP)) {
TAILQ_REMOVE(&head->so_incomp, so, so_list);
so->so_state &= ~SS_INCOMP;
+ so->so_incqlen--;
TAILQ_INSERT_TAIL(&head->so_comp, so, so_list);
so->so_state |= SS_COMP;
sorwakeup(head);
@@ -149,6 +147,47 @@ soisdisconnected(so)
}
/*
+ * Return a random connection that hasn't been serviced yet and
+ * is eligible for discard.
+ *
+ * This may be used in conjunction with protocol specific queue
+ * congestion routines.
+ */
+struct socket *
+sodropablereq(head)
+ register struct socket *head;
+{
+ register struct socket *so;
+ unsigned int i, j, qlen;
+
+ static int rnd;
+ static long old_mono_secs;
+ static unsigned int cur_cnt, old_cnt;
+
+ so = TAILQ_FIRST(&head->so_incomp);
+ if (!so)
+ return (so);
+
+ qlen = head->so_incqlen;
+
+ if ((i = (mono_time.tv_sec - old_mono_secs)) != 0) {
+ old_mono_secs = mono_time.tv_sec;
+ old_cnt = cur_cnt / i;
+ cur_cnt = 0;
+ }
+
+ if (++cur_cnt > qlen || old_cnt > qlen) {
+ rnd = (314159 * rnd + 66329) & 0xffff;
+ j = ((qlen + 1) * rnd) >> 16;
+
+ while (j-- && so)
+ so = TAILQ_NEXT(so, so_list);
+ }
+
+ return (so);
+}
+
+/*
* When an attempt at a new connection is noted on a socket
* which accepts connections, sonewconn is called. If the
* connection is possible (subject to space constraints, etc.)
@@ -166,8 +205,7 @@ sonewconn1(head, connstatus)
{
register struct socket *so;
- if ((head->so_qlen > 3 * head->so_qlimit / 2) &&
- (head->so_qlen > sominqueue))
+ if (head->so_qlen > 3 * head->so_qlimit / 2)
return ((struct socket *)0);
MALLOC(so, struct socket *, sizeof(*so), M_SOCKET, M_DONTWAIT);
if (so == NULL)
@@ -188,6 +226,7 @@ sonewconn1(head, connstatus)
} else {
TAILQ_INSERT_TAIL(&head->so_incomp, so, so_list);
so->so_state |= SS_INCOMP;
+ head->so_incqlen++;
}
head->so_qlen++;
if ((*so->so_proto->pr_usrreqs->pru_attach)(so, 0)) {
@@ -195,6 +234,7 @@ sonewconn1(head, connstatus)
TAILQ_REMOVE(&head->so_comp, so, so_list);
} else {
TAILQ_REMOVE(&head->so_incomp, so, so_list);
+ head->so_incqlen--;
}
head->so_qlen--;
(void) free((caddr_t)so, M_SOCKET);
diff --git a/sys/netinet/tcp_input.c b/sys/netinet/tcp_input.c
index 35a3ba5..a31fe9f 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.50 1996/09/21 06:30:06 ache Exp $
+ * $Id: tcp_input.c,v 1.51 1996/09/21 06:39:20 pst Exp $
*/
#ifndef TUBA_INCLUDE
@@ -411,20 +411,25 @@ findpcb:
if (so->so_options & SO_ACCEPTCONN) {
register struct tcpcb *tp0 = tp;
struct socket *so2;
- /*
- * If the attempt to get onto the socket queue failed,
- * drop the oldest queue entry and try again.
- */
+ if ((tiflags & (TH_RST|TH_ACK|TH_SYN)) != TH_SYN) {
+ /*
+ * Note: dropwithreset makes sure we don't
+ * send a RST in response to a RST.
+ */
+ if (tiflags & TH_ACK) {
+ tcpstat.tcps_badsyn++;
+ goto dropwithreset;
+ }
+ goto drop;
+ }
so2 = sonewconn(so, 0);
- if (!so2) {
+ if (so2 == 0) {
tcpstat.tcps_listendrop++;
- so2 = TAILQ_FIRST(&so->so_incomp);
- if (so2) {
- tcp_drop(sototcpcb(so2), ETIMEDOUT);
- so2 = sonewconn(so, 0);
- }
- if (!so2)
- goto drop;
+ so2 = sodropablereq(so);
+ if (so2)
+ tcp_drop(sototcpcb(so2), ETIMEDOUT);
+ else
+ goto drop;
}
so = so2;
/*
@@ -753,6 +758,8 @@ findpcb:
}
/*
+ * If the state is SYN_RECEIVED:
+ * do just the ack and RST checks from SYN_SENT state.
* If the state is SYN_SENT:
* if seg contains an ACK, but not for our SYN, drop the input.
* if seg contains a RST, then drop the connection.
@@ -764,6 +771,7 @@ findpcb:
* arrange for segment to be acked (eventually)
* continue processing rest of data/controls, beginning with URG
*/
+ case TCPS_SYN_RECEIVED:
case TCPS_SYN_SENT:
if ((taop = tcp_gettaocache(inp)) == NULL) {
taop = &tao_noncached;
@@ -791,6 +799,8 @@ findpcb:
tp = tcp_drop(tp, ECONNREFUSED);
goto drop;
}
+ if (tp->t_state == TCPS_SYN_RECEIVED)
+ break;
if ((tiflags & TH_SYN) == 0)
goto drop;
tp->snd_wnd = ti->ti_win; /* initial send window */
diff --git a/sys/netinet/tcp_reass.c b/sys/netinet/tcp_reass.c
index 35a3ba5..a31fe9f 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.50 1996/09/21 06:30:06 ache Exp $
+ * $Id: tcp_input.c,v 1.51 1996/09/21 06:39:20 pst Exp $
*/
#ifndef TUBA_INCLUDE
@@ -411,20 +411,25 @@ findpcb:
if (so->so_options & SO_ACCEPTCONN) {
register struct tcpcb *tp0 = tp;
struct socket *so2;
- /*
- * If the attempt to get onto the socket queue failed,
- * drop the oldest queue entry and try again.
- */
+ if ((tiflags & (TH_RST|TH_ACK|TH_SYN)) != TH_SYN) {
+ /*
+ * Note: dropwithreset makes sure we don't
+ * send a RST in response to a RST.
+ */
+ if (tiflags & TH_ACK) {
+ tcpstat.tcps_badsyn++;
+ goto dropwithreset;
+ }
+ goto drop;
+ }
so2 = sonewconn(so, 0);
- if (!so2) {
+ if (so2 == 0) {
tcpstat.tcps_listendrop++;
- so2 = TAILQ_FIRST(&so->so_incomp);
- if (so2) {
- tcp_drop(sototcpcb(so2), ETIMEDOUT);
- so2 = sonewconn(so, 0);
- }
- if (!so2)
- goto drop;
+ so2 = sodropablereq(so);
+ if (so2)
+ tcp_drop(sototcpcb(so2), ETIMEDOUT);
+ else
+ goto drop;
}
so = so2;
/*
@@ -753,6 +758,8 @@ findpcb:
}
/*
+ * If the state is SYN_RECEIVED:
+ * do just the ack and RST checks from SYN_SENT state.
* If the state is SYN_SENT:
* if seg contains an ACK, but not for our SYN, drop the input.
* if seg contains a RST, then drop the connection.
@@ -764,6 +771,7 @@ findpcb:
* arrange for segment to be acked (eventually)
* continue processing rest of data/controls, beginning with URG
*/
+ case TCPS_SYN_RECEIVED:
case TCPS_SYN_SENT:
if ((taop = tcp_gettaocache(inp)) == NULL) {
taop = &tao_noncached;
@@ -791,6 +799,8 @@ findpcb:
tp = tcp_drop(tp, ECONNREFUSED);
goto drop;
}
+ if (tp->t_state == TCPS_SYN_RECEIVED)
+ break;
if ((tiflags & TH_SYN) == 0)
goto drop;
tp->snd_wnd = ti->ti_win; /* initial send window */
diff --git a/sys/sys/socketvar.h b/sys/sys/socketvar.h
index fbab678..968b428 100644
--- a/sys/sys/socketvar.h
+++ b/sys/sys/socketvar.h
@@ -31,7 +31,7 @@
* SUCH DAMAGE.
*
* @(#)socketvar.h 8.3 (Berkeley) 2/19/95
- * $Id: socketvar.h,v 1.13 1996/03/11 15:37:44 davidg Exp $
+ * $Id: socketvar.h,v 1.14 1996/05/01 01:53:59 bde Exp $
*/
#ifndef _SYS_SOCKETVAR_H_
@@ -69,6 +69,8 @@ struct socket {
TAILQ_HEAD(, socket) so_comp; /* queue of complete unaccepted connections */
TAILQ_ENTRY(socket) so_list; /* list of unaccepted connections */
short so_qlen; /* number of unaccepted connections */
+ short so_incqlen; /* number of unaccepted incomplete
+ connections */
short so_qlimit; /* max number queued connections */
short so_timeo; /* connection timeout */
u_short so_error; /* error affecting connection */
@@ -256,6 +258,8 @@ void soisdisconnected __P((struct socket *so));
void soisdisconnecting __P((struct socket *so));
int solisten __P((struct socket *so, int backlog));
struct socket *
+ sodropablereq __P((struct socket *head));
+struct socket *
sonewconn1 __P((struct socket *head, int connstatus));
int soreceive __P((struct socket *so, struct mbuf **paddr, struct uio *uio,
struct mbuf **mp0, struct mbuf **controlp, int *flagsp));
diff --git a/sys/sys/sysctl.h b/sys/sys/sysctl.h
index 78575a7..b46d7b7 100644
--- a/sys/sys/sysctl.h
+++ b/sys/sys/sysctl.h
@@ -34,7 +34,7 @@
* SUCH DAMAGE.
*
* @(#)sysctl.h 8.1 (Berkeley) 6/2/93
- * $Id: sysctl.h,v 1.44 1996/09/10 23:31:13 bde Exp $
+ * $Id: sysctl.h,v 1.45 1996/09/19 00:54:29 pst Exp $
*/
#ifndef _SYS_SYSCTL_H_
@@ -223,8 +223,7 @@ int sysctl_handle_opaque SYSCTL_HANDLER_ARGS;
#define KERN_MAXSOCKBUF 31 /* int: max size of a socket buffer */
#define KERN_PS_STRINGS 32 /* int: address of PS_STRINGS */
#define KERN_USRSTACK 33 /* int: address of USRSTACK */
-#define KERN_SOMINQUEUE 34 /* int: override socket listen() */
-#define KERN_MAXID 35 /* number of valid kern ids */
+#define KERN_MAXID 34 /* number of valid kern ids */
#define CTL_KERN_NAMES { \
{ 0, 0 }, \
@@ -261,7 +260,6 @@ int sysctl_handle_opaque SYSCTL_HANDLER_ARGS;
{ "maxsockbuf", CTLTYPE_INT }, \
{ "ps_strings", CTLTYPE_INT }, \
{ "usrstack", CTLTYPE_INT }, \
- { "sominqueue", CTLTYPE_INT }, \
}
/*
OpenPOWER on IntegriCloud