aboutsummaryrefslogtreecommitdiffstats
path: root/src/plugins/http/http.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/http/http.c')
-rw-r--r--src/plugins/http/http.c382
1 files changed, 171 insertions, 211 deletions
diff --git a/src/plugins/http/http.c b/src/plugins/http/http.c
index fc5b7d5d72d..5998a9ebd18 100644
--- a/src/plugins/http/http.c
+++ b/src/plugins/http/http.c
@@ -36,26 +36,6 @@ http_register_engine (const http_engine_vft_t *vft, http_version_t version)
http_vfts[version] = *vft;
}
-always_inline http_version_t
-http_version_from_handle (http_conn_handle_t hc_handle)
-{
- /* the first 3 bits are http version */
- return hc_handle >> 29;
-}
-
-always_inline u32
-http_conn_index_from_handle (http_conn_handle_t hc_handle)
-{
- return hc_handle & 0x1FFFFFFF;
-}
-
-always_inline http_conn_handle_t
-http_make_handle (u32 hc_index, http_version_t version)
-{
- ASSERT (hc_index <= 0x1FFFFFFF);
- return (version << 29) | hc_index;
-}
-
int
http_v_find_index (u8 *vec, u32 offset, u32 num, char *str)
{
@@ -145,13 +125,7 @@ http_conn_alloc_w_thread (u32 thread_index)
http_conn_t *hc;
pool_get_aligned_safe (wrk->conn_pool, hc, CLIB_CACHE_LINE_BYTES);
- clib_memset (hc, 0, sizeof (*hc));
- hc->c_thread_index = thread_index;
- hc->h_hc_index = hc - wrk->conn_pool;
- hc->h_pa_session_handle = SESSION_INVALID_HANDLE;
- hc->h_tc_session_handle = SESSION_INVALID_HANDLE;
- hc->version = HTTP_VERSION_NA;
- return hc->h_hc_index;
+ return (hc - wrk->conn_pool);
}
static inline http_conn_t *
@@ -211,7 +185,7 @@ http_ho_try_free (u32 ho_hc_index)
if (!(ho_hc->flags & HTTP_CONN_F_HO_DONE))
{
HTTP_DBG (1, "postponed cleanup");
- ho_hc->h_tc_session_handle = SESSION_INVALID_HANDLE;
+ ho_hc->hc_tc_session_handle = SESSION_INVALID_HANDLE;
http_add_postponed_ho_cleanups (ho_hc_index);
return;
}
@@ -247,12 +221,12 @@ http_ho_conn_alloc (void)
pool_get_aligned_safe (hm->ho_conn_pool, hc, CLIB_CACHE_LINE_BYTES);
clib_memset (hc, 0, sizeof (*hc));
- hc->h_hc_index = hc - hm->ho_conn_pool;
- hc->h_pa_session_handle = SESSION_INVALID_HANDLE;
- hc->h_tc_session_handle = SESSION_INVALID_HANDLE;
+ hc->hc_hc_index = hc - hm->ho_conn_pool;
+ hc->hc_pa_session_handle = SESSION_INVALID_HANDLE;
+ hc->hc_tc_session_handle = SESSION_INVALID_HANDLE;
hc->timeout = HTTP_CONN_TIMEOUT;
hc->version = HTTP_VERSION_NA;
- return hc->h_hc_index;
+ return hc->hc_hc_index;
}
static u32
@@ -262,10 +236,10 @@ http_listener_alloc (void)
http_conn_t *lhc;
pool_get_zero (hm->listener_pool, lhc);
- lhc->h_hc_index = lhc - hm->listener_pool;
+ lhc->hc_hc_index = lhc - hm->listener_pool;
lhc->timeout = HTTP_CONN_TIMEOUT;
lhc->version = HTTP_VERSION_NA;
- return lhc->h_hc_index;
+ return lhc->hc_hc_index;
}
static http_conn_t *
@@ -289,7 +263,7 @@ void
http_disconnect_transport (http_conn_t *hc)
{
vnet_disconnect_args_t a = {
- .handle = hc->h_tc_session_handle,
+ .handle = hc->hc_tc_session_handle,
.app_index = http_main.app_index,
};
@@ -307,14 +281,14 @@ http_sc_by_u16 (u16 status_code)
}
u8 *
-http_get_app_header_list (http_conn_t *hc, http_msg_t *msg)
+http_get_app_header_list (http_req_t *req, http_msg_t *msg)
{
http_main_t *hm = &http_main;
session_t *as;
u8 *app_headers;
int rv;
- as = session_get_from_handle (hc->h_pa_session_handle);
+ as = session_get_from_handle (req->hr_pa_session_handle);
if (msg->data.type == HTTP_MSG_DATA_PTR)
{
@@ -326,7 +300,7 @@ http_get_app_header_list (http_conn_t *hc, http_msg_t *msg)
}
else
{
- app_headers = hm->app_header_lists[hc->c_thread_index];
+ app_headers = hm->app_header_lists[as->thread_index];
rv = svm_fifo_dequeue (as->tx_fifo, msg->data.headers_len, app_headers);
ASSERT (rv == msg->data.headers_len);
}
@@ -341,7 +315,7 @@ http_get_app_target (http_req_t *req, http_msg_t *msg)
u8 *target;
int rv;
- as = session_get_from_handle (req->app_session_handle);
+ as = session_get_from_handle (req->hr_pa_session_handle);
if (msg->data.type == HTTP_MSG_DATA_PTR)
{
@@ -384,7 +358,7 @@ http_get_rx_buf (http_conn_t *hc)
void
http_req_tx_buffer_init (http_req_t *req, http_msg_t *msg)
{
- session_t *as = session_get_from_handle (req->app_session_handle);
+ session_t *as = session_get_from_handle (req->hr_pa_session_handle);
http_buffer_init (&req->tx_buf, msg_to_buf_type[msg->data.type], as->tx_fifo,
msg->data.body_len);
}
@@ -431,7 +405,7 @@ http_conn_timeout_cb (void *hc_handlep)
return;
}
- session_transport_closing_notify (&hc->connection);
+ http_vfts[hc->version].transport_close_callback (hc);
http_disconnect_transport (hc);
}
@@ -442,11 +416,10 @@ http_conn_timeout_cb (void *hc_handlep)
int
http_ts_accept_callback (session_t *ts)
{
- session_t *ts_listener, *as, *asl;
- app_worker_t *app_wrk;
+ session_t *ts_listener;
http_conn_t *lhc, *hc;
u32 hc_index, thresh;
- int rv;
+ http_conn_handle_t hc_handle;
ts_listener = listen_session_get_from_handle (ts->listener_handle);
lhc = http_listener_get (ts_listener->opaque);
@@ -456,61 +429,27 @@ http_ts_accept_callback (session_t *ts)
clib_memcpy_fast (hc, lhc, sizeof (*lhc));
hc->timer_handle = HTTP_TIMER_HANDLE_INVALID;
hc->c_thread_index = ts->thread_index;
- hc->h_hc_index = hc_index;
-
- hc->h_tc_session_handle = session_handle (ts);
+ hc->hc_hc_index = hc_index;
+ hc->flags |= HTTP_CONN_F_NO_APP_SESSION;
+ hc->hc_tc_session_handle = session_handle (ts);
hc->c_flags |= TRANSPORT_CONNECTION_F_NO_LOOKUP;
hc->state = HTTP_CONN_STATE_ESTABLISHED;
ts->session_state = SESSION_STATE_READY;
- /* TODO: TLS set by ALPN result, TCP: first try HTTP/1 */
+ /* TODO: TLS set by ALPN result, TCP: will decide in http_ts_rx_callback */
hc->version = HTTP_VERSION_1;
- ts->opaque = http_make_handle (hc_index, hc->version);
-
- /*
- * Alloc session and initialize
- */
- as = session_alloc (hc->c_thread_index);
- hc->c_s_index = as->session_index;
-
- as->app_wrk_index = hc->h_pa_wrk_index;
- as->connection_index = hc->h_hc_index;
- as->session_state = SESSION_STATE_ACCEPTING;
-
- asl = listen_session_get_from_handle (lhc->h_pa_session_handle);
- as->session_type = asl->session_type;
- as->listener_handle = lhc->h_pa_session_handle;
-
- /*
- * Init session fifos and notify app
- */
- if ((rv = app_worker_init_accepted (as)))
- {
- HTTP_DBG (1, "failed to allocate fifos");
- hc->h_pa_session_handle = SESSION_INVALID_HANDLE;
- session_free (as);
- return rv;
- }
-
- hc->h_pa_session_handle = session_handle (as);
- hc->h_pa_wrk_index = as->app_wrk_index;
- app_wrk = app_worker_get (as->app_wrk_index);
+ hc_handle.version = hc->version;
+ hc_handle.conn_index = hc_index;
+ ts->opaque = hc_handle.as_u32;
HTTP_DBG (1, "Accepted on listener %u new connection [%u]%x",
ts_listener->opaque, vlib_get_thread_index (), hc_index);
- if ((rv = app_worker_accept_notify (app_wrk, as)))
- {
- HTTP_DBG (0, "app accept returned");
- session_free (as);
- return rv;
- }
-
/* Avoid enqueuing small chunks of data on transport tx notifications. If
* the fifo is small (under 16K) we set the threshold to it's size, meaning
* a notification will be given when the fifo empties.
*/
- ts = session_get_from_handle (hc->h_tc_session_handle);
+ ts = session_get_from_handle (hc->hc_tc_session_handle);
thresh = clib_min (svm_fifo_size (ts->tx_fifo), HTTP_FIFO_THRESH);
svm_fifo_set_deq_thresh (ts->tx_fifo, thresh);
@@ -524,9 +463,9 @@ http_ts_connected_callback (u32 http_app_index, u32 ho_hc_index, session_t *ts,
session_error_t err)
{
u32 new_hc_index;
- session_t *as;
http_conn_t *hc, *ho_hc;
app_worker_t *app_wrk;
+ http_conn_handle_t hc_handle;
int rv;
ho_hc = http_ho_conn_get (ho_hc_index);
@@ -537,9 +476,9 @@ http_ts_connected_callback (u32 http_app_index, u32 ho_hc_index, session_t *ts,
clib_warning ("half-open hc index %d, error: %U", ho_hc_index,
format_session_error, err);
ho_hc->flags |= HTTP_CONN_F_HO_DONE;
- app_wrk = app_worker_get_if_valid (ho_hc->h_pa_wrk_index);
+ app_wrk = app_worker_get_if_valid (ho_hc->hc_pa_wrk_index);
if (app_wrk)
- app_worker_connect_notify (app_wrk, 0, err, ho_hc->h_pa_app_api_ctx);
+ app_worker_connect_notify (app_wrk, 0, err, ho_hc->hc_pa_app_api_ctx);
return 0;
}
@@ -553,43 +492,26 @@ http_ts_connected_callback (u32 http_app_index, u32 ho_hc_index, session_t *ts,
hc->timer_handle = HTTP_TIMER_HANDLE_INVALID;
hc->c_thread_index = ts->thread_index;
- hc->h_tc_session_handle = session_handle (ts);
- hc->h_hc_index = new_hc_index;
+ hc->hc_tc_session_handle = session_handle (ts);
+ hc->hc_hc_index = new_hc_index;
hc->c_flags |= TRANSPORT_CONNECTION_F_NO_LOOKUP;
hc->state = HTTP_CONN_STATE_ESTABLISHED;
ts->session_state = SESSION_STATE_READY;
+ hc->flags |= HTTP_CONN_F_NO_APP_SESSION;
/* TODO: TLS set by ALPN result, TCP: prior knowledge (set in ho) */
- ts->opaque = http_make_handle (new_hc_index, hc->version);
-
- /* allocate app session and initialize */
-
- as = session_alloc (hc->c_thread_index);
- hc->c_s_index = as->session_index;
- as->connection_index = new_hc_index;
- as->app_wrk_index = hc->h_pa_wrk_index;
- as->session_state = SESSION_STATE_READY;
- as->opaque = hc->h_pa_app_api_ctx;
- as->session_type = session_type_from_proto_and_ip (
- TRANSPORT_PROTO_HTTP, session_type_is_ip4 (ts->session_type));
+ hc_handle.version = hc->version;
+ hc_handle.conn_index = new_hc_index;
+ ts->opaque = hc_handle.as_u32;
HTTP_DBG (1, "half-open hc index %x, hc [%u]%x", ho_hc_index,
ts->thread_index, new_hc_index);
- app_wrk = app_worker_get (hc->h_pa_wrk_index);
- if (!app_wrk)
- {
- clib_warning ("no app worker");
- return -1;
- }
-
- if ((rv = app_worker_init_connected (app_wrk, as)))
+ if ((rv = http_vfts[hc->version].transport_connected_callback (hc)))
{
- HTTP_DBG (1, "failed to allocate fifos");
- session_free (as);
+ clib_warning ("transport_connected_callback failed, rv=%d", rv);
return rv;
}
- app_worker_connect_notify (app_wrk, as, err, hc->h_pa_app_api_ctx);
- hc->h_pa_session_handle = session_handle (as);
+
http_conn_timer_start (hc);
return 0;
@@ -599,11 +521,13 @@ static void
http_ts_disconnect_callback (session_t *ts)
{
http_conn_t *hc;
- u32 hc_index = http_conn_index_from_handle (ts->opaque);
+ http_conn_handle_t hc_handle;
+
+ hc_handle.as_u32 = ts->opaque;
HTTP_DBG (1, "hc [%u]%x", ts->thread_index, hc_index);
- hc = http_conn_get_w_thread (hc_index, ts->thread_index);
+ hc = http_conn_get_w_thread (hc_handle.conn_index, ts->thread_index);
if (hc->state < HTTP_CONN_STATE_TRANSPORT_CLOSED)
hc->state = HTTP_CONN_STATE_TRANSPORT_CLOSED;
@@ -615,14 +539,16 @@ static void
http_ts_reset_callback (session_t *ts)
{
http_conn_t *hc;
- u32 hc_index = http_conn_index_from_handle (ts->opaque);
+ http_conn_handle_t hc_handle;
+
+ hc_handle.as_u32 = ts->opaque;
HTTP_DBG (1, "hc [%u]%x", ts->thread_index, hc_index);
- hc = http_conn_get_w_thread (hc_index, ts->thread_index);
+ hc = http_conn_get_w_thread (hc_handle.conn_index, ts->thread_index);
hc->state = HTTP_CONN_STATE_CLOSED;
- session_transport_reset_notify (&hc->connection);
+ http_vfts[hc->version].transport_reset_callback (hc);
http_disconnect_transport (hc);
}
@@ -631,11 +557,13 @@ static int
http_ts_rx_callback (session_t *ts)
{
http_conn_t *hc;
- u32 hc_index = http_conn_index_from_handle (ts->opaque);
+ http_conn_handle_t hc_handle;
- HTTP_DBG (1, "hc [%u]%x", ts->thread_index, hc_index);
+ hc_handle.as_u32 = ts->opaque;
- hc = http_conn_get_w_thread (hc_index, ts->thread_index);
+ HTTP_DBG (1, "hc [%u]%x", ts->thread_index, hc_handle.conn_index);
+
+ hc = http_conn_get_w_thread (hc_handle.conn_index, ts->thread_index);
if (hc->state == HTTP_CONN_STATE_CLOSED)
{
@@ -644,13 +572,11 @@ http_ts_rx_callback (session_t *ts)
return 0;
}
- http_vfts[http_version_from_handle (ts->opaque)].transport_rx_callback (hc);
+ /* TODO: if version is unknown */
+ http_vfts[hc_handle.version].transport_rx_callback (hc);
if (hc->state == HTTP_CONN_STATE_TRANSPORT_CLOSED)
- {
- if (!svm_fifo_max_dequeue_cons (ts->rx_fifo))
- session_transport_closing_notify (&hc->connection);
- }
+ http_vfts[hc->version].transport_close_callback (hc);
return 0;
}
@@ -658,11 +584,13 @@ int
http_ts_builtin_tx_callback (session_t *ts)
{
http_conn_t *hc;
+ http_conn_handle_t hc_handle;
- hc = http_conn_get_w_thread (http_conn_index_from_handle (ts->opaque),
- ts->thread_index);
+ hc_handle.as_u32 = ts->opaque;
+
+ hc = http_conn_get_w_thread (hc_handle.conn_index, ts->thread_index);
HTTP_DBG (1, "transport connection reschedule");
- transport_connection_reschedule (&hc->connection);
+ http_vfts[hc->version].transport_conn_reschedule_callback (hc);
return 0;
}
@@ -671,29 +599,20 @@ static void
http_ts_cleanup_callback (session_t *ts, session_cleanup_ntf_t ntf)
{
http_conn_t *hc;
- http_req_t *req;
- u32 hc_index;
+ http_conn_handle_t hc_handle;
if (ntf == SESSION_CLEANUP_TRANSPORT)
return;
- hc_index = http_conn_index_from_handle (ts->opaque);
- hc = http_conn_get_w_thread (hc_index, ts->thread_index);
+ hc_handle.as_u32 = ts->opaque;
+ hc = http_conn_get_w_thread (hc_handle.conn_index, ts->thread_index);
HTTP_DBG (1, "going to free hc [%u]%x", ts->thread_index, hc_index);
- pool_foreach (req, hc->req_pool)
- {
- vec_free (req->headers);
- vec_free (req->target);
- http_buffer_free (&req->tx_buf);
- }
- pool_free (hc->req_pool);
-
if (!(hc->flags & HTTP_CONN_F_PENDING_TIMER))
http_conn_timer_stop (hc);
- session_transport_delete_notify (&hc->connection);
+ http_vfts[hc->version].conn_cleanup_callback (hc);
if (!(hc->flags & HTTP_CONN_F_IS_SERVER))
{
@@ -706,9 +625,8 @@ http_ts_cleanup_callback (session_t *ts, session_cleanup_ntf_t ntf)
static void
http_ts_ho_cleanup_callback (session_t *ts)
{
- u32 ho_hc_index = http_conn_index_from_handle (ts->opaque);
- HTTP_DBG (1, "half open: %x", ho_hc_index);
- http_ho_try_free (ho_hc_index);
+ HTTP_DBG (1, "half open: %x", ts->opaque);
+ http_ho_try_free (ts->opaque);
}
int
@@ -750,6 +668,7 @@ http_transport_enable (vlib_main_t *vm, u8 is_en)
u64 options[APP_OPTIONS_N_OPTIONS];
http_main_t *hm = &http_main;
u32 num_threads, i;
+ http_engine_vft_t *http_version;
if (!is_en)
{
@@ -806,6 +725,12 @@ http_transport_enable (vlib_main_t *vm, u8 is_en)
http_timers_init (vm, http_conn_timeout_cb, http_conn_invalidate_timer_cb);
hm->is_init = 1;
+ vec_foreach (http_version, http_vfts)
+ {
+ if (http_version->enable_callback)
+ http_version->enable_callback ();
+ }
+
return 0;
}
@@ -832,10 +757,10 @@ http_transport_connect (transport_endpoint_cfg_t *tep)
hc_index = http_ho_conn_alloc ();
hc = http_ho_conn_get (hc_index);
- hc->h_pa_wrk_index = sep->app_wrk_index;
- hc->h_pa_app_api_ctx = sep->opaque;
+ hc->hc_pa_wrk_index = sep->app_wrk_index;
+ hc->hc_pa_app_api_ctx = sep->opaque;
hc->state = HTTP_CONN_STATE_CONNECTING;
- /* TODO: set to HTTP_VERSION_NA in case of TLS (when supported) */
+ /* TODO: set to HTTP_VERSION_NA in case of TLS */
hc->version = HTTP_VERSION_1;
cargs->api_context = hc_index;
@@ -878,7 +803,7 @@ http_transport_connect (transport_endpoint_cfg_t *tep)
ho->opaque = sep->opaque;
ho->session_type =
session_type_from_proto_and_ip (TRANSPORT_PROTO_HTTP, sep->is_ip4);
- hc->h_tc_session_handle = cargs->sh;
+ hc->hc_tc_session_handle = cargs->sh;
hc->c_s_index = ho->session_index;
return 0;
@@ -933,15 +858,15 @@ http_start_listen (u32 app_listener_index, transport_endpoint_cfg_t *tep)
}
/* Grab transport connection listener and link to http listener */
- lhc->h_tc_session_handle = args->handle;
- al = app_listener_get_w_handle (lhc->h_tc_session_handle);
+ lhc->hc_tc_session_handle = args->handle;
+ al = app_listener_get_w_handle (lhc->hc_tc_session_handle);
ts_listener = app_listener_get_session (al);
ts_listener->opaque = lhc_index;
/* Grab application listener and link to http listener */
app_listener = listen_session_get (app_listener_index);
- lhc->h_pa_wrk_index = sep->app_wrk_index;
- lhc->h_pa_session_handle = listen_session_get_handle (app_listener);
+ lhc->hc_pa_wrk_index = sep->app_wrk_index;
+ lhc->hc_pa_session_handle = listen_session_get_handle (app_listener);
lhc->c_s_index = app_listener_index;
lhc->c_flags |= TRANSPORT_CONNECTION_F_NO_LOOKUP;
@@ -964,7 +889,7 @@ http_stop_listen (u32 listener_index)
lhc = http_listener_get (listener_index);
vnet_unlisten_args_t a = {
- .handle = lhc->h_tc_session_handle,
+ .handle = lhc->hc_tc_session_handle,
.app_index = http_main.app_index,
.wrk_map_index = 0 /* default wrk */
};
@@ -978,15 +903,22 @@ http_stop_listen (u32 listener_index)
}
static void
-http_transport_close (u32 hc_index, u32 thread_index)
+http_transport_close (u32 rh, u32 thread_index)
{
http_conn_t *hc;
+ u32 hc_index;
+ http_req_handle_t hr_handle;
+ hr_handle.as_u32 = rh;
+
+ hc_index = http_vfts[hr_handle.version].hc_index_get_by_req_index (
+ hr_handle.req_index, thread_index);
HTTP_DBG (1, "App disconnecting [%u]%x", thread_index, hc_index);
hc = http_conn_get_w_thread (hc_index, thread_index);
if (hc->state == HTTP_CONN_STATE_CONNECTING)
{
+ HTTP_DBG (1, "in connecting state, close now");
hc->state = HTTP_CONN_STATE_APP_CLOSED;
http_disconnect_transport (hc);
return;
@@ -997,14 +929,20 @@ http_transport_close (u32 hc_index, u32 thread_index)
return;
}
- http_vfts[hc->version].app_close_callback (hc);
+ http_vfts[hc->version].app_close_callback (hc, hr_handle.req_index,
+ thread_index);
}
static void
-http_transport_reset (u32 hc_index, u32 thread_index)
+http_transport_reset (u32 rh, u32 thread_index)
{
http_conn_t *hc;
+ u32 hc_index;
+ http_req_handle_t hr_handle;
+ hr_handle.as_u32 = rh;
+ hc_index = http_vfts[hr_handle.version].hc_index_get_by_req_index (
+ hr_handle.req_index, thread_index);
HTTP_DBG (1, "App disconnecting [%u]%x", thread_index, hc_index);
hc = http_conn_get_w_thread (hc_index, thread_index);
@@ -1014,14 +952,18 @@ http_transport_reset (u32 hc_index, u32 thread_index)
return;
}
- http_vfts[hc->version].app_reset_callback (hc);
+ http_vfts[hc->version].app_reset_callback (hc, hr_handle.req_index,
+ thread_index);
}
static transport_connection_t *
-http_transport_get_connection (u32 hc_index, u32 thread_index)
+http_transport_get_connection (u32 rh, u32 thread_index)
{
- http_conn_t *hc = http_conn_get_w_thread (hc_index, thread_index);
- return &hc->connection;
+ http_req_handle_t hr_handle;
+
+ hr_handle.as_u32 = rh;
+ return http_vfts[hr_handle.version].req_get_connection (hr_handle.req_index,
+ thread_index);
}
static transport_connection_t *
@@ -1035,12 +977,16 @@ static int
http_app_tx_callback (void *session, transport_send_params_t *sp)
{
session_t *as = (session_t *) session;
- u32 max_burst_sz, sent;
+ u32 max_burst_sz, sent, hc_index;
http_conn_t *hc;
+ http_req_handle_t hr_handle;
+ hr_handle.as_u32 = as->connection_index;
- HTTP_DBG (1, "hc [%u]%x", as->thread_index, as->connection_index);
+ hc_index = http_vfts[hr_handle.version].hc_index_get_by_req_index (
+ hr_handle.req_index, as->thread_index);
+ HTTP_DBG (1, "hc [%u]%x", hc_index, as->connection_index);
- hc = http_conn_get_w_thread (as->connection_index, as->thread_index);
+ hc = http_conn_get_w_thread (hc_index, as->thread_index);
if (hc->state == HTTP_CONN_STATE_CLOSED)
{
@@ -1052,16 +998,11 @@ http_app_tx_callback (void *session, transport_send_params_t *sp)
max_burst_sz = sp->max_burst_size * TRANSPORT_PACER_MIN_MSS;
sp->max_burst_size = max_burst_sz;
- http_vfts[hc->version].app_tx_callback (hc, sp);
+ http_vfts[hc->version].app_tx_callback (hc, hr_handle.req_index, sp);
if (hc->state == HTTP_CONN_STATE_APP_CLOSED)
- {
- if (!svm_fifo_max_dequeue_cons (as->tx_fifo))
- {
- session_transport_closed_notify (&hc->connection);
- http_disconnect_transport (hc);
- }
- }
+ http_vfts[hc->version].app_close_callback (hc, hr_handle.req_index,
+ as->thread_index);
sent = max_burst_sz - sp->max_burst_size;
@@ -1071,37 +1012,36 @@ http_app_tx_callback (void *session, transport_send_params_t *sp)
static int
http_app_rx_evt_cb (transport_connection_t *tc)
{
- http_conn_t *hc = (http_conn_t *) tc;
- HTTP_DBG (1, "hc [%u]%x", vlib_get_thread_index (), hc->h_hc_index);
+ http_req_t *req = (http_req_t *) tc;
+ http_conn_t *hc;
+ http_req_handle_t hr_handle;
+
+ HTTP_DBG (1, "hc [%u]%x", vlib_get_thread_index (), req->hr_hc_index);
- http_vfts[hc->version].app_rx_evt_callback (hc);
+ hr_handle.as_u32 = req->hr_req_handle;
+ hc = http_conn_get_w_thread (req->hr_hc_index, req->c_thread_index);
+ http_vfts[hr_handle.version].app_rx_evt_callback (hc, hr_handle.req_index,
+ req->c_thread_index);
return 0;
}
static void
-http_transport_get_endpoint (u32 hc_index, u32 thread_index,
+http_transport_get_endpoint (u32 rh, u32 thread_index,
transport_endpoint_t *tep, u8 is_lcl)
{
- http_conn_t *hc = http_conn_get_w_thread (hc_index, thread_index);
- session_t *ts;
-
- ts = session_get_from_handle (hc->h_tc_session_handle);
- session_get_endpoint (ts, tep, is_lcl);
-}
-
-static u8 *
-format_http_connection (u8 *s, va_list *args)
-{
- http_conn_t *hc = va_arg (*args, http_conn_t *);
+ http_conn_t *hc;
session_t *ts;
+ u32 hc_index;
+ http_req_handle_t hr_handle;
- ts = session_get_from_handle (hc->h_tc_session_handle);
- s = format (s, "[%d:%d][H] app_wrk %u ts %d:%d", hc->c_thread_index,
- hc->c_s_index, hc->h_pa_wrk_index, ts->thread_index,
- ts->session_index);
+ hr_handle.as_u32 = rh;
+ hc_index = http_vfts[hr_handle.version].hc_index_get_by_req_index (
+ hr_handle.req_index, thread_index);
+ hc = http_conn_get_w_thread (hc_index, thread_index);
- return s;
+ ts = session_get_from_handle (hc->hc_tc_session_handle);
+ session_get_endpoint (ts, tep, is_lcl);
}
static u8 *
@@ -1111,10 +1051,10 @@ format_http_listener (u8 *s, va_list *args)
app_listener_t *al;
session_t *lts;
- al = app_listener_get_w_handle (lhc->h_tc_session_handle);
+ al = app_listener_get_w_handle (lhc->hc_tc_session_handle);
lts = app_listener_get_session (al);
s = format (s, "[%d:%d][H] app_wrk %u ts %d:%d", lhc->c_thread_index,
- lhc->c_s_index, lhc->h_pa_wrk_index, lts->thread_index,
+ lhc->c_s_index, lhc->hc_pa_wrk_index, lts->thread_index,
lts->session_index);
return s;
@@ -1123,22 +1063,18 @@ format_http_listener (u8 *s, va_list *args)
static u8 *
format_http_transport_connection (u8 *s, va_list *args)
{
- u32 tc_index = va_arg (*args, u32);
+ http_req_handle_t rh = va_arg (*args, http_req_handle_t);
u32 thread_index = va_arg (*args, u32);
u32 verbose = va_arg (*args, u32);
+ u32 hc_index;
http_conn_t *hc;
- hc = http_conn_get_w_thread (tc_index, thread_index);
-
- s = format (s, "%-" SESSION_CLI_ID_LEN "U", format_http_connection, hc);
- if (verbose)
- {
- s =
- format (s, "%-" SESSION_CLI_STATE_LEN "U", format_http_conn_state, hc);
- if (verbose > 1)
- s = format (s, "\n");
- }
+ hc_index = http_vfts[rh.version].hc_index_get_by_req_index (rh.req_index,
+ thread_index);
+ hc = http_conn_get_w_thread (hc_index, thread_index);
+ s = format (s, "%U", http_vfts[rh.version].format_req, rh.req_index,
+ thread_index, hc, verbose);
return s;
}
@@ -1167,10 +1103,10 @@ format_http_transport_half_open (u8 *s, va_list *args)
session_t *tcp_ho;
ho_hc = http_ho_conn_get (ho_index);
- tcp_ho = session_get_from_handle (ho_hc->h_tc_session_handle);
+ tcp_ho = session_get_from_handle (ho_hc->hc_tc_session_handle);
s = format (s, "[%d:%d][H] half-open app_wrk %u ts %d:%d",
- ho_hc->c_thread_index, ho_hc->c_s_index, ho_hc->h_pa_wrk_index,
+ ho_hc->c_thread_index, ho_hc->c_s_index, ho_hc->hc_pa_wrk_index,
tcp_ho->thread_index, tcp_ho->session_index);
return s;
}
@@ -1192,13 +1128,13 @@ http_transport_cleanup_ho (u32 ho_hc_index)
HTTP_DBG (1, "half open: %x", ho_hc_index);
ho_hc = http_ho_conn_get (ho_hc_index);
- if (ho_hc->h_tc_session_handle == SESSION_INVALID_HANDLE)
+ if (ho_hc->hc_tc_session_handle == SESSION_INVALID_HANDLE)
{
HTTP_DBG (1, "already pending cleanup");
ho_hc->flags |= HTTP_CONN_F_NO_APP_SESSION;
return;
}
- session_cleanup_half_open (ho_hc->h_tc_session_handle);
+ session_cleanup_half_open (ho_hc->hc_tc_session_handle);
http_ho_conn_free (ho_hc);
}
@@ -1267,6 +1203,28 @@ http_transport_init (vlib_main_t *vm)
VLIB_INIT_FUNCTION (http_transport_init);
+static uword
+unformat_http_version_cfg (unformat_input_t *input, va_list *va)
+{
+ http_engine_vft_t *http_version;
+ unformat_input_t sub_input;
+ int found = 0;
+
+ vec_foreach (http_version, http_vfts)
+ {
+ if (!unformat (input, http_version->name))
+ continue;
+
+ if (http_version->unformat_cfg_callback &&
+ unformat (input, "%U", unformat_vlib_cli_sub_input, &sub_input))
+ {
+ if (http_version->unformat_cfg_callback (&sub_input))
+ found = 1;
+ }
+ }
+ return found;
+}
+
static clib_error_t *
http_config_fn (vlib_main_t *vm, unformat_input_t *input)
{
@@ -1295,6 +1253,8 @@ http_config_fn (vlib_main_t *vm, unformat_input_t *input)
if (hm->fifo_size != mem_sz)
clib_warning ("invalid fifo size %lu", mem_sz);
}
+ else if (unformat (input, "%U", unformat_http_version_cfg))
+ ;
else
return clib_error_return (0, "unknown input `%U'",
format_unformat_error, input);