|
@@ -5154,7 +5154,7 @@ sctp_disposition_t sctp_sf_do_9_2_start_shutdown(
|
|
* The sender of the SHUTDOWN MAY also start an overall guard timer
|
|
* The sender of the SHUTDOWN MAY also start an overall guard timer
|
|
* 'T5-shutdown-guard' to bound the overall time for shutdown sequence.
|
|
* 'T5-shutdown-guard' to bound the overall time for shutdown sequence.
|
|
*/
|
|
*/
|
|
- sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_START,
|
|
|
|
|
|
+ sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_RESTART,
|
|
SCTP_TO(SCTP_EVENT_TIMEOUT_T5_SHUTDOWN_GUARD));
|
|
SCTP_TO(SCTP_EVENT_TIMEOUT_T5_SHUTDOWN_GUARD));
|
|
|
|
|
|
if (asoc->autoclose)
|
|
if (asoc->autoclose)
|
|
@@ -5299,14 +5299,28 @@ sctp_disposition_t sctp_sf_do_6_3_3_rtx(const struct sctp_endpoint *ep,
|
|
SCTP_INC_STATS(SCTP_MIB_T3_RTX_EXPIREDS);
|
|
SCTP_INC_STATS(SCTP_MIB_T3_RTX_EXPIREDS);
|
|
|
|
|
|
if (asoc->overall_error_count >= asoc->max_retrans) {
|
|
if (asoc->overall_error_count >= asoc->max_retrans) {
|
|
- sctp_add_cmd_sf(commands, SCTP_CMD_SET_SK_ERR,
|
|
|
|
- SCTP_ERROR(ETIMEDOUT));
|
|
|
|
- /* CMD_ASSOC_FAILED calls CMD_DELETE_TCB. */
|
|
|
|
- sctp_add_cmd_sf(commands, SCTP_CMD_ASSOC_FAILED,
|
|
|
|
- SCTP_PERR(SCTP_ERROR_NO_ERROR));
|
|
|
|
- SCTP_INC_STATS(SCTP_MIB_ABORTEDS);
|
|
|
|
- SCTP_DEC_STATS(SCTP_MIB_CURRESTAB);
|
|
|
|
- return SCTP_DISPOSITION_DELETE_TCB;
|
|
|
|
|
|
+ if (asoc->state == SCTP_STATE_SHUTDOWN_PENDING) {
|
|
|
|
+ /*
|
|
|
|
+ * We are here likely because the receiver had its rwnd
|
|
|
|
+ * closed for a while and we have not been able to
|
|
|
|
+ * transmit the locally queued data within the maximum
|
|
|
|
+ * retransmission attempts limit. Start the T5
|
|
|
|
+ * shutdown guard timer to give the receiver one last
|
|
|
|
+ * chance and some additional time to recover before
|
|
|
|
+ * aborting.
|
|
|
|
+ */
|
|
|
|
+ sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_START_ONCE,
|
|
|
|
+ SCTP_TO(SCTP_EVENT_TIMEOUT_T5_SHUTDOWN_GUARD));
|
|
|
|
+ } else {
|
|
|
|
+ sctp_add_cmd_sf(commands, SCTP_CMD_SET_SK_ERR,
|
|
|
|
+ SCTP_ERROR(ETIMEDOUT));
|
|
|
|
+ /* CMD_ASSOC_FAILED calls CMD_DELETE_TCB. */
|
|
|
|
+ sctp_add_cmd_sf(commands, SCTP_CMD_ASSOC_FAILED,
|
|
|
|
+ SCTP_PERR(SCTP_ERROR_NO_ERROR));
|
|
|
|
+ SCTP_INC_STATS(SCTP_MIB_ABORTEDS);
|
|
|
|
+ SCTP_DEC_STATS(SCTP_MIB_CURRESTAB);
|
|
|
|
+ return SCTP_DISPOSITION_DELETE_TCB;
|
|
|
|
+ }
|
|
}
|
|
}
|
|
|
|
|
|
/* E1) For the destination address for which the timer
|
|
/* E1) For the destination address for which the timer
|