files: update API and callers to take stream config

This is to allow not storing the stream buffer config in each file.
pull/8426/head
Victor Julien 3 years ago
parent f7dbdb7631
commit e3e55406a7

@ -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

@ -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
}
}

@ -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 => {

@ -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,

@ -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;
}

@ -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
}
}

@ -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 {

@ -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();
}

@ -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

@ -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();

@ -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__ */

@ -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++;
}

@ -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);

@ -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);

@ -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,

@ -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;
}
}

@ -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);
}
}

@ -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);
}

@ -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);

@ -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.
*/

@ -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__ */

Loading…
Cancel
Save