aboutsummaryrefslogtreecommitdiffstats
path: root/net/sctp/sm_statefuns.c
diff options
context:
space:
mode:
authorThomas Graf <tgraf@infradead.org>2011-07-06 20:28:35 -0400
committerDavid S. Miller <davem@davemloft.net>2011-07-07 17:08:44 -0400
commitf8d9605243280f1870dd2c6c37a735b925c15f3c (patch)
tree2d6a3ce33c503bce8fca71489d4c4dc266579469 /net/sctp/sm_statefuns.c
parent31cb852809c86541c817538c98003678546dfa58 (diff)
sctp: Enforce retransmission limit during shutdown
When initiating a graceful shutdown while having data chunks on the retransmission queue with a peer which is in zero window mode the shutdown is never completed because the retransmission error count is reset periodically by the following two rules: - Do not timeout association while doing zero window probe. - Reset overall error count when a heartbeat request has been acknowledged. The graceful shutdown will wait for all outstanding TSN to be acknowledged before sending the SHUTDOWN request. This never happens due to the peer's zero window not acknowledging the continuously retransmitted data chunks. Although the error counter is incremented for each failed retransmission, the receiving of the SACK announcing the zero window clears the error count again immediately. Also heartbeat requests continue to be sent periodically. The peer acknowledges these requests causing the error counter to be reset as well. This patch changes behaviour to only reset the overall error counter for the above rules while not in shutdown. After reaching the maximum number of retransmission attempts, the T5 shutdown guard timer is scheduled to give the receiver some additional time to recover. The timer is stopped as soon as the receiver acknowledges any data. The issue can be easily reproduced by establishing a sctp association over the loopback device, constantly queueing data at the sender while not reading any at the receiver. Wait for the window to reach zero, then initiate a shutdown by killing both processes simultaneously. The association will never be freed and the chunks on the retransmission queue will be retransmitted indefinitely. Signed-off-by: Thomas Graf <tgraf@infradead.org> Acked-by: Vlad Yasevich <vladislav.yasevich@hp.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/sctp/sm_statefuns.c')
-rw-r--r--net/sctp/sm_statefuns.c32
1 files changed, 23 insertions, 9 deletions
diff --git a/net/sctp/sm_statefuns.c b/net/sctp/sm_statefuns.c
index a297283154d5..246117142b5c 100644
--- a/net/sctp/sm_statefuns.c
+++ b/net/sctp/sm_statefuns.c
@@ -5154,7 +5154,7 @@ sctp_disposition_t sctp_sf_do_9_2_start_shutdown(
5154 * The sender of the SHUTDOWN MAY also start an overall guard timer 5154 * The sender of the SHUTDOWN MAY also start an overall guard timer
5155 * 'T5-shutdown-guard' to bound the overall time for shutdown sequence. 5155 * 'T5-shutdown-guard' to bound the overall time for shutdown sequence.
5156 */ 5156 */
5157 sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_START, 5157 sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_RESTART,
5158 SCTP_TO(SCTP_EVENT_TIMEOUT_T5_SHUTDOWN_GUARD)); 5158 SCTP_TO(SCTP_EVENT_TIMEOUT_T5_SHUTDOWN_GUARD));
5159 5159
5160 if (asoc->autoclose) 5160 if (asoc->autoclose)
@@ -5299,14 +5299,28 @@ sctp_disposition_t sctp_sf_do_6_3_3_rtx(const struct sctp_endpoint *ep,
5299 SCTP_INC_STATS(SCTP_MIB_T3_RTX_EXPIREDS); 5299 SCTP_INC_STATS(SCTP_MIB_T3_RTX_EXPIREDS);
5300 5300
5301 if (asoc->overall_error_count >= asoc->max_retrans) { 5301 if (asoc->overall_error_count >= asoc->max_retrans) {
5302 sctp_add_cmd_sf(commands, SCTP_CMD_SET_SK_ERR, 5302 if (asoc->state == SCTP_STATE_SHUTDOWN_PENDING) {
5303 SCTP_ERROR(ETIMEDOUT)); 5303 /*
5304 /* CMD_ASSOC_FAILED calls CMD_DELETE_TCB. */ 5304 * We are here likely because the receiver had its rwnd
5305 sctp_add_cmd_sf(commands, SCTP_CMD_ASSOC_FAILED, 5305 * closed for a while and we have not been able to
5306 SCTP_PERR(SCTP_ERROR_NO_ERROR)); 5306 * transmit the locally queued data within the maximum
5307 SCTP_INC_STATS(SCTP_MIB_ABORTEDS); 5307 * retransmission attempts limit. Start the T5
5308 SCTP_DEC_STATS(SCTP_MIB_CURRESTAB); 5308 * shutdown guard timer to give the receiver one last
5309 return SCTP_DISPOSITION_DELETE_TCB; 5309 * chance and some additional time to recover before
5310 * aborting.
5311 */
5312 sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_START_ONCE,
5313 SCTP_TO(SCTP_EVENT_TIMEOUT_T5_SHUTDOWN_GUARD));
5314 } else {
5315 sctp_add_cmd_sf(commands, SCTP_CMD_SET_SK_ERR,
5316 SCTP_ERROR(ETIMEDOUT));
5317 /* CMD_ASSOC_FAILED calls CMD_DELETE_TCB. */
5318 sctp_add_cmd_sf(commands, SCTP_CMD_ASSOC_FAILED,
5319 SCTP_PERR(SCTP_ERROR_NO_ERROR));
5320 SCTP_INC_STATS(SCTP_MIB_ABORTEDS);
5321 SCTP_DEC_STATS(SCTP_MIB_CURRESTAB);
5322 return SCTP_DISPOSITION_DELETE_TCB;
5323 }
5310 } 5324 }
5311 5325
5312 /* E1) For the destination address for which the timer 5326 /* E1) For the destination address for which the timer