aboutsummaryrefslogtreecommitdiffstats
path: root/src/vnet/tcp/tcp_input.c
diff options
context:
space:
mode:
authorFlorin Coras <fcoras@cisco.com>2017-08-18 19:28:03 -0700
committerDave Barach <openvpp@barachs.net>2017-08-25 16:39:42 +0000
commit1f152cd6faf96b524b6b7071b5cffe1916f9c5cc (patch)
treeb778792a51e949cd1133b5ca03e5645538e6cf1a /src/vnet/tcp/tcp_input.c
parent27de761048e561f849fdda690d69e5644a9360d4 (diff)
tcp: retransmit and multi-buffer segment fixes and improvements
- set session state as closed on session manager delete - enable retransmit as opposed to persist timer after persist timer completes - properly discard buffer chain bytes when new data overlaps ooo segments - don't use rxt bytes in snd space estimate used on tx path Change-Id: Id9cab686e532e5fe70c775d5440260e8eb890a9f Signed-off-by: Florin Coras <fcoras@cisco.com>
Diffstat (limited to 'src/vnet/tcp/tcp_input.c')
-rw-r--r--src/vnet/tcp/tcp_input.c27
1 files changed, 16 insertions, 11 deletions
diff --git a/src/vnet/tcp/tcp_input.c b/src/vnet/tcp/tcp_input.c
index 6f9e4c7a..95f9ade1 100644
--- a/src/vnet/tcp/tcp_input.c
+++ b/src/vnet/tcp/tcp_input.c
@@ -1363,7 +1363,7 @@ always_inline int
tcp_session_enqueue_data (tcp_connection_t * tc, vlib_buffer_t * b,
u16 data_len)
{
- int written;
+ int written, error = TCP_ERROR_ENQUEUED;
ASSERT (seq_geq (vnet_buffer (b)->tcp.seq_number, tc->rcv_nxt));
@@ -1381,12 +1381,12 @@ tcp_session_enqueue_data (tcp_connection_t * tc, vlib_buffer_t * b,
/* Update rcv_nxt */
if (PREDICT_TRUE (written == data_len))
{
- tc->rcv_nxt = vnet_buffer (b)->tcp.seq_end;
+ tc->rcv_nxt += written;
}
/* If more data written than expected, account for out-of-order bytes. */
else if (written > data_len)
{
- tc->rcv_nxt = vnet_buffer (b)->tcp.seq_end + written - data_len;
+ tc->rcv_nxt += written;
/* Send ACK confirming the update */
tc->flags |= TCP_CONN_SNDACK;
@@ -1400,7 +1400,7 @@ tcp_session_enqueue_data (tcp_connection_t * tc, vlib_buffer_t * b,
* not be enqueued. Inform peer */
tc->flags |= TCP_CONN_SNDACK;
- return TCP_ERROR_PARTIALLY_ENQUEUED;
+ error = TCP_ERROR_PARTIALLY_ENQUEUED;
}
else
{
@@ -1415,7 +1415,7 @@ tcp_session_enqueue_data (tcp_connection_t * tc, vlib_buffer_t * b,
tcp_update_sack_list (tc, tc->rcv_nxt, tc->rcv_nxt);
}
- return TCP_ERROR_ENQUEUED;
+ return error;
}
/** Enqueue out-of-order data */
@@ -1495,10 +1495,10 @@ tcp_can_delack (tcp_connection_t * tc)
static int
tcp_buffer_discard_bytes (vlib_buffer_t * b, u32 n_bytes_to_drop)
{
- u32 discard;
+ u32 discard, first = b->current_length;
vlib_main_t *vm = vlib_get_main ();
- /* Handle multi segment packets */
+ /* Handle multi-buffer segments */
if (n_bytes_to_drop > b->current_length)
{
if (!(b->flags & VLIB_BUFFER_NEXT_PRESENT))
@@ -1511,7 +1511,12 @@ tcp_buffer_discard_bytes (vlib_buffer_t * b, u32 n_bytes_to_drop)
n_bytes_to_drop -= discard;
}
while (n_bytes_to_drop);
+ if (n_bytes_to_drop > first)
+ b->total_length_not_including_first_buffer -= n_bytes_to_drop - first;
}
+ else
+ vlib_buffer_advance (b, n_bytes_to_drop);
+ vnet_buffer (b)->tcp.data_len -= n_bytes_to_drop;
return 0;
}
@@ -1908,7 +1913,7 @@ tcp46_syn_sent_inline (vlib_main_t * vm, vlib_node_runtime_t * node,
if (ack0 <= tc0->iss || ack0 > tc0->snd_nxt)
{
if (!tcp_rst (tcp0))
- tcp_send_reset (tc0, b0, is_ip4);
+ tcp_send_reset_w_pkt (tc0, b0, is_ip4);
goto drop;
}
@@ -1995,7 +2000,7 @@ tcp46_syn_sent_inline (vlib_main_t * vm, vlib_node_runtime_t * node,
* allocate session send reset */
if (stream_session_connect_notify (&new_tc0->connection, 0))
{
- tcp_send_reset (new_tc0, b0, is_ip4);
+ tcp_send_reset_w_pkt (new_tc0, b0, is_ip4);
tcp_connection_cleanup (new_tc0);
goto drop;
}
@@ -2017,7 +2022,7 @@ tcp46_syn_sent_inline (vlib_main_t * vm, vlib_node_runtime_t * node,
if (stream_session_connect_notify (&new_tc0->connection, 0))
{
tcp_connection_cleanup (new_tc0);
- tcp_send_reset (tc0, b0, is_ip4);
+ tcp_send_reset_w_pkt (tc0, b0, is_ip4);
TCP_EVT_DBG (TCP_EVT_RST_SENT, tc0);
goto drop;
}
@@ -2221,7 +2226,7 @@ tcp46_rcv_process_inline (vlib_main_t * vm, vlib_node_runtime_t * node,
*/
if (!tcp_rcv_ack_is_acceptable (tc0, b0))
{
- tcp_send_reset (tc0, b0, is_ip4);
+ tcp_send_reset_w_pkt (tc0, b0, is_ip4);
goto drop;
}