sctp: fasthandoff with ASCONF at server-node
authorMichio Honda <micchie@sfc.wide.ad.jp>
Fri, 17 Jun 2011 02:22:35 +0000 (11:22 +0900)
committerDavid S. Miller <davem@davemloft.net>
Tue, 8 Nov 2011 20:11:30 +0000 (15:11 -0500)
Retransmit chunks to newly confirmed destination when ASCONF and
HEARTBEAT negotiation has success with a single-homed peer.

Signed-off-by: Michio Honda <micchie@sfc.wide.ad.jp>
Signed-off-by: David S. Miller <davem@davemloft.net>
net/sctp/sm_sideeffect.c

index 76388b083f283a2e2c62ab3f605ee8a12469454f..1ff51c9d18d5d5ca925da9bd24544fe46014ad7b 100644 (file)
@@ -666,6 +666,7 @@ static void sctp_cmd_transport_on(sctp_cmd_seq_t *cmds,
                                  struct sctp_chunk *chunk)
 {
        sctp_sender_hb_info_t *hbinfo;
+       int was_unconfirmed = 0;
 
        /* 8.3 Upon the receipt of the HEARTBEAT ACK, the sender of the
         * HEARTBEAT should clear the error counter of the destination
@@ -692,9 +693,11 @@ static void sctp_cmd_transport_on(sctp_cmd_seq_t *cmds,
        /* Mark the destination transport address as active if it is not so
         * marked.
         */
-       if ((t->state == SCTP_INACTIVE) || (t->state == SCTP_UNCONFIRMED))
+       if ((t->state == SCTP_INACTIVE) || (t->state == SCTP_UNCONFIRMED)) {
+               was_unconfirmed = 1;
                sctp_assoc_control_transport(asoc, t, SCTP_TRANSPORT_UP,
                                             SCTP_HEARTBEAT_SUCCESS);
+       }
 
        /* The receiver of the HEARTBEAT ACK should also perform an
         * RTT measurement for that destination transport address
@@ -712,6 +715,9 @@ static void sctp_cmd_transport_on(sctp_cmd_seq_t *cmds,
        /* Update the heartbeat timer.  */
        if (!mod_timer(&t->hb_timer, sctp_transport_timeout(t)))
                sctp_transport_hold(t);
+
+       if (was_unconfirmed && asoc->peer.transport_count == 1)
+               sctp_transport_immediate_rtx(t);
 }