SCTP: calculate RTO / RTT and RTTVAR as per RFC
This patch addresses the need to calculate the RTO / RTT and RTTVAR
according to the rules depicted by the RFC4960 at section 6.3.1
Change-Id: I1d346f3c67610070b3f602f32c7738d58b99ffed
Signed-off-by: Marco Varlese <marco.varlese@suse.com>
diff --git a/src/vnet/sctp/sctp_output.c b/src/vnet/sctp/sctp_output.c
index 3d870ff..ed9ffd3 100644
--- a/src/vnet/sctp/sctp_output.c
+++ b/src/vnet/sctp/sctp_output.c
@@ -556,6 +556,9 @@
vnet_sctp_set_chunk_type (&cookie_ack_chunk->chunk_hdr, COOKIE_ACK);
vnet_sctp_set_chunk_length (&cookie_ack_chunk->chunk_hdr, chunk_len);
+ /* Measure RTT with this */
+ sctp_conn->sub_conn[idx].rtt_ts = sctp_time_now ();
+
vnet_buffer (b)->sctp.connection_index =
sctp_conn->sub_conn[idx].connection.c_index;
}
@@ -589,6 +592,10 @@
vnet_sctp_set_chunk_length (&cookie_echo_chunk->chunk_hdr, chunk_len);
clib_memcpy (&(cookie_echo_chunk->cookie), sc,
sizeof (sctp_state_cookie_param_t));
+
+ /* Measure RTT with this */
+ sctp_conn->sub_conn[idx].rtt_ts = sctp_time_now ();
+
vnet_buffer (b)->sctp.connection_index =
sctp_conn->sub_conn[idx].connection.c_index;
}
@@ -732,6 +739,9 @@
sctp_conn->local_tag = init_ack_chunk->initiate_tag;
+ /* Measure RTT with this */
+ sctp_conn->sub_conn[idx].rtt_ts = sctp_time_now ();
+
vnet_buffer (b)->sctp.connection_index =
sctp_conn->sub_conn[idx].connection.c_index;
}
@@ -799,6 +809,9 @@
sctp_push_ip_hdr (tm, &sctp_conn->sub_conn[idx], b);
sctp_enqueue_to_output_now (vm, b, bi,
sctp_conn->sub_conn[idx].connection.is_ip4);
+
+ /* Measure RTT with this */
+ sctp_conn->sub_conn[idx].rtt_ts = sctp_time_now ();
}
/**
@@ -858,8 +871,12 @@
sctp_enqueue_to_ip_lookup (vm, b, bi,
sctp_conn->sub_conn[idx].connection.is_ip4);
+ /* Measure RTT with this */
+ sctp_conn->sub_conn[idx].rtt_ts = sctp_time_now ();
+
/* Start the SCTP_TIMER_T2_SHUTDOWN timer */
- sctp_timer_set (sctp_conn, idx, SCTP_TIMER_T2_SHUTDOWN, SCTP_RTO_INIT);
+ sctp_timer_set (sctp_conn, idx, SCTP_TIMER_T2_SHUTDOWN,
+ sctp_conn->sub_conn[idx].RTO);
sctp_conn->state = SCTP_STATE_SHUTDOWN_ACK_SENT;
}
@@ -1034,35 +1051,28 @@
sctp_init_buffer (vm, b);
sctp_prepare_init_chunk (sctp_conn, b);
- /* Measure RTT with this */
- sctp_conn->rtt_ts = sctp_time_now ();
- sctp_conn->rtt_seq = sctp_conn->next_tsn;
-
sctp_push_ip_hdr (tm, &sctp_conn->sub_conn[idx], b);
sctp_enqueue_to_ip_lookup_now (vm, b, bi,
sctp_conn->sub_conn[idx].c_is_ip4);
+ /* Measure RTT with this */
+ sctp_conn->sub_conn[idx].rtt_ts = sctp_time_now ();
+
/* Start the T1_INIT timer */
- sctp_timer_set (sctp_conn, idx, SCTP_TIMER_T1_INIT, SCTP_RTO_INIT);
+ sctp_timer_set (sctp_conn, idx, SCTP_TIMER_T1_INIT,
+ sctp_conn->sub_conn[idx].RTO);
+
/* Change state to COOKIE_WAIT */
sctp_conn->state = SCTP_STATE_COOKIE_WAIT;
}
-always_inline u8
-sctp_in_cong_recovery (sctp_connection_t * sctp_conn)
-{
- return 0;
-}
-
/**
* Push SCTP header and update connection variables
*/
static void
-sctp_push_hdr_i (sctp_connection_t * sctp_conn, vlib_buffer_t * b,
+sctp_push_hdr_i (sctp_connection_t * sctp_conn, u8 idx, vlib_buffer_t * b,
sctp_state_t next_state)
{
- u8 idx = sctp_pick_conn_idx_on_chunk (DATA);
-
u16 data_len =
b->current_length + b->total_length_not_including_first_buffer;
ASSERT (!b->total_length_not_including_first_buffer
@@ -1112,13 +1122,17 @@
{
sctp_connection_t *sctp_conn =
sctp_get_connection_from_transport (trans_conn);
- sctp_push_hdr_i (sctp_conn, b, SCTP_STATE_ESTABLISHED);
- if (sctp_conn->rtt_ts == 0 && !sctp_in_cong_recovery (sctp_conn))
+ u8 idx = sctp_pick_conn_idx_on_chunk (DATA);
+
+ sctp_push_hdr_i (sctp_conn, idx, b, SCTP_STATE_ESTABLISHED);
+
+ if (sctp_conn->sub_conn[idx].RTO_pending == 0)
{
- sctp_conn->rtt_ts = sctp_time_now ();
- sctp_conn->rtt_seq = sctp_conn->next_tsn;
+ sctp_conn->sub_conn[idx].RTO_pending = 1;
+ sctp_conn->sub_conn[idx].rtt_ts = sctp_time_now ();
}
+
sctp_trajectory_add_start (b0, 3);
return 0;
@@ -1341,14 +1355,14 @@
{
/* Start the SCTP_TIMER_T2_SHUTDOWN timer */
sctp_timer_set (sctp_conn, idx, SCTP_TIMER_T2_SHUTDOWN,
- SCTP_RTO_INIT);
+ sctp_conn->sub_conn[idx].RTO);
sctp_conn->state = SCTP_STATE_SHUTDOWN_SENT;
}
if (chunk_type == DATA)
{
sctp_timer_update (sctp_conn, idx, SCTP_TIMER_T3_RXTX,
- SCTP_RTO_INIT);
+ sctp_conn->sub_conn[idx].RTO);
}
vnet_buffer (b0)->sw_if_index[VLIB_RX] = 0;