]> git.ipfire.org Git - thirdparty/snort3.git/commitdiff
Merge pull request #638 in SNORT/snort3 from full_retransmit to master
authorShawn Turner (shaturne) <shaturne@cisco.com>
Tue, 27 Sep 2016 17:47:26 +0000 (13:47 -0400)
committerShawn Turner (shaturne) <shaturne@cisco.com>
Tue, 27 Sep 2016 17:47:26 +0000 (13:47 -0400)
Squashed commit of the following:

commit 8801fc1c994927d371735109f88ed08d667b0c15
Author: Bhagya Tholpady <bbantwal@cisco.com>
Date:   Mon Sep 26 16:08:57 2016 -0400

    porting full retransmit changes from snort 2.8.3

src/stream/tcp/segment_overlap_editor.cc
src/stream/tcp/segment_overlap_editor.h
src/stream/tcp/tcp_segment_node.cc
src/stream/tcp/tcp_segment_node.h

index 2e460439a1221f99c67b2461b58ea75bfb3d846f..73a709e378e09dbfd12ad9db3af39369a5ac1b72 100644 (file)
 #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 )
         {
@@ -84,7 +88,7 @@ int SegmentOverlapEditor::eval_right()
 
         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();
@@ -101,11 +105,16 @@ int SegmentOverlapEditor::eval_right()
         }
         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++;
index 5c557b915ee78655379131f4dfd4951f7f7bf8ee..85d930c101417d2fa611ddf67feee7ef00877181 100644 (file)
@@ -63,7 +63,7 @@ protected:
     int eval_left();
     int eval_right();
 
-    virtual bool is_segment_retransmit();
+    virtual bool is_segment_retransmit(bool*);
     virtual void drop_old_segment();
     virtual int generate_bad_segment_event();
 
index 597195e7911bfb522c8b30ed691a5d1e1550c790..4335d10997c4100f4cb03bcbb154dbf6e4c2b30f 100644 (file)
@@ -71,16 +71,27 @@ void TcpSegmentNode::term()
     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;
 }
-
index 42401d0515c4d24777cbb00f2c597d30378e253a..179030e5ed30088ade013042a21052cc60e18d1e 100644 (file)
@@ -45,7 +45,7 @@ public:
     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;