summaryrefslogtreecommitdiffstats
path: root/net/sctp/sm_sideeffect.c
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2011-07-14 16:56:40 +0200
committerDavid S. Miller <davem@davemloft.net>2011-07-14 16:56:40 +0200
commit6a7ebdf2fd15417e87b4fd02ff411aeaca34da5f (patch)
tree86b15d8cd3e25c97b348b5a61bdb16c02726a480 /net/sctp/sm_sideeffect.c
parentnet: Embed hh_cache inside of struct neighbour. (diff)
parentMerge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/cjb... (diff)
downloadlinux-6a7ebdf2fd15417e87b4fd02ff411aeaca34da5f.tar.xz
linux-6a7ebdf2fd15417e87b4fd02ff411aeaca34da5f.zip
Merge branch 'master' of master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6
Conflicts: net/bluetooth/l2cap_core.c
Diffstat (limited to 'net/sctp/sm_sideeffect.c')
-rw-r--r--net/sctp/sm_sideeffect.c20
1 files changed, 18 insertions, 2 deletions
diff --git a/net/sctp/sm_sideeffect.c b/net/sctp/sm_sideeffect.c
index 1b2bb6487342..167c880cf8da 100644
--- a/net/sctp/sm_sideeffect.c
+++ b/net/sctp/sm_sideeffect.c
@@ -670,10 +670,19 @@ static void sctp_cmd_transport_on(sctp_cmd_seq_t *cmds,
/* 8.3 Upon the receipt of the HEARTBEAT ACK, the sender of the
* HEARTBEAT should clear the error counter of the destination
* transport address to which the HEARTBEAT was sent.
- * The association's overall error count is also cleared.
*/
t->error_count = 0;
- t->asoc->overall_error_count = 0;
+
+ /*
+ * Although RFC4960 specifies that the overall error count must
+ * be cleared when a HEARTBEAT ACK is received, we make an
+ * exception while in SHUTDOWN PENDING. If the peer keeps its
+ * window shut forever, we may never be able to transmit our
+ * outstanding data and rely on the retransmission limit be reached
+ * to shutdown the association.
+ */
+ if (t->asoc->state != SCTP_STATE_SHUTDOWN_PENDING)
+ t->asoc->overall_error_count = 0;
/* Clear the hb_sent flag to signal that we had a good
* acknowledgement.
@@ -1437,6 +1446,13 @@ static int sctp_cmd_interpreter(sctp_event_t event_type,
sctp_cmd_setup_t2(commands, asoc, cmd->obj.ptr);
break;
+ case SCTP_CMD_TIMER_START_ONCE:
+ timer = &asoc->timers[cmd->obj.to];
+
+ if (timer_pending(timer))
+ break;
+ /* fall through */
+
case SCTP_CMD_TIMER_START:
timer = &asoc->timers[cmd->obj.to];
timeout = asoc->timeouts[cmd->obj.to];