#include <vnet/tcp/tcp.h>
#include <vnet/tcp/tcp_inlines.h>
#include <math.h>
+#include <vnet/ip/ip4_inlines.h>
+#include <vnet/ip/ip6_inlines.h>
typedef enum _tcp_output_next
{
len += TCP_OPTION_LEN_WINDOW_SCALE;
opts->flags |= TCP_OPTS_FLAG_TSTAMP;
- opts->tsval = tcp_time_now ();
+ opts->tsval = tcp_time_tstamp (tc->c_thread_index);
opts->tsecr = 0;
len += TCP_OPTION_LEN_TIMESTAMP;
if (tcp_opts_tstamp (&tc->rcv_opts))
{
opts->flags |= TCP_OPTS_FLAG_TSTAMP;
- opts->tsval = tcp_time_now ();
+ opts->tsval = tcp_time_tstamp (tc->c_thread_index);
opts->tsecr = tc->tsval_recent;
len += TCP_OPTION_LEN_TIMESTAMP;
}
tcp_cc_event (tc, TCP_CC_EVT_START_TX);
tcp_connection_tx_pacer_reset (tc, tc->cwnd, TRANSPORT_PACER_MIN_BURST);
}
+
+ if (tc->flags & TCP_CONN_PSH_PENDING)
+ {
+ u32 max_deq = transport_max_tx_dequeue (&tc->connection);
+ /* Last byte marked for push */
+ tc->psh_seq = tc->snd_una + max_deq - 1;
+ }
}
#endif /* CLIB_MARCH_VARIANT */
}
else
{
- b->flags |= VNET_BUFFER_F_OFFLOAD_TCP_CKSUM;
+ vnet_buffer_offload_flags_set (b, VNET_BUFFER_OFFLOAD_F_TCP_CKSUM);
}
return checksum;
}
vnet_buffer (b)->tcp.connection_index = tc->c_c_index;
if (wnd == 0)
- tcp_zero_rwnd_sent_on (tc);
+ {
+ transport_rx_fifo_req_deq_ntf (&tc->connection);
+ tcp_zero_rwnd_sent_on (tc);
+ }
else
tcp_zero_rwnd_sent_off (tc);
}
vlib_buffer_t *b;
u32 bi;
- tcp_retransmit_timer_force_update (&wrk->timer_wheel, tc);
+ ASSERT (tc->snd_una != tc->snd_nxt);
+ tcp_retransmit_timer_update (&wrk->timer_wheel, tc);
if (PREDICT_FALSE (!vlib_buffer_alloc (vm, &bi, 1)))
{
if ((tc->flags & TCP_CONN_SNDACK) && !tc->pending_dupacks)
tc->flags &= ~TCP_CONN_SNDACK;
- tcp_retransmit_timer_force_update (&wrk->timer_wheel, tc);
b = vlib_get_buffer (vm, bi);
tcp_init_buffer (vm, b);
tcp_make_fin (tc, b);
TCP_EVT (TCP_EVT_FIN_SENT, tc);
/* Account for the FIN */
tc->snd_nxt += 1;
+ tcp_retransmit_timer_update (&wrk->timer_wheel, tc);
if (!fin_snt)
{
tc->flags |= TCP_CONN_FINSNT;
tc->flags &= ~TCP_CONN_FINPNDG;
- tc->snd_una_max = seq_max (tc->snd_una_max, tc->snd_nxt);
}
}
tcp_push_hdr_i (tc, b, tc->snd_nxt, /* compute opts */ 0, /* burst */ 1,
/* update_snd_nxt */ 1);
- tc->snd_una_max = seq_max (tc->snd_nxt, tc->snd_una_max);
- tcp_validate_txf_size (tc, tc->snd_una_max - tc->snd_una);
+ tcp_validate_txf_size (tc, tc->snd_nxt - tc->snd_una);
/* If not tracking an ACK, start tracking */
if (tc->rtt_ts == 0 && !tcp_in_cong_recovery (tc))
{
tc->rtt_ts = 0;
tc->cwnd_acc_bytes = 0;
tc->tr_occurences += 1;
+ tc->sack_sb.reorder = TCP_DUPACK_THRESHOLD;
tcp_recovery_on (tc);
}
return;
}
- /* Shouldn't be here. This condition is tricky because it has to take
- * into account boff > 0 due to persist timeout. */
- if ((tc->rto_boff == 0 && tc->snd_una == tc->snd_nxt)
- || (tc->rto_boff > 0 && seq_geq (tc->snd_una, tc->snd_congestion)
- && !tcp_flight_size (tc)))
+ /* Shouldn't be here */
+ if (tc->snd_una == tc->snd_nxt)
{
ASSERT (!tcp_in_recovery (tc));
tc->rto_boff = 0;
tcp_enqueue_to_output (wrk, b, bi, tc->c_is_ip4);
tc->rto = clib_min (tc->rto << 1, TCP_RTO_MAX);
- tcp_retransmit_timer_force_update (&wrk->timer_wheel, tc);
+ tcp_retransmit_timer_update (&wrk->timer_wheel, tc);
tc->rto_boff += 1;
if (tc->rto_boff == 1)
if (tc->rto_boff > TCP_RTO_SYN_RETRIES)
tc->rto = clib_min (tc->rto << 1, TCP_RTO_MAX);
- tcp_retransmit_timer_force_update (&wrk->timer_wheel, tc);
+ ASSERT (tc->snd_una != tc->snd_nxt);
+ tcp_retransmit_timer_update (&wrk->timer_wheel, tc);
b = vlib_get_buffer (vm, bi);
tcp_init_buffer (vm, b);
max_snd_bytes);
b->current_length = n_bytes;
ASSERT (n_bytes != 0 && (tcp_timer_is_active (tc, TCP_TIMER_RETRANSMIT)
- || tc->snd_nxt == tc->snd_una_max
+ || tc->snd_una == tc->snd_nxt
|| tc->rto_boff > 1));
if (tc->cfg_flags & TCP_CFG_F_RATE_SAMPLE)
tcp_push_hdr_i (tc, b, tc->snd_nxt, /* compute opts */ 0,
/* burst */ 0, /* update_snd_nxt */ 1);
- tc->snd_una_max = seq_max (tc->snd_nxt, tc->snd_una_max);
- tcp_validate_txf_size (tc, tc->snd_una_max - tc->snd_una);
+ tcp_validate_txf_size (tc, tc->snd_nxt - tc->snd_una);
tcp_enqueue_to_output (wrk, b, bi, tc->c_is_ip4);
/* Just sent new data, enable retransmit */
tcp_bt_track_tx (tc, n_written);
tc->snd_nxt += n_written;
- tc->snd_una_max = seq_max (tc->snd_nxt, tc->snd_una_max);
}
done:
from = vlib_frame_vector_args (frame);
n_left_from = frame->n_vectors;
- tcp_set_time_now (tcp_get_worker (thread_index));
+ tcp_update_time_now (tcp_get_worker (thread_index));
if (PREDICT_FALSE (node->flags & VLIB_NODE_FLAG_TRACE))
tcp46_output_trace_frame (vm, node, from, n_left_from);