rust/nfs: fix read reply handling

READ replies with large data chunks are processed partially to avoid
queuing too much data. When the final chunk was received however, the
start of the chunk would already tag the transaction as 'done'. The
more aggressive tx freeing that was recently merged would cause this
tx to be freed before the rest of the in-progress chunk was done.

This patch delays the tagging of the tx until the final data has been
received.
pull/3201/head
Victor Julien 7 years ago
parent d75d9d0b45
commit d27ed5957f

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

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

Loading…
Cancel
Save