diff options
-rw-r--r-- | src/vnet/tcp/tcp_inlines.h | 1 | ||||
-rw-r--r-- | src/vnet/tcp/tcp_input.c | 13 |
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]; |