Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next
[pandora-kernel.git] / net / sctp / sm_sideeffect.c
index 1b2bb64..167c880 100644 (file)
@@ -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];