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 @@ -2105,7 +2105,7 @@ * SYN-SENT -> SYN-RECEIVED * SYN-SENT* -> SYN-RECEIVED* */ - tp->t_flags |= (TF_ACKNOW | TF_NEEDSYN); + tp->t_flags |= (TF_ACKNOW | TF_NEEDSYN | TF_SONOTCONN); tcp_timer_activate(tp, TT_REXMT, 0); tcp_state_change(tp, TCPS_SYN_RECEIVED); } @@ -2433,8 +2433,17 @@ case TCPS_SYN_RECEIVED: TCPSTAT_INC(tcps_connects); - if (tp->t_flags & TF_INCQUEUE) { - tp->t_flags &= ~TF_INCQUEUE; + if (tp->t_flags & TF_SONOTCONN) { + /* + * Usually SYN_RECEIVED had been created from a LISTEN, + * and solisten_enqueue() has already marked the socket + * layer as connected. If it didn't, which can happen + * only with an accept_filter(9), then the tp is marked + * with TF_SONOTCONN. The other reason for this mark + * to to be set is a simultaneous open, a SYN_RECEIVED + * that had been created from SYN_SENT. + */ + tp->t_flags &= ~TF_SONOTCONN; soisconnected(so); } /* Do window scaling? */ diff --git a/sys/netinet/tcp_stacks/bbr.c b/sys/netinet/tcp_stacks/bbr.c --- a/sys/netinet/tcp_stacks/bbr.c +++ b/sys/netinet/tcp_stacks/bbr.c @@ -8902,7 +8902,7 @@ * SYN-SENT -> SYN-RECEIVED SYN-SENT* -> SYN-RECEIVED* If * there was no CC option, clear cached CC value. */ - tp->t_flags |= (TF_ACKNOW | TF_NEEDSYN); + tp->t_flags |= (TF_ACKNOW | TF_NEEDSYN | TF_SONOTCONN); tcp_state_change(tp, TCPS_SYN_RECEIVED); } INP_WLOCK_ASSERT(tp->t_inpcb); @@ -9088,7 +9088,10 @@ tiwin, thflags, nxt_pkt)); } KMOD_TCPSTAT_INC(tcps_connects); - soisconnected(so); + if (tp->t_flags & TF_SONOTCONN) { + tp->t_flags &= ~TF_SONOTCONN; + 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_stacks/rack.c b/sys/netinet/tcp_stacks/rack.c --- a/sys/netinet/tcp_stacks/rack.c +++ b/sys/netinet/tcp_stacks/rack.c @@ -11318,7 +11318,7 @@ * SYN-SENT -> SYN-RECEIVED SYN-SENT* -> SYN-RECEIVED* If * there was no CC option, clear cached CC value. */ - tp->t_flags |= (TF_ACKNOW | TF_NEEDSYN); + tp->t_flags |= (TF_ACKNOW | TF_NEEDSYN | TF_SONOTCONN); tcp_state_change(tp, TCPS_SYN_RECEIVED); } INP_WLOCK_ASSERT(tp->t_inpcb); @@ -11507,7 +11507,10 @@ tiwin, thflags, nxt_pkt)); } KMOD_TCPSTAT_INC(tcps_connects); - soisconnected(so); + if (tp->t_flags & TF_SONOTCONN) { + tp->t_flags &= ~TF_SONOTCONN; + 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 @@ -1040,7 +1040,7 @@ TCP_PROBE6(state__change, NULL, tp, NULL, tp, NULL, TCPS_LISTEN); if (!solisten_enqueue(so, SS_ISCONNECTED)) - tp->t_flags |= TF_INCQUEUE; + tp->t_flags |= TF_SONOTCONN; 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_INCQUEUE) { - db_printf("%sTF_INCQUEUE", comma ? ", " : ""); + if (t_flags & TF_SONOTCONN) { + db_printf("%sTF_SONOTCONN", 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_INCQUEUE 0x00020000 /* on incomplete queue of listener */ +#define TF_SONOTCONN 0x00020000 /* needs soisconnected() on ESTAB */ #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 */