diff options
author | Marco Varlese <marco.varlese@suse.com> | 2018-03-05 12:31:45 +0100 |
---|---|---|
committer | Damjan Marion <dmarion.lists@gmail.com> | 2018-03-05 13:46:32 +0000 |
commit | 9e09ff394ac0e731b5b33caf4d0cddff8de570b4 (patch) | |
tree | 5fdb5784570dadce34afc4cfe824f51a3f00e948 /src/vnet/sctp/sctp_input.c | |
parent | eac3b11b67a9ee2d5b85c3e2e90220a04cd5db61 (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.c | 20 |
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 |