detect/http2: use ThreadCtx for http.request_header

And also for http.response_header

Instead of custom inefficient "escaped" Vec

Ticket: 8291
(cherry picked from commit 4e538dfa3b)
pull/15050/head
Philippe Antoine 2 months ago committed by Victor Julien
parent 7b77edfa69
commit 029cc968c8

@ -763,7 +763,8 @@ pub unsafe extern "C" fn SCHttp2TxGetHeaderNames(
tbuf: *mut c_void,
) -> u8 {
let tbuf = cast_pointer!(tbuf, Http2ThreadBuf);
tbuf.data = vec![b'\r', b'\n'];
tbuf.data.clear();
tbuf.data.extend_from_slice(b"\r\n");
let frames = if direction & Direction::ToServer as u8 != 0 {
&tx.frames_ts
} else {
@ -826,7 +827,7 @@ pub unsafe extern "C" fn SCHttp2TxGetHeaders(
tbuf: *mut c_void,
) -> u8 {
let tbuf = cast_pointer!(tbuf, Http2ThreadBuf);
tbuf.data = Vec::new();
tbuf.data.clear();
let frames = if direction & Direction::ToServer as u8 != 0 {
&tx.frames_ts
} else {
@ -860,7 +861,7 @@ pub unsafe extern "C" fn SCHttp2TxGetHeadersRaw(
tbuf: *mut c_void,
) -> u8 {
let tbuf = cast_pointer!(tbuf, Http2ThreadBuf);
tbuf.data = Vec::new();
tbuf.data.clear();
let frames = if direction & Direction::ToServer as u8 != 0 {
&tx.frames_ts
} else {
@ -885,22 +886,42 @@ pub unsafe extern "C" fn SCHttp2TxGetHeadersRaw(
return 0;
}
#[derive(Default)]
struct Http2ThreadMultiBuf {
data: Vec<Vec<u8>>,
}
#[no_mangle]
pub unsafe extern "C" fn SCHttp2ThreadMultiBufDataInit(_cfg: *mut c_void) -> *mut c_void {
let boxed = Box::new(Http2ThreadMultiBuf::default());
return Box::into_raw(boxed) as *mut c_void;
}
#[no_mangle]
pub unsafe extern "C" fn SCHttp2ThreadMultiBufDataFree(ctx: *mut c_void) {
std::mem::drop(Box::from_raw(ctx as *mut Http2ThreadMultiBuf));
}
#[no_mangle]
pub unsafe extern "C" fn SCHttp2TxGetHeader(
_de: *mut DetectEngineThreadCtx, tx: *const c_void, direction: u8, nb: u32,
buffer: *mut *const u8, buffer_len: *mut u32,
tbuf: *mut c_void, tx: *const c_void, direction: u8, nb: u32, buffer: *mut *const u8,
buffer_len: *mut u32,
) -> bool {
let tbuf = cast_pointer!(tbuf, Http2ThreadMultiBuf);
let tx = cast_pointer!(tx, HTTP2Transaction);
let mut pos = 0_u32;
if nb == 0 {
tbuf.data.clear();
}
match direction.into() {
Direction::ToServer => {
for i in 0..tx.frames_ts.len() {
if let Some(blocks) = http2_header_blocks(&tx.frames_ts[i]) {
if nb < pos + blocks.len() as u32 {
let ehdr = http2_escape_header(blocks, nb - pos);
tx.escaped.push(ehdr);
let idx = tx.escaped.len() - 1;
let value = &tx.escaped[idx];
tbuf.data.push(ehdr);
let idx = tbuf.data.len() - 1;
let value = &tbuf.data[idx];
*buffer = value.as_ptr(); //unsafe
*buffer_len = value.len() as u32;
return true;
@ -915,9 +936,9 @@ pub unsafe extern "C" fn SCHttp2TxGetHeader(
if let Some(blocks) = http2_header_blocks(&tx.frames_tc[i]) {
if nb < pos + blocks.len() as u32 {
let ehdr = http2_escape_header(blocks, nb - pos);
tx.escaped.push(ehdr);
let idx = tx.escaped.len() - 1;
let value = &tx.escaped[idx];
tbuf.data.push(ehdr);
let idx = tbuf.data.len() - 1;
let value = &tbuf.data[idx];
*buffer = value.as_ptr(); //unsafe
*buffer_len = value.len() as u32;
return true;

@ -465,6 +465,8 @@ static int g_http_request_header_buffer_id = 0;
static int g_http_response_header_buffer_id = 0;
static int g_request_header_thread_id = 0;
static int g_response_header_thread_id = 0;
static int g_h2_request_header_thread_id = 0;
static int g_h2_response_header_thread_id = 0;
typedef struct HttpMultiBufItem {
uint8_t *buffer;
@ -503,6 +505,22 @@ static void HttpMultiBufHeaderThreadDataFree(void *data)
SCFree(td);
}
static bool GetHttp2HeaderData(DetectEngineThreadCtx *det_ctx, const void *txv, const uint8_t flags,
uint32_t local_id, const uint8_t **buf, uint32_t *buf_len)
{
int kw_thread_id;
if (flags & STREAM_TOSERVER) {
kw_thread_id = g_h2_request_header_thread_id;
} else {
kw_thread_id = g_h2_response_header_thread_id;
}
void *hdr_td = DetectThreadCtxGetGlobalKeywordThreadCtx(det_ctx, kw_thread_id);
if (unlikely(hdr_td == NULL)) {
return false;
}
return SCHttp2TxGetHeader(hdr_td, txv, flags, local_id, buf, buf_len);
}
static bool GetHttp1HeaderData(DetectEngineThreadCtx *det_ctx, const void *txv, const uint8_t flags,
uint32_t local_id, const uint8_t **buf, uint32_t *buf_len)
{
@ -598,7 +616,7 @@ void DetectHttpRequestHeaderRegister(void)
SIGMATCH_NOOPT | SIGMATCH_INFO_STICKY_BUFFER;
DetectAppLayerMultiRegister("http_request_header", ALPROTO_HTTP2, SIG_FLAG_TOSERVER,
HTTP2StateOpen, SCHttp2TxGetHeader, 2);
HTTP2StateOpen, GetHttp2HeaderData, 2);
DetectAppLayerMultiRegister("http_request_header", ALPROTO_HTTP1, SIG_FLAG_TOSERVER,
HTP_REQUEST_PROGRESS_HEADERS, GetHttp1HeaderData, 2);
@ -607,6 +625,8 @@ void DetectHttpRequestHeaderRegister(void)
DetectBufferTypeSupportsMultiInstance("http_request_header");
g_request_header_thread_id = DetectRegisterThreadCtxGlobalFuncs("http_request_header",
HttpMultiBufHeaderThreadDataInit, NULL, HttpMultiBufHeaderThreadDataFree);
g_h2_request_header_thread_id = DetectRegisterThreadCtxGlobalFuncs("http2_request_header",
SCHttp2ThreadMultiBufDataInit, NULL, SCHttp2ThreadMultiBufDataFree);
}
static int DetectHTTPResponseHeaderSetup(DetectEngineCtx *de_ctx, Signature *s, const char *arg)
@ -631,7 +651,7 @@ void DetectHttpResponseHeaderRegister(void)
SIGMATCH_NOOPT | SIGMATCH_INFO_STICKY_BUFFER;
DetectAppLayerMultiRegister("http_response_header", ALPROTO_HTTP2, SIG_FLAG_TOCLIENT,
HTTP2StateOpen, SCHttp2TxGetHeader, 2);
HTTP2StateOpen, GetHttp2HeaderData, 2);
DetectAppLayerMultiRegister("http_response_header", ALPROTO_HTTP1, SIG_FLAG_TOCLIENT,
HTP_RESPONSE_PROGRESS_HEADERS, GetHttp1HeaderData, 2);
@ -640,6 +660,8 @@ void DetectHttpResponseHeaderRegister(void)
DetectBufferTypeSupportsMultiInstance("http_response_header");
g_response_header_thread_id = DetectRegisterThreadCtxGlobalFuncs("http_response_header",
HttpMultiBufHeaderThreadDataInit, NULL, HttpMultiBufHeaderThreadDataFree);
g_h2_response_header_thread_id = DetectRegisterThreadCtxGlobalFuncs("http2_response_header",
SCHttp2ThreadMultiBufDataInit, NULL, SCHttp2ThreadMultiBufDataFree);
}
/************************************Unittests*********************************/

Loading…
Cancel
Save