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 */
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;
*/
if (!tcp_rcv_ack_is_acceptable (tc0, b0))
{
- TCP_DBG ("connection not accepted");
- tcp_send_reset_w_pkt (tc0, b0, is_ip4);
+ tcp_connection_reset (tc0);
error0 = TCP_ERROR_ACK_INVALID;
goto drop;
}
/* Make sure the ack is exactly right */
- if (tc0->rcv_nxt != vnet_buffer (b0)->tcp.seq_number)
+ if (tc0->rcv_nxt != vnet_buffer (b0)->tcp.seq_number || is_fin0)
{
+ tcp_connection_reset (tc0);
error0 = TCP_ERROR_SEGMENT_INVALID;
- tcp_send_reset_w_pkt (tc0, b0, is_ip4);
goto drop;
}
}
/* Create child session and send SYN-ACK */
- child0 = tcp_connection_new (my_thread_index);
+ child0 = tcp_connection_alloc (my_thread_index);
child0->c_lcl_port = th0->dst_port;
child0->c_rmt_port = th0->src_port;
child0->c_is_ip4 = is_ip4;
if (tcp_options_parse (th0, &child0->rcv_opts, 1))
{
- clib_warning ("options parse fail");
+ error0 = TCP_ERROR_OPTIONS;
+ tcp_connection_free (child0);
goto drop;
}