session: add explicit reset api
Type: feature This can be used to forcefully close a session. It's only available to builtin applications for now. Transports must support the reset api otherwise normal close is used. Change-Id: I5e6d681cbc4c8045385e293e0e9d86fa2bf45849 Signed-off-by: Florin Coras <fcoras@cisco.com>
This commit is contained in:

committed by
Damjan Marion

parent
12f6936cd8
commit
dfb3b87712
src/vnet
@ -144,7 +144,7 @@ session_add_self_custom_tx_evt (transport_connection_t * tc, u8 has_prio)
|
||||
}
|
||||
|
||||
static void
|
||||
session_program_transport_close (session_t * s)
|
||||
session_program_transport_ctrl_evt (session_t * s, session_evt_type_t evt)
|
||||
{
|
||||
u32 thread_index = vlib_get_thread_index ();
|
||||
session_evt_elt_t *elt;
|
||||
@ -158,10 +158,10 @@ session_program_transport_close (session_t * s)
|
||||
elt = session_evt_alloc_ctrl (wrk);
|
||||
clib_memset (&elt->evt, 0, sizeof (session_event_t));
|
||||
elt->evt.session_handle = session_handle (s);
|
||||
elt->evt.event_type = SESSION_CTRL_EVT_CLOSE;
|
||||
elt->evt.event_type = evt;
|
||||
}
|
||||
else
|
||||
session_send_ctrl_evt_to_thread (s, SESSION_CTRL_EVT_CLOSE);
|
||||
session_send_ctrl_evt_to_thread (s, evt);
|
||||
}
|
||||
|
||||
session_t *
|
||||
@ -888,7 +888,7 @@ session_transport_delete_notify (transport_connection_t * tc)
|
||||
s->session_state = SESSION_STATE_CLOSED;
|
||||
session_cleanup_notify (s, SESSION_CLEANUP_TRANSPORT);
|
||||
svm_fifo_dequeue_drop_all (s->tx_fifo);
|
||||
session_program_transport_close (s);
|
||||
session_program_transport_ctrl_evt (s, SESSION_CTRL_EVT_CLOSE);
|
||||
break;
|
||||
case SESSION_STATE_TRANSPORT_DELETED:
|
||||
break;
|
||||
@ -1194,12 +1194,26 @@ session_close (session_t * s)
|
||||
* acknowledge the close */
|
||||
if (s->session_state == SESSION_STATE_TRANSPORT_CLOSED
|
||||
|| s->session_state == SESSION_STATE_TRANSPORT_DELETED)
|
||||
session_program_transport_close (s);
|
||||
session_program_transport_ctrl_evt (s, SESSION_CTRL_EVT_CLOSE);
|
||||
return;
|
||||
}
|
||||
|
||||
s->session_state = SESSION_STATE_CLOSING;
|
||||
session_program_transport_close (s);
|
||||
session_program_transport_ctrl_evt (s, SESSION_CTRL_EVT_CLOSE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Force a close without waiting for data to be flushed
|
||||
*/
|
||||
void
|
||||
session_reset (session_t * s)
|
||||
{
|
||||
if (s->session_state >= SESSION_STATE_CLOSING)
|
||||
return;
|
||||
/* Drop all outstanding tx data */
|
||||
svm_fifo_dequeue_drop_all (s->tx_fifo);
|
||||
s->session_state = SESSION_STATE_CLOSING;
|
||||
session_program_transport_ctrl_evt (s, SESSION_CTRL_EVT_RESET);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1234,6 +1248,26 @@ session_transport_close (session_t * s)
|
||||
s->thread_index);
|
||||
}
|
||||
|
||||
/**
|
||||
* Force transport close
|
||||
*/
|
||||
void
|
||||
session_transport_reset (session_t * s)
|
||||
{
|
||||
if (s->session_state >= SESSION_STATE_APP_CLOSED)
|
||||
{
|
||||
if (s->session_state == SESSION_STATE_TRANSPORT_CLOSED)
|
||||
s->session_state = SESSION_STATE_CLOSED;
|
||||
else if (s->session_state >= SESSION_STATE_TRANSPORT_DELETED)
|
||||
session_free_w_fifos (s);
|
||||
return;
|
||||
}
|
||||
|
||||
s->session_state = SESSION_STATE_APP_CLOSED;
|
||||
transport_reset (session_get_transport_proto (s), s->connection_index,
|
||||
s->thread_index);
|
||||
}
|
||||
|
||||
/**
|
||||
* Cleanup transport and session state.
|
||||
*
|
||||
|
@ -376,7 +376,9 @@ int session_open (u32 app_index, session_endpoint_t * tep, u32 opaque);
|
||||
int session_listen (session_t * s, session_endpoint_cfg_t * sep);
|
||||
int session_stop_listen (session_t * s);
|
||||
void session_close (session_t * s);
|
||||
void session_reset (session_t * s);
|
||||
void session_transport_close (session_t * s);
|
||||
void session_transport_reset (session_t * s);
|
||||
void session_transport_cleanup (session_t * s);
|
||||
int session_send_io_evt_to_thread (svm_fifo_t * f,
|
||||
session_evt_type_t evt_type);
|
||||
|
@ -902,6 +902,12 @@ session_event_dispatch (session_worker_t * wrk, vlib_node_runtime_t * node,
|
||||
break;
|
||||
session_transport_close (s);
|
||||
break;
|
||||
case SESSION_CTRL_EVT_RESET:
|
||||
s = session_get_from_handle_if_valid (e->session_handle);
|
||||
if (PREDICT_FALSE (!s))
|
||||
break;
|
||||
session_transport_reset (s);
|
||||
break;
|
||||
case SESSION_IO_EVT_BUILTIN_RX:
|
||||
s = session_event_get_session (e, thread_index);
|
||||
if (PREDICT_FALSE (!s || s->session_state >= SESSION_STATE_CLOSING))
|
||||
|
@ -324,6 +324,15 @@ transport_close (transport_proto_t tp, u32 conn_index, u8 thread_index)
|
||||
tp_vfts[tp].close (conn_index, thread_index);
|
||||
}
|
||||
|
||||
void
|
||||
transport_reset (transport_proto_t tp, u32 conn_index, u8 thread_index)
|
||||
{
|
||||
if (tp_vfts[tp].reset)
|
||||
tp_vfts[tp].reset (conn_index, thread_index);
|
||||
else
|
||||
tp_vfts[tp].close (conn_index, thread_index);
|
||||
}
|
||||
|
||||
u32
|
||||
transport_start_listen (transport_proto_t tp, u32 session_index,
|
||||
transport_endpoint_t * tep)
|
||||
|
@ -39,6 +39,7 @@ typedef struct _transport_proto_vft
|
||||
u32 (*stop_listen) (u32 conn_index);
|
||||
int (*connect) (transport_endpoint_cfg_t * rmt);
|
||||
void (*close) (u32 conn_index, u32 thread_index);
|
||||
void (*reset) (u32 conn_index, u32 thread_index);
|
||||
void (*cleanup) (u32 conn_index, u32 thread_index);
|
||||
clib_error_t *(*enable) (vlib_main_t * vm, u8 is_en);
|
||||
|
||||
@ -96,6 +97,7 @@ do { \
|
||||
|
||||
int transport_connect (transport_proto_t tp, transport_endpoint_cfg_t * tep);
|
||||
void transport_close (transport_proto_t tp, u32 conn_index, u8 thread_index);
|
||||
void transport_reset (transport_proto_t tp, u32 conn_index, u8 thread_index);
|
||||
u32 transport_start_listen (transport_proto_t tp, u32 session_index,
|
||||
transport_endpoint_t * tep);
|
||||
u32 transport_stop_listen (transport_proto_t tp, u32 conn_index);
|
||||
|
@ -477,6 +477,18 @@ tcp_session_cleanup (u32 conn_index, u32 thread_index)
|
||||
tcp_connection_cleanup (tc);
|
||||
}
|
||||
|
||||
static void
|
||||
tcp_session_reset (u32 conn_index, u32 thread_index)
|
||||
{
|
||||
tcp_connection_t *tc;
|
||||
tc = tcp_connection_get (conn_index, thread_index);
|
||||
session_transport_closed_notify (&tc->connection);
|
||||
tcp_send_reset (tc);
|
||||
tcp_connection_timers_reset (tc);
|
||||
tcp_connection_set_state (tc, TCP_STATE_CLOSED);
|
||||
tcp_timer_update (tc, TCP_TIMER_WAITCLOSE, tcp_cfg.cleanup_time);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize all connection timers as invalid
|
||||
*/
|
||||
@ -1258,6 +1270,7 @@ const static transport_proto_vft_t tcp_proto = {
|
||||
.connect = tcp_session_open,
|
||||
.close = tcp_session_close,
|
||||
.cleanup = tcp_session_cleanup,
|
||||
.reset = tcp_session_reset,
|
||||
.send_mss = tcp_session_send_mss,
|
||||
.send_space = tcp_session_send_space,
|
||||
.update_time = tcp_update_time,
|
||||
|
Reference in New Issue
Block a user