Commit a000c01e authored by Wei Yongjun's avatar Wei Yongjun Committed by David S. Miller

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: default avatarWei Yongjun <yjwei@cn.fujitsu.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent b10cec8a
...@@ -107,6 +107,7 @@ typedef enum { ...@@ -107,6 +107,7 @@ typedef enum {
SCTP_CMD_UPDATE_INITTAG, /* Update peer inittag */ SCTP_CMD_UPDATE_INITTAG, /* Update peer inittag */
SCTP_CMD_SEND_MSG, /* Send the whole use message */ SCTP_CMD_SEND_MSG, /* Send the whole use message */
SCTP_CMD_SEND_NEXT_ASCONF, /* Send the next ASCONF after ACK */ SCTP_CMD_SEND_NEXT_ASCONF, /* Send the next ASCONF after ACK */
SCTP_CMD_PURGE_ASCONF_QUEUE, /* Purge all asconf queues.*/
SCTP_CMD_LAST SCTP_CMD_LAST
} sctp_verb_t; } sctp_verb_t;
......
...@@ -1993,7 +1993,7 @@ void sctp_assoc_clean_asconf_ack_cache(const struct sctp_association *asoc); ...@@ -1993,7 +1993,7 @@ void sctp_assoc_clean_asconf_ack_cache(const struct sctp_association *asoc);
struct sctp_chunk *sctp_assoc_lookup_asconf_ack( struct sctp_chunk *sctp_assoc_lookup_asconf_ack(
const struct sctp_association *asoc, const struct sctp_association *asoc,
__be32 serial); __be32 serial);
void sctp_asconf_queue_teardown(struct sctp_association *asoc);
int sctp_cmp_addr_exact(const union sctp_addr *ss1, int sctp_cmp_addr_exact(const union sctp_addr *ss1,
const union sctp_addr *ss2); const union sctp_addr *ss2);
......
...@@ -444,15 +444,7 @@ void sctp_association_free(struct sctp_association *asoc) ...@@ -444,15 +444,7 @@ void sctp_association_free(struct sctp_association *asoc)
asoc->peer.transport_count = 0; asoc->peer.transport_count = 0;
/* Free any cached ASCONF_ACK chunk. */ sctp_asconf_queue_teardown(asoc);
sctp_assoc_free_asconf_acks(asoc);
/* Free the ASCONF queue. */
sctp_assoc_free_asconf_queue(asoc);
/* Free any cached ASCONF chunk. */
if (asoc->addip_last_asconf)
sctp_chunk_free(asoc->addip_last_asconf);
/* AUTH - Free the endpoint shared keys */ /* AUTH - Free the endpoint shared keys */
sctp_auth_destroy_keys(&asoc->endpoint_shared_keys); sctp_auth_destroy_keys(&asoc->endpoint_shared_keys);
...@@ -1646,3 +1638,16 @@ struct sctp_chunk *sctp_assoc_lookup_asconf_ack( ...@@ -1646,3 +1638,16 @@ struct sctp_chunk *sctp_assoc_lookup_asconf_ack(
return NULL; return NULL;
} }
void sctp_asconf_queue_teardown(struct sctp_association *asoc)
{
/* Free any cached ASCONF_ACK chunk. */
sctp_assoc_free_asconf_acks(asoc);
/* Free the ASCONF queue. */
sctp_assoc_free_asconf_queue(asoc);
/* Free any cached ASCONF chunk. */
if (asoc->addip_last_asconf)
sctp_chunk_free(asoc->addip_last_asconf);
}
...@@ -1670,6 +1670,9 @@ static int sctp_cmd_interpreter(sctp_event_t event_type, ...@@ -1670,6 +1670,9 @@ static int sctp_cmd_interpreter(sctp_event_t event_type,
case SCTP_CMD_SEND_NEXT_ASCONF: case SCTP_CMD_SEND_NEXT_ASCONF:
sctp_cmd_send_asconf(asoc); sctp_cmd_send_asconf(asoc);
break; break;
case SCTP_CMD_PURGE_ASCONF_QUEUE:
sctp_asconf_queue_teardown(asoc);
break;
default: default:
pr_warn("Impossible command: %u, %p\n", pr_warn("Impossible command: %u, %p\n",
cmd->verb, cmd->obj.ptr); cmd->verb, cmd->obj.ptr);
......
...@@ -1718,11 +1718,21 @@ static sctp_disposition_t sctp_sf_do_dupcook_a(const struct sctp_endpoint *ep, ...@@ -1718,11 +1718,21 @@ static sctp_disposition_t sctp_sf_do_dupcook_a(const struct sctp_endpoint *ep,
return SCTP_DISPOSITION_CONSUME; return SCTP_DISPOSITION_CONSUME;
} }
/* For now, fail any unsent/unacked data. Consider the optional /* For now, stop pending T3-rtx and SACK timers, fail any unsent/unacked
* choice of resending of this data. * data. Consider the optional choice of resending of this data.
*/ */
sctp_add_cmd_sf(commands, SCTP_CMD_T3_RTX_TIMERS_STOP, SCTP_NULL());
sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP,
SCTP_TO(SCTP_EVENT_TIMEOUT_SACK));
sctp_add_cmd_sf(commands, SCTP_CMD_PURGE_OUTQUEUE, SCTP_NULL()); sctp_add_cmd_sf(commands, SCTP_CMD_PURGE_OUTQUEUE, SCTP_NULL());
/* Stop pending T4-rto timer, teardown ASCONF queue, ASCONF-ACK queue
* and ASCONF-ACK cache.
*/
sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP,
SCTP_TO(SCTP_EVENT_TIMEOUT_T4_RTO));
sctp_add_cmd_sf(commands, SCTP_CMD_PURGE_ASCONF_QUEUE, SCTP_NULL());
repl = sctp_make_cookie_ack(new_asoc, chunk); repl = sctp_make_cookie_ack(new_asoc, chunk);
if (!repl) if (!repl)
goto nomem; goto nomem;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment