Review/fix/change file reassembly functionality.

- Re-arrange how some fa_file fields (e.g. source, connection info, mime
  type) get updated/set for consistency.

- Add more robust mechanisms for flushing the reassembly buffer.
  The goal being to report all gaps and deliveries to file analyzers
  regardless of the state of the reassembly buffer at the time it has to
  be flushed.
This commit is contained in:
Jon Siwek 2014-12-16 14:05:15 -06:00
parent edaf7edc11
commit cbbe7b52dc
26 changed files with 370 additions and 238 deletions

View file

@ -8,7 +8,7 @@ namespace file_analysis {
class File;
FileReassembler::FileReassembler(File *f, uint64 starting_offset)
: Reassembler(starting_offset), the_file(f)
: Reassembler(starting_offset), the_file(f), flushing(false)
{
}
@ -16,6 +16,35 @@ FileReassembler::~FileReassembler()
{
}
uint64 FileReassembler::Flush()
{
if ( flushing )
return 0;
if ( last_block )
{
// This is expected to call back into FileReassembler::Undelivered().
flushing = true;
uint64 rval = TrimToSeq(last_block->upper);
flushing = false;
return rval;
}
return 0;
}
uint64 FileReassembler::FlushTo(uint64 sequence)
{
if ( flushing )
return 0;
flushing = true;
uint64 rval = TrimToSeq(sequence);
flushing = false;
last_reassem_seq = sequence;
return rval;
}
void FileReassembler::BlockInserted(DataBlock* start_block)
{
if ( start_block->seq > last_reassem_seq ||
@ -28,7 +57,6 @@ void FileReassembler::BlockInserted(DataBlock* start_block)
if ( b->seq == last_reassem_seq )
{ // New stuff.
uint64 len = b->Size();
uint64 seq = last_reassem_seq;
last_reassem_seq += len;
the_file->DeliverStream(b->block, len);
}
@ -40,7 +68,37 @@ void FileReassembler::BlockInserted(DataBlock* start_block)
void FileReassembler::Undelivered(uint64 up_to_seq)
{
// Not doing anything here yet.
// If we have blocks that begin below up_to_seq, deliver them.
DataBlock* b = blocks;
while ( b )
{
if ( b->seq < last_reassem_seq )
{
// Already delivered this block.
b = b->next;
continue;
}
if ( b->seq >= up_to_seq )
// Block is beyond what we need to process at this point.
break;
uint64 gap_at_seq = last_reassem_seq;
uint64 gap_len = b->seq - last_reassem_seq;
the_file->Gap(gap_at_seq, gap_len);
last_reassem_seq += gap_len;
BlockInserted(b);
// Inserting a block may cause trimming of what's buffered,
// so have to assume 'b' is invalid, hence re-assign to start.
b = blocks;
}
if ( up_to_seq > last_reassem_seq )
{
the_file->Gap(last_reassem_seq, up_to_seq - last_reassem_seq);
last_reassem_seq = up_to_seq;
}
}
void FileReassembler::Overlap(const u_char* b1, const u_char* b2, uint64 n)