#include <vnet/sctp/sctp.h>
#include <vnet/sctp/sctp_debug.h>
#include <vppinfra/random.h>
+#include <openssl/hmac.h>
vlib_node_registration_t sctp4_output_node;
vlib_node_registration_t sctp6_output_node;
init_chunk->sctp_hdr.dst_port);
}
-u64
-sctp_compute_mac ()
+void
+sctp_compute_mac (sctp_connection_t * sctp_conn,
+ sctp_state_cookie_param_t * state_cookie)
{
- return 0x0;
+#if OPENSSL_VERSION_NUMBER >= 0x10100000L
+ HMAC_CTX *ctx;
+#else
+ HMAC_CTX ctx;
+ const EVP_MD *md = EVP_sha1 ();
+#endif
+ unsigned int len = 0;
+
+#if OPENSSL_VERSION_NUMBER >= 0x10100000L
+ ctx = HMAC_CTX_new ();
+ HMAC_Init_ex (&ctx, &state_cookie->creation_time,
+ sizeof (state_cookie->creation_time), md, NULL);
+ HMAC_Update (ctx, (const unsigned char *) &sctp_conn, sizeof (sctp_conn));
+ HMAC_Final (ctx, state_cookie->mac, &len);
+#else
+ HMAC_CTX_init (&ctx);
+ HMAC_Init_ex (&ctx, &state_cookie->creation_time,
+ sizeof (state_cookie->creation_time), md, NULL);
+
+ HMAC_Update (&ctx, (const unsigned char *) &sctp_conn, sizeof (sctp_conn));
+ HMAC_Final (&ctx, state_cookie->mac, &len);
+ HMAC_CTX_cleanup (&ctx);
+#endif
+
+ ENDIANESS_SWAP (state_cookie->mac);
}
void
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;
}
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;
}
state_cookie_param->creation_time = clib_host_to_net_u32 (sctp_time_now ());
state_cookie_param->cookie_lifespan =
clib_host_to_net_u32 (SCTP_VALID_COOKIE_LIFE);
- state_cookie_param->mac = clib_host_to_net_u64 (sctp_compute_mac ());
+
+ sctp_compute_mac (sctp_conn, state_cookie_param);
pointer_offset += sizeof (sctp_state_cookie_param_t);
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;
}
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 ();
}
/**
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;
}
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
vnet_sctp_set_chunk_type (&data_chunk->chunk_hdr, DATA);
vnet_sctp_set_chunk_length (&data_chunk->chunk_hdr, chunk_length);
+ vnet_sctp_set_bbit (&data_chunk->chunk_hdr);
+ vnet_sctp_set_ebit (&data_chunk->chunk_hdr);
+
SCTP_ADV_DBG_OUTPUT ("POINTER_WITH_DATA = %p, DATA_OFFSET = %u",
b->data, b->current_data);
{
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;
{
/* 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;