summaryrefslogtreecommitdiffstats
path: root/src/vnet/sctp/sctp_input.c
diff options
context:
space:
mode:
authorMarco Varlese <marco.varlese@suse.com>2018-03-05 12:31:45 +0100
committerDamjan Marion <dmarion.lists@gmail.com>2018-03-05 13:46:32 +0000
commit9e09ff394ac0e731b5b33caf4d0cddff8de570b4 (patch)
tree5fdb5784570dadce34afc4cfe824f51a3f00e948 /src/vnet/sctp/sctp_input.c
parenteac3b11b67a9ee2d5b85c3e2e90220a04cd5db61 (diff)
SCTP: retransmission in INIT/SHUTDOWN phase
This patch addresses the need to handle timers timeouts (e.g. sent chunks not being acked) for both the INIT and SHUTDOWN phases. The INIT phase requires the handling of two timers the T1-init and T1-cookie timers whilst the SHUTDOWN phase requires the handling of the T2-shutdown timer only for the retransmission case. Left to be implemented is the handling of the DATA chunks retransmission (e.g. T3-rxtx expiration) but that will be submitted with a separate patch. Change-Id: I2b2e13dce11000aea3c7d965f02b27b76c97e605 Signed-off-by: Marco Varlese <marco.varlese@suse.com>
Diffstat (limited to 'src/vnet/sctp/sctp_input.c')
-rw-r--r--src/vnet/sctp/sctp_input.c20
1 files changed, 17 insertions, 3 deletions
diff --git a/src/vnet/sctp/sctp_input.c b/src/vnet/sctp/sctp_input.c
index 00d0a61feff..70adc7c3e34 100644
--- a/src/vnet/sctp/sctp_input.c
+++ b/src/vnet/sctp/sctp_input.c
@@ -374,7 +374,7 @@ sctp_handle_init (sctp_header_t * sctp_hdr,
SCTP_CONN_TRACKING_DBG ("sctp_conn->remote_initial_tsn = %u",
sctp_conn->remote_initial_tsn);
- sctp_conn->snd_opts.a_rwnd = clib_net_to_host_u32 (init_chunk->a_rwnd);
+ sctp_conn->peer_rwnd = clib_net_to_host_u32 (init_chunk->a_rwnd);
/*
* If the length specified in the INIT message is bigger than the size in bytes of our structure it means that
@@ -500,6 +500,9 @@ sctp_handle_init_ack (sctp_header_t * sctp_hdr,
if (sctp_is_bundling (sctp_implied_length, &init_ack_chunk->chunk_hdr))
return SCTP_ERROR_BUNDLING_VIOLATION;
+ /* Stop the T1_INIT timer */
+ sctp_timer_reset (sctp_conn, idx, SCTP_TIMER_T1_INIT);
+
sctp_calculate_rto (sctp_conn, idx);
/* remote_tag to be placed in the VERIFICATION_TAG field of the COOKIE_ECHO chunk */
@@ -510,7 +513,7 @@ sctp_handle_init_ack (sctp_header_t * sctp_hdr,
sctp_conn->next_tsn_expected = sctp_conn->remote_initial_tsn + 1;
SCTP_CONN_TRACKING_DBG ("sctp_conn->remote_initial_tsn = %u",
sctp_conn->remote_initial_tsn);
- sctp_conn->snd_opts.a_rwnd = clib_net_to_host_u32 (init_ack_chunk->a_rwnd);
+ sctp_conn->peer_rwnd = clib_net_to_host_u32 (init_ack_chunk->a_rwnd);
u16 length = vnet_sctp_get_chunk_length (sctp_chunk_hdr);
@@ -585,7 +588,10 @@ sctp_handle_init_ack (sctp_header_t * sctp_hdr,
}
}
- sctp_prepare_cookie_echo_chunk (sctp_conn, idx, b0, &state_cookie);
+ clib_memcpy (&(sctp_conn->cookie_param), &state_cookie,
+ sizeof (sctp_state_cookie_param_t));
+
+ sctp_prepare_cookie_echo_chunk (sctp_conn, idx, b0, 1);
/* Start the T1_COOKIE timer */
sctp_timer_set (sctp_conn, idx,
@@ -705,6 +711,14 @@ sctp_session_enqueue_data (sctp_connection_t * sctp_conn, vlib_buffer_t * b,
always_inline u8
sctp_is_sack_delayable (sctp_connection_t * sctp_conn, u8 idx, u8 is_gapping)
{
+ /* Section 4.4 of the RFC4960 */
+ if (sctp_conn->state == SCTP_STATE_SHUTDOWN_SENT)
+ {
+ SCTP_CONN_TRACKING_DBG ("sctp_conn->state = %s; SACK not delayable",
+ sctp_state_to_string (sctp_conn->state));
+ return 0;
+ }
+
if (is_gapping != 0)
{
SCTP_CONN_TRACKING_DBG