#include "tcp_normalizer.h"
#include "tcp_reassembler.h"
-bool SegmentOverlapEditor::is_segment_retransmit()
+bool SegmentOverlapEditor::is_segment_retransmit(bool* full_retransmit)
{
// Don't want to count retransmits as overlaps or do anything
// else with them. Account for retransmits of multiple PDUs
// in one segment.
- if ( right->is_retransmit(rdata, rsize, rseq) )
+ if ( right->is_retransmit(rdata, rsize, rseq, right->orig_dsize, ((rseq == tsd->get_seg_seq())?full_retransmit:nullptr)) )
{
- rdata += right->payload_size;
- rsize -= right->payload_size;
- rseq += right->payload_size;
-
- seq += right->payload_size;
- left = right;
- right = right->next;
+ if ( !(*full_retransmit) )
+ {
+ rdata += right->payload_size;
+ rsize -= right->payload_size;
+ rseq += right->payload_size;
+ seq += right->payload_size;
+ left = right;
+ right = right->next;
+ }
+ else
+ rsize = 0;
if ( rsize == 0 )
{
if ( overlap < right->payload_size )
{
- if ( right->is_retransmit(rdata, rsize, rseq) )
+ if ( right->is_retransmit(rdata, rsize, rseq, right->orig_dsize, nullptr) )
{
// All data was retransmitted
session->retransmit_process();
}
else // Full overlap
{
+ bool full_retransmit = false;
// Don't want to count retransmits as overlaps or do anything
// else with them. Account for retransmits of multiple PDUs
// in one segment.
- if ( is_segment_retransmit() )
+ if ( is_segment_retransmit(&full_retransmit) )
+ {
+ if ( full_retransmit )
+ break;
continue;
+ }
tcpStats.overlaps++;
overlap_count++;
delete this;
}
-bool TcpSegmentNode::is_retransmit(const uint8_t* rdata, uint16_t rsize, uint32_t rseq)
+bool TcpSegmentNode::is_retransmit(const uint8_t* rdata, uint16_t rsize, uint32_t rseq, uint16_t orig_dsize, bool *full_retransmit)
{
// retransmit must have same payload at same place
if ( !SEQ_EQ(seq, rseq) )
return false;
- if ( ( ( payload_size <= rsize )and !memcmp(data, rdata, payload_size) )
- or ( ( payload_size > rsize )and !memcmp(data, rdata, rsize) ) )
+ if( orig_dsize == payload_size )
+ {
+ if ( ( ( payload_size <= rsize )and !memcmp(data, rdata, payload_size) )
+ or ( ( payload_size > rsize )and !memcmp(data, rdata, rsize) ) )
+ {
+ return true;
+ }
+ }
+ //Checking for a possible split of segment in which case
+ //we compare complete data of the segment to find a retransmission
+ else if(full_retransmit and (orig_dsize == rsize) and !memcmp(data, rdata, rsize) )
+ {
+ *full_retransmit = true;
return true;
+ }
return false;
}
-
static TcpSegmentNode* init(const struct timeval&, const uint8_t*, unsigned);
void term();
- bool is_retransmit(const uint8_t*, uint16_t size, uint32_t);
+ bool is_retransmit(const uint8_t*, uint16_t size, uint32_t, uint16_t, bool*);
TcpSegmentNode* prev;
TcpSegmentNode* next;