From acc89464f475033f37c393aca42eb8627bc8292e Mon Sep 17 00:00:00 2001 From: Matus Fabian Date: Thu, 3 Apr 2025 05:59:06 -0400 Subject: [PATCH] http: http_buffer improvements needed for http/2 to make data frame header http_buffer_get_segs return number bytes in returned segments http_buffer_is_drain changed to http_buffer_bytes_left ptr buffer can track u64 data length Type: improvement Change-Id: I586bec69c851cb38d7be7af9e254cd240bbd7e62 Signed-off-by: Matus Fabian --- src/plugins/http/http1.c | 10 ++++----- src/plugins/http/http_buffer.c | 50 +++++++++++++++++++++++------------------- src/plugins/http/http_buffer.h | 18 ++++++++------- 3 files changed, 42 insertions(+), 36 deletions(-) diff --git a/src/plugins/http/http1.c b/src/plugins/http/http1.c index 09d69f57bdf..e71a458e95c 100644 --- a/src/plugins/http/http1.c +++ b/src/plugins/http/http1.c @@ -1504,12 +1504,12 @@ static http_sm_result_t http1_req_state_app_io_more_data (http_conn_t *hc, http_req_t *req, transport_send_params_t *sp) { - u32 max_write, n_segs, n_written = 0; + u32 max_write, n_read, n_segs, n_written = 0; http_buffer_t *hb = &req->tx_buf; svm_fifo_seg_t *seg; u8 finished = 0; - ASSERT (!http_buffer_is_drained (hb)); + ASSERT (http_buffer_bytes_left (hb) > 0); max_write = http_io_ts_max_write (hc, sp); if (max_write == 0) { @@ -1517,8 +1517,8 @@ http1_req_state_app_io_more_data (http_conn_t *hc, http_req_t *req, goto check_fifo; } - seg = http_buffer_get_segs (hb, max_write, &n_segs); - if (!seg) + n_read = http_buffer_get_segs (hb, max_write, &seg, &n_segs); + if (n_read == 0) { HTTP_DBG (1, "no data to deq"); goto check_fifo; @@ -1527,7 +1527,7 @@ http1_req_state_app_io_more_data (http_conn_t *hc, http_req_t *req, n_written = http_io_ts_write_segs (hc, seg, n_segs, sp); http_buffer_drain (hb, n_written); - finished = http_buffer_is_drained (hb); + finished = http_buffer_bytes_left (hb) == 0; if (finished) { diff --git a/src/plugins/http/http_buffer.c b/src/plugins/http/http_buffer.c index 909aa538396..fd90fbfed8c 100644 --- a/src/plugins/http/http_buffer.c +++ b/src/plugins/http/http_buffer.c @@ -57,8 +57,9 @@ buf_fifo_free (http_buffer_t *hb) vec_free (bf->segs); } -static svm_fifo_seg_t * -buf_fifo_get_segs (http_buffer_t *hb, u32 max_len, u32 *n_segs) +static u32 +buf_fifo_get_segs (http_buffer_t *hb, u32 max_len, svm_fifo_seg_t **fs, + u32 *n_segs) { http_buffer_fifo_t *bf = (http_buffer_fifo_t *) &hb->data; @@ -77,7 +78,8 @@ buf_fifo_get_segs (http_buffer_t *hb, u32 max_len, u32 *n_segs) HTTP_DBG (1, "available to send %u n_segs %u", len, *n_segs); - return bf->segs; + *fs = bf->segs; + return len; } static u32 @@ -92,13 +94,13 @@ buf_fifo_drain (http_buffer_t *hb, u32 len) return len; } -static u8 -buf_fifo_is_drained (http_buffer_t *hb) +static u64 +buf_fifo_bytes_left (http_buffer_t *hb) { http_buffer_fifo_t *bf = (http_buffer_fifo_t *) &hb->data; ASSERT (bf->offset <= bf->len); - return (bf->offset == bf->len); + return (bf->len - bf->offset); } const static http_buffer_vft_t buf_fifo_vft = { @@ -106,7 +108,7 @@ const static http_buffer_vft_t buf_fifo_vft = { .free = buf_fifo_free, .get_segs = buf_fifo_get_segs, .drain = buf_fifo_drain, - .is_drained = buf_fifo_is_drained, + .bytes_left = buf_fifo_bytes_left, }; HTTP_BUFFER_REGISTER_VFT (HTTP_BUFFER_FIFO, buf_fifo_vft); @@ -115,6 +117,7 @@ typedef struct http_buffer_ptr_ { svm_fifo_seg_t *segs; svm_fifo_t *f; + u64 len; } http_buffer_ptr_t; STATIC_ASSERT (sizeof (http_buffer_ptr_t) <= HTTP_BUFFER_DATA_SZ, "buf data"); @@ -135,12 +138,11 @@ buf_ptr_init (http_buffer_t *hb, void *data, u64 len) bf->f = f; bf->segs = 0; - vec_validate (bf->segs, 1); + vec_validate (bf->segs, 0); bf->segs[0].data = uword_to_pointer (ptr, u8 *); - bf->segs[0].len = len; - bf->segs[1] = bf->segs[0]; + bf->len = len; } static void @@ -152,15 +154,17 @@ buf_ptr_free (http_buffer_t *hb) vec_free (bf->segs); } -static svm_fifo_seg_t * -buf_ptr_get_segs (http_buffer_t *hb, u32 max_len, u32 *n_segs) +static u32 +buf_ptr_get_segs (http_buffer_t *hb, u32 max_len, svm_fifo_seg_t **fs, + u32 *n_segs) { http_buffer_ptr_t *bf = (http_buffer_ptr_t *) &hb->data; *n_segs = 1; - bf->segs[1].len = clib_min (bf->segs[0].len, max_len); + bf->segs[0].len = clib_min (bf->len, (u64) max_len); - return &bf->segs[1]; + *fs = bf->segs; + return bf->segs[0].len; } static u32 @@ -168,14 +172,14 @@ buf_ptr_drain (http_buffer_t *hb, u32 len) { http_buffer_ptr_t *bf = (http_buffer_ptr_t *) &hb->data; - ASSERT (bf->segs[0].len >= len); + ASSERT (bf->len >= len); - bf->segs[1].data += len; - bf->segs[0].len -= len; + bf->segs[0].data += len; + bf->len -= len; - HTTP_DBG (1, "drained %u left %u", len, bf->segs[0].len); + HTTP_DBG (1, "drained %u left %u", len, bf->len); - if (!bf->segs[0].len) + if (!bf->len) { svm_fifo_dequeue_drop (bf->f, sizeof (uword)); return sizeof (uword); @@ -184,12 +188,12 @@ buf_ptr_drain (http_buffer_t *hb, u32 len) return 0; } -static u8 -buf_ptr_is_drained (http_buffer_t *hb) +static u64 +buf_ptr_bytes_left (http_buffer_t *hb) { http_buffer_ptr_t *bf = (http_buffer_ptr_t *) &hb->data; - return (bf->segs[0].len == 0); + return bf->len; } const static http_buffer_vft_t buf_ptr_vft = { @@ -197,7 +201,7 @@ const static http_buffer_vft_t buf_ptr_vft = { .free = buf_ptr_free, .get_segs = buf_ptr_get_segs, .drain = buf_ptr_drain, - .is_drained = buf_ptr_is_drained, + .bytes_left = buf_ptr_bytes_left, }; HTTP_BUFFER_REGISTER_VFT (HTTP_BUFFER_PTR, buf_ptr_vft); diff --git a/src/plugins/http/http_buffer.h b/src/plugins/http/http_buffer.h index 1140be42d6e..01b37d4173b 100644 --- a/src/plugins/http/http_buffer.h +++ b/src/plugins/http/http_buffer.h @@ -38,9 +38,10 @@ struct http_buffer_vft_ { void (*init) (http_buffer_t *, void *data, u64 len); void (*free) (http_buffer_t *); - svm_fifo_seg_t *(*get_segs) (http_buffer_t *, u32 max_len, u32 *n_segs); + u32 (*get_segs) (http_buffer_t *, u32 max_len, svm_fifo_seg_t **fs, + u32 *n_segs); u32 (*drain) (http_buffer_t *, u32 len); - u8 (*is_drained) (http_buffer_t *); + u64 (*bytes_left) (http_buffer_t *); }; void http_buffer_init (http_buffer_t *hb, http_buffer_type_t type, @@ -53,10 +54,11 @@ http_buffer_free (http_buffer_t *hb) hb->vft->free (hb); } -static inline svm_fifo_seg_t * -http_buffer_get_segs (http_buffer_t *hb, u32 max_len, u32 *n_segs) +static inline u32 +http_buffer_get_segs (http_buffer_t *hb, u32 max_len, svm_fifo_seg_t **fs, + u32 *n_segs) { - return hb->vft->get_segs (hb, max_len, n_segs); + return hb->vft->get_segs (hb, max_len, fs, n_segs); } static inline u32 @@ -65,10 +67,10 @@ http_buffer_drain (http_buffer_t *hb, u32 len) return hb->vft->drain (hb, len); } -static inline u8 -http_buffer_is_drained (http_buffer_t *hb) +static inline u64 +http_buffer_bytes_left (http_buffer_t *hb) { - return hb->vft->is_drained (hb); + return hb->vft->bytes_left (hb); } #endif /* SRC_PLUGINS_HTTP_HTTP_BUFFER_H_ */ -- 2.16.6