diff --git a/rust/src/http2/detect.rs b/rust/src/http2/detect.rs index 689d2144c5..49bd35d5cc 100644 --- a/rust/src/http2/detect.rs +++ b/rust/src/http2/detect.rs @@ -359,7 +359,7 @@ pub unsafe extern "C" fn SCHttp2TxGetHeaderName( } fn http2_frames_get_header_firstvalue<'a>( - tx: &'a mut HTTP2Transaction, direction: Direction, name: &str, + tx: &'a HTTP2Transaction, direction: Direction, name: &str, ) -> Result<&'a [u8], ()> { let frames = if direction == Direction::ToServer { &tx.frames_ts @@ -465,20 +465,16 @@ fn http2_frames_get_header_value<'a>( } // we mutate the tx to cache req_line -fn http2_tx_get_req_line(tx: &mut HTTP2Transaction) { - if !tx.req_line.is_empty() { - return; - } +fn http2_tx_get_req_line(tx: &HTTP2Transaction, tbuf: &mut DetectThreadBuf) { let empty = Vec::new(); - let mut req_line = Vec::new(); let method = if let Ok(value) = http2_frames_get_header_firstvalue(tx, Direction::ToServer, ":method") { value } else { &empty }; - req_line.extend(method); - req_line.push(b' '); + tbuf.data.extend(method); + tbuf.data.push(b' '); let uri = if let Ok(value) = http2_frames_get_header_firstvalue(tx, Direction::ToServer, ":path") { @@ -486,53 +482,50 @@ fn http2_tx_get_req_line(tx: &mut HTTP2Transaction) { } else { &empty }; - req_line.extend(uri); - req_line.extend(b" HTTP/2\r\n"); - tx.req_line.extend(req_line) + tbuf.data.extend(uri); + tbuf.data.extend(b" HTTP/2\r\n"); } #[no_mangle] pub unsafe extern "C" fn SCHttp2TxGetRequestLine( - tx: &mut HTTP2Transaction, buffer: *mut *const u8, buffer_len: *mut u32, + tx: &HTTP2Transaction, buffer: *mut *const u8, buffer_len: *mut u32, tbuf: *mut c_void, ) -> u8 { - http2_tx_get_req_line(tx); - *buffer = tx.req_line.as_ptr(); //unsafe - *buffer_len = tx.req_line.len() as u32; + let tbuf = cast_pointer!(tbuf, DetectThreadBuf); + tbuf.data.clear(); + http2_tx_get_req_line(tx, tbuf); + *buffer = tbuf.data.as_ptr(); //unsafe + *buffer_len = tbuf.data.len() as u32; return 1; } -fn http2_tx_get_resp_line(tx: &mut HTTP2Transaction) { - if !tx.resp_line.is_empty() { - return; - } +fn http2_tx_get_resp_line(tx: &HTTP2Transaction, tbuf: &mut DetectThreadBuf) { let empty = Vec::new(); - let mut resp_line: Vec = Vec::new(); - let status = if let Ok(value) = http2_frames_get_header_firstvalue(tx, Direction::ToClient, ":status") { value } else { &empty }; - resp_line.extend(b"HTTP/2 "); - resp_line.extend(status); - resp_line.extend(b"\r\n"); - tx.resp_line.extend(resp_line) + tbuf.data.extend(b"HTTP/2 "); + tbuf.data.extend(status); + tbuf.data.extend(b"\r\n"); } #[no_mangle] pub unsafe extern "C" fn SCHttp2TxGetResponseLine( - tx: &mut HTTP2Transaction, buffer: *mut *const u8, buffer_len: *mut u32, + tx: &HTTP2Transaction, buffer: *mut *const u8, buffer_len: *mut u32, tbuf: *mut c_void, ) -> u8 { - http2_tx_get_resp_line(tx); - *buffer = tx.resp_line.as_ptr(); //unsafe - *buffer_len = tx.resp_line.len() as u32; + let tbuf = cast_pointer!(tbuf, DetectThreadBuf); + tbuf.data.clear(); + http2_tx_get_resp_line(tx, tbuf); + *buffer = tbuf.data.as_ptr(); //unsafe + *buffer_len = tbuf.data.len() as u32; return 1; } #[no_mangle] pub unsafe extern "C" fn SCHttp2TxGetUri( - tx: &mut HTTP2Transaction, buffer: *mut *const u8, buffer_len: *mut u32, + tx: &HTTP2Transaction, buffer: *mut *const u8, buffer_len: *mut u32, ) -> u8 { if let Ok(value) = http2_frames_get_header_firstvalue(tx, Direction::ToServer, ":path") { *buffer = value.as_ptr(); //unsafe @@ -544,7 +537,7 @@ pub unsafe extern "C" fn SCHttp2TxGetUri( #[no_mangle] pub unsafe extern "C" fn SCHttp2TxGetMethod( - tx: &mut HTTP2Transaction, buffer: *mut *const u8, buffer_len: *mut u32, + tx: &HTTP2Transaction, buffer: *mut *const u8, buffer_len: *mut u32, ) -> u8 { if let Ok(value) = http2_frames_get_header_firstvalue(tx, Direction::ToServer, ":method") { *buffer = value.as_ptr(); //unsafe @@ -556,7 +549,7 @@ pub unsafe extern "C" fn SCHttp2TxGetMethod( #[no_mangle] pub unsafe extern "C" fn SCHttp2TxGetHost( - tx: &mut HTTP2Transaction, buffer: *mut *const u8, buffer_len: *mut u32, tbuf: *mut c_void, + tx: &HTTP2Transaction, buffer: *mut *const u8, buffer_len: *mut u32, tbuf: *mut c_void, ) -> u8 { let tbuf = cast_pointer!(tbuf, DetectThreadBuf); if let Some(value) = http2_get_host(tx) { @@ -648,7 +641,7 @@ fn http2_get_host(tx: &HTTP2Transaction) -> Option> { #[no_mangle] pub unsafe extern "C" fn SCHttp2TxGetHostNorm( - tx: &mut HTTP2Transaction, buffer: *mut *const u8, buffer_len: *mut u32, tbuf: *mut c_void, + tx: &HTTP2Transaction, buffer: *mut *const u8, buffer_len: *mut u32, tbuf: *mut c_void, ) -> u8 { let tbuf = cast_pointer!(tbuf, DetectThreadBuf); if let Some(value) = http2_get_host(tx) { @@ -671,7 +664,7 @@ pub unsafe extern "C" fn SCHttp2TxGetHostNorm( #[no_mangle] pub unsafe extern "C" fn SCHttp2TxGetUserAgent( - tx: &mut HTTP2Transaction, buffer: *mut *const u8, buffer_len: *mut u32, tbuf: *mut c_void, + tx: &HTTP2Transaction, buffer: *mut *const u8, buffer_len: *mut u32, tbuf: *mut c_void, ) -> u8 { let tbuf = cast_pointer!(tbuf, DetectThreadBuf); if let Some(value) = http2_frames_get_header_value(tx, Direction::ToServer, "user-agent") { @@ -694,7 +687,7 @@ pub unsafe extern "C" fn SCHttp2TxGetUserAgent( #[no_mangle] pub unsafe extern "C" fn SCHttp2TxGetStatus( - tx: &mut HTTP2Transaction, buffer: *mut *const u8, buffer_len: *mut u32, + tx: &HTTP2Transaction, buffer: *mut *const u8, buffer_len: *mut u32, ) -> u8 { if let Ok(value) = http2_frames_get_header_firstvalue(tx, Direction::ToClient, ":status") { *buffer = value.as_ptr(); //unsafe @@ -706,7 +699,7 @@ pub unsafe extern "C" fn SCHttp2TxGetStatus( #[no_mangle] pub unsafe extern "C" fn SCHttp2TxGetCookie( - tx: &mut HTTP2Transaction, direction: u8, buffer: *mut *const u8, buffer_len: *mut u32, + tx: &HTTP2Transaction, direction: u8, buffer: *mut *const u8, buffer_len: *mut u32, tbuf: *mut c_void, ) -> u8 { let tbuf = cast_pointer!(tbuf, DetectThreadBuf); @@ -747,7 +740,7 @@ pub unsafe extern "C" fn SCHttp2TxGetCookie( #[no_mangle] pub unsafe extern "C" fn SCHttp2TxGetHeaderValue( - tx: &mut HTTP2Transaction, direction: u8, strname: *const std::os::raw::c_char, + tx: &HTTP2Transaction, direction: u8, strname: *const std::os::raw::c_char, buffer: *mut *const u8, buffer_len: *mut u32, tbuf: *mut c_void, ) -> u8 { let tbuf = cast_pointer!(tbuf, DetectThreadBuf); @@ -785,7 +778,7 @@ fn http2_escape_header(blocks: &[parser::HTTP2FrameHeaderBlock], i: u32, vec: &m #[no_mangle] pub unsafe extern "C" fn SCHttp2TxGetHeaderNames( - tx: &mut HTTP2Transaction, direction: u8, buffer: *mut *const u8, buffer_len: *mut u32, + tx: &HTTP2Transaction, direction: u8, buffer: *mut *const u8, buffer_len: *mut u32, tbuf: *mut c_void, ) -> u8 { let tbuf = cast_pointer!(tbuf, DetectThreadBuf); @@ -849,7 +842,7 @@ fn http2_header_trimspaces(value: &[u8]) -> &[u8] { #[no_mangle] pub unsafe extern "C" fn SCHttp2TxGetHeaders( - tx: &mut HTTP2Transaction, direction: u8, buffer: *mut *const u8, buffer_len: *mut u32, + tx: &HTTP2Transaction, direction: u8, buffer: *mut *const u8, buffer_len: *mut u32, tbuf: *mut c_void, ) -> u8 { let tbuf = cast_pointer!(tbuf, DetectThreadBuf); @@ -883,7 +876,7 @@ pub unsafe extern "C" fn SCHttp2TxGetHeaders( #[no_mangle] pub unsafe extern "C" fn SCHttp2TxGetHeadersRaw( - tx: &mut HTTP2Transaction, direction: u8, buffer: *mut *const u8, buffer_len: *mut u32, + tx: &HTTP2Transaction, direction: u8, buffer: *mut *const u8, buffer_len: *mut u32, tbuf: *mut c_void, ) -> u8 { let tbuf = cast_pointer!(tbuf, DetectThreadBuf); diff --git a/rust/src/http2/http2.rs b/rust/src/http2/http2.rs index 399341a960..f53939bb3d 100644 --- a/rust/src/http2/http2.rs +++ b/rust/src/http2/http2.rs @@ -300,9 +300,6 @@ pub struct HTTP2Transaction { pub ft_tc: FileTransferTracker, pub ft_ts: FileTransferTracker, - pub req_line: Vec, - pub resp_line: Vec, - pub doh: Option, } @@ -333,8 +330,6 @@ impl HTTP2Transaction { tx_data: AppLayerTxData::new(), ft_tc: FileTransferTracker::new(), ft_ts: FileTransferTracker::new(), - req_line: Vec::new(), - resp_line: Vec::new(), doh: None, } } diff --git a/src/detect-http-request-line.c b/src/detect-http-request-line.c index e30bd39c9a..74770a410a 100644 --- a/src/detect-http-request-line.c +++ b/src/detect-http-request-line.c @@ -69,6 +69,7 @@ static InspectionBuffer *GetData(DetectEngineThreadCtx *det_ctx, Flow *_f, const uint8_t _flow_flags, void *txv, const int list_id); static int g_http_request_line_buffer_id = 0; +static int g_http2_thread_id = 0; static InspectionBuffer *GetData2(DetectEngineThreadCtx *det_ctx, const DetectEngineTransforms *transforms, Flow *_f, const uint8_t _flow_flags, void *txv, @@ -81,7 +82,11 @@ static InspectionBuffer *GetData2(DetectEngineThreadCtx *det_ctx, uint32_t b_len = 0; const uint8_t *b = NULL; - if (SCHttp2TxGetRequestLine(txv, &b, &b_len) != 1) + void *thread_buf = SCDetectThreadCtxGetGlobalKeywordThreadCtx(det_ctx, g_http2_thread_id); + if (thread_buf == NULL) + return NULL; + + if (SCHttp2TxGetRequestLine(txv, &b, &b_len, thread_buf) != 1) return NULL; if (b == NULL || b_len == 0) return NULL; @@ -125,6 +130,9 @@ void DetectHttpRequestLineRegister(void) "http request line"); g_http_request_line_buffer_id = DetectBufferTypeGetByName("http_request_line"); + + g_http2_thread_id = SCDetectRegisterThreadCtxGlobalFuncs( + "http.request_line", SCDetectThreadBufDataInit, NULL, SCDetectThreadBufDataFree); } /** diff --git a/src/detect-http-response-line.c b/src/detect-http-response-line.c index d275178c1a..5d88938a1c 100644 --- a/src/detect-http-response-line.c +++ b/src/detect-http-response-line.c @@ -69,6 +69,7 @@ static InspectionBuffer *GetData(DetectEngineThreadCtx *det_ctx, Flow *_f, const uint8_t _flow_flags, void *txv, const int list_id); static int g_http_response_line_id = 0; +static int g_http2_thread_id = 0; static InspectionBuffer *GetData2(DetectEngineThreadCtx *det_ctx, const DetectEngineTransforms *transforms, Flow *_f, const uint8_t _flow_flags, void *txv, @@ -81,7 +82,10 @@ static InspectionBuffer *GetData2(DetectEngineThreadCtx *det_ctx, uint32_t b_len = 0; const uint8_t *b = NULL; - if (SCHttp2TxGetResponseLine(txv, &b, &b_len) != 1) + void *thread_buf = SCDetectThreadCtxGetGlobalKeywordThreadCtx(det_ctx, g_http2_thread_id); + if (thread_buf == NULL) + return NULL; + if (SCHttp2TxGetResponseLine(txv, &b, &b_len, thread_buf) != 1) return NULL; if (b == NULL || b_len == 0) return NULL; @@ -124,6 +128,8 @@ void DetectHttpResponseLineRegister(void) "http response line"); g_http_response_line_id = DetectBufferTypeGetByName("http_response_line"); + g_http2_thread_id = SCDetectRegisterThreadCtxGlobalFuncs( + "http.response_line", SCDetectThreadBufDataInit, NULL, SCDetectThreadBufDataFree); } /**