X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;f=src%2Fvnet%2Fsctp%2Fsctp_output.c;h=ed9ffd36262f320ffbf7a31070d3e7fd9ce8c579;hb=f47276f6fcf75197fb237b7742e45638fc750b8e;hp=7b22cc59ac451d1b2b22f4b827e3b3be68b33e84;hpb=8ad6a2dfed0a7248be9d005dd04c76da142f2238;p=vpp.git diff --git a/src/vnet/sctp/sctp_output.c b/src/vnet/sctp/sctp_output.c index 7b22cc59ac4..ed9ffd36262 100644 --- a/src/vnet/sctp/sctp_output.c +++ b/src/vnet/sctp/sctp_output.c @@ -15,6 +15,7 @@ #include #include #include +#include vlib_node_registration_t sctp4_output_node; vlib_node_registration_t sctp6_output_node; @@ -494,10 +495,35 @@ sctp_prepare_init_chunk (sctp_connection_t * sctp_conn, vlib_buffer_t * b) 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 @@ -530,6 +556,9 @@ sctp_prepare_cookie_ack_chunk (sctp_connection_t * sctp_conn, 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; } @@ -563,6 +592,10 @@ sctp_prepare_cookie_echo_chunk (sctp_connection_t * sctp_conn, 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; } @@ -626,7 +659,8 @@ sctp_prepare_initack_chunk (sctp_connection_t * sctp_conn, vlib_buffer_t * b, 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); @@ -705,6 +739,9 @@ sctp_prepare_initack_chunk (sctp_connection_t * sctp_conn, vlib_buffer_t * b, 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; } @@ -772,6 +809,9 @@ sctp_send_shutdown (sctp_connection_t * sctp_conn) 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 (); } /** @@ -831,8 +871,12 @@ sctp_send_shutdown_ack (sctp_connection_t * sctp_conn) 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; } @@ -1007,35 +1051,28 @@ sctp_send_init (sctp_connection_t * sctp_conn) 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 @@ -1068,6 +1105,9 @@ sctp_push_hdr_i (sctp_connection_t * sctp_conn, vlib_buffer_t * b, 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); @@ -1082,13 +1122,17 @@ sctp_push_header (transport_connection_t * trans_conn, vlib_buffer_t * b) { 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; @@ -1311,14 +1355,14 @@ sctp46_output_inline (vlib_main_t * vm, { /* 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;