int
tcp_half_open_connection_cleanup (tcp_connection_t * tc)
{
+ tcp_worker_ctx_t *wrk;
+
/* Make sure this is the owning thread */
if (tc->c_thread_index != vlib_get_thread_index ())
return 1;
- tcp_timer_reset (tc, TCP_TIMER_RETRANSMIT_SYN);
+
+ wrk = tcp_get_worker (tc->c_thread_index);
+ tcp_timer_reset (&wrk->timer_wheel, tc, TCP_TIMER_RETRANSMIT_SYN);
tcp_half_open_connection_del (tc);
return 0;
}
void
tcp_connection_close (tcp_connection_t * tc)
{
+ tcp_worker_ctx_t *wrk = tcp_get_worker (tc->c_thread_index);
+
TCP_EVT (TCP_EVT_CLOSE, tc);
/* Send/Program FIN if needed and switch state */
tcp_connection_timers_reset (tc);
tcp_send_fin (tc);
tcp_connection_set_state (tc, TCP_STATE_FIN_WAIT_1);
- tcp_timer_update (tc, TCP_TIMER_WAITCLOSE, tcp_cfg.finwait1_time);
+ tcp_timer_update (&wrk->timer_wheel, tc, TCP_TIMER_WAITCLOSE,
+ tcp_cfg.finwait1_time);
break;
case TCP_STATE_ESTABLISHED:
/* If closing with unread data, reset the connection */
tcp_connection_set_state (tc, TCP_STATE_CLOSED);
session_transport_closed_notify (&tc->connection);
tcp_program_cleanup (tcp_get_worker (tc->c_thread_index), tc);
- tcp_worker_stats_inc (tc->c_thread_index, rst_unread, 1);
+ tcp_worker_stats_inc (wrk, rst_unread, 1);
break;
}
if (!transport_max_tx_dequeue (&tc->connection))
/* Set a timer in case the peer stops responding. Otherwise the
* connection will be stuck here forever. */
ASSERT (tc->timers[TCP_TIMER_WAITCLOSE] == TCP_TIMER_HANDLE_INVALID);
- tcp_timer_set (tc, TCP_TIMER_WAITCLOSE, tcp_cfg.finwait1_time);
+ tcp_timer_set (&wrk->timer_wheel, tc, TCP_TIMER_WAITCLOSE,
+ tcp_cfg.finwait1_time);
break;
case TCP_STATE_CLOSE_WAIT:
if (!transport_max_tx_dequeue (&tc->connection))
tcp_send_fin (tc);
tcp_connection_timers_reset (tc);
tcp_connection_set_state (tc, TCP_STATE_LAST_ACK);
- tcp_timer_update (tc, TCP_TIMER_WAITCLOSE, tcp_cfg.lastack_time);
+ tcp_timer_update (&wrk->timer_wheel, tc, TCP_TIMER_WAITCLOSE,
+ tcp_cfg.lastack_time);
}
else
tc->flags |= TCP_CONN_FINPNDG;
break;
case TCP_STATE_FIN_WAIT_1:
- tcp_timer_update (tc, TCP_TIMER_WAITCLOSE, tcp_cfg.finwait1_time);
+ tcp_timer_update (&wrk->timer_wheel, tc, TCP_TIMER_WAITCLOSE,
+ tcp_cfg.finwait1_time);
break;
case TCP_STATE_CLOSED:
/* Cleanup should've been programmed already */
void
tcp_connection_timers_reset (tcp_connection_t * tc)
{
+ tcp_worker_ctx_t *wrk = tcp_get_worker (tc->c_thread_index);
int i;
+
for (i = 0; i < TCP_N_TIMERS; i++)
- {
- tcp_timer_reset (tc, i);
- }
+ tcp_timer_reset (&wrk->timer_wheel, tc, i);
}
#if 0
}
port = transport_alloc_local_port (TRANSPORT_PROTO_TCP, lcl_addr);
if (port < 1)
- {
- clib_warning ("Failed to allocate src port");
- return -1;
- }
+ return SESSION_E_NOPORT;
*lcl_port = port;
return 0;
}
rmt, &lcl_addr, &lcl_port);
if (rv)
- return -1;
+ {
+ if (rv != SESSION_E_PORTINUSE)
+ return rv;
+
+ if (session_lookup_connection (rmt->fib_index, &lcl_addr, &rmt->ip,
+ lcl_port, rmt->port, TRANSPORT_PROTO_UDP,
+ rmt->is_ip4))
+ return SESSION_E_PORTINUSE;
+
+ /* 5-tuple is available so increase lcl endpoint refcount and proceed
+ * with connection allocation */
+ transport_share_local_endpoint (TRANSPORT_PROTO_UDP, &lcl_addr,
+ lcl_port);
+ }
/*
* Create connection and send SYN
tcp_connection_set_state (tc, TCP_STATE_CLOSED);
session_transport_closed_notify (&tc->connection);
tcp_program_cleanup (wrk, tc);
- tcp_workerp_stats_inc (wrk, to_closewait, 1);
+ tcp_worker_stats_inc (wrk, to_closewait, 1);
break;
}
session_transport_closed_notify (&tc->connection);
/* Make sure we don't wait in LAST ACK forever */
- tcp_timer_set (tc, TCP_TIMER_WAITCLOSE, tcp_cfg.lastack_time);
- tcp_workerp_stats_inc (wrk, to_closewait2, 1);
+ tcp_timer_set (&wrk->timer_wheel, tc, TCP_TIMER_WAITCLOSE,
+ tcp_cfg.lastack_time);
+ tcp_worker_stats_inc (wrk, to_closewait2, 1);
/* Don't delete the connection yet */
break;
tcp_program_cleanup (wrk, tc);
}
session_transport_closed_notify (&tc->connection);
- tcp_workerp_stats_inc (wrk, to_finwait1, 1);
+ tcp_worker_stats_inc (wrk, to_finwait1, 1);
break;
case TCP_STATE_LAST_ACK:
tcp_connection_timers_reset (tc);
tcp_connection_set_state (tc, TCP_STATE_CLOSED);
session_transport_closed_notify (&tc->connection);
tcp_program_cleanup (wrk, tc);
- tcp_workerp_stats_inc (wrk, to_lastack, 1);
+ tcp_worker_stats_inc (wrk, to_lastack, 1);
break;
case TCP_STATE_CLOSING:
tcp_connection_timers_reset (tc);
tcp_connection_set_state (tc, TCP_STATE_CLOSED);
session_transport_closed_notify (&tc->connection);
tcp_program_cleanup (wrk, tc);
- tcp_workerp_stats_inc (wrk, to_closing, 1);
+ tcp_worker_stats_inc (wrk, to_closing, 1);
break;
case TCP_STATE_FIN_WAIT_2:
tcp_send_reset (tc);
tcp_connection_set_state (tc, TCP_STATE_CLOSED);
session_transport_closed_notify (&tc->connection);
tcp_program_cleanup (wrk, tc);
- tcp_workerp_stats_inc (wrk, to_finwait2, 1);
+ tcp_worker_stats_inc (wrk, to_finwait2, 1);
break;
case TCP_STATE_TIME_WAIT:
tcp_connection_set_state (tc, TCP_STATE_CLOSED);
wrk = tcp_get_worker (thread_index);
n_expired = vec_len (expired_timers);
- tcp_workerp_stats_inc (wrk, timer_expirations, n_expired);
+ tcp_worker_stats_inc (wrk, timer_expirations, n_expired);
n_left = clib_fifo_elts (wrk->pending_timers);
/*