Index: sys/netinet/tcp_syncache.c =================================================================== --- sys/netinet/tcp_syncache.c +++ sys/netinet/tcp_syncache.c @@ -1181,6 +1181,7 @@ struct ucred *cred; #ifdef TCP_RFC7413 uint64_t tfo_response_cookie; + unsigned int *tfo_pending = NULL; int tfo_cookie_valid = 0; int tfo_response_cookie_valid = 0; #endif @@ -1226,8 +1227,13 @@ &tfo_response_cookie); tfo_cookie_valid = (result > 0); tfo_response_cookie_valid = (result >= 0); - } else - atomic_subtract_int(tp->t_tfo_pending, 1); + } + + /* + * Remember the TFO pending counter as it will have to be + * decremented below if a TFO socket is not created. + */ + tfo_pending = tp->t_tfo_pending; } #endif @@ -1468,9 +1474,9 @@ #ifdef TCP_RFC7413 if (tfo_cookie_valid) { syncache_tfo_expand(sc, lsop, m, tfo_response_cookie); - /* INP_WUNLOCK(inp) will be performed by the called */ + /* INP_WUNLOCK(inp) will be performed by the caller */ rv = 1; - goto tfo_done; + goto tfo_socket_created; } #endif @@ -1496,7 +1502,16 @@ m_freem(m); } #ifdef TCP_RFC7413 -tfo_done: + /* + * If tfo_pending is not NULL here, then a TFO SYN that did not + * result in a new socket was processed, and the associated pending + * counter must be decremented. All such TFO processing paths + * transit this point. + */ + if (tfo_pending != NULL) + tcp_fastopen_decrement_counter(tfo_pending); + +tfo_socket_created: #endif if (cred != NULL) crfree(cred);