summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/vnet/tcp/tcp_inlines.h1
-rw-r--r--src/vnet/tcp/tcp_input.c13
2 files changed, 11 insertions, 3 deletions
diff --git a/src/vnet/tcp/tcp_inlines.h b/src/vnet/tcp/tcp_inlines.h
index 25bf7387c69..45762671da8 100644
--- a/src/vnet/tcp/tcp_inlines.h
+++ b/src/vnet/tcp/tcp_inlines.h
@@ -310,7 +310,6 @@ tcp_input_lookup_buffer (vlib_buffer_t * b, u8 thread_index, u32 * error,
vnet_buffer (b)->tcp.data_len = n_data_bytes;
vnet_buffer (b)->tcp.seq_end = vnet_buffer (b)->tcp.seq_number
+ n_data_bytes;
- vnet_buffer (b)->tcp.flags = 0;
*error = result ? TCP_ERROR_NONE + result : *error;
diff --git a/src/vnet/tcp/tcp_input.c b/src/vnet/tcp/tcp_input.c
index a159d850728..f5d17eabc36 100644
--- a/src/vnet/tcp/tcp_input.c
+++ b/src/vnet/tcp/tcp_input.c
@@ -2561,14 +2561,19 @@ tcp46_listen_inline (vlib_main_t * vm, vlib_node_runtime_t * node,
b = vlib_get_buffer (vm, bi);
- lc = tcp_listener_get (vnet_buffer (b)->tcp.connection_index);
- if (PREDICT_FALSE (lc == 0))
+ /* Flags initialized with connection state after lookup */
+ if (vnet_buffer (b)->tcp.flags == TCP_STATE_LISTEN)
+ {
+ lc = tcp_listener_get (vnet_buffer (b)->tcp.connection_index);
+ }
+ else
{
tcp_connection_t *tc;
tc = tcp_connection_get (vnet_buffer (b)->tcp.connection_index,
thread_index);
if (tc->state != TCP_STATE_TIME_WAIT)
{
+ lc = 0;
error = TCP_ERROR_CREATE_EXISTS;
goto done;
}
@@ -2802,6 +2807,10 @@ tcp_input_dispatch_buffer (tcp_main_t * tm, tcp_connection_t * tc,
error = tm->dispatch_table[tc->state][flags].error;
tc->segs_in += 1;
+ /* Track connection state when packet was received. It helps
+ * @ref tcp46_listen_inline detect port reuse */
+ vnet_buffer (b)->tcp.flags = tc->state;
+
if (PREDICT_FALSE (error != TCP_ERROR_NONE))
{
b->error = error_node->errors[error];