tcp_time_now_w_thread (tc0->c_thread_index)))
{
tc0->tsval_recent = tc0->rcv_opts.tsval;
- clib_warning ("paws failed - really old segment. REALLY?");
+ clib_warning ("paws failed: 24-day old segment");
}
- else
+ /* Drop after ack if not rst. Resets can fail paws check as per
+ * RFC 7323 sec. 5.2: When an <RST> segment is received, it MUST NOT
+ * be subjected to the PAWS check by verifying an acceptable value in
+ * SEG.TSval */
+ else if (!tcp_rst (th0))
{
- /* Drop after ack if not rst */
- if (!tcp_rst (th0))
- {
- tcp_program_ack (wrk, tc0);
- TCP_EVT_DBG (TCP_EVT_DUPACK_SENT, tc0, vnet_buffer (b0)->tcp);
- }
+ tcp_program_ack (wrk, tc0);
+ TCP_EVT_DBG (TCP_EVT_DUPACK_SENT, tc0, vnet_buffer (b0)->tcp);
+ goto error;
}
- goto error;
}
/* 1st: check sequence number */
tc->burst_acked = 0;
tcp_validate_txf_size (tc, tc->snd_una_max - tc->snd_una);
+ if (PREDICT_FALSE (tc->flags & TCP_CONN_PSH_PENDING))
+ {
+ if (seq_leq (tc->psh_seq, tc->snd_una))
+ tc->flags &= ~TCP_CONN_PSH_PENDING;
+ }
+
/* If everything has been acked, stop retransmit timer
* otherwise update. */
tcp_retransmit_timer_update (tc);
{
if (seq_lt (blk->start, blk->end)
&& seq_gt (blk->start, tc->snd_una)
- && seq_gt (blk->start, ack) && seq_leq (blk->end, tc->snd_una_max))
+ && seq_gt (blk->start, ack)
+ && seq_lt (blk->start, tc->snd_una_max)
+ && seq_leq (blk->end, tc->snd_una_max))
{
blk++;
continue;
if (tcp_opts_wscale (&new_tc0->rcv_opts))
new_tc0->snd_wscale = new_tc0->rcv_opts.wscale;
+ else
+ new_tc0->rcv_wscale = 0;
new_tc0->snd_wnd = clib_net_to_host_u16 (tcp0->window)
<< new_tc0->snd_wscale;
goto drop;
}
+ /* Make sure the ack is exactly right */
+ if (tc0->rcv_nxt != vnet_buffer (b0)->tcp.seq_number || is_fin0)
+ {
+ error0 = TCP_ERROR_SEGMENT_INVALID;
+ tcp_send_reset_w_pkt (tc0, b0, is_ip4);
+ goto drop;
+ }
+
/* Update rtt and rto */
tcp_estimate_initial_rtt (tc0);