summaryrefslogtreecommitdiff
path: root/net/sctp/associola.c
diff options
context:
space:
mode:
authorVlad Yasevich <vladislav.yasevich@hp.com>2007-03-20 03:02:30 +0300
committerDavid S. Miller <davem@sunset.davemloft.net>2007-03-20 10:09:45 +0300
commit749bf9215ed1a8b6edb4bb03693c2b62c6b9c2a4 (patch)
treed5656c441181fddef41392a4aa07f54e56487312 /net/sctp/associola.c
parentfb78525ae1b75bfac1da600ceb008aef4d293649 (diff)
downloadlinux-749bf9215ed1a8b6edb4bb03693c2b62c6b9c2a4.tar.xz
[SCTP]: Reset some transport and association variables on restart
If the association has been restarted, we need to reset the transport congestion variables as well as accumulated error counts and CACC variables. If we do not, the association will use the wrong values and may terminate prematurely. This was found with a scenario where the peer restarted the association when lksctp was in the last HB timeout for its association. The restart happened, but the error counts have not been reset and when the timeout occurred, a newly restarted association was terminated due to excessive retransmits. Signed-off-by: Vlad Yasevich <vladislav.yasevich@hp.com> Signed-off-by: Sridhar Samudrala <sri@us.ibm.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/sctp/associola.c')
-rw-r--r--net/sctp/associola.c9
1 files changed, 9 insertions, 0 deletions
diff --git a/net/sctp/associola.c b/net/sctp/associola.c
index 2505cd3b8d29..78d2ddb5ca18 100644
--- a/net/sctp/associola.c
+++ b/net/sctp/associola.c
@@ -1046,6 +1046,9 @@ void sctp_assoc_update(struct sctp_association *asoc,
trans = list_entry(pos, struct sctp_transport, transports);
if (!sctp_assoc_lookup_paddr(new, &trans->ipaddr))
sctp_assoc_del_peer(asoc, &trans->ipaddr);
+
+ if (asoc->state >= SCTP_STATE_ESTABLISHED)
+ sctp_transport_reset(trans);
}
/* If the case is A (association restart), use
@@ -1069,6 +1072,12 @@ void sctp_assoc_update(struct sctp_association *asoc,
*/
sctp_ulpq_flush(&asoc->ulpq);
+ /* reset the overall association error count so
+ * that the restarted association doesn't get torn
+ * down on the next retransmission timer.
+ */
+ asoc->overall_error_count = 0;
+
} else {
/* Add any peer addresses from the new association. */
list_for_each(pos, &new->peer.transport_addr_list) {