diff options
| author | John Stultz <john.stultz@linaro.org> | 2011-07-25 09:58:06 -0700 |
|---|---|---|
| committer | John Stultz <john.stultz@linaro.org> | 2011-07-25 09:58:06 -0700 |
| commit | 21a602b5cdc203cbcf8bbeeb26edeb3de7c65955 (patch) | |
| tree | 8618b4a8882f78076a779ebb416b54332cc213db /net/sctp/outqueue.c | |
| parent | 1a3807e5a6bea7e4b195fbb399bbc09e73230d4c (diff) | |
| parent | 81f6236c4811b2b2b3ea64a306c071f76788ac4b (diff) | |
Merge branch 'upstream/linaro-3.0' into linaro-android-3.0
Diffstat (limited to 'net/sctp/outqueue.c')
| -rw-r--r-- | net/sctp/outqueue.c | 20 |
1 files changed, 19 insertions, 1 deletions
diff --git a/net/sctp/outqueue.c b/net/sctp/outqueue.c index 1c88c8911dc..d03682109b7 100644 --- a/net/sctp/outqueue.c +++ b/net/sctp/outqueue.c @@ -1582,6 +1582,8 @@ static void sctp_check_transmitted(struct sctp_outq *q, #endif /* SCTP_DEBUG */ if (transport) { if (bytes_acked) { + struct sctp_association *asoc = transport->asoc; + /* We may have counted DATA that was migrated * to this transport due to DEL-IP operation. * Subtract those bytes, since the were never @@ -1600,6 +1602,17 @@ static void sctp_check_transmitted(struct sctp_outq *q, transport->error_count = 0; transport->asoc->overall_error_count = 0; + /* + * While in SHUTDOWN PENDING, we may have started + * the T5 shutdown guard timer after reaching the + * retransmission limit. Stop that timer as soon + * as the receiver acknowledged any data. + */ + if (asoc->state == SCTP_STATE_SHUTDOWN_PENDING && + del_timer(&asoc->timers + [SCTP_EVENT_TIMEOUT_T5_SHUTDOWN_GUARD])) + sctp_association_put(asoc); + /* Mark the destination transport address as * active if it is not so marked. */ @@ -1629,10 +1642,15 @@ static void sctp_check_transmitted(struct sctp_outq *q, * A sender is doing zero window probing when the * receiver's advertised window is zero, and there is * only one data chunk in flight to the receiver. + * + * Allow the association to timeout while in SHUTDOWN + * PENDING or SHUTDOWN RECEIVED in case the receiver + * stays in zero window mode forever. */ if (!q->asoc->peer.rwnd && !list_empty(&tlist) && - (sack_ctsn+2 == q->asoc->next_tsn)) { + (sack_ctsn+2 == q->asoc->next_tsn) && + q->asoc->state < SCTP_STATE_SHUTDOWN_PENDING) { SCTP_DEBUG_PRINTK("%s: SACK received for zero " "window probe: %u\n", __func__, sack_ctsn); |
