diff --git a/rust/src/filetracker.rs b/rust/src/filetracker.rs index b1b7a4d5df..9092599922 100644 --- a/rust/src/filetracker.rs +++ b/rust/src/filetracker.rs @@ -89,6 +89,10 @@ impl FileTransferTracker { } } + pub fn is_done(&self) -> bool { + self.file_open == false + } + fn open(&mut self, config: &'static SuricataFileContext, files: &mut FileContainer, flags: u16, name: &[u8]) -> i32 { diff --git a/rust/src/nfs/nfs.rs b/rust/src/nfs/nfs.rs index 20b35575e4..ff0e0558f2 100644 --- a/rust/src/nfs/nfs.rs +++ b/rust/src/nfs/nfs.rs @@ -1174,6 +1174,16 @@ impl NFSState { tdf.chunk_count += 1; let cs = tdf.file_tracker.update(files, flags, data, gap_size); + /* see if we need to close the tx */ + if tdf.file_tracker.is_done() { + if direction == STREAM_TOCLIENT { + tx.response_done = true; + SCLogDebug!("TX {} response is done now that the file track is ready", tx.id); + } else { + tx.request_done = true; + SCLogDebug!("TX {} request is done now that the file track is ready", tx.id); + } + } cs }, None => { 0 }, @@ -1235,6 +1245,9 @@ impl NFSState { } + let is_partial = reply.data.len() < reply.count as usize; + SCLogDebug!("partial data? {}", is_partial); + let found = match self.get_file_tx_by_handle(&file_handle, STREAM_TOCLIENT) { Some((tx, files, flags)) => { let ref mut tdf = match tx.type_data { @@ -1251,7 +1264,13 @@ impl NFSState { tx.nfs_response_status = reply.status; tx.is_last = true; tx.request_done = true; - tx.response_done = true; + + /* if this is a partial record we will close the tx + * when we've received the final data */ + if !is_partial { + tx.response_done = true; + SCLogDebug!("TX {} is DONE", tx.id); + } } true }, @@ -1275,7 +1294,13 @@ impl NFSState { tx.nfs_response_status = reply.status; tx.is_last = true; tx.request_done = true; - tx.response_done = true; + + /* if this is a partial record we will close the tx + * when we've received the final data */ + if !is_partial { + tx.response_done = true; + SCLogDebug!("TX {} is DONE", tx.id); + } } }