From: Victor Julien Date: Sat, 21 Jan 2023 09:13:22 +0000 (+0100) Subject: files: update API and callers to take stream config X-Git-Tag: suricata-7.0.0-rc1~127 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=e3e55406a738059feff2abf0ac3ec49deb19ce16;p=thirdparty%2Fsuricata.git files: update API and callers to take stream config This is to allow not storing the stream buffer config in each file. --- diff --git a/rust/src/core.rs b/rust/src/core.rs index cff169b10a..64a6c843d0 100644 --- a/rust/src/core.rs +++ b/rust/src/core.rs @@ -152,6 +152,7 @@ pub enum HttpRangeContainerBlock {} pub type SCHttpRangeFreeBlock = extern "C" fn ( c: *mut HttpRangeContainerBlock); pub type SCHTPFileCloseHandleRange = extern "C" fn ( + sbcfg: &StreamingBufferConfig, fc: *mut FileContainer, flags: u16, c: *mut HttpRangeContainerBlock, @@ -166,19 +167,23 @@ pub type SCFileOpenFileWithId = extern "C" fn ( flags: u16) -> i32; pub type SCFileCloseFileById = extern "C" fn ( file_container: &FileContainer, + sbcfg: &StreamingBufferConfig, track_id: u32, data: *const u8, data_len: u32, flags: u16) -> i32; pub type SCFileAppendDataById = extern "C" fn ( file_container: &FileContainer, + sbcfg: &StreamingBufferConfig, track_id: u32, data: *const u8, data_len: u32) -> i32; pub type SCFileAppendGAPById = extern "C" fn ( file_container: &FileContainer, + sbcfg: &StreamingBufferConfig, track_id: u32, data: *const u8, data_len: u32) -> i32; pub type SCFileContainerRecycle = extern "C" fn ( - file_container: &FileContainer); + file_container: &FileContainer, + sbcfg: &StreamingBufferConfig); // A Suricata context that is passed in from C. This is alternative to // using functions from Suricata directly, so they can be wrapped so diff --git a/rust/src/filecontainer.rs b/rust/src/filecontainer.rs index 96b0f6b92c..ff4ff2e2ab 100644 --- a/rust/src/filecontainer.rs +++ b/rust/src/filecontainer.rs @@ -62,10 +62,10 @@ impl Default for FileContainer { } impl FileContainer { - pub fn free(&mut self) { + pub fn free(&mut self, cfg: &'static SuricataFileContext) { SCLogDebug!("freeing self"); if let Some(c) = unsafe {SC} { - (c.FileContainerRecycle)(self); + (c.FileContainerRecycle)(self, cfg.files_sbcfg); } } @@ -83,7 +83,7 @@ impl FileContainer { } } - pub fn file_append(&mut self, track_id: &u32, data: &[u8], is_gap: bool) -> i32 { + pub fn file_append(&mut self, cfg: &'static SuricataFileContext, track_id: &u32, data: &[u8], is_gap: bool) -> i32 { SCLogDebug!("FILECONTAINER: append {}", data.len()); if data.is_empty() { return 0 @@ -94,13 +94,13 @@ impl FileContainer { let res = match is_gap { false => { SCLogDebug!("appending file data"); - let r = (c.FileAppendData)(self, *track_id, + let r = (c.FileAppendData)(self, cfg.files_sbcfg, *track_id, data.as_ptr(), data.len() as u32); r }, true => { SCLogDebug!("appending GAP"); - let r = (c.FileAppendGAP)(self, *track_id, + let r = (c.FileAppendGAP)(self, cfg.files_sbcfg, *track_id, data.as_ptr(), data.len() as u32); r }, @@ -110,13 +110,13 @@ impl FileContainer { } } - pub fn file_close(&mut self, track_id: &u32, flags: u16) -> i32 { + pub fn file_close(&mut self, cfg: &'static SuricataFileContext, track_id: &u32, flags: u16) -> i32 { SCLogDebug!("FILECONTAINER: CLOSEing"); match unsafe {SC} { None => panic!("BUG no suricata_config"), Some(c) => { - let res = (c.FileCloseFile)(self, *track_id, ptr::null(), 0u32, flags); + let res = (c.FileCloseFile)(self, cfg.files_sbcfg, *track_id, ptr::null(), 0u32, flags); res } } diff --git a/rust/src/filetracker.rs b/rust/src/filetracker.rs index 9425ebf011..6330ed8063 100644 --- a/rust/src/filetracker.rs +++ b/rust/src/filetracker.rs @@ -92,21 +92,25 @@ impl FileTransferTracker { r } - pub fn close(&mut self, files: &mut FileContainer, flags: u16) { + pub fn close(&mut self, config: &'static SuricataFileContext, + files: &mut FileContainer, flags: u16) + { if !self.file_is_truncated { SCLogDebug!("closing file with id {}", self.track_id); - files.file_close(&self.track_id, flags); + files.file_close(config, &self.track_id, flags); } self.file_open = false; self.tracked = 0; } - pub fn trunc (&mut self, files: &mut FileContainer, flags: u16) { + pub fn trunc (&mut self, config: &'static SuricataFileContext, + files: &mut FileContainer, flags: u16) + { if self.file_is_truncated || !self.file_open { return; } let myflags = flags | 1; // TODO util-file.c::FILE_TRUNCATED - files.file_close(&self.track_id, myflags); + files.file_close(config, &self.track_id, myflags); SCLogDebug!("truncated file"); self.file_is_truncated = true; self.chunks.clear(); @@ -127,7 +131,7 @@ impl FileTransferTracker { { if self.chunk_left != 0 || self.fill_bytes != 0 { SCLogDebug!("current chunk incomplete: truncating"); - self.trunc(files, flags); + self.trunc(config, files, flags); } SCLogDebug!("NEW CHUNK: chunk_size {} fill_bytes {}", chunk_size, fill_bytes); @@ -139,7 +143,7 @@ impl FileTransferTracker { SCLogDebug!("NEW CHUNK IS OOO: expected {}, got {}", self.tracked, chunk_offset); if is_last { SCLogDebug!("last chunk is out of order, this means we missed data before"); - self.trunc(files, flags); + self.trunc(config, files, flags); } self.chunk_is_ooo = true; self.cur_ooo_chunk_offset = chunk_offset; @@ -159,7 +163,7 @@ impl FileTransferTracker { } if self.file_open { - let res = self.update(files, flags, data, 0); + let res = self.update(config, files, flags, data, 0); SCLogDebug!("NEW CHUNK: update res {:?}", res); return res; } @@ -170,7 +174,9 @@ impl FileTransferTracker { /// update the file tracker /// If gap_size > 0 'data' should not be used. /// return how much we consumed of data - pub fn update(&mut self, files: &mut FileContainer, flags: u16, data: &[u8], gap_size: u32) -> u32 { + pub fn update(&mut self, config: &'static SuricataFileContext, + files: &mut FileContainer, flags: u16, data: &[u8], gap_size: u32) -> u32 + { if self.file_is_truncated { let consumed = std::cmp::min(data.len() as u32, self.chunk_left); self.chunk_left = self.chunk_left.saturating_sub(data.len() as u32); @@ -186,7 +192,7 @@ impl FileTransferTracker { //SCLogDebug!("UPDATE: nothing to do"); if self.chunk_is_last { SCLogDebug!("last empty chunk, closing"); - self.close(files, flags); + self.close(config, files, flags); self.chunk_is_last = false; } return 0 @@ -211,7 +217,7 @@ impl FileTransferTracker { let d = &data[0..self.chunk_left as usize]; if !self.chunk_is_ooo { - let res = files.file_append(&self.track_id, d, is_gap); + let res = files.file_append(config, &self.track_id, d, is_gap); match res { 0 => { }, -2 => { @@ -264,7 +270,7 @@ impl FileTransferTracker { Some(c) => { self.in_flight -= c.chunk.len() as u64; - let res = files.file_append(&self.track_id, &c.chunk, c.contains_gap); + let res = files.file_append(config, &self.track_id, &c.chunk, c.contains_gap); match res { 0 => { }, -2 => { @@ -296,7 +302,7 @@ impl FileTransferTracker { } if self.chunk_is_last { SCLogDebug!("last chunk, closing"); - self.close(files, flags); + self.close(config, files, flags); self.chunk_is_last = false; } else { SCLogDebug!("NOT last chunk, keep going"); @@ -304,7 +310,7 @@ impl FileTransferTracker { } else { if !self.chunk_is_ooo { - let res = files.file_append(&self.track_id, data, is_gap); + let res = files.file_append(config, &self.track_id, data, is_gap); match res { 0 => { }, -2 => { diff --git a/rust/src/http2/http2.rs b/rust/src/http2/http2.rs index ba4ae1f746..63fc31c73e 100644 --- a/rust/src/http2/http2.rs +++ b/rust/src/http2/http2.rs @@ -179,17 +179,17 @@ impl HTTP2Transaction { pub fn free(&mut self) { if !self.file_range.is_null() { - match unsafe { SC } { - None => panic!("BUG no suricata_config"), - Some(c) => { + if let Some(c) = unsafe { SC } { + if let Some(sfcm) = unsafe { SURICATA_HTTP2_FILE_CONFIG } { //TODO get a file container instead of NULL (c.HTPFileCloseHandleRange)( - std::ptr::null_mut(), - 0, - self.file_range, - std::ptr::null_mut(), - 0, - ); + sfcm.files_sbcfg, + std::ptr::null_mut(), + 0, + self.file_range, + std::ptr::null_mut(), + 0, + ); (c.HttpRangeFreeBlock)(self.file_range); self.file_range = std::ptr::null_mut(); } @@ -247,7 +247,7 @@ impl HTTP2Transaction { if over { range::http2_range_close(self, Direction::ToClient, decompressed) } else { - range::http2_range_append(self.file_range, decompressed) + range::http2_range_append(sfcm, self.file_range, decompressed) } } let (files, flags) = self.files.get(Direction::ToClient); @@ -364,8 +364,10 @@ impl HTTP2Transaction { impl Drop for HTTP2Transaction { fn drop(&mut self) { - self.files.files_ts.free(); - self.files.files_tc.free(); + if let Some(sfcm) = unsafe { SURICATA_HTTP2_FILE_CONFIG } { + self.files.files_ts.free(sfcm); + self.files.files_tc.free(sfcm); + } self.free(); } } @@ -460,10 +462,10 @@ impl HTTP2State { // but we need state's file container cf https://redmine.openinfosecfoundation.org/issues/4444 for tx in &mut self.transactions { if !tx.file_range.is_null() { - match unsafe { SC } { - None => panic!("BUG no suricata_config"), - Some(c) => { + if let Some(c) = unsafe { SC } { + if let Some(sfcm) = unsafe { SURICATA_HTTP2_FILE_CONFIG } { (c.HTPFileCloseHandleRange)( + sfcm.files_sbcfg, &mut tx.files.files_tc, 0, tx.file_range, @@ -501,10 +503,10 @@ impl HTTP2State { // this should be in HTTP2Transaction::free // but we need state's file container cf https://redmine.openinfosecfoundation.org/issues/4444 if !tx.file_range.is_null() { - match unsafe { SC } { - None => panic!("BUG no suricata_config"), - Some(c) => { + if let Some(c) = unsafe { SC } { + if let Some(sfcm) = unsafe { SURICATA_HTTP2_FILE_CONFIG } { (c.HTPFileCloseHandleRange)( + sfcm.files_sbcfg, &mut tx.files.files_tc, 0, tx.file_range, diff --git a/rust/src/http2/range.rs b/rust/src/http2/range.rs index 05f204daba..a6510a37d9 100644 --- a/rust/src/http2/range.rs +++ b/rust/src/http2/range.rs @@ -20,6 +20,7 @@ use crate::core::{ Direction, Flow, HttpRangeContainerBlock, StreamingBufferConfig, SuricataFileContext, SC, }; use crate::http2::http2::HTTP2Transaction; +use crate::http2::http2::SURICATA_HTTP2_FILE_CONFIG; use nom7::branch::alt; use nom7::bytes::streaming::{take_till, take_while}; @@ -150,9 +151,9 @@ pub fn http2_range_open( } } -pub fn http2_range_append(fr: *mut HttpRangeContainerBlock, data: &[u8]) { +pub fn http2_range_append(cfg: &'static SuricataFileContext, fr: *mut HttpRangeContainerBlock, data: &[u8]) { unsafe { - HttpRangeAppendData(fr, data.as_ptr(), data.len() as u32); + HttpRangeAppendData(cfg.files_sbcfg, fr, data.as_ptr(), data.len() as u32); } } @@ -160,16 +161,21 @@ pub fn http2_range_close( tx: &mut HTTP2Transaction, dir: Direction, data: &[u8], ) { let added = if let Some(c) = unsafe { SC } { - let (files, flags) = tx.files.get(dir); - let added = (c.HTPFileCloseHandleRange)( - files, - flags, - tx.file_range, - data.as_ptr(), - data.len() as u32, - ); - (c.HttpRangeFreeBlock)(tx.file_range); - added + if let Some(sfcm) = unsafe { SURICATA_HTTP2_FILE_CONFIG } { + let (files, flags) = tx.files.get(dir); + let added = (c.HTPFileCloseHandleRange)( + sfcm.files_sbcfg, + files, + flags, + tx.file_range, + data.as_ptr(), + data.len() as u32, + ); + (c.HttpRangeFreeBlock)(tx.file_range); + added + } else { + false + } } else { false }; @@ -187,7 +193,7 @@ extern "C" { data: *const c_uchar, data_len: u32, ) -> *mut HttpRangeContainerBlock; pub fn HttpRangeAppendData( - c: *mut HttpRangeContainerBlock, data: *const c_uchar, data_len: u32, + cfg: *const StreamingBufferConfig, c: *mut HttpRangeContainerBlock, data: *const c_uchar, data_len: u32, ) -> std::os::raw::c_int; } diff --git a/rust/src/nfs/nfs.rs b/rust/src/nfs/nfs.rs index 8190a48b6f..152b0c2946 100644 --- a/rust/src/nfs/nfs.rs +++ b/rust/src/nfs/nfs.rs @@ -260,8 +260,10 @@ impl Transaction for NFSTransaction { impl Drop for NFSTransaction { fn drop(&mut self) { if let Some(NFSTransactionTypeData::FILE(ref mut tdf)) = self.type_data { - tdf.files.files_ts.free(); - tdf.files.files_tc.free(); + if let Some(sfcm) = unsafe { SURICATA_NFS_FILE_CONFIG } { + tdf.files.files_ts.free(sfcm); + tdf.files.files_tc.free(sfcm); + } } self.free(); } @@ -309,19 +311,27 @@ pub fn filetracker_newchunk(ft: &mut FileTransferTracker, files: &mut FileContai fn filetracker_trunc(ft: &mut FileTransferTracker, files: &mut FileContainer, flags: u16) { - ft.trunc(files, flags); + if let Some(sfcm) = unsafe { SURICATA_NFS_FILE_CONFIG } { + ft.trunc(sfcm, files, flags); + } } pub fn filetracker_close(ft: &mut FileTransferTracker, files: &mut FileContainer, flags: u16) { - ft.close(files, flags); + if let Some(sfcm) = unsafe { SURICATA_NFS_FILE_CONFIG } { + ft.close(sfcm, files, flags); + } } fn filetracker_update(ft: &mut FileTransferTracker, files: &mut FileContainer, flags: u16, data: &[u8], gap_size: u32) -> u32 { - ft.update(files, flags, data, gap_size) + if let Some(sfcm) = unsafe { SURICATA_NFS_FILE_CONFIG } { + ft.update(sfcm, files, flags, data, gap_size) + } else { + 0 + } } diff --git a/rust/src/smb/files.rs b/rust/src/smb/files.rs index 955e867aef..9d759729ea 100644 --- a/rust/src/smb/files.rs +++ b/rust/src/smb/files.rs @@ -64,19 +64,27 @@ pub fn filetracker_newchunk(ft: &mut FileTransferTracker, files: &mut FileContai pub fn filetracker_trunc(ft: &mut FileTransferTracker, files: &mut FileContainer, flags: u16) { - ft.trunc(files, flags); + if let Some(sfcm) = unsafe { SURICATA_SMB_FILE_CONFIG } { + ft.trunc(sfcm, files, flags); + } } pub fn filetracker_close(ft: &mut FileTransferTracker, files: &mut FileContainer, flags: u16) { - ft.close(files, flags); + if let Some(sfcm) = unsafe { SURICATA_SMB_FILE_CONFIG } { + ft.close(sfcm, files, flags); + } } fn filetracker_update(ft: &mut FileTransferTracker, files: &mut FileContainer, flags: u16, data: &[u8], gap_size: u32) -> u32 { - ft.update(files, flags, data, gap_size) + if let Some(sfcm) = unsafe { SURICATA_SMB_FILE_CONFIG } { + ft.update(sfcm, files, flags, data, gap_size) + } else { + 0 + } } impl SMBState { diff --git a/rust/src/smb/smb.rs b/rust/src/smb/smb.rs index 9979fc52e3..5d04039f13 100644 --- a/rust/src/smb/smb.rs +++ b/rust/src/smb/smb.rs @@ -529,8 +529,10 @@ impl SMBTransaction { impl Drop for SMBTransaction { fn drop(&mut self) { if let Some(SMBTransactionTypeData::FILE(ref mut tdf)) = self.type_data { - tdf.files.files_ts.free(); - tdf.files.files_tc.free(); + if let Some(sfcm) = unsafe { SURICATA_SMB_FILE_CONFIG } { + tdf.files.files_ts.free(sfcm); + tdf.files.files_tc.free(sfcm); + } } self.free(); } diff --git a/src/app-layer-ftp.c b/src/app-layer-ftp.c index bdd5a85a91..1c0fea1e33 100644 --- a/src/app-layer-ftp.c +++ b/src/app-layer-ftp.c @@ -1162,7 +1162,7 @@ static AppLayerResult FTPDataParse(Flow *f, FtpDataState *ftpdata_state, SCReturnStruct(APP_LAYER_OK); } if (input_len != 0) { - ret = FileAppendData(ftpdata_state->files, input, input_len); + ret = FileAppendData(ftpdata_state->files, &sbcfg, input, input_len); if (ret == -2) { ret = 0; SCLogDebug("FileAppendData() - file no longer being extracted"); @@ -1177,7 +1177,7 @@ static AppLayerResult FTPDataParse(Flow *f, FtpDataState *ftpdata_state, BUG_ON((direction & ftpdata_state->direction) == 0); // should be unreachble if (eof) { - ret = FileCloseFile(ftpdata_state->files, NULL, 0, flags); + ret = FileCloseFile(ftpdata_state->files, &sbcfg, NULL, 0, flags); ftpdata_state->state = FTPDATA_STATE_FINISHED; SCLogDebug("closed because of eof"); } @@ -1235,7 +1235,7 @@ static void FTPDataStateFree(void *s) FTPFree(fstate->file_name, fstate->file_len + 1); } - FileContainerFree(fstate->files); + FileContainerFree(fstate->files, &sbcfg); FTPFree(s, sizeof(FtpDataState)); #ifdef DEBUG diff --git a/src/app-layer-htp-body.c b/src/app-layer-htp-body.c index 2421895a00..e430ce1ac1 100644 --- a/src/app-layer-htp-body.c +++ b/src/app-layer-htp-body.c @@ -121,7 +121,7 @@ void HtpBodyPrint(HtpBody *body) * \param body pointer to the HtpBody holding the list * \retval none */ -void HtpBodyFree(HtpBody *body) +void HtpBodyFree(const HTPCfgDir *hcfg, HtpBody *body) { SCEnter(); diff --git a/src/app-layer-htp-body.h b/src/app-layer-htp-body.h index 637eb07d61..fe59ac6210 100644 --- a/src/app-layer-htp-body.h +++ b/src/app-layer-htp-body.h @@ -30,7 +30,7 @@ int HtpBodyAppendChunk(const HTPCfgDir *, HtpBody *, const uint8_t *, uint32_t); void HtpBodyPrint(HtpBody *); -void HtpBodyFree(HtpBody *); +void HtpBodyFree(const HTPCfgDir *, HtpBody *); void HtpBodyPrune(HtpState *, HtpBody *, int); #endif /* __APP_LAYER_HTP_BODY_H__ */ diff --git a/src/app-layer-htp-file.c b/src/app-layer-htp-file.c index 78e8799d71..ac4616d026 100644 --- a/src/app-layer-htp-file.c +++ b/src/app-layer-htp-file.c @@ -201,6 +201,7 @@ int HTPFileOpenWithRange(HtpState *s, HtpTxUserData *txud, const uint8_t *filena /** * \brief Store a chunk of data in the flow * + * \param s HtpState * \param tx HtpTxUserData * \param data data chunk (if any) * \param data_len length of the data portion @@ -210,18 +211,22 @@ int HTPFileOpenWithRange(HtpState *s, HtpTxUserData *txud, const uint8_t *filena * \retval -1 error * \retval -2 file doesn't need storing */ -int HTPFileStoreChunk(HtpTxUserData *tx, const uint8_t *data, uint32_t data_len, uint8_t direction) +int HTPFileStoreChunk( + HtpState *s, HtpTxUserData *tx, const uint8_t *data, uint32_t data_len, uint8_t direction) { SCEnter(); int retval = 0; int result = 0; FileContainer *files = NULL; + const StreamingBufferConfig *sbcfg = NULL; if (direction & STREAM_TOCLIENT) { files = &tx->files_tc; + sbcfg = &s->cfg->response.sbcfg; } else { files = &tx->files_ts; + sbcfg = &s->cfg->request.sbcfg; } SCLogDebug("files %p data %p data_len %" PRIu32, files, data, data_len); @@ -232,12 +237,12 @@ int HTPFileStoreChunk(HtpTxUserData *tx, const uint8_t *data, uint32_t data_len, } if (tx->file_range != NULL) { - if (HttpRangeAppendData(tx->file_range, data, data_len) < 0) { + if (HttpRangeAppendData(sbcfg, tx->file_range, data, data_len) < 0) { SCLogDebug("Failed to append data"); } } - result = FileAppendData(files, data, data_len); + result = FileAppendData(files, sbcfg, data, data_len); if (result == -1) { SCLogDebug("appending data failed"); retval = -1; @@ -254,11 +259,11 @@ end: * \retval true if reassembled file was added * \retval false if no reassembled file was added */ -bool HTPFileCloseHandleRange(FileContainer *files, const uint16_t flags, HttpRangeContainerBlock *c, - const uint8_t *data, uint32_t data_len) +bool HTPFileCloseHandleRange(const StreamingBufferConfig *sbcfg, FileContainer *files, + const uint16_t flags, HttpRangeContainerBlock *c, const uint8_t *data, uint32_t data_len) { bool added = false; - if (HttpRangeAppendData(c, data, data_len) < 0) { + if (HttpRangeAppendData(sbcfg, c, data, data_len) < 0) { SCLogDebug("Failed to append data"); } if (c->container) { @@ -268,7 +273,7 @@ bool HTPFileCloseHandleRange(FileContainer *files, const uint16_t flags, HttpRan if (c->container->error) { SCLogDebug("range in ERROR state"); } - File *ranged = HttpRangeClose(c, flags); + File *ranged = HttpRangeClose(sbcfg, c, flags); if (ranged && files) { /* HtpState owns the constructed file now */ FileContainerAdd(files, ranged); @@ -296,8 +301,8 @@ bool HTPFileCloseHandleRange(FileContainer *files, const uint16_t flags, HttpRan * \retval -1 error * \retval -2 not storing files on this flow/tx */ -int HTPFileClose( - HtpTxUserData *tx, const uint8_t *data, uint32_t data_len, uint8_t flags, uint8_t direction) +int HTPFileClose(HtpState *s, HtpTxUserData *tx, const uint8_t *data, uint32_t data_len, + uint8_t flags, uint8_t direction) { SCEnter(); @@ -306,12 +311,16 @@ int HTPFileClose( int retval = 0; int result = 0; FileContainer *files = NULL; + const StreamingBufferConfig *sbcfg = NULL; if (direction & STREAM_TOCLIENT) { files = &tx->files_tc; + sbcfg = &s->cfg->response.sbcfg; } else { files = &tx->files_ts; + sbcfg = &s->cfg->request.sbcfg; } + SCLogDebug("files %p data %p data_len %" PRIu32, files, data, data_len); if (files == NULL) { @@ -319,7 +328,7 @@ int HTPFileClose( goto end; } - result = FileCloseFile(files, data, data_len, flags); + result = FileCloseFile(files, sbcfg, data, data_len, flags); if (result == -1) { retval = -1; } else if (result == -2) { @@ -328,7 +337,7 @@ int HTPFileClose( SCLogDebug("result %u", result); if (tx->file_range != NULL) { - bool added = HTPFileCloseHandleRange(files, flags, tx->file_range, data, data_len); + bool added = HTPFileCloseHandleRange(sbcfg, files, flags, tx->file_range, data, data_len); if (added) { tx->tx_data.files_opened++; } diff --git a/src/app-layer-htp-file.h b/src/app-layer-htp-file.h index feaeda3b22..4b682bc037 100644 --- a/src/app-layer-htp-file.h +++ b/src/app-layer-htp-file.h @@ -31,13 +31,13 @@ int HTPFileOpen(HtpState *, HtpTxUserData *, const uint8_t *, uint16_t, const ui uint64_t, uint8_t); int HTPFileOpenWithRange(HtpState *, HtpTxUserData *, const uint8_t *, uint16_t, const uint8_t *, uint32_t, uint64_t, bstr *rawvalue, HtpTxUserData *htud); -bool HTPFileCloseHandleRange( - FileContainer *, const uint16_t, HttpRangeContainerBlock *, const uint8_t *, uint32_t); -int HTPFileStoreChunk(HtpTxUserData *, const uint8_t *, uint32_t, uint8_t); +bool HTPFileCloseHandleRange(const StreamingBufferConfig *sbcfg, FileContainer *, const uint16_t, + HttpRangeContainerBlock *, const uint8_t *, uint32_t); +int HTPFileStoreChunk(HtpState *, HtpTxUserData *, const uint8_t *, uint32_t, uint8_t); int HTPParseContentRange(bstr *rawvalue, HTTPContentRange *range); -int HTPFileClose(HtpTxUserData *tx, const uint8_t *data, uint32_t data_len, uint8_t flags, - uint8_t direction); +int HTPFileClose(HtpState *, HtpTxUserData *tx, const uint8_t *data, uint32_t data_len, + uint8_t flags, uint8_t direction); void HTPFileParserRegisterTests(void); diff --git a/src/app-layer-htp-range.c b/src/app-layer-htp-range.c index 18c44ef409..76099aa938 100644 --- a/src/app-layer-htp-range.c +++ b/src/app-layer-htp-range.c @@ -117,7 +117,7 @@ static void ContainerUrlRangeFree(void *s) HttpRangeContainerFile *cu = s; SCFree(cu->key); cu->key = NULL; - FileContainerFree(cu->files); + FileContainerFree(cu->files, cu->sbcfg); cu->files = NULL; RB_FOREACH_SAFE (range, HTTP_RANGES, &cu->fragment_tree, tmp) { RB_REMOVE(HTTP_RANGES, &cu->fragment_tree, range); @@ -351,7 +351,7 @@ static HttpRangeContainerBlock *HttpRangeOpenFile(HttpRangeContainerFile *c, uin { HttpRangeContainerBlock *r = HttpRangeOpenFileAux(c, start, end, total, sbcfg, name, name_len, flags); - if (HttpRangeAppendData(r, data, len) < 0) { + if (HttpRangeAppendData(sbcfg, r, data, len) < 0) { SCLogDebug("Failed to append data while openeing"); } return r; @@ -367,6 +367,8 @@ HttpRangeContainerBlock *HttpRangeContainerOpenFile(const uint8_t *key, uint32_t // probably reached memcap return NULL; } + file_range_container->sbcfg = sbcfg; + HttpRangeContainerBlock *r = HttpRangeOpenFile(file_range_container, crparsed->start, crparsed->end, crparsed->size, sbcfg, name, name_len, flags, data, data_len); SCLogDebug("s->file_range == %p", r); @@ -391,7 +393,8 @@ HttpRangeContainerBlock *HttpRangeContainerOpenFile(const uint8_t *key, uint32_t return r; } -int HttpRangeAppendData(HttpRangeContainerBlock *c, const uint8_t *data, uint32_t len) +int HttpRangeAppendData(const StreamingBufferConfig *sbcfg, HttpRangeContainerBlock *c, + const uint8_t *data, uint32_t len) { if (len == 0) { return 0; @@ -407,9 +410,9 @@ int HttpRangeAppendData(HttpRangeContainerBlock *c, const uint8_t *data, uint32_ if (c->files) { if (data == NULL) { // gap overlaping already known data - r = FileAppendData(c->files, NULL, len - c->toskip); + r = FileAppendData(c->files, sbcfg, NULL, len - c->toskip); } else { - r = FileAppendData(c->files, data + c->toskip, len - c->toskip); + r = FileAppendData(c->files, sbcfg, data + c->toskip, len - c->toskip); } } c->toskip = 0; @@ -418,7 +421,7 @@ int HttpRangeAppendData(HttpRangeContainerBlock *c, const uint8_t *data, uint32_ // If we are owning the file to append to it, let's do it if (c->files) { SCLogDebug("update files (FileAppendData)"); - return FileAppendData(c->files, data, len); + return FileAppendData(c->files, sbcfg, data, len); } // Maybe we were in the skipping case, // but we get more data than expected and had set c->toskip = 0 @@ -449,12 +452,13 @@ int HttpRangeAppendData(HttpRangeContainerBlock *c, const uint8_t *data, uint32_ return 0; } -static void HttpRangeFileClose(HttpRangeContainerFile *c, uint16_t flags) +static void HttpRangeFileClose( + const StreamingBufferConfig *sbcfg, HttpRangeContainerFile *c, uint16_t flags) { SCLogDebug("closing range %p flags %04x", c, flags); DEBUG_VALIDATE_BUG_ON(SC_ATOMIC_GET(c->hdata->use_cnt) == 0); // move ownership of file c->files->head to caller - FileCloseFile(c->files, NULL, 0, c->flags | flags); + FileCloseFile(c->files, sbcfg, NULL, 0, c->flags | flags); c->files->head = NULL; c->files->tail = NULL; } @@ -462,7 +466,7 @@ static void HttpRangeFileClose(HttpRangeContainerFile *c, uint16_t flags) /** * \note if `f` is non-NULL, the ownership of the file is transfered to the caller. */ -File *HttpRangeClose(HttpRangeContainerBlock *c, uint16_t flags) +File *HttpRangeClose(const StreamingBufferConfig *sbcfg, HttpRangeContainerBlock *c, uint16_t flags) { SCLogDebug("c %p c->container %p c->current %p", c, c->container, c->current); @@ -539,16 +543,16 @@ File *HttpRangeClose(HttpRangeContainerBlock *c, uint16_t flags) // a new range just begins where we ended, append it if (range->gap > 0) { // if the range had a gap, begin by it - if (FileAppendData(c->container->files, NULL, range->gap) != 0) { + if (FileAppendData(c->container->files, sbcfg, NULL, range->gap) != 0) { c->container->lastsize = f->size; - HttpRangeFileClose(c->container, flags | FILE_TRUNCATED); + HttpRangeFileClose(sbcfg, c->container, flags | FILE_TRUNCATED); c->container->error = true; return f; } } - if (FileAppendData(c->container->files, range->buffer, range->offset) != 0) { + if (FileAppendData(c->container->files, sbcfg, range->buffer, range->offset) != 0) { c->container->lastsize = f->size; - HttpRangeFileClose(c->container, flags | FILE_TRUNCATED); + HttpRangeFileClose(sbcfg, c->container, flags | FILE_TRUNCATED); c->container->error = true; return f; } @@ -558,19 +562,19 @@ File *HttpRangeClose(HttpRangeContainerBlock *c, uint16_t flags) if (overlap < range->offset) { if (range->gap > 0) { // if the range had a gap, begin by it - if (FileAppendData(c->container->files, NULL, range->gap) != 0) { + if (FileAppendData(c->container->files, sbcfg, NULL, range->gap) != 0) { c->container->lastsize = f->size; - HttpRangeFileClose(c->container, flags | FILE_TRUNCATED); + HttpRangeFileClose(sbcfg, c->container, flags | FILE_TRUNCATED); c->container->error = true; return f; } } // And the range ends beyond where we ended // in this case of overlap, only add the extra data - if (FileAppendData(c->container->files, range->buffer + overlap, + if (FileAppendData(c->container->files, sbcfg, range->buffer + overlap, range->offset - overlap) != 0) { c->container->lastsize = f->size; - HttpRangeFileClose(c->container, flags | FILE_TRUNCATED); + HttpRangeFileClose(sbcfg, c->container, flags | FILE_TRUNCATED); c->container->error = true; return f; } @@ -587,7 +591,7 @@ File *HttpRangeClose(HttpRangeContainerBlock *c, uint16_t flags) if (f->size >= c->container->totalsize) { // we finished the whole file - HttpRangeFileClose(c->container, flags); + HttpRangeFileClose(sbcfg, c->container, flags); } else { // we are expecting more ranges f = NULL; @@ -609,6 +613,9 @@ static void HttpRangeBlockDerefContainer(HttpRangeContainerBlock *b) void HttpRangeFreeBlock(HttpRangeContainerBlock *b) { if (b) { + BUG_ON(b->container == NULL && b->files != NULL); + const StreamingBufferConfig *sbcfg = b->container ? b->container->sbcfg : NULL; + HttpRangeBlockDerefContainer(b); if (b->current) { @@ -619,7 +626,7 @@ void HttpRangeFreeBlock(HttpRangeContainerBlock *b) // we did not move ownership of the file container back to HttpRangeContainerFile DEBUG_VALIDATE_BUG_ON(b->files != NULL); if (b->files != NULL) { - FileContainerFree(b->files); + FileContainerFree(b->files, sbcfg); b->files = NULL; } SCFree(b); diff --git a/src/app-layer-htp-range.h b/src/app-layer-htp-range.h index 1770510b05..fe6c8e0676 100644 --- a/src/app-layer-htp-range.h +++ b/src/app-layer-htp-range.h @@ -70,6 +70,8 @@ typedef struct HttpRangeContainerFile { uint64_t totalsize; /** size of the file after last sync */ uint64_t lastsize; + /** streaming buffer config for files below */ + const StreamingBufferConfig *sbcfg; /** file container, with only one file */ FileContainer *files; /** red and black tree list of ranges which came out of order */ @@ -96,8 +98,10 @@ typedef struct HttpRangeContainerBlock { FileContainer *files; } HttpRangeContainerBlock; -int HttpRangeAppendData(HttpRangeContainerBlock *c, const uint8_t *data, uint32_t len); -File *HttpRangeClose(HttpRangeContainerBlock *c, uint16_t flags); +int HttpRangeAppendData(const StreamingBufferConfig *sbcfg, HttpRangeContainerBlock *c, + const uint8_t *data, uint32_t len); +File *HttpRangeClose( + const StreamingBufferConfig *sbcfg, HttpRangeContainerBlock *c, uint16_t flags); // HttpRangeContainerBlock but trouble with headers inclusion order HttpRangeContainerBlock *HttpRangeContainerOpenFile(const unsigned char *key, uint32_t keylen, diff --git a/src/app-layer-htp.c b/src/app-layer-htp.c index dd39508f8d..1c50fe2529 100644 --- a/src/app-layer-htp.c +++ b/src/app-layer-htp.c @@ -355,8 +355,8 @@ static void *HTPStateAlloc(void *orig_state, AppProto proto_orig) static void HtpTxUserDataFree(HtpState *state, HtpTxUserData *htud) { if (likely(htud)) { - HtpBodyFree(&htud->request_body); - HtpBodyFree(&htud->response_body); + HtpBodyFree(&state->cfg->request, &htud->request_body); + HtpBodyFree(&state->cfg->response, &htud->response_body); bstr_free(htud->request_uri_normalized); if (htud->request_headers_raw) HTPFree(htud->request_headers_raw, htud->request_headers_raw_len); @@ -369,11 +369,12 @@ static void HtpTxUserDataFree(HtpState *state, HtpTxUserData *htud) DetectEngineStateFree(htud->tx_data.de_state); } if (htud->file_range) { - HTPFileCloseHandleRange(&htud->files_tc, 0, htud->file_range, NULL, 0); + HTPFileCloseHandleRange( + &state->cfg->response.sbcfg, &htud->files_tc, 0, htud->file_range, NULL, 0); HttpRangeFreeBlock(htud->file_range); } - FileContainerRecycle(&htud->files_ts); - FileContainerRecycle(&htud->files_tc); + FileContainerRecycle(&htud->files_ts, &state->cfg->request.sbcfg); + FileContainerRecycle(&htud->files_tc, &state->cfg->response.sbcfg); HTPFree(htud, sizeof(HtpTxUserData)); } } @@ -1428,7 +1429,8 @@ static int HtpRequestBodyHandleMultipart(HtpState *hstate, HtpTxUserData *htud, printf("FILEDATA (final chunk) END: \n"); #endif if (!(htud->tsflags & HTP_DONTSTORE)) { - if (HTPFileClose(htud, filedata, filedata_len, flags, STREAM_TOSERVER) == -1) { + if (HTPFileClose(hstate, htud, filedata, filedata_len, flags, STREAM_TOSERVER) == + -1) { goto end; } } @@ -1449,7 +1451,8 @@ static int HtpRequestBodyHandleMultipart(HtpState *hstate, HtpTxUserData *htud, #endif if (!(htud->tsflags & HTP_DONTSTORE)) { - result = HTPFileStoreChunk(htud, filedata, filedata_len, STREAM_TOSERVER); + result = HTPFileStoreChunk( + hstate, htud, filedata, filedata_len, STREAM_TOSERVER); if (result == -1) { goto end; } else if (result == -2) { @@ -1549,7 +1552,7 @@ static int HtpRequestBodyHandleMultipart(HtpState *hstate, HtpTxUserData *htud, } else if (result == -2) { htud->tsflags |= HTP_DONTSTORE; } else { - if (HTPFileClose(htud, NULL, 0, 0, STREAM_TOSERVER) == -1) { + if (HTPFileClose(hstate, htud, NULL, 0, 0, STREAM_TOSERVER) == -1) { goto end; } } @@ -1616,7 +1619,7 @@ static int HtpRequestBodyHandleMultipart(HtpState *hstate, HtpTxUserData *htud, } else if (result == -2) { htud->tsflags |= HTP_DONTSTORE; } else { - if (HTPFileClose(htud, NULL, 0, 0, STREAM_TOSERVER) == -1) { + if (HTPFileClose(hstate, htud, NULL, 0, 0, STREAM_TOSERVER) == -1) { goto end; } } @@ -1704,7 +1707,7 @@ static int HtpRequestBodyHandlePOSTorPUT(HtpState *hstate, HtpTxUserData *htud, /* otherwise, just store the data */ if (!(htud->tsflags & HTP_DONTSTORE)) { - result = HTPFileStoreChunk(htud, data, data_len, STREAM_TOSERVER); + result = HTPFileStoreChunk(hstate, htud, data, data_len, STREAM_TOSERVER); if (result == -1) { goto end; } else if (result == -2) { @@ -1788,7 +1791,7 @@ static int HtpResponseBodyHandle(HtpState *hstate, HtpTxUserData *htud, /* otherwise, just store the data */ if (!(htud->tcflags & HTP_DONTSTORE)) { - result = HTPFileStoreChunk(htud, data, data_len, STREAM_TOCLIENT); + result = HTPFileStoreChunk(hstate, htud, data, data_len, STREAM_TOCLIENT); SCLogDebug("result %d", result); if (result == -1) { goto end; @@ -1904,7 +1907,7 @@ static int HTPCallbackRequestBodyData(htp_tx_data_t *d) } else { if (tx_ud->tsflags & HTP_FILENAME_SET) { SCLogDebug("closing file that was being stored"); - (void)HTPFileClose(tx_ud, NULL, 0, FILE_TRUNCATED, STREAM_TOSERVER); + (void)HTPFileClose(hstate, tx_ud, NULL, 0, FILE_TRUNCATED, STREAM_TOSERVER); tx_ud->tsflags &= ~HTP_FILENAME_SET; } } @@ -1995,7 +1998,7 @@ static int HTPCallbackResponseBodyData(htp_tx_data_t *d) } else { if (tx_ud->tcflags & HTP_FILENAME_SET) { SCLogDebug("closing file that was being stored"); - (void)HTPFileClose(tx_ud, NULL, 0, FILE_TRUNCATED, STREAM_TOCLIENT); + (void)HTPFileClose(hstate, tx_ud, NULL, 0, FILE_TRUNCATED, STREAM_TOCLIENT); tx_ud->tcflags &= ~HTP_FILENAME_SET; } } @@ -2219,7 +2222,7 @@ static int HTPCallbackRequestComplete(htp_tx_t *tx) if (htud != NULL) { if (htud->tsflags & HTP_FILENAME_SET) { SCLogDebug("closing file that was being stored"); - (void)HTPFileClose(htud, NULL, 0, 0, STREAM_TOSERVER); + (void)HTPFileClose(hstate, htud, NULL, 0, 0, STREAM_TOSERVER); htud->tsflags &= ~HTP_FILENAME_SET; if (abs_right_edge < (uint64_t)UINT32_MAX) { StreamTcpReassemblySetMinInspectDepth( @@ -2274,7 +2277,7 @@ static int HTPCallbackResponseComplete(htp_tx_t *tx) if (htud != NULL) { if (htud->tcflags & HTP_FILENAME_SET) { SCLogDebug("closing file that was being stored"); - (void)HTPFileClose(htud, NULL, 0, 0, STREAM_TOCLIENT); + (void)HTPFileClose(hstate, htud, NULL, 0, 0, STREAM_TOCLIENT); htud->tcflags &= ~HTP_FILENAME_SET; } } diff --git a/src/app-layer-parser.c b/src/app-layer-parser.c index cb91d69c90..12173e74e5 100644 --- a/src/app-layer-parser.c +++ b/src/app-layer-parser.c @@ -905,10 +905,7 @@ static void AppLayerParserFileTxHousekeeping( { AppLayerGetFileState files = AppLayerParserGetTxFiles(f, FlowGetAppState(f), tx, pkt_dir); if (files.fc) { - if (trunc) { - FileTruncateAllOpenFiles(files.fc); - } - FilePrune(files.fc); + FilesPrune(files.fc, files.cfg, trunc); } } diff --git a/src/app-layer-smtp.c b/src/app-layer-smtp.c index 40f173f72c..95e84b64c1 100644 --- a/src/app-layer-smtp.c +++ b/src/app-layer-smtp.c @@ -535,7 +535,7 @@ int SMTPProcessDataChunk(const uint8_t *chunk, uint32_t len, SCLogDebug("Closing file...%u bytes", len); if (files->tail->state == FILE_STATE_OPENED) { - ret = FileCloseFile(files, (uint8_t *) NULL, 0, flags); + ret = FileCloseFile(files, &smtp_config.sbcfg, (uint8_t *)NULL, 0, flags); if (ret != 0) { SCLogDebug("FileCloseFile() failed: %d", ret); ret = MIME_DEC_ERR_DATA; @@ -556,7 +556,7 @@ int SMTPProcessDataChunk(const uint8_t *chunk, uint32_t len, SCLogDebug("Closing file...%u bytes", len); if (files->tail && files->tail->state == FILE_STATE_OPENED) { - ret = FileCloseFile(files, (uint8_t *) chunk, len, flags); + ret = FileCloseFile(files, &smtp_config.sbcfg, (uint8_t *)chunk, len, flags); if (ret != 0) { SCLogDebug("FileCloseFile() failed: %d", ret); ret = MIME_DEC_ERR_DATA; @@ -574,7 +574,7 @@ int SMTPProcessDataChunk(const uint8_t *chunk, uint32_t len, /* Append data chunk to file */ SCLogDebug("Appending file...%u bytes", len); /* 0 is ok, -2 is not stored, -1 is error */ - ret = FileAppendData(files, (uint8_t *) chunk, len); + ret = FileAppendData(files, &smtp_config.sbcfg, (uint8_t *)chunk, len); if (ret == -2) { ret = 0; SCLogDebug("FileAppendData() - file no longer being extracted"); @@ -802,7 +802,7 @@ static int SMTPProcessCommandDATA(SMTPState *state, SMTPTransaction *tx, Flow *f SMTPInsertCommandIntoCommandBuffer(SMTP_COMMAND_DATA_MODE, state, f); if (smtp_config.raw_extraction) { /* we use this as the signal that message data is complete. */ - FileCloseFile(&tx->files_ts, NULL, 0, 0); + FileCloseFile(&tx->files_ts, &smtp_config.sbcfg, NULL, 0, 0); } else if (smtp_config.decode_mime && tx->mime_state != NULL) { /* Complete parsing task */ int ret = MimeDecParseComplete(tx->mime_state); @@ -819,7 +819,7 @@ static int SMTPProcessCommandDATA(SMTPState *state, SMTPTransaction *tx, Flow *f } else if (smtp_config.raw_extraction) { // message not over, store the line. This is a substitution of // ProcessDataChunk - FileAppendData(&tx->files_ts, line->buf, line->len + line->delim_len); + FileAppendData(&tx->files_ts, &smtp_config.sbcfg, line->buf, line->len + line->delim_len); } /* If DATA, then parse out a MIME message */ @@ -1151,7 +1151,7 @@ static int SMTPProcessRequest(SMTPState *state, Flow *f, AppLayerParserState *ps if (state->tx_cnt > 1 && !state->curr_tx->done) { // we did not close the previous tx, set error SMTPSetEvent(state, SMTP_DECODER_EVENT_UNPARSABLE_CONTENT); - FileCloseFile(&tx->files_ts, NULL, 0, FILE_TRUNCATED); + FileCloseFile(&tx->files_ts, &smtp_config.sbcfg, NULL, 0, FILE_TRUNCATED); tx = SMTPTransactionCreate(); if (tx == NULL) return -1; @@ -1515,7 +1515,7 @@ static void SMTPTransactionFree(SMTPTransaction *tx, SMTPState *state) TAILQ_REMOVE(&tx->rcpt_to_list, str, next); SMTPStringFree(str); } - FileContainerRecycle(&tx->files_ts); + FileContainerRecycle(&tx->files_ts, &smtp_config.sbcfg); SCFree(tx); } diff --git a/src/rust-context.h b/src/rust-context.h index 41b1b52de5..ba99ac6b72 100644 --- a/src/rust-context.h +++ b/src/rust-context.h @@ -46,19 +46,19 @@ typedef struct SuricataContext_ { void (*AppLayerParserTriggerRawStreamReassembly)(Flow *, int direction); void (*HttpRangeFreeBlock)(HttpRangeContainerBlock *); - bool (*HTPFileCloseHandleRange)( - FileContainer *, const uint16_t, HttpRangeContainerBlock *, const uint8_t *, uint32_t); + bool (*HTPFileCloseHandleRange)(const StreamingBufferConfig *sbcfg, FileContainer *, + const uint16_t, HttpRangeContainerBlock *, const uint8_t *, uint32_t); int (*FileOpenFileWithId)(FileContainer *, const StreamingBufferConfig *, uint32_t track_id, const uint8_t *name, uint16_t name_len, const uint8_t *data, uint32_t data_len, uint16_t flags); - int (*FileCloseFileById)(FileContainer *, uint32_t track_id, + int (*FileCloseFileById)(FileContainer *, const StreamingBufferConfig *, uint32_t track_id, const uint8_t *data, uint32_t data_len, uint16_t flags); - int (*FileAppendDataById)(FileContainer *, uint32_t track_id, + int (*FileAppendDataById)(FileContainer *, const StreamingBufferConfig *, uint32_t track_id, const uint8_t *data, uint32_t data_len); - int (*FileAppendGAPById)(FileContainer *, uint32_t track_id, + int (*FileAppendGAPById)(FileContainer *, const StreamingBufferConfig *, uint32_t track_id, const uint8_t *data, uint32_t data_len); - void (*FileContainerRecycle)(FileContainer *ffc); + void (*FileContainerRecycle)(FileContainer *ffc, const StreamingBufferConfig *); int (*AppLayerRegisterParser)(const struct AppLayerParser *p, AppProto alproto); diff --git a/src/util-file.c b/src/util-file.c index 2476129fd7..876b690cd6 100644 --- a/src/util-file.c +++ b/src/util-file.c @@ -86,7 +86,7 @@ static int g_file_store_enable = 0; static uint32_t g_file_store_reassembly_depth = 0; /* prototypes */ -static void FileFree(File *); +static void FileFree(File *, const StreamingBufferConfig *cfg); static void FileEndSha256(File *ff); void FileForceFilestoreEnable(void) @@ -360,7 +360,7 @@ uint64_t FileTrackedSize(const File *file) * \retval 1 prune (free) this file * \retval 0 file not ready to be freed */ -static int FilePruneFile(File *file) +static int FilePruneFile(File *file, const StreamingBufferConfig *cfg) { SCEnter(); @@ -447,7 +447,7 @@ void FilePrintFlags(const File *file) #undef P #endif -void FilePrune(FileContainer *ffc) +static void FilePrune(FileContainer *ffc, const StreamingBufferConfig *cfg) { SCEnter(); SCLogDebug("ffc %p head %p", ffc, ffc->head); @@ -458,7 +458,7 @@ void FilePrune(FileContainer *ffc) #ifdef DEBUG FilePrintFlags(file); #endif - if (FilePruneFile(file) == 0) { + if (FilePruneFile(file, cfg) == 0) { prev = file; file = file->next; continue; @@ -476,7 +476,7 @@ void FilePrune(FileContainer *ffc) if (file == ffc->tail) ffc->tail = prev; - FileFree(file); + FileFree(file, cfg); file = file_next; } SCReturn; @@ -505,7 +505,7 @@ FileContainer *FileContainerAlloc(void) * * \param ffc FileContainer */ -void FileContainerRecycle(FileContainer *ffc) +void FileContainerRecycle(FileContainer *ffc, const StreamingBufferConfig *cfg) { SCLogDebug("ffc %p", ffc); if (ffc == NULL) @@ -515,7 +515,7 @@ void FileContainerRecycle(FileContainer *ffc) File *next = NULL; for (;cur != NULL; cur = next) { next = cur->next; - FileFree(cur); + FileFree(cur, cfg); } ffc->head = ffc->tail = NULL; } @@ -525,7 +525,7 @@ void FileContainerRecycle(FileContainer *ffc) * * \param ffc FileContainer */ -void FileContainerFree(FileContainer *ffc) +void FileContainerFree(FileContainer *ffc, const StreamingBufferConfig *cfg) { SCLogDebug("ffc %p", ffc); if (ffc == NULL) @@ -535,7 +535,7 @@ void FileContainerFree(FileContainer *ffc) File *next = NULL; for (;ptr != NULL; ptr = next) { next = ptr->next; - FileFree(ptr); + FileFree(ptr, cfg); } ffc->head = ffc->tail = NULL; SCFree(ffc); @@ -577,7 +577,7 @@ static File *FileAlloc(const uint8_t *name, uint16_t name_len) return new; } -static void FileFree(File *ff) +static void FileFree(File *ff, const StreamingBufferConfig *sbcfg) { SCLogDebug("ff %p", ff); if (ff == NULL) @@ -655,7 +655,8 @@ static int FileStoreNoStoreCheck(File *ff) SCReturnInt(0); } -static int AppendData(File *file, const uint8_t *data, uint32_t data_len) +static int AppendData( + const StreamingBufferConfig *sbcfg, File *file, const uint8_t *data, uint32_t data_len) { SCLogDebug("file %p data_len %u", file, data_len); if (StreamingBufferAppendNoTrack(file->sb, data, data_len) != 0) { @@ -700,7 +701,8 @@ static void FileFlagGap(File *ff) { * \retval -1 error * \retval -2 no store for this file */ -static int FileAppendDataDo(File *ff, const uint8_t *data, uint32_t data_len) +static int FileAppendDataDo( + const StreamingBufferConfig *sbcfg, File *ff, const uint8_t *data, uint32_t data_len) { SCEnter(); #ifdef DEBUG_VALIDATION @@ -751,7 +753,7 @@ static int FileAppendDataDo(File *ff, const uint8_t *data, uint32_t data_len) SCLogDebug("appending %"PRIu32" bytes", data_len); - int r = AppendData(ff, data, data_len); + int r = AppendData(sbcfg, ff, data, data_len); if (r != 0) { ff->state = FILE_STATE_ERROR; SCReturnInt(r); @@ -772,14 +774,15 @@ static int FileAppendDataDo(File *ff, const uint8_t *data, uint32_t data_len) * \retval -1 error * \retval -2 no store for this file */ -int FileAppendData(FileContainer *ffc, const uint8_t *data, uint32_t data_len) +int FileAppendData(FileContainer *ffc, const StreamingBufferConfig *sbcfg, const uint8_t *data, + uint32_t data_len) { SCEnter(); - if (ffc == NULL || ffc->tail == NULL || data_len == 0) { + if (ffc == NULL || ffc->tail == NULL || data_len == 0 || sbcfg == NULL) { SCReturnInt(-1); } - int r = FileAppendDataDo(ffc->tail, data, data_len); + int r = FileAppendDataDo(sbcfg, ffc->tail, data, data_len); SCReturnInt(r); } @@ -796,7 +799,7 @@ int FileAppendData(FileContainer *ffc, const uint8_t *data, uint32_t data_len) * \retval -1 error * \retval -2 no store for this file */ -int FileAppendDataById(FileContainer *ffc, uint32_t track_id, +int FileAppendDataById(FileContainer *ffc, const StreamingBufferConfig *sbcfg, uint32_t track_id, const uint8_t *data, uint32_t data_len) { SCEnter(); @@ -807,7 +810,7 @@ int FileAppendDataById(FileContainer *ffc, uint32_t track_id, File *ff = ffc->head; for ( ; ff != NULL; ff = ff->next) { if (track_id == ff->file_track_id) { - int r = FileAppendDataDo(ff, data, data_len); + int r = FileAppendDataDo(sbcfg, ff, data, data_len); SCReturnInt(r); } } @@ -827,7 +830,7 @@ int FileAppendDataById(FileContainer *ffc, uint32_t track_id, * \retval -1 error * \retval -2 no store for this file */ -int FileAppendGAPById(FileContainer *ffc, uint32_t track_id, +int FileAppendGAPById(FileContainer *ffc, const StreamingBufferConfig *sbcfg, uint32_t track_id, const uint8_t *data, uint32_t data_len) { SCEnter(); @@ -841,7 +844,7 @@ int FileAppendGAPById(FileContainer *ffc, uint32_t track_id, FileFlagGap(ff); SCLogDebug("FILE_HAS_GAPS set"); - int r = FileAppendDataDo(ff, data, data_len); + int r = FileAppendDataDo(sbcfg, ff, data, data_len); SCReturnInt(r); } } @@ -906,7 +909,7 @@ static File *FileOpenFile(FileContainer *ffc, const StreamingBufferConfig *sbcfg ff->sb = StreamingBufferInit(sbcfg); if (ff->sb == NULL) { - FileFree(ff); + FileFree(ff, sbcfg); SCReturnPtr(NULL, "File"); } SCLogDebug("ff->sb %p", ff->sb); @@ -961,7 +964,7 @@ static File *FileOpenFile(FileContainer *ffc, const StreamingBufferConfig *sbcfg ff->size += data_len; if (data != NULL) { - if (AppendData(ff, data, data_len) != 0) { + if (AppendData(sbcfg, ff, data, data_len) != 0) { ff->state = FILE_STATE_ERROR; SCReturnPtr(NULL, "File"); } @@ -989,7 +992,7 @@ int FileOpenFileWithId(FileContainer *ffc, const StreamingBufferConfig *sbcfg, return 0; } -int FileCloseFilePtr(File *ff, const uint8_t *data, +int FileCloseFilePtr(File *ff, const StreamingBufferConfig *sbcfg, const uint8_t *data, uint32_t data_len, uint16_t flags) { SCEnter(); @@ -1015,7 +1018,7 @@ int FileCloseFilePtr(File *ff, const uint8_t *data, SCSha256Update(ff->sha256_ctx, data, data_len); } } else { - if (AppendData(ff, data, data_len) != 0) { + if (AppendData(sbcfg, ff, data, data_len) != 0) { ff->state = FILE_STATE_ERROR; SCReturnInt(-1); } @@ -1072,7 +1075,7 @@ int FileCloseFilePtr(File *ff, const uint8_t *data, * \retval 0 ok * \retval -1 error */ -int FileCloseFile(FileContainer *ffc, const uint8_t *data, +int FileCloseFile(FileContainer *ffc, const StreamingBufferConfig *sbcfg, const uint8_t *data, uint32_t data_len, uint16_t flags) { SCEnter(); @@ -1081,14 +1084,14 @@ int FileCloseFile(FileContainer *ffc, const uint8_t *data, SCReturnInt(-1); } - if (FileCloseFilePtr(ffc->tail, data, data_len, flags) == -1) { + if (FileCloseFilePtr(ffc->tail, sbcfg, data, data_len, flags) == -1) { SCReturnInt(-1); } SCReturnInt(0); } -int FileCloseFileById(FileContainer *ffc, uint32_t track_id, +int FileCloseFileById(FileContainer *ffc, const StreamingBufferConfig *sbcfg, uint32_t track_id, const uint8_t *data, uint32_t data_len, uint16_t flags) { SCEnter(); @@ -1100,7 +1103,7 @@ int FileCloseFileById(FileContainer *ffc, uint32_t track_id, File *ff = ffc->head; for ( ; ff != NULL; ff = ff->next) { if (track_id == ff->file_track_id) { - int r = FileCloseFilePtr(ff, data, data_len, flags); + int r = FileCloseFilePtr(ff, sbcfg, data, data_len, flags); SCReturnInt(r); } } @@ -1184,7 +1187,7 @@ void FileStoreFileById(FileContainer *fc, uint32_t file_id) } } -void FileTruncateAllOpenFiles(FileContainer *fc) +static void FileTruncateAllOpenFiles(FileContainer *fc, const StreamingBufferConfig *sbcfg) { File *ptr = NULL; @@ -1193,12 +1196,20 @@ void FileTruncateAllOpenFiles(FileContainer *fc) if (fc != NULL) { for (ptr = fc->head; ptr != NULL; ptr = ptr->next) { if (ptr->state == FILE_STATE_OPENED) { - FileCloseFilePtr(ptr, NULL, 0, FILE_TRUNCATED); + FileCloseFilePtr(ptr, sbcfg, NULL, 0, FILE_TRUNCATED); } } } } +void FilesPrune(FileContainer *fc, const StreamingBufferConfig *sbcfg, const bool trunc) +{ + if (trunc) { + FileTruncateAllOpenFiles(fc, sbcfg); + } + FilePrune(fc, sbcfg); +} + /** * \brief Finish the SHA256 calculation. */ diff --git a/src/util-file.h b/src/util-file.h index e68baf1422..6310b49c20 100644 --- a/src/util-file.h +++ b/src/util-file.h @@ -116,9 +116,9 @@ typedef struct FileContainer_ { } FileContainer; FileContainer *FileContainerAlloc(void); -void FileContainerFree(FileContainer *); +void FileContainerFree(FileContainer *, const StreamingBufferConfig *cfg); -void FileContainerRecycle(FileContainer *); +void FileContainerRecycle(FileContainer *, const StreamingBufferConfig *cfg); void FileContainerAdd(FileContainer *, File *); @@ -157,11 +157,11 @@ int FileOpenFileWithId(FileContainer *, const StreamingBufferConfig *, * \retval 0 ok * \retval -1 error */ -int FileCloseFile(FileContainer *, const uint8_t *data, uint32_t data_len, - uint16_t flags); -int FileCloseFileById(FileContainer *, uint32_t track_id, +int FileCloseFile(FileContainer *, const StreamingBufferConfig *sbcfg, const uint8_t *data, + uint32_t data_len, uint16_t flags); +int FileCloseFileById(FileContainer *, const StreamingBufferConfig *sbcfg, uint32_t track_id, const uint8_t *data, uint32_t data_len, uint16_t flags); -int FileCloseFilePtr(File *ff, const uint8_t *data, +int FileCloseFilePtr(File *ff, const StreamingBufferConfig *sbcfg, const uint8_t *data, uint32_t data_len, uint16_t flags); /** @@ -175,10 +175,11 @@ int FileCloseFilePtr(File *ff, const uint8_t *data, * \retval 0 ok * \retval -1 error */ -int FileAppendData(FileContainer *, const uint8_t *data, uint32_t data_len); -int FileAppendDataById(FileContainer *, uint32_t track_id, +int FileAppendData(FileContainer *, const StreamingBufferConfig *sbcfg, const uint8_t *data, + uint32_t data_len); +int FileAppendDataById(FileContainer *, const StreamingBufferConfig *sbcfg, uint32_t track_id, const uint8_t *data, uint32_t data_len); -int FileAppendGAPById(FileContainer *ffc, uint32_t track_id, +int FileAppendGAPById(FileContainer *ffc, const StreamingBufferConfig *sbcfg, uint32_t track_id, const uint8_t *data, uint32_t data_len); void FileSetInspectSizes(File *file, const uint32_t win, const uint32_t min); @@ -213,7 +214,6 @@ int FileStore(File *); void FileDisableStoringForTransaction(Flow *f, const uint8_t direction, void *tx, uint64_t tx_id); void FlowFileDisableStoringForTransaction(struct Flow_ *f, uint64_t tx_id); -void FilePrune(FileContainer *ffc); void FileForceFilestoreEnable(void); int FileForceFilestore(void); @@ -240,8 +240,6 @@ void FileForceTrackingEnable(void); void FileStoreFileById(FileContainer *fc, uint32_t); -void FileTruncateAllOpenFiles(FileContainer *); - uint64_t FileDataSize(const File *file); uint64_t FileTrackedSize(const File *file); @@ -254,4 +252,6 @@ void FilePrintFlags(const File *file); #define FilePrintFlags(file) #endif +void FilesPrune(FileContainer *fc, const StreamingBufferConfig *sbcfg, const bool trunc); + #endif /* __UTIL_FILE_H__ */