From d9ae4adff2715cfab4a941037ec15aa07108efa1 Mon Sep 17 00:00:00 2001 From: Michael Tuexen Date: Wed, 3 May 2023 17:30:50 +0200 Subject: [PATCH] sctp: improve shutdown(..., SHUT_WR) handling When shutdown(..., SHUT_WR) is called in the front states, send a SHUTDOWN chunk when a COOKIE ACK chunk is received and there is no outstanding data. MFC after: 1 week --- sys/netinet/sctp_input.c | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/sys/netinet/sctp_input.c b/sys/netinet/sctp_input.c index 26abf495316..fc362d091a2 100644 --- a/sys/netinet/sctp_input.c +++ b/sys/netinet/sctp_input.c @@ -2782,16 +2782,13 @@ sctp_handle_cookie_ack(struct sctp_cookie_ack_chunk *cp SCTP_UNUSED, __LINE__); } sctp_stop_all_cookie_timers(stcb); + sctp_toss_old_cookies(stcb, asoc); /* process according to association state */ if (SCTP_GET_STATE(stcb) == SCTP_STATE_COOKIE_ECHOED) { /* state change only needed when I am in right state */ SCTPDBG(SCTP_DEBUG_INPUT2, "moving to OPEN state\n"); SCTP_SET_STATE(stcb, SCTP_STATE_OPEN); sctp_start_net_timers(stcb); - if (asoc->state & SCTP_STATE_SHUTDOWN_PENDING) { - sctp_timer_start(SCTP_TIMER_TYPE_SHUTDOWNGUARD, - stcb->sctp_ep, stcb, NULL); - } /* update RTO */ SCTP_STAT_INCR_COUNTER32(sctps_activeestab); SCTP_STAT_INCR_GAUGE32(sctps_currestab); @@ -2815,6 +2812,21 @@ sctp_handle_cookie_ack(struct sctp_cookie_ack_chunk *cp SCTP_UNUSED, } } + if ((asoc->state & SCTP_STATE_SHUTDOWN_PENDING) && + TAILQ_EMPTY(&asoc->send_queue) && + TAILQ_EMPTY(&asoc->sent_queue) && + (asoc->stream_queue_cnt == 0)) { + SCTP_STAT_DECR_GAUGE32(sctps_currestab); + SCTP_SET_STATE(stcb, SCTP_STATE_SHUTDOWN_SENT); + sctp_stop_timers_for_shutdown(stcb); + sctp_send_shutdown(stcb, net); + sctp_timer_start(SCTP_TIMER_TYPE_SHUTDOWN, + stcb->sctp_ep, stcb, net); + sctp_timer_start(SCTP_TIMER_TYPE_SHUTDOWNGUARD, + stcb->sctp_ep, stcb, NULL); + sctp_chunk_output(stcb->sctp_ep, stcb, SCTP_OUTPUT_FROM_T3, SCTP_SO_LOCKED); + } + if (stcb->asoc.state & SCTP_STATE_CLOSED_SOCKET) { /* * We don't need to do the asconf thing, nor hb or @@ -2850,8 +2862,6 @@ sctp_handle_cookie_ack(struct sctp_cookie_ack_chunk *cp SCTP_UNUSED, } } closed_socket: - /* Toss the cookie if I can */ - sctp_toss_old_cookies(stcb, asoc); /* Restart the timer if we have pending data */ TAILQ_FOREACH(chk, &asoc->sent_queue, sctp_next) { if (chk->whoTo != NULL) { -- 2.45.0