diff options
| author | Wei Yongjun <yjwei@cn.fujitsu.com> | 2011-05-29 19:23:36 -0400 |
|---|---|---|
| committer | David S. Miller <davem@davemloft.net> | 2011-05-31 18:29:17 -0400 |
| commit | a000c01e60e40e15304ffe48fff051d17a7bea91 (patch) | |
| tree | 429060980f87287a3df70d8d286b73d6f1985cc8 | |
| parent | b10cec8a4e8167075b9e1ff3f05419769e7f381a (diff) | |
sctp: stop pending timers and purge queues when peer restart asoc
If the peer restart the asoc, we should not only fail any unsent/unacked
data, but also stop the T3-rtx, SACK, T4-rto timers, and teardown ASCONF
queues.
Signed-off-by: Wei Yongjun <yjwei@cn.fujitsu.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
| -rw-r--r-- | include/net/sctp/command.h | 1 | ||||
| -rw-r--r-- | include/net/sctp/structs.h | 2 | ||||
| -rw-r--r-- | net/sctp/associola.c | 23 | ||||
| -rw-r--r-- | net/sctp/sm_sideeffect.c | 3 | ||||
| -rw-r--r-- | net/sctp/sm_statefuns.c | 14 |
5 files changed, 31 insertions, 12 deletions
diff --git a/include/net/sctp/command.h b/include/net/sctp/command.h index 2b447646ce4b..dd6847e5d6e4 100644 --- a/include/net/sctp/command.h +++ b/include/net/sctp/command.h | |||
| @@ -107,6 +107,7 @@ typedef enum { | |||
| 107 | SCTP_CMD_UPDATE_INITTAG, /* Update peer inittag */ | 107 | SCTP_CMD_UPDATE_INITTAG, /* Update peer inittag */ |
| 108 | SCTP_CMD_SEND_MSG, /* Send the whole use message */ | 108 | SCTP_CMD_SEND_MSG, /* Send the whole use message */ |
| 109 | SCTP_CMD_SEND_NEXT_ASCONF, /* Send the next ASCONF after ACK */ | 109 | SCTP_CMD_SEND_NEXT_ASCONF, /* Send the next ASCONF after ACK */ |
| 110 | SCTP_CMD_PURGE_ASCONF_QUEUE, /* Purge all asconf queues.*/ | ||
| 110 | SCTP_CMD_LAST | 111 | SCTP_CMD_LAST |
| 111 | } sctp_verb_t; | 112 | } sctp_verb_t; |
| 112 | 113 | ||
diff --git a/include/net/sctp/structs.h b/include/net/sctp/structs.h index 795f4886e111..7df327a6d564 100644 --- a/include/net/sctp/structs.h +++ b/include/net/sctp/structs.h | |||
| @@ -1993,7 +1993,7 @@ void sctp_assoc_clean_asconf_ack_cache(const struct sctp_association *asoc); | |||
| 1993 | struct sctp_chunk *sctp_assoc_lookup_asconf_ack( | 1993 | struct sctp_chunk *sctp_assoc_lookup_asconf_ack( |
| 1994 | const struct sctp_association *asoc, | 1994 | const struct sctp_association *asoc, |
| 1995 | __be32 serial); | 1995 | __be32 serial); |
| 1996 | 1996 | void sctp_asconf_queue_teardown(struct sctp_association *asoc); | |
| 1997 | 1997 | ||
| 1998 | int sctp_cmp_addr_exact(const union sctp_addr *ss1, | 1998 | int sctp_cmp_addr_exact(const union sctp_addr *ss1, |
| 1999 | const union sctp_addr *ss2); | 1999 | const union sctp_addr *ss2); |
diff --git a/net/sctp/associola.c b/net/sctp/associola.c index 525f97c467e9..4a62888f2e43 100644 --- a/net/sctp/associola.c +++ b/net/sctp/associola.c | |||
| @@ -444,15 +444,7 @@ void sctp_association_free(struct sctp_association *asoc) | |||
| 444 | 444 | ||
| 445 | asoc->peer.transport_count = 0; | 445 | asoc->peer.transport_count = 0; |
| 446 | 446 | ||
| 447 | /* Free any cached ASCONF_ACK chunk. */ | 447 | sctp_asconf_queue_teardown(asoc); |
| 448 | sctp_assoc_free_asconf_acks(asoc); | ||
| 449 | |||
| 450 | /* Free the ASCONF queue. */ | ||
| 451 | sctp_assoc_free_asconf_queue(asoc); | ||
| 452 | |||
| 453 | /* Free any cached ASCONF chunk. */ | ||
| 454 | if (asoc->addip_last_asconf) | ||
| 455 | sctp_chunk_free(asoc->addip_last_asconf); | ||
| 456 | 448 | ||
| 457 | /* AUTH - Free the endpoint shared keys */ | 449 | /* AUTH - Free the endpoint shared keys */ |
| 458 | sctp_auth_destroy_keys(&asoc->endpoint_shared_keys); | 450 | sctp_auth_destroy_keys(&asoc->endpoint_shared_keys); |
| @@ -1646,3 +1638,16 @@ struct sctp_chunk *sctp_assoc_lookup_asconf_ack( | |||
| 1646 | 1638 | ||
| 1647 | return NULL; | 1639 | return NULL; |
| 1648 | } | 1640 | } |
| 1641 | |||
| 1642 | void sctp_asconf_queue_teardown(struct sctp_association *asoc) | ||
| 1643 | { | ||
| 1644 | /* Free any cached ASCONF_ACK chunk. */ | ||
| 1645 | sctp_assoc_free_asconf_acks(asoc); | ||
| 1646 | |||
| 1647 | /* Free the ASCONF queue. */ | ||
| 1648 | sctp_assoc_free_asconf_queue(asoc); | ||
| 1649 | |||
| 1650 | /* Free any cached ASCONF chunk. */ | ||
| 1651 | if (asoc->addip_last_asconf) | ||
| 1652 | sctp_chunk_free(asoc->addip_last_asconf); | ||
| 1653 | } | ||
diff --git a/net/sctp/sm_sideeffect.c b/net/sctp/sm_sideeffect.c index d612ca1ca6c0..534c2e5feb05 100644 --- a/net/sctp/sm_sideeffect.c +++ b/net/sctp/sm_sideeffect.c | |||
| @@ -1670,6 +1670,9 @@ static int sctp_cmd_interpreter(sctp_event_t event_type, | |||
| 1670 | case SCTP_CMD_SEND_NEXT_ASCONF: | 1670 | case SCTP_CMD_SEND_NEXT_ASCONF: |
| 1671 | sctp_cmd_send_asconf(asoc); | 1671 | sctp_cmd_send_asconf(asoc); |
| 1672 | break; | 1672 | break; |
| 1673 | case SCTP_CMD_PURGE_ASCONF_QUEUE: | ||
| 1674 | sctp_asconf_queue_teardown(asoc); | ||
| 1675 | break; | ||
| 1673 | default: | 1676 | default: |
| 1674 | pr_warn("Impossible command: %u, %p\n", | 1677 | pr_warn("Impossible command: %u, %p\n", |
| 1675 | cmd->verb, cmd->obj.ptr); | 1678 | cmd->verb, cmd->obj.ptr); |
diff --git a/net/sctp/sm_statefuns.c b/net/sctp/sm_statefuns.c index 7f4a4f8368ee..a297283154d5 100644 --- a/net/sctp/sm_statefuns.c +++ b/net/sctp/sm_statefuns.c | |||
| @@ -1718,11 +1718,21 @@ static sctp_disposition_t sctp_sf_do_dupcook_a(const struct sctp_endpoint *ep, | |||
| 1718 | return SCTP_DISPOSITION_CONSUME; | 1718 | return SCTP_DISPOSITION_CONSUME; |
| 1719 | } | 1719 | } |
| 1720 | 1720 | ||
| 1721 | /* For now, fail any unsent/unacked data. Consider the optional | 1721 | /* For now, stop pending T3-rtx and SACK timers, fail any unsent/unacked |
| 1722 | * choice of resending of this data. | 1722 | * data. Consider the optional choice of resending of this data. |
| 1723 | */ | 1723 | */ |
| 1724 | sctp_add_cmd_sf(commands, SCTP_CMD_T3_RTX_TIMERS_STOP, SCTP_NULL()); | ||
| 1725 | sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP, | ||
| 1726 | SCTP_TO(SCTP_EVENT_TIMEOUT_SACK)); | ||
| 1724 | sctp_add_cmd_sf(commands, SCTP_CMD_PURGE_OUTQUEUE, SCTP_NULL()); | 1727 | sctp_add_cmd_sf(commands, SCTP_CMD_PURGE_OUTQUEUE, SCTP_NULL()); |
| 1725 | 1728 | ||
| 1729 | /* Stop pending T4-rto timer, teardown ASCONF queue, ASCONF-ACK queue | ||
| 1730 | * and ASCONF-ACK cache. | ||
| 1731 | */ | ||
| 1732 | sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP, | ||
| 1733 | SCTP_TO(SCTP_EVENT_TIMEOUT_T4_RTO)); | ||
| 1734 | sctp_add_cmd_sf(commands, SCTP_CMD_PURGE_ASCONF_QUEUE, SCTP_NULL()); | ||
| 1735 | |||
| 1726 | repl = sctp_make_cookie_ack(new_asoc, chunk); | 1736 | repl = sctp_make_cookie_ack(new_asoc, chunk); |
| 1727 | if (!repl) | 1737 | if (!repl) |
| 1728 | goto nomem; | 1738 | goto nomem; |
