diff options
-rw-r--r-- | src/vnet/session/session_lookup.c | 8 | ||||
-rw-r--r-- | src/vnet/session/session_lookup.h | 4 | ||||
-rw-r--r-- | src/vnet/tcp/tcp.h | 5 | ||||
-rwxr-xr-x | src/vnet/tcp/tcp_input.c | 41 |
4 files changed, 50 insertions, 8 deletions
diff --git a/src/vnet/session/session_lookup.c b/src/vnet/session/session_lookup.c index 604344a27cd..b1c8fbbef8e 100644 --- a/src/vnet/session/session_lookup.c +++ b/src/vnet/session/session_lookup.c @@ -654,13 +654,13 @@ session_lookup_listener4_i (session_table_t * st, ip4_address_t * lcl, session_t * session_lookup_listener4 (u32 fib_index, ip4_address_t * lcl, u16 lcl_port, - u8 proto) + u8 proto, u8 use_wildcard) { session_table_t *st; st = session_table_get_for_fib_index (FIB_PROTOCOL_IP4, fib_index); if (!st) return 0; - return session_lookup_listener4_i (st, lcl, lcl_port, proto, 0); + return session_lookup_listener4_i (st, lcl, lcl_port, proto, use_wildcard); } static session_t * @@ -697,13 +697,13 @@ session_lookup_listener6_i (session_table_t * st, ip6_address_t * lcl, session_t * session_lookup_listener6 (u32 fib_index, ip6_address_t * lcl, u16 lcl_port, - u8 proto) + u8 proto, u8 use_wildcard) { session_table_t *st; st = session_table_get_for_fib_index (FIB_PROTOCOL_IP6, fib_index); if (!st) return 0; - return session_lookup_listener6_i (st, lcl, lcl_port, proto, 1); + return session_lookup_listener6_i (st, lcl, lcl_port, proto, use_wildcard); } /** diff --git a/src/vnet/session/session_lookup.h b/src/vnet/session/session_lookup.h index 63ba6c3cde9..c2e644654fb 100644 --- a/src/vnet/session/session_lookup.h +++ b/src/vnet/session/session_lookup.h @@ -61,10 +61,10 @@ transport_connection_t *session_lookup_connection6 (u32 fib_index, u16 rmt_port, u8 proto); session_t *session_lookup_listener4 (u32 fib_index, ip4_address_t * lcl, u16 lcl_port, - u8 proto); + u8 proto, u8 use_wildcard); session_t *session_lookup_listener6 (u32 fib_index, ip6_address_t * lcl, u16 lcl_port, - u8 proto); + u8 proto, u8 use_wildcard); session_t *session_lookup_listener (u32 table_index, session_endpoint_t * sep); session_t *session_lookup_listener_wildcard (u32 table_index, diff --git a/src/vnet/tcp/tcp.h b/src/vnet/tcp/tcp.h index 2de25277b60..52cc308871b 100644 --- a/src/vnet/tcp/tcp.h +++ b/src/vnet/tcp/tcp.h @@ -765,7 +765,10 @@ u8 *format_tcp_connection (u8 * s, va_list * args); always_inline tcp_connection_t * tcp_listener_get (u32 tli) { - return pool_elt_at_index (tcp_main.listener_pool, tli); + tcp_connection_t *tc = 0; + if (!pool_is_free_index (tcp_main.listener_pool, tli)) + tc = pool_elt_at_index (tcp_main.listener_pool, tli); + return tc; } always_inline tcp_connection_t * diff --git a/src/vnet/tcp/tcp_input.c b/src/vnet/tcp/tcp_input.c index 52d73169654..675bc3f4283 100755 --- a/src/vnet/tcp/tcp_input.c +++ b/src/vnet/tcp/tcp_input.c @@ -2360,6 +2360,36 @@ tcp_lookup_connection (u32 fib_index, vlib_buffer_t * b, u8 thread_index, return tc; } +static tcp_connection_t * +tcp_lookup_listener (vlib_buffer_t * b, u32 fib_index, int is_ip4) +{ + session_t *s; + + if (is_ip4) + { + ip4_header_t *ip4 = vlib_buffer_get_current (b); + tcp_header_t *tcp = tcp_buffer_hdr (b); + s = session_lookup_listener4 (fib_index, + &ip4->dst_address, + tcp->dst_port, TRANSPORT_PROTO_TCP, 1); + } + else + { + ip6_header_t *ip6 = vlib_buffer_get_current (b); + tcp_header_t *tcp = tcp_buffer_hdr (b); + s = session_lookup_listener6 (fib_index, + &ip6->dst_address, + tcp->dst_port, TRANSPORT_PROTO_TCP, 1); + + } + if (PREDICT_TRUE (s != 0)) + return tcp_get_connection_from_transport (transport_get_listener + (TRANSPORT_PROTO_TCP, + s->connection_index)); + else + return 0; +} + always_inline void tcp_check_tx_offload (tcp_connection_t * tc, int is_ipv4) { @@ -3138,6 +3168,7 @@ tcp46_listen_inline (vlib_main_t * vm, vlib_node_runtime_t * node, { u32 n_left_from, *from, n_syns = 0, *first_buffer; u32 my_thread_index = vm->thread_index; + tcp_connection_t *tc0; from = first_buffer = vlib_frame_vector_args (from_frame); n_left_from = from_frame->n_vectors; @@ -3160,6 +3191,14 @@ tcp46_listen_inline (vlib_main_t * vm, vlib_node_runtime_t * node, b0 = vlib_get_buffer (vm, bi0); lc0 = tcp_listener_get (vnet_buffer (b0)->tcp.connection_index); + if (PREDICT_FALSE (lc0 == 0)) + { + tc0 = tcp_connection_get (vnet_buffer (b0)->tcp.connection_index, + my_thread_index); + /* clean up the old session */ + lc0 = tcp_lookup_listener (b0, tc0->c_fib_index, is_ip4); + tcp_connection_del (tc0); + } if (is_ip4) { @@ -3957,7 +3996,7 @@ do { \ TCP_ERROR_NONE); _(LAST_ACK, TCP_FLAG_SYN | TCP_FLAG_RST | TCP_FLAG_ACK, TCP_INPUT_NEXT_RCV_PROCESS, TCP_ERROR_NONE); - _(TIME_WAIT, TCP_FLAG_SYN, TCP_INPUT_NEXT_RCV_PROCESS, TCP_ERROR_NONE); + _(TIME_WAIT, TCP_FLAG_SYN, TCP_INPUT_NEXT_LISTEN, TCP_ERROR_NONE); _(TIME_WAIT, TCP_FLAG_FIN, TCP_INPUT_NEXT_RCV_PROCESS, TCP_ERROR_NONE); _(TIME_WAIT, TCP_FLAG_FIN | TCP_FLAG_ACK, TCP_INPUT_NEXT_RCV_PROCESS, TCP_ERROR_NONE); |