if (!(seq_leq (tc->snd_una, vnet_buffer (b)->tcp.ack_number)
&& seq_leq (vnet_buffer (b)->tcp.ack_number, tc->snd_nxt)))
{
- if (seq_leq (vnet_buffer (b)->tcp.ack_number, tc->snd_una_max)
+ if (seq_leq (vnet_buffer (b)->tcp.ack_number, tc->snd_nxt)
&& seq_gt (vnet_buffer (b)->tcp.ack_number, tc->snd_una))
{
tc->snd_nxt = vnet_buffer (b)->tcp.ack_number;
/* Dequeue the newly ACKed bytes */
session_tx_fifo_dequeue_drop (&tc->connection, tc->burst_acked);
- 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;
- }
+ tcp_validate_txf_size (tc, tc->snd_nxt - tc->snd_una);
if (tcp_is_descheduled (tc))
tcp_reschedule (tc);
{
/* We've probably entered recovery and the peer still has some
* of the data we've sent. Update snd_nxt and accept the ack */
- if (seq_leq (vnet_buffer (b)->tcp.ack_number, tc->snd_una_max)
+ if (seq_leq (vnet_buffer (b)->tcp.ack_number, tc->snd_nxt)
&& seq_gt (vnet_buffer (b)->tcp.ack_number, tc->snd_una))
{
tc->snd_nxt = vnet_buffer (b)->tcp.ack_number;
ASSERT (n_data_bytes);
tc->data_segs_in += 1;
+ /* Make sure we don't consume trailing bytes */
+ if (PREDICT_FALSE (b->current_length > n_data_bytes))
+ b->current_length = n_data_bytes;
+
/* Handle out-of-order data */
if (PREDICT_FALSE (vnet_buffer (b)->tcp.seq_number != tc->rcv_nxt))
{
goto cleanup_ho;
}
+ transport_fifos_init_ooo (&new_tc0->connection);
new_tc0->tx_fifo_size =
transport_tx_fifo_size (&new_tc0->connection);
/* Update rtt with the syn-ack sample */
goto cleanup_ho;
}
+ transport_fifos_init_ooo (&new_tc0->connection);
new_tc0->tx_fifo_size =
transport_tx_fifo_size (&new_tc0->connection);
new_tc0->rtt_ts = 0;
case TCP_STATE_FIN_WAIT_2:
if (vnet_buffer (b0)->tcp.data_len)
error0 = tcp_segment_rcv (wrk, tc0, b0);
+ /* Don't accept out of order fins lower */
+ if (vnet_buffer (b0)->tcp.seq_end != tc0->rcv_nxt)
+ goto drop;
break;
case TCP_STATE_CLOSE_WAIT:
case TCP_STATE_CLOSING:
lc = tcp_lookup_listener (b, tc->c_fib_index, is_ip4);
/* clean up the old session */
tcp_connection_del (tc);
+ /* listener was cleaned up */
+ if (!lc)
+ {
+ error = TCP_ERROR_NO_LISTENER;
+ goto done;
+ }
}
/* Make sure connection wasn't just created */
goto done;
}
+ transport_fifos_init_ooo (&child->connection);
child->tx_fifo_size = transport_tx_fifo_size (&child->connection);
tcp_send_synack (child);
if (PREDICT_FALSE (b->flags & VLIB_BUFFER_IS_TRACED))
{
- tcp_rx_trace_t *t;
- t = vlib_add_trace (vm, node, b, sizeof (*t));
- clib_memcpy_fast (&t->tcp_header, tcp_buffer_hdr (b),
- sizeof (t->tcp_header));
- clib_memcpy_fast (&t->tcp_connection, lc,
- sizeof (t->tcp_connection));
+ tcp_rx_trace_t *t = vlib_add_trace (vm, node, b, sizeof (*t));
+ tcp_set_rx_trace_data (t, lc, tcp_buffer_hdr (b), b, is_ip4);
}
n_syns += (error == TCP_ERROR_NONE);