From 7f8695c3bbee56cf84db4465e8679da881fc516d Mon Sep 17 00:00:00 2001 From: Philippe Antoine Date: Wed, 18 Feb 2026 21:06:50 +0100 Subject: [PATCH] detect/http2: use ThreadCtx for http.header.raw Instead of custom inefficient "escaped" Vec Ticket: 8291 (cherry picked from commit 0933e944dfaa5b6a6b907ad4f4cf9ca5d0aa8a3b) --- rust/src/http2/detect.rs | 23 +++++++++++------------ src/detect-http-raw-header.c | 9 ++++++++- 2 files changed, 19 insertions(+), 13 deletions(-) diff --git a/rust/src/http2/detect.rs b/rust/src/http2/detect.rs index 98811118f6..f647133e6e 100644 --- a/rust/src/http2/detect.rs +++ b/rust/src/http2/detect.rs @@ -852,10 +852,12 @@ pub unsafe extern "C" fn SCHttp2TxGetHeaders( } #[no_mangle] -pub unsafe extern "C" fn rs_http2_tx_get_headers_raw( +pub unsafe extern "C" fn SCHttp2TxGetHeadersRaw( tx: &mut HTTP2Transaction, direction: u8, buffer: *mut *const u8, buffer_len: *mut u32, + tbuf: *mut c_void, ) -> u8 { - let mut vec = Vec::new(); + let tbuf = cast_pointer!(tbuf, Http2ThreadBuf); + tbuf.data = Vec::new(); let frames = if direction & Direction::ToServer as u8 != 0 { &tx.frames_ts } else { @@ -865,19 +867,16 @@ pub unsafe extern "C" fn rs_http2_tx_get_headers_raw( if let Some(blocks) = http2_header_blocks(frame) { for block in blocks.iter() { // we do not escape linefeeds nor : in headers names - vec.extend_from_slice(&block.name); - vec.extend_from_slice(b": "); - vec.extend_from_slice(&block.value); - vec.extend_from_slice(b"\r\n"); + tbuf.data.extend_from_slice(&block.name); + tbuf.data.extend_from_slice(b": "); + tbuf.data.extend_from_slice(&block.value); + tbuf.data.extend_from_slice(b"\r\n"); } } } - if !vec.is_empty() { - tx.escaped.push(vec); - let idx = tx.escaped.len() - 1; - let value = &tx.escaped[idx]; - *buffer = value.as_ptr(); //unsafe - *buffer_len = value.len() as u32; + if !tbuf.data.is_empty() { + *buffer = tbuf.data.as_ptr(); //unsafe + *buffer_len = tbuf.data.len() as u32; return 1; } return 0; diff --git a/src/detect-http-raw-header.c b/src/detect-http-raw-header.c index 946c2233e5..3569bb3fdb 100644 --- a/src/detect-http-raw-header.c +++ b/src/detect-http-raw-header.c @@ -60,6 +60,8 @@ static void DetectHttpRawHeaderRegisterTests(void); #endif static bool DetectHttpRawHeaderValidateCallback(const Signature *s, const char **sigerror); static int g_http_raw_header_buffer_id = 0; +static int g_http2_thread_id = 0; + static InspectionBuffer *GetData(DetectEngineThreadCtx *det_ctx, const DetectEngineTransforms *transforms, Flow *_f, const uint8_t flow_flags, void *txv, const int list_id); @@ -122,6 +124,8 @@ void DetectHttpRawHeaderRegister(void) DetectBufferTypeRegisterValidateCallback("http_raw_header", DetectHttpRawHeaderValidateCallback); + g_http2_thread_id = DetectRegisterThreadCtxGlobalFuncs( + "http2.raw_header", SCHttp2ThreadBufDataInit, NULL, SCHttp2ThreadBufDataFree); g_http_raw_header_buffer_id = DetectBufferTypeGetByName("http_raw_header"); } @@ -213,7 +217,10 @@ static InspectionBuffer *GetData2(DetectEngineThreadCtx *det_ctx, uint32_t b_len = 0; const uint8_t *b = NULL; - if (rs_http2_tx_get_headers_raw(txv, flow_flags, &b, &b_len) != 1) + void *thread_buf = DetectThreadCtxGetGlobalKeywordThreadCtx(det_ctx, g_http2_thread_id); + if (thread_buf == NULL) + return NULL; + if (SCHttp2TxGetHeadersRaw(txv, flow_flags, &b, &b_len, thread_buf) != 1) return NULL; if (b == NULL || b_len == 0) return NULL;