Skip to content

Commit 0f4e396

Browse files
catenacyberjasonish
authored andcommitted
detect/http2: use ThreadCtx for http.request_header
And also for http.response_header Instead of custom inefficient "escaped" Vec Ticket: 8291
1 parent 6855f7f commit 0f4e396

2 files changed

Lines changed: 56 additions & 13 deletions

File tree

rust/src/http2/detect.rs

Lines changed: 32 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -722,7 +722,8 @@ pub unsafe extern "C" fn SCHttp2TxGetHeaderNames(
722722
tbuf: *mut c_void,
723723
) -> u8 {
724724
let tbuf = cast_pointer!(tbuf, Http2ThreadBuf);
725-
tbuf.data = vec![b'\r', b'\n'];
725+
tbuf.data.clear();
726+
tbuf.data.extend_from_slice(b"\r\n");
726727
let frames = if direction & Direction::ToServer as u8 != 0 {
727728
&tx.frames_ts
728729
} else {
@@ -785,7 +786,7 @@ pub unsafe extern "C" fn SCHttp2TxGetHeaders(
785786
tbuf: *mut c_void,
786787
) -> u8 {
787788
let tbuf = cast_pointer!(tbuf, Http2ThreadBuf);
788-
tbuf.data = Vec::new();
789+
tbuf.data.clear();
789790
let frames = if direction & Direction::ToServer as u8 != 0 {
790791
&tx.frames_ts
791792
} else {
@@ -819,7 +820,7 @@ pub unsafe extern "C" fn SCHttp2TxGetHeadersRaw(
819820
tbuf: *mut c_void,
820821
) -> u8 {
821822
let tbuf = cast_pointer!(tbuf, Http2ThreadBuf);
822-
tbuf.data = Vec::new();
823+
tbuf.data.clear();
823824
let frames = if direction & Direction::ToServer as u8 != 0 {
824825
&tx.frames_ts
825826
} else {
@@ -844,22 +845,42 @@ pub unsafe extern "C" fn SCHttp2TxGetHeadersRaw(
844845
return 0;
845846
}
846847

848+
#[derive(Default)]
849+
struct Http2ThreadMultiBuf {
850+
data: Vec<Vec<u8>>,
851+
}
852+
853+
#[no_mangle]
854+
pub unsafe extern "C" fn SCHttp2ThreadMultiBufDataInit(_cfg: *mut c_void) -> *mut c_void {
855+
let boxed = Box::new(Http2ThreadMultiBuf::default());
856+
return Box::into_raw(boxed) as *mut c_void;
857+
}
858+
859+
#[no_mangle]
860+
pub unsafe extern "C" fn SCHttp2ThreadMultiBufDataFree(ctx: *mut c_void) {
861+
std::mem::drop(Box::from_raw(ctx as *mut Http2ThreadMultiBuf));
862+
}
863+
847864
#[no_mangle]
848865
pub unsafe extern "C" fn SCHttp2TxGetHeader(
849-
_de: *mut DetectEngineThreadCtx, tx: *const c_void, direction: u8, nb: u32,
850-
buffer: *mut *const u8, buffer_len: *mut u32,
866+
tbuf: *mut c_void, tx: *const c_void, direction: u8, nb: u32, buffer: *mut *const u8,
867+
buffer_len: *mut u32,
851868
) -> bool {
869+
let tbuf = cast_pointer!(tbuf, Http2ThreadMultiBuf);
852870
let tx = cast_pointer!(tx, HTTP2Transaction);
853871
let mut pos = 0_u32;
872+
if nb == 0 {
873+
tbuf.data.clear();
874+
}
854875
match direction.into() {
855876
Direction::ToServer => {
856877
for i in 0..tx.frames_ts.len() {
857878
if let Some(blocks) = http2_header_blocks(&tx.frames_ts[i]) {
858879
if nb < pos + blocks.len() as u32 {
859880
let ehdr = http2_escape_header(blocks, nb - pos);
860-
tx.escaped.push(ehdr);
861-
let idx = tx.escaped.len() - 1;
862-
let value = &tx.escaped[idx];
881+
tbuf.data.push(ehdr);
882+
let idx = tbuf.data.len() - 1;
883+
let value = &tbuf.data[idx];
863884
*buffer = value.as_ptr(); //unsafe
864885
*buffer_len = value.len() as u32;
865886
return true;
@@ -874,9 +895,9 @@ pub unsafe extern "C" fn SCHttp2TxGetHeader(
874895
if let Some(blocks) = http2_header_blocks(&tx.frames_tc[i]) {
875896
if nb < pos + blocks.len() as u32 {
876897
let ehdr = http2_escape_header(blocks, nb - pos);
877-
tx.escaped.push(ehdr);
878-
let idx = tx.escaped.len() - 1;
879-
let value = &tx.escaped[idx];
898+
tbuf.data.push(ehdr);
899+
let idx = tbuf.data.len() - 1;
900+
let value = &tbuf.data[idx];
880901
*buffer = value.as_ptr(); //unsafe
881902
*buffer_len = value.len() as u32;
882903
return true;

src/detect-http-header.c

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -424,6 +424,8 @@ static int g_http_request_header_buffer_id = 0;
424424
static int g_http_response_header_buffer_id = 0;
425425
static int g_request_header_thread_id = 0;
426426
static int g_response_header_thread_id = 0;
427+
static int g_h2_request_header_thread_id = 0;
428+
static int g_h2_response_header_thread_id = 0;
427429

428430
typedef struct HttpMultiBufItem {
429431
uint8_t *buffer;
@@ -462,6 +464,22 @@ static void HttpMultiBufHeaderThreadDataFree(void *data)
462464
SCFree(td);
463465
}
464466

467+
static bool GetHttp2HeaderData(DetectEngineThreadCtx *det_ctx, const void *txv, const uint8_t flags,
468+
uint32_t local_id, const uint8_t **buf, uint32_t *buf_len)
469+
{
470+
int kw_thread_id;
471+
if (flags & STREAM_TOSERVER) {
472+
kw_thread_id = g_h2_request_header_thread_id;
473+
} else {
474+
kw_thread_id = g_h2_response_header_thread_id;
475+
}
476+
void *hdr_td = DetectThreadCtxGetGlobalKeywordThreadCtx(det_ctx, kw_thread_id);
477+
if (unlikely(hdr_td == NULL)) {
478+
return false;
479+
}
480+
return SCHttp2TxGetHeader(hdr_td, txv, flags, local_id, buf, buf_len);
481+
}
482+
465483
static bool GetHttp1HeaderData(DetectEngineThreadCtx *det_ctx, const void *txv, const uint8_t flags,
466484
uint32_t local_id, const uint8_t **buf, uint32_t *buf_len)
467485
{
@@ -557,7 +575,7 @@ void DetectHttpRequestHeaderRegister(void)
557575
SIGMATCH_NOOPT | SIGMATCH_INFO_STICKY_BUFFER | SIGMATCH_INFO_MULTI_BUFFER;
558576

559577
DetectAppLayerMultiRegister("http_request_header", ALPROTO_HTTP2, SIG_FLAG_TOSERVER,
560-
HTTP2StateOpen, SCHttp2TxGetHeader, 2);
578+
HTTP2StateOpen, GetHttp2HeaderData, 2);
561579
DetectAppLayerMultiRegister("http_request_header", ALPROTO_HTTP1, SIG_FLAG_TOSERVER,
562580
HTP_REQUEST_PROGRESS_HEADERS, GetHttp1HeaderData, 2);
563581

@@ -566,6 +584,8 @@ void DetectHttpRequestHeaderRegister(void)
566584
DetectBufferTypeSupportsMultiInstance("http_request_header");
567585
g_request_header_thread_id = DetectRegisterThreadCtxGlobalFuncs("http_request_header",
568586
HttpMultiBufHeaderThreadDataInit, NULL, HttpMultiBufHeaderThreadDataFree);
587+
g_h2_request_header_thread_id = DetectRegisterThreadCtxGlobalFuncs("http2_request_header",
588+
SCHttp2ThreadMultiBufDataInit, NULL, SCHttp2ThreadMultiBufDataFree);
569589
}
570590

571591
static int DetectHTTPResponseHeaderSetup(DetectEngineCtx *de_ctx, Signature *s, const char *arg)
@@ -590,7 +610,7 @@ void DetectHttpResponseHeaderRegister(void)
590610
SIGMATCH_NOOPT | SIGMATCH_INFO_STICKY_BUFFER | SIGMATCH_INFO_MULTI_BUFFER;
591611

592612
DetectAppLayerMultiRegister("http_response_header", ALPROTO_HTTP2, SIG_FLAG_TOCLIENT,
593-
HTTP2StateOpen, SCHttp2TxGetHeader, 2);
613+
HTTP2StateOpen, GetHttp2HeaderData, 2);
594614
DetectAppLayerMultiRegister("http_response_header", ALPROTO_HTTP1, SIG_FLAG_TOCLIENT,
595615
HTP_RESPONSE_PROGRESS_HEADERS, GetHttp1HeaderData, 2);
596616

@@ -599,6 +619,8 @@ void DetectHttpResponseHeaderRegister(void)
599619
DetectBufferTypeSupportsMultiInstance("http_response_header");
600620
g_response_header_thread_id = DetectRegisterThreadCtxGlobalFuncs("http_response_header",
601621
HttpMultiBufHeaderThreadDataInit, NULL, HttpMultiBufHeaderThreadDataFree);
622+
g_h2_response_header_thread_id = DetectRegisterThreadCtxGlobalFuncs("http2_response_header",
623+
SCHttp2ThreadMultiBufDataInit, NULL, SCHttp2ThreadMultiBufDataFree);
602624
}
603625

604626
/************************************Unittests*********************************/

0 commit comments

Comments
 (0)