- tcp_worker_ctx_t *wrk = tcp_get_worker (thread_index);
-
- tcp_set_time_now (wrk);
- tw_timer_expire_timers_16t_2w_512sl (&wrk->timer_wheel, now);
- tcp_do_fastretransmits (wrk);
- tcp_send_acks (wrk);
- tcp_flush_frames_to_output (wrk);
-}
-
-static void
-tcp_session_flush_data (transport_connection_t * tconn)
-{
- tcp_connection_t *tc = (tcp_connection_t *) tconn;
- if (tc->flags & TCP_CONN_PSH_PENDING)
- return;
- tc->flags |= TCP_CONN_PSH_PENDING;
- tc->psh_seq = tc->snd_una_max + transport_max_tx_dequeue (tconn) - 1;
-}
-
-/* *INDENT-OFF* */
-const static transport_proto_vft_t tcp_proto = {
- .enable = vnet_tcp_enable_disable,
- .start_listen = tcp_session_bind,
- .stop_listen = tcp_session_unbind,
- .push_header = tcp_session_push_header,
- .get_connection = tcp_session_get_transport,
- .get_listener = tcp_session_get_listener,
- .get_half_open = tcp_half_open_session_get_transport,
- .connect = tcp_session_open,
- .close = tcp_session_close,
- .cleanup = tcp_session_cleanup,
- .send_mss = tcp_session_send_mss,
- .send_space = tcp_session_send_space,
- .update_time = tcp_update_time,
- .tx_fifo_offset = tcp_session_tx_fifo_offset,
- .flush_data = tcp_session_flush_data,
- .format_connection = format_tcp_session,
- .format_listener = format_tcp_listener_session,
- .format_half_open = format_tcp_half_open_session,
- .tx_type = TRANSPORT_TX_PEEK,
- .service_type = TRANSPORT_SERVICE_VC,
-};
-/* *INDENT-ON* */
-
-void
-tcp_connection_tx_pacer_update (tcp_connection_t * tc)
-{
- f64 srtt;
- u64 rate;
-
- if (!transport_connection_is_tx_paced (&tc->connection))
- return;
-
- srtt = clib_min ((f64) tc->srtt * TCP_TICK, tc->mrtt_us);
- /* TODO should constrain to interface's max throughput but
- * we don't have link speeds for sw ifs ..*/
- rate = tc->cwnd / srtt;
- transport_connection_tx_pacer_update (&tc->connection, rate);
-}
-
-void
-tcp_connection_tx_pacer_reset (tcp_connection_t * tc, u32 window,
- u32 start_bucket)
-{
- tcp_worker_ctx_t *wrk = tcp_get_worker (tc->c_thread_index);
- u32 byte_rate = window / ((f64) TCP_TICK * tc->srtt);
- u64 last_time = wrk->vm->clib_time.last_cpu_time;
- transport_connection_tx_pacer_reset (&tc->connection, byte_rate,
- start_bucket, last_time);
-}
-
-static void
-tcp_timer_keep_handler (u32 conn_index)
-{
- u32 thread_index = vlib_get_thread_index ();
- tcp_connection_t *tc;
-
- tc = tcp_connection_get (conn_index, thread_index);
- tc->timers[TCP_TIMER_KEEP] = TCP_TIMER_HANDLE_INVALID;
-
- tcp_connection_close (tc);
-}
-
-static void
-tcp_timer_establish_handler (u32 conn_index)
-{
- tcp_connection_t *tc;
-
- tc = tcp_connection_get (conn_index, vlib_get_thread_index ());
- /* note: the connection may have already disappeared */
- if (PREDICT_FALSE (tc == 0))
- return;
- ASSERT (tc->state == TCP_STATE_SYN_RCVD);
- tc->timers[TCP_TIMER_ESTABLISH] = TCP_TIMER_HANDLE_INVALID;
- tcp_connection_set_state (tc, TCP_STATE_CLOSED);
- /* Start cleanup. App wasn't notified yet so use delete notify as
- * opposed to delete to cleanup session layer state. */
- tcp_connection_timers_reset (tc);
- session_transport_delete_notify (&tc->connection);
- tcp_timer_update (tc, TCP_TIMER_WAITCLOSE, TCP_CLEANUP_TIME);
-}
-
-static void
-tcp_timer_establish_ao_handler (u32 conn_index)
-{
- tcp_connection_t *tc;
-
- tc = tcp_half_open_connection_get (conn_index);
- if (!tc)
- return;
-
- ASSERT (tc->state == TCP_STATE_SYN_SENT);
- /* Notify app if we haven't tried to clean this up already */
- if (!(tc->flags & TCP_CONN_HALF_OPEN_DONE))
- session_stream_connect_notify (&tc->connection, 1 /* fail */ );
-
- tc->timers[TCP_TIMER_ESTABLISH_AO] = TCP_TIMER_HANDLE_INVALID;
- tcp_connection_cleanup (tc);
-}
-
-static void
-tcp_timer_waitclose_handler (u32 conn_index)
-{
- u32 thread_index = vlib_get_thread_index (), rto;
- tcp_connection_t *tc;
-
- tc = tcp_connection_get (conn_index, thread_index);
- if (!tc)
- return;
- tc->timers[TCP_TIMER_WAITCLOSE] = TCP_TIMER_HANDLE_INVALID;
-