]> git.ipfire.org Git - thirdparty/suricata.git/commitdiff
stream: make app_progress relative to STREAM_BASE_OFFSET
authorVictor Julien <victor@inliniac.net>
Thu, 28 Apr 2016 06:44:10 +0000 (08:44 +0200)
committerVictor Julien <victor@inliniac.net>
Thu, 20 Apr 2017 15:41:11 +0000 (17:41 +0200)
src/stream-tcp-list.c
src/stream-tcp-private.h
src/stream-tcp-reassemble.c

index 6007bae85e2f8dde02d510d0f54281b7e0ee5bb1..68dfab7af7806c06631a397a5f63ecbddcac21b1 100644 (file)
@@ -635,13 +635,13 @@ static inline uint64_t GetLeftEdge(TcpSession *ssn, TcpStream *stream)
     }
 
     if (use_app && use_raw) {
-        left_edge = MIN(stream->app_progress, stream->raw_progress);
+        left_edge = MIN(STREAM_APP_PROGRESS(stream), stream->raw_progress);
         SCLogDebug("left_edge %"PRIu64", using both app:%"PRIu64", raw:%"PRIu64,
-                left_edge, stream->app_progress, stream->raw_progress);
+                left_edge, STREAM_APP_PROGRESS(stream), stream->raw_progress);
     } else if (use_app) {
-        left_edge = stream->app_progress;
+        left_edge = STREAM_APP_PROGRESS(stream);
         SCLogDebug("left_edge %"PRIu64", using app:%"PRIu64,
-                left_edge, stream->app_progress);
+                left_edge, STREAM_APP_PROGRESS(stream));
     } else if (use_raw) {
         left_edge = stream->raw_progress;
         SCLogDebug("left_edge %"PRIu64", using raw:%"PRIu64,
@@ -732,6 +732,13 @@ void StreamTcpPruneSession(Flow *f, uint8_t flags)
             SCLogDebug("buffer sliding %u to offset %"PRIu64, slide, left_edge);
             StreamingBufferSlideToOffset(stream->sb, left_edge);
             stream->base_seq += slide;
+
+            if (slide <= stream->app_progress_rel) {
+                stream->app_progress_rel -= slide;
+            } else {
+                stream->app_progress_rel = 0;
+            }
+
             SCLogDebug("stream base_seq %u at stream offset %"PRIu64,
                     stream->base_seq, STREAM_BASE_OFFSET(stream));
         }
index 448efba5eed58a952a97a8dab59b46d239a81628..7e360633211fb37748280985733041ff9debc723 100644 (file)
@@ -87,8 +87,9 @@ typedef struct TcpStream_ {
     /* reassembly */
     uint32_t base_seq;              /**< seq where we are left with reassebly. Matches STREAM_BASE_OFFSET below. */
 
+    uint32_t app_progress_rel;      /**< app-layer progress relative to STREAM_BASE_OFFSET */
+
     StreamingBuffer *sb;
-    uint64_t app_progress;
     uint64_t raw_progress;
 
     TcpSegment *seg_list;           /**< list of TCP segments that are not yet (fully) used in reassembly */
@@ -99,6 +100,7 @@ typedef struct TcpStream_ {
 } TcpStream;
 
 #define STREAM_BASE_OFFSET(stream)  ((stream)->sb ? (stream)->sb->stream_offset : 0)
+#define STREAM_APP_PROGRESS(stream) (STREAM_BASE_OFFSET((stream)) + (stream)->app_progress_rel)
 
 /* from /usr/include/netinet/tcp.h */
 enum
index 979893d3c36e957c443c03b4f6e2125ef2d31e7d..2cf1e2be6fb4283aa50af9c2a4830fdfbe18ca2a 100644 (file)
@@ -996,7 +996,7 @@ int StreamNeedsReassembly(TcpSession *ssn, int direction)
         SCLogDebug("%s: list %p app %"PRIu64" (use: %s), raw %"PRIu64" (use: %s). Stream right edge: %"PRIu64,
                 dirstr,
                 stream->seg_list,
-                stream->app_progress, use_app ? "yes" : "no",
+                STREAM_APP_PROGRESS(stream), use_app ? "yes" : "no",
                 stream->raw_progress, use_raw ? "yes" : "no",
                 right_edge);
 
@@ -1007,7 +1007,7 @@ int StreamNeedsReassembly(TcpSession *ssn, int direction)
             }
         }
         if (use_app) {
-            if (right_edge > stream->app_progress) {
+            if (right_edge > STREAM_APP_PROGRESS(stream)) {
                 SCLogDebug("%s: STREAM_HAS_UNPROCESSED_SEGMENTS_NEED_REASSEMBLY", dirstr);
                 return STREAM_HAS_UNPROCESSED_SEGMENTS_NEED_REASSEMBLY;
             }
@@ -1107,10 +1107,10 @@ static int ReassembleUpdateAppLayer (ThreadVars *tv,
         TcpSession *ssn, TcpStream *stream,
         Packet *p)
 {
-    const uint64_t app_progress = stream->app_progress;
-    uint64_t last_ack_abs = app_progress; /* absolute right edge of ack'd data */
+    const uint64_t app_progress = STREAM_APP_PROGRESS(stream);
+    uint64_t last_ack_abs = 0; /* absolute right edge of ack'd data */
 
-    SCLogDebug("app progress %"PRIu64, stream->app_progress);
+    SCLogDebug("app progress %"PRIu64, app_progress);
     SCLogDebug("last_ack %u, base_seq %u", stream->last_ack, stream->base_seq);
 
     if (STREAM_LASTACK_GT_BASESEQ(stream)) {
@@ -1122,19 +1122,19 @@ static int ReassembleUpdateAppLayer (ThreadVars *tv,
 
     const uint8_t *mydata;
     uint32_t mydata_len;
-    GetAppBuffer(stream, &mydata, &mydata_len, stream->app_progress);
+    GetAppBuffer(stream, &mydata, &mydata_len, app_progress);
     //PrintRawDataFp(stdout, mydata, mydata_len);
 
-    SCLogDebug("stream %p data in buffer %p of len %u and offset %u",
-            stream, stream->sb, mydata_len, (uint)stream->app_progress);
+    SCLogDebug("stream %p data in buffer %p of len %u and offset %"PRIu64,
+            stream, stream->sb, mydata_len, app_progress);
 
     /* get window of data that is acked */
     if (StreamTcpInlineMode() == 0 && (p->flags & PKT_PSEUDO_STREAM_END)) {
         //
     } else if (StreamTcpInlineMode() == 0) {
         /* see if the buffer contains unack'd data as well */
-        if (stream->app_progress + mydata_len > last_ack_abs) {
-            mydata_len = last_ack_abs - stream->app_progress;
+        if (app_progress + mydata_len > last_ack_abs) {
+            mydata_len = last_ack_abs - app_progress;
             SCLogDebug("data len adjusted to %u to make sure only ACK'd "
                     "data is considered", mydata_len);
         }
@@ -1149,13 +1149,13 @@ static int ReassembleUpdateAppLayer (ThreadVars *tv,
     if (r == 0 && StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(stream)) {
         if (mydata_len > 0) {
             SCLogDebug("app progress %"PRIu64" increasing with data len %u to %"PRIu64,
-                    stream->app_progress, mydata_len, stream->app_progress + mydata_len);
+                    app_progress, mydata_len, app_progress + mydata_len);
 
-            stream->app_progress += mydata_len;
-            SCLogDebug("app progress now %"PRIu64, stream->app_progress);
+            stream->app_progress_rel += mydata_len;
+            SCLogDebug("app progress now %"PRIu64, STREAM_APP_PROGRESS(stream));
         }
     } else {
-        SCLogDebug("NOT UPDATED app progress now %"PRIu64, stream->app_progress);
+        SCLogDebug("NOT UPDATED app progress still %"PRIu64, app_progress);
     }
 
     SCReturnInt(0);
@@ -1241,7 +1241,7 @@ int StreamTcpReassembleAppLayer (ThreadVars *tv, TcpReassemblyThreadCtx *ra_ctx,
      * and state is beyond established, we send an empty msg */
     TcpSegment *seg_tail = stream->seg_list_tail;
     if (seg_tail == NULL ||
-            SEGMENT_BEFORE_OFFSET(stream, seg_tail, stream->app_progress))
+            SEGMENT_BEFORE_OFFSET(stream, seg_tail, STREAM_APP_PROGRESS(stream)))
     {
         /* send an empty EOF msg if we have no segments but TCP state
          * is beyond ESTABLISHED */
@@ -3181,7 +3181,7 @@ static int StreamTcpReassembleTest40 (void)
 
     /* check is have the segment in the list and flagged or not */
     if (ssn.client.seg_list == NULL ||
-        SEGMENT_BEFORE_OFFSET(&ssn.client, ssn.client.seg_list, ssn.client.app_progress))
+        SEGMENT_BEFORE_OFFSET(&ssn.client, ssn.client.seg_list, STREAM_APP_PROGRESS(&ssn.client)))
 //        (ssn.client.seg_list->flags & SEGMENTTCP_FLAG_APPLAYER_PROCESSED))
     {
         printf("the list is NULL or the processed segment has not been flaged (7): ");
@@ -4563,9 +4563,9 @@ static int StreamTcpReassembleInlineTest10(void)
         goto end;
     }
 
-    if (ssn.server.app_progress != 17) {
+    if (STREAM_APP_PROGRESS(&ssn.server) != 17) {
         printf("expected ssn.server.app_progress == 17got %"PRIu64": ",
-                ssn.server.app_progress);
+                STREAM_APP_PROGRESS(&ssn.server));
         goto end;
     }