sctp: enable cookie-echo retransmission transport switch

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>
This commit is contained in:
Vlad Yasevich 2008-09-08 14:00:26 -04:00
parent 8190f89dfd
commit 96cd0d3d71
2 changed files with 46 additions and 34 deletions

View 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:

View 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));