http2: files inspection API fixes

uses right transaction id for file tracker
uses FILE_USE_DETECT for good matches with keyword startswith
pull/5627/head
Philippe Antoine 4 years ago committed by Victor Julien
parent a63ee5adbd
commit f574663352

@ -24,6 +24,8 @@ use crate::core::*;
extern {
pub fn FileFlowToFlags(flow: *const Flow, flags: u8) -> u16;
}
pub const FILE_USE_DETECT: u16 = 0x2000;
pub struct File;
#[repr(C)]

@ -361,20 +361,11 @@ impl HTTP2State {
return None;
}
fn find_tx_index(&mut self, sid: u32, header: &parser::HTTP2FrameHeader) -> usize {
fn find_tx_index(&mut self, sid: u32) -> usize {
for i in 0..self.transactions.len() {
//reverse order should be faster
let idx = self.transactions.len() - 1 - i;
if sid == self.transactions[idx].stream_id {
if self.transactions[idx].state == HTTP2TransactionState::HTTP2StateClosed {
//these frames can be received in this state for a short period
if header.ftype != parser::HTTP2FrameType::RSTSTREAM as u8
&& header.ftype != parser::HTTP2FrameType::WINDOWUPDATE as u8
&& header.ftype != parser::HTTP2FrameType::PRIORITY as u8
{
self.set_event(HTTP2Event::StreamIdReuse);
}
}
return idx + 1;
}
}
@ -424,8 +415,17 @@ impl HTTP2State {
}
_ => header.stream_id,
};
let index = self.find_tx_index(sid, header);
let index = self.find_tx_index(sid);
if index > 0 {
if self.transactions[index - 1].state == HTTP2TransactionState::HTTP2StateClosed {
//these frames can be received in this state for a short period
if header.ftype != parser::HTTP2FrameType::RSTSTREAM as u8
&& header.ftype != parser::HTTP2FrameType::WINDOWUPDATE as u8
&& header.ftype != parser::HTTP2FrameType::PRIORITY as u8
{
self.set_event(HTTP2Event::StreamIdReuse);
}
}
return &mut self.transactions[index - 1];
} else {
let mut tx = HTTP2Transaction::new();
@ -701,34 +701,6 @@ impl HTTP2State {
}
}
fn stream_data(&mut self, dir: u8, input: &[u8], over: bool, txid: u64) {
match unsafe { SURICATA_HTTP2_FILE_CONFIG } {
Some(sfcm) => {
for tx in &mut self.transactions {
if tx.tx_id == txid {
let xid: u32 = tx.tx_id as u32;
let (files, flags) = self.files.get(dir);
tx.ft.tx_id = tx.tx_id;
tx.ft.new_chunk(
sfcm,
files,
flags,
b"",
input,
tx.ft.tracked, //offset = append
input.len() as u32,
0,
over,
&xid,
);
break;
}
}
}
None => panic!("BUG"),
}
}
fn parse_frames(&mut self, mut input: &[u8], il: usize, dir: u8) -> AppLayerResult {
while input.len() > 0 {
match parser::http2_parse_frame_header(input) {
@ -776,8 +748,8 @@ impl HTTP2State {
let tx = self.find_or_create_tx(&head, &txdata, dir);
tx.handle_frame(&head, &txdata, dir);
let over = head.flags & parser::HTTP2_FLAG_HEADER_EOS != 0;
let txid = tx.tx_id;
let ftype = head.ftype;
let sid = head.stream_id;
if dir == STREAM_TOSERVER {
tx.frames_ts.push(HTTP2Frame {
header: head,
@ -790,7 +762,31 @@ impl HTTP2State {
});
}
if ftype == parser::HTTP2FrameType::DATA as u8 {
self.stream_data(dir, &rem[..hlsafe], over, txid);
match unsafe { SURICATA_HTTP2_FILE_CONFIG } {
Some(sfcm) => {
//borrow checker forbids to reuse directly tx
let index = self.find_tx_index(sid);
if index > 0 {
let mut tx_same = &mut self.transactions[index - 1];
let xid: u32 = tx_same.tx_id as u32;
tx_same.ft.tx_id = tx_same.tx_id - 1;
let (files, flags) = self.files.get(dir);
tx_same.ft.new_chunk(
sfcm,
files,
flags,
b"",
&rem[..hlsafe],
tx_same.ft.tracked, //offset = append
hlsafe as u32,
0,
over,
&xid,
);
}
}
None => panic!("BUG"),
}
}
input = &rem[hlsafe..];
}
@ -978,6 +974,7 @@ pub extern "C" fn rs_http2_parse_ts(
let buf = build_slice!(input, input_len as usize);
state.files.flags_ts = unsafe { FileFlowToFlags(flow, STREAM_TOSERVER) };
state.files.flags_ts = state.files.flags_ts | FILE_USE_DETECT;
return state.parse_ts(buf);
}
@ -989,6 +986,7 @@ pub extern "C" fn rs_http2_parse_tc(
let state = cast_pointer!(state, HTTP2State);
let buf = build_slice!(input, input_len as usize);
state.files.flags_tc = unsafe { FileFlowToFlags(flow, STREAM_TOCLIENT) };
state.files.flags_tc = state.files.flags_tc | FILE_USE_DETECT;
return state.parse_tc(buf);
}

Loading…
Cancel
Save