This is to allow not storing the stream buffer config in each file.
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,
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
}
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);
}
}
}
}
- 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
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
},
}
}
- 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
}
}
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();
{
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);
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;
}
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;
}
/// 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);
//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
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 => {
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 => {
}
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");
} 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 => {
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();
}
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);
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();
}
}
// 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,
// 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,
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};
}
}
-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);
}
}
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
};
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;
}
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();
}
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
+ }
}
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 {
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();
}
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");
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");
}
FTPFree(fstate->file_name, fstate->file_len + 1);
}
- FileContainerFree(fstate->files);
+ FileContainerFree(fstate->files, &sbcfg);
FTPFree(s, sizeof(FtpDataState));
#ifdef DEBUG
* \param body pointer to the HtpBody holding the list
* \retval none
*/
-void HtpBodyFree(HtpBody *body)
+void HtpBodyFree(const HTPCfgDir *hcfg, HtpBody *body)
{
SCEnter();
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__ */
/**
* \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
* \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);
}
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;
* \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) {
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);
* \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();
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) {
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) {
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++;
}
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);
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);
{
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;
// 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);
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;
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;
// 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
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;
}
/**
* \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);
// 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;
}
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;
}
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;
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) {
// 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);
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 */
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,
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);
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));
}
}
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;
}
}
#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) {
} 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;
}
}
} 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;
}
}
/* 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) {
/* 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;
} 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;
}
}
} 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;
}
}
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(
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;
}
}
{
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);
}
}
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;
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;
/* 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");
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);
} 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 */
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;
TAILQ_REMOVE(&tx->rcpt_to_list, str, next);
SMTPStringFree(str);
}
- FileContainerRecycle(&tx->files_ts);
+ FileContainerRecycle(&tx->files_ts, &smtp_config.sbcfg);
SCFree(tx);
}
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);
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)
* \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();
#undef P
#endif
-void FilePrune(FileContainer *ffc)
+static void FilePrune(FileContainer *ffc, const StreamingBufferConfig *cfg)
{
SCEnter();
SCLogDebug("ffc %p head %p", ffc, ffc->head);
#ifdef DEBUG
FilePrintFlags(file);
#endif
- if (FilePruneFile(file) == 0) {
+ if (FilePruneFile(file, cfg) == 0) {
prev = file;
file = file->next;
continue;
if (file == ffc->tail)
ffc->tail = prev;
- FileFree(file);
+ FileFree(file, cfg);
file = file_next;
}
SCReturn;
*
* \param ffc FileContainer
*/
-void FileContainerRecycle(FileContainer *ffc)
+void FileContainerRecycle(FileContainer *ffc, const StreamingBufferConfig *cfg)
{
SCLogDebug("ffc %p", ffc);
if (ffc == NULL)
File *next = NULL;
for (;cur != NULL; cur = next) {
next = cur->next;
- FileFree(cur);
+ FileFree(cur, cfg);
}
ffc->head = ffc->tail = NULL;
}
*
* \param ffc FileContainer
*/
-void FileContainerFree(FileContainer *ffc)
+void FileContainerFree(FileContainer *ffc, const StreamingBufferConfig *cfg)
{
SCLogDebug("ffc %p", ffc);
if (ffc == NULL)
File *next = NULL;
for (;ptr != NULL; ptr = next) {
next = ptr->next;
- FileFree(ptr);
+ FileFree(ptr, cfg);
}
ffc->head = ffc->tail = NULL;
SCFree(ffc);
return new;
}
-static void FileFree(File *ff)
+static void FileFree(File *ff, const StreamingBufferConfig *sbcfg)
{
SCLogDebug("ff %p", ff);
if (ff == NULL)
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) {
* \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
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);
* \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);
}
* \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();
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);
}
}
* \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();
FileFlagGap(ff);
SCLogDebug("FILE_HAS_GAPS set");
- int r = FileAppendDataDo(ff, data, data_len);
+ int r = FileAppendDataDo(sbcfg, ff, data, data_len);
SCReturnInt(r);
}
}
ff->sb = StreamingBufferInit(sbcfg);
if (ff->sb == NULL) {
- FileFree(ff);
+ FileFree(ff, sbcfg);
SCReturnPtr(NULL, "File");
}
SCLogDebug("ff->sb %p", ff->sb);
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");
}
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();
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);
}
* \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();
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();
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);
}
}
}
}
-void FileTruncateAllOpenFiles(FileContainer *fc)
+static void FileTruncateAllOpenFiles(FileContainer *fc, const StreamingBufferConfig *sbcfg)
{
File *ptr = NULL;
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.
*/
} 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 *);
* \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);
/**
* \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);
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);
void FileStoreFileById(FileContainer *fc, uint32_t);
-void FileTruncateAllOpenFiles(FileContainer *);
-
uint64_t FileDataSize(const File *file);
uint64_t FileTrackedSize(const File *file);
#define FilePrintFlags(file)
#endif
+void FilesPrune(FileContainer *fc, const StreamingBufferConfig *sbcfg, const bool trunc);
+
#endif /* __UTIL_FILE_H__ */