Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

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
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -107,6 +107,7 @@ typedef enum {
	SCTP_CMD_UPDATE_INITTAG, /* Update peer inittag */
	SCTP_CMD_SEND_MSG,	 /* Send the whole use message */
	SCTP_CMD_SEND_NEXT_ASCONF, /* Send the next ASCONF after ACK */
	SCTP_CMD_PURGE_ASCONF_QUEUE, /* Purge all asconf queues.*/
	SCTP_CMD_LAST
} sctp_verb_t;

+1 −1
Original line number Diff line number Diff line
@@ -1993,7 +1993,7 @@ void sctp_assoc_clean_asconf_ack_cache(const struct sctp_association *asoc);
struct sctp_chunk *sctp_assoc_lookup_asconf_ack(
					const struct sctp_association *asoc,
					__be32 serial);

void sctp_asconf_queue_teardown(struct sctp_association *asoc);

int sctp_cmp_addr_exact(const union sctp_addr *ss1,
			const union sctp_addr *ss2);
+14 −9
Original line number Diff line number Diff line
@@ -444,15 +444,7 @@ void sctp_association_free(struct sctp_association *asoc)

	asoc->peer.transport_count = 0;

	/* 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);
	sctp_asconf_queue_teardown(asoc);

	/* AUTH - Free the endpoint shared keys */
	sctp_auth_destroy_keys(&asoc->endpoint_shared_keys);
@@ -1646,3 +1638,16 @@ struct sctp_chunk *sctp_assoc_lookup_asconf_ack(

	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);
}
+3 −0
Original line number Diff line number Diff line
@@ -1670,6 +1670,9 @@ static int sctp_cmd_interpreter(sctp_event_t event_type,
		case SCTP_CMD_SEND_NEXT_ASCONF:
			sctp_cmd_send_asconf(asoc);
			break;
		case SCTP_CMD_PURGE_ASCONF_QUEUE:
			sctp_asconf_queue_teardown(asoc);
			break;
		default:
			pr_warn("Impossible command: %u, %p\n",
				cmd->verb, cmd->obj.ptr);
+12 −2
Original line number Diff line number Diff line
@@ -1718,11 +1718,21 @@ static sctp_disposition_t sctp_sf_do_dupcook_a(const struct sctp_endpoint *ep,
		return SCTP_DISPOSITION_CONSUME;
	}

	/* For now, fail any unsent/unacked data.  Consider the optional
	 * choice of resending of this data.
	/* For now, stop pending T3-rtx and SACK timers, fail any unsent/unacked
	 * 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());

	/* 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);
	if (!repl)
		goto nomem;