diff --git a/sys/kern/uipc_socket.c b/sys/kern/uipc_socket.c --- a/sys/kern/uipc_socket.c +++ b/sys/kern/uipc_socket.c @@ -800,7 +800,7 @@ return (NULL); } - solisten_enqueue(so, connstatus); + (void)solisten_enqueue(so, connstatus); return (so); } @@ -808,8 +808,10 @@ /* * Enqueue socket cloned by solisten_clone() to the listen queue of the * listener it has been cloned from. + * + * Return 'true' if socket landed on complete queue, otherwise 'false'. */ -void +bool solisten_enqueue(struct socket *so, int connstatus) { struct socket *head = so->so_listen; @@ -827,6 +829,7 @@ so->so_qstate = SQ_COMP; head->sol_qlen++; solisten_wakeup(head); /* unlocks */ + return (true); } else { /* * Keep removing sockets from the head until there's room for @@ -853,6 +856,7 @@ so->so_qstate = SQ_INCOMP; head->sol_incqlen++; SOLISTEN_UNLOCK(head); + return (false); } } diff --git a/sys/netinet/tcp_input.c b/sys/netinet/tcp_input.c --- a/sys/netinet/tcp_input.c +++ b/sys/netinet/tcp_input.c @@ -2433,7 +2433,10 @@ case TCPS_SYN_RECEIVED: TCPSTAT_INC(tcps_connects); - soisconnected(so); + if (tp->t_flags & TF_INCQUEUE) { + tp->t_flags &= ~TF_INCQUEUE; + soisconnected(so); + } /* Do window scaling? */ if ((tp->t_flags & (TF_RCVD_SCALE|TF_REQ_SCALE)) == (TF_RCVD_SCALE|TF_REQ_SCALE)) { diff --git a/sys/netinet/tcp_syncache.c b/sys/netinet/tcp_syncache.c --- a/sys/netinet/tcp_syncache.c +++ b/sys/netinet/tcp_syncache.c @@ -1039,7 +1039,8 @@ TCPSTAT_INC(tcps_accepts); TCP_PROBE6(state__change, NULL, tp, NULL, tp, NULL, TCPS_LISTEN); - solisten_enqueue(so, SS_ISCONNECTED); + if (!solisten_enqueue(so, SS_ISCONNECTED)) + tp->t_flags |= TF_INCQUEUE; return (so); diff --git a/sys/netinet/tcp_usrreq.c b/sys/netinet/tcp_usrreq.c --- a/sys/netinet/tcp_usrreq.c +++ b/sys/netinet/tcp_usrreq.c @@ -2978,8 +2978,8 @@ db_printf("%sTF_MORETOCOME", comma ? ", " : ""); comma = 1; } - if (t_flags & TF_LQ_OVERFLOW) { - db_printf("%sTF_LQ_OVERFLOW", comma ? ", " : ""); + if (t_flags & TF_INCQUEUE) { + db_printf("%sTF_INCQUEUE", comma ? ", " : ""); comma = 1; } if (t_flags & TF_LASTIDLE) { diff --git a/sys/netinet/tcp_var.h b/sys/netinet/tcp_var.h --- a/sys/netinet/tcp_var.h +++ b/sys/netinet/tcp_var.h @@ -515,7 +515,7 @@ #define TF_WAKESOR 0x00004000 /* wake up receive socket */ #define TF_GPUTINPROG 0x00008000 /* Goodput measurement in progress */ #define TF_MORETOCOME 0x00010000 /* More data to be appended to sock */ -#define TF_LQ_OVERFLOW 0x00020000 /* listen queue overflow */ +#define TF_INCQUEUE 0x00020000 /* on incomplete queue of listener */ #define TF_LASTIDLE 0x00040000 /* connection was previously idle */ #define TF_RXWIN0SENT 0x00080000 /* sent a receiver win 0 in response */ #define TF_FASTRECOVERY 0x00100000 /* in NewReno Fast Recovery */ diff --git a/sys/sys/socketvar.h b/sys/sys/socketvar.h --- a/sys/sys/socketvar.h +++ b/sys/sys/socketvar.h @@ -474,7 +474,7 @@ void solisten_proto(struct socket *so, int backlog); void solisten_proto_abort(struct socket *so); int solisten_proto_check(struct socket *so); -void solisten_enqueue(struct socket *, int); +bool solisten_enqueue(struct socket *, int); int solisten_dequeue(struct socket *, struct socket **, int); struct socket * solisten_clone(struct socket *);