sctp: enable cookie-echo retransmission transport switch
Vlad Yasevich [Mon, 8 Sep 2008 18:00:26 +0000 (14:00 -0400)]
This patch enables cookie-echo retransmission transport switch
feature. If COOKIE-ECHO retransmission happens, it will be sent
to the address other than the one last sent to.

Signed-off-by: Gui Jianfeng <guijianfeng@cn.fujitsu.com>
Signed-off-by: Vlad Yasevich <vladislav.yasevich@hp.com>

net/sctp/sm_sideeffect.c
net/sctp/sm_statefuns.c

index 9732c79..13d9eea 100644 (file)
@@ -889,6 +889,35 @@ static void sctp_cmd_adaptation_ind(sctp_cmd_seq_t *commands,
                sctp_ulpq_tail_event(&asoc->ulpq, ev);
 }
 
+
+static void sctp_cmd_t1_timer_update(struct sctp_association *asoc,
+                                   sctp_event_timeout_t timer,
+                                   char *name)
+{
+       struct sctp_transport *t;
+
+       t = asoc->init_last_sent_to;
+       asoc->init_err_counter++;
+
+       if (t->init_sent_count > (asoc->init_cycle + 1)) {
+               asoc->timeouts[timer] *= 2;
+               if (asoc->timeouts[timer] > asoc->max_init_timeo) {
+                       asoc->timeouts[timer] = asoc->max_init_timeo;
+               }
+               asoc->init_cycle++;
+               SCTP_DEBUG_PRINTK(
+                       "T1 %s Timeout adjustment"
+                       " init_err_counter: %d"
+                       " cycle: %d"
+                       " timeout: %ld\n",
+                       name,
+                       asoc->init_err_counter,
+                       asoc->init_cycle,
+                       asoc->timeouts[timer]);
+       }
+
+}
+
 /* These three macros allow us to pull the debugging code out of the
  * main flow of sctp_do_sm() to keep attention focused on the real
  * functionality there.
@@ -1196,6 +1225,11 @@ static int sctp_cmd_interpreter(sctp_event_t event_type,
                                sctp_add_cmd_sf(commands, SCTP_CMD_REPLY,
                                                SCTP_CHUNK(cmd->obj.ptr));
 
+                       if (new_obj->transport) {
+                               new_obj->transport->init_sent_count++;
+                               asoc->init_last_sent_to = new_obj->transport;
+                       }
+
                        /* FIXME - Eventually come up with a cleaner way to
                         * enabling COOKIE-ECHO + DATA bundling during
                         * multihoming stale cookie scenarios, the following
@@ -1345,26 +1379,9 @@ static int sctp_cmd_interpreter(sctp_event_t event_type,
                         * all transports have been tried at the current
                         * timeout.
                         */
-                       t = asoc->init_last_sent_to;
-                       asoc->init_err_counter++;
-
-                       if (t->init_sent_count > (asoc->init_cycle + 1)) {
-                               asoc->timeouts[SCTP_EVENT_TIMEOUT_T1_INIT] *= 2;
-                               if (asoc->timeouts[SCTP_EVENT_TIMEOUT_T1_INIT] >
-                                   asoc->max_init_timeo) {
-                                       asoc->timeouts[SCTP_EVENT_TIMEOUT_T1_INIT] =
-                                               asoc->max_init_timeo;
-                               }
-                               asoc->init_cycle++;
-                               SCTP_DEBUG_PRINTK(
-                                       "T1 INIT Timeout adjustment"
-                                       " init_err_counter: %d"
-                                       " cycle: %d"
-                                       " timeout: %ld\n",
-                                       asoc->init_err_counter,
-                                       asoc->init_cycle,
-                                       asoc->timeouts[SCTP_EVENT_TIMEOUT_T1_INIT]);
-                       }
+                       sctp_cmd_t1_timer_update(asoc,
+                                               SCTP_EVENT_TIMEOUT_T1_INIT,
+                                               "INIT");
 
                        sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_RESTART,
                                        SCTP_TO(SCTP_EVENT_TIMEOUT_T1_INIT));
@@ -1377,20 +1394,9 @@ static int sctp_cmd_interpreter(sctp_event_t event_type,
                         * all transports have been tried at the current
                         * timeout.
                         */
-                       asoc->init_err_counter++;
-
-                       asoc->timeouts[SCTP_EVENT_TIMEOUT_T1_COOKIE] *= 2;
-                       if (asoc->timeouts[SCTP_EVENT_TIMEOUT_T1_COOKIE] >
-                           asoc->max_init_timeo) {
-                               asoc->timeouts[SCTP_EVENT_TIMEOUT_T1_COOKIE] =
-                                       asoc->max_init_timeo;
-                       }
-                       SCTP_DEBUG_PRINTK(
-                               "T1 COOKIE Timeout adjustment"
-                               " init_err_counter: %d"
-                               " timeout: %ld\n",
-                               asoc->init_err_counter,
-                               asoc->timeouts[SCTP_EVENT_TIMEOUT_T1_COOKIE]);
+                       sctp_cmd_t1_timer_update(asoc,
+                                               SCTP_EVENT_TIMEOUT_T1_COOKIE,
+                                               "COOKIE");
 
                        /* If we've sent any data bundled with
                         * COOKIE-ECHO we need to resend.
@@ -1422,6 +1428,10 @@ static int sctp_cmd_interpreter(sctp_event_t event_type,
                case SCTP_CMD_INIT_COUNTER_RESET:
                        asoc->init_err_counter = 0;
                        asoc->init_cycle = 0;
+                       list_for_each_entry(t, &asoc->peer.transport_addr_list,
+                                           transports) {
+                               t->init_sent_count = 0;
+                       }
                        break;
 
                case SCTP_CMD_REPORT_DUP:
index 81dfaee..ea3a34c 100644 (file)
@@ -5307,6 +5307,8 @@ sctp_disposition_t sctp_sf_t1_cookie_timer_expire(const struct sctp_endpoint *ep
                if (!repl)
                        return SCTP_DISPOSITION_NOMEM;
 
+               sctp_add_cmd_sf(commands, SCTP_CMD_INIT_CHOOSE_TRANSPORT,
+                               SCTP_CHUNK(repl));
                /* Issue a sideeffect to do the needed accounting. */
                sctp_add_cmd_sf(commands, SCTP_CMD_COOKIEECHO_RESTART,
                                SCTP_TO(SCTP_EVENT_TIMEOUT_T1_COOKIE));