]> git.ipfire.org Git - thirdparty/suricata.git/commitdiff
stream: set 'trigger raw' per direction
authorVictor Julien <victor@inliniac.net>
Sat, 18 Feb 2017 23:54:45 +0000 (00:54 +0100)
committerVictor Julien <victor@inliniac.net>
Thu, 20 Apr 2017 15:41:11 +0000 (17:41 +0200)
src/app-layer-htp.c
src/app-layer-parser.c
src/app-layer-parser.h
src/app-layer-ssl.c
src/stream-tcp-private.h
src/stream-tcp-reassemble.c
src/stream-tcp-reassemble.h

index 5b8e61c25f2f109099584385db600eac2801a9c1..3588a9e88b3147936cf64f5d8984552f2aa4995a 100644 (file)
@@ -1974,7 +1974,7 @@ static int HTPCallbackRequest(htp_tx_t *tx)
 
     /* request done, do raw reassembly now to inspect state and stream
      * at the same time. */
-    AppLayerParserTriggerRawStreamReassembly(hstate->f);
+    AppLayerParserTriggerRawStreamReassembly(hstate->f, STREAM_TOSERVER);
     SCReturnInt(HTP_OK);
 }
 
@@ -2010,7 +2010,7 @@ static int HTPCallbackResponse(htp_tx_t *tx)
 
     /* response done, do raw reassembly now to inspect state and stream
      * at the same time. */
-    AppLayerParserTriggerRawStreamReassembly(hstate->f);
+    AppLayerParserTriggerRawStreamReassembly(hstate->f, STREAM_TOCLIENT);
     SCReturnInt(HTP_OK);
 }
 
index 49975175ebae55b88b4ea0b746e897a09c06410b..483724d4801adf8fbb8246ea03e74db4121cbba9 100644 (file)
@@ -1153,12 +1153,13 @@ int AppLayerParserProtocolHasLogger(uint8_t ipproto, AppProto alproto)
     SCReturnInt(r);
 }
 
-void AppLayerParserTriggerRawStreamReassembly(Flow *f)
+void AppLayerParserTriggerRawStreamReassembly(Flow *f, int direction)
 {
     SCEnter();
 
+    SCLogDebug("f %p tcp %p direction %d", f, f ? f->protoctx : NULL, direction);
     if (f != NULL && f->protoctx != NULL)
-        StreamTcpReassembleTriggerRawReassembly(f->protoctx);
+        StreamTcpReassembleTriggerRawReassembly(f->protoctx, direction);
 
     SCReturn;
 }
index 29e668ce7f1412b0685e198f5fe2e9bd6ae14aec..c31a9d9a96849919cc0847da9057368cea40cbbe 100644 (file)
@@ -207,7 +207,7 @@ int AppLayerParserProtocolIsTxAware(uint8_t ipproto, AppProto alproto);
 int AppLayerParserProtocolIsTxEventAware(uint8_t ipproto, AppProto alproto);
 int AppLayerParserProtocolSupportsTxs(uint8_t ipproto, AppProto alproto);
 int AppLayerParserProtocolHasLogger(uint8_t ipproto, AppProto alproto);
-void AppLayerParserTriggerRawStreamReassembly(Flow *f);
+void AppLayerParserTriggerRawStreamReassembly(Flow *f, int direction);
 void AppLayerParserSetStreamDepth(uint8_t ipproto, AppProto alproto, uint32_t stream_depth);
 uint32_t AppLayerParserGetStreamDepth(uint8_t ipproto, AppProto alproto);
 
index 239773981924f182b91c5fcd6989a5d92bf63810..47c3e9ef6025d3bf8a19a271161d96d3eb2a1db8 100644 (file)
@@ -1286,7 +1286,8 @@ static int SSLv3Decode(uint8_t direction, SSLState *ssl_state,
                 }
 
                 SCLogDebug("trigger RAW! (post HS)");
-                AppLayerParserTriggerRawStreamReassembly(ssl_state->f);
+                AppLayerParserTriggerRawStreamReassembly(ssl_state->f,
+                        direction == 0 ? STREAM_TOSERVER : STREAM_TOCLIENT);
                 return parsed;
             }
 
@@ -1317,7 +1318,8 @@ static int SSLv3Decode(uint8_t direction, SSLState *ssl_state,
         }
 
         SCLogDebug("record complete, trigger RAW");
-        AppLayerParserTriggerRawStreamReassembly(ssl_state->f);
+        AppLayerParserTriggerRawStreamReassembly(ssl_state->f,
+                direction == 0 ? STREAM_TOSERVER : STREAM_TOCLIENT);
 
         /* looks like we have another record */
         uint32_t diff = ssl_state->curr_connp->record_length +
index f51e8ac8ff773554aa853a5b8b35c2c2ac4c48f6..9569be4edb7626abc7a0028d92d850ca4947b2f1 100644 (file)
@@ -150,7 +150,7 @@ enum
 #define STREAMTCP_FLAG_SACKOK                       0x0400
 /** Flag for triggering RAW reassembly before the size limit is reached or
     the stream reaches EOF. */
-#define STREAMTCP_FLAG_TRIGGER_RAW_REASSEMBLY       0x0800
+//#define STREAMTCP_FLAG_TRIGGER_RAW_REASSEMBLY       0x0800
 /** 3WHS confirmed by server -- if suri sees 3whs ACK but server doesn't (pkt
  *  is lost on the way to server), SYN/ACK is retransmitted. If server sends
  *  normal packet we assume 3whs to be completed. Only used for SYN/ACK resend
@@ -171,7 +171,8 @@ enum
 #define STREAMTCP_STREAM_FLAG_KEEPALIVE         0x0004
 /** Stream has reached it's reassembly depth, all further packets are ignored */
 #define STREAMTCP_STREAM_FLAG_DEPTH_REACHED     0x0008
-// vacancy
+/** Trigger reassembly next time we need 'raw' */
+#define STREAMTCP_STREAM_FLAG_TRIGGER_RAW       0x0010
 /** Stream supports TIMESTAMP -- used to set ssn STREAMTCP_FLAG_TIMESTAMP
  *  flag. */
 #define STREAMTCP_STREAM_FLAG_TIMESTAMP         0x0020
index 48587b7efcdec58b87afd90c30f7b4158c4dccfa..39e9ea9ea5e0a333216ac2890d4e090fbed70324 100644 (file)
@@ -701,7 +701,7 @@ static uint8_t StreamGetAppLayerFlags(TcpSession *ssn, TcpStream *stream,
  *  \retval 0 don't reassemble yet
  *  \retval 1 do reassemble
  */
-static int StreamTcpReassembleRawCheckLimit(TcpSession *ssn,
+static int StreamTcpReassembleRawCheckLimit(const TcpSession *ssn,
         const TcpStream *stream, const Packet *p)
 {
     SCEnter();
@@ -711,9 +711,8 @@ static int StreamTcpReassembleRawCheckLimit(TcpSession *ssn,
         SCReturnInt(1);
     }
 
-    if (ssn->flags & STREAMTCP_FLAG_TRIGGER_RAW_REASSEMBLY) {
-        SCLogDebug("reassembling now as STREAMTCP_FLAG_TRIGGER_RAW_REASSEMBLY is set");
-        ssn->flags &= ~STREAMTCP_FLAG_TRIGGER_RAW_REASSEMBLY;
+    if (stream->flags & STREAMTCP_STREAM_FLAG_TRIGGER_RAW) {
+        SCLogDebug("reassembling now as STREAMTCP_STREAM_FLAG_TRIGGER_RAW is set");
         SCReturnInt(1);
     }
 
@@ -1205,6 +1204,7 @@ void StreamReassembleRawUpdateProgress(TcpSession *ssn, Packet *p, uint64_t prog
     if (progress > STREAM_RAW_PROGRESS(stream)) {
         uint32_t slide = progress - STREAM_RAW_PROGRESS(stream);
         stream->raw_progress_rel += slide;
+        stream->flags &= ~STREAMTCP_STREAM_FLAG_TRIGGER_RAW;
     }
 
     SCLogDebug("stream raw progress now %"PRIu64, STREAM_RAW_PROGRESS(stream));
@@ -1249,6 +1249,13 @@ int StreamReassembleRaw(TcpSession *ssn, const Packet *p,
         stream = &ssn->server;
     }
 
+    if (StreamTcpInlineMode() == FALSE &&
+            StreamTcpReassembleRawCheckLimit(ssn, stream, p) == 0)
+    {
+        *progress_out = STREAM_RAW_PROGRESS(stream);
+        return 0;
+    }
+
     StreamingBufferBlock *iter = NULL;
     uint64_t progress = STREAM_RAW_PROGRESS(stream);
     uint64_t last_ack_abs = 0; /* absolute right edge of ack'd data */
@@ -1482,21 +1489,25 @@ TcpSegment *StreamTcpGetSegment(ThreadVars *tv, TcpReassemblyThreadCtx *ra_ctx)
  *  reassembly from the applayer, for example upon completion of a
  *  HTTP request.
  *
- *  Works by setting a flag in the TcpSession that is unset as soon
- *  as it's checked. Since everything happens when operating under
- *  a single lock period, no side effects are expected.
+ *  It sets a flag in the stream so that the next Raw call will return
+ *  the data.
  *
  *  \param ssn TcpSession
  */
-void StreamTcpReassembleTriggerRawReassembly(TcpSession *ssn)
+void StreamTcpReassembleTriggerRawReassembly(TcpSession *ssn, int direction)
 {
 #ifdef DEBUG
     BUG_ON(ssn == NULL);
 #endif
 
     if (ssn != NULL) {
+        if (direction == STREAM_TOSERVER) {
+            ssn->client.flags |= STREAMTCP_STREAM_FLAG_TRIGGER_RAW;
+        } else {
+            ssn->server.flags |= STREAMTCP_STREAM_FLAG_TRIGGER_RAW;
+        }
+
         SCLogDebug("flagged ssn %p for immediate raw reassembly", ssn);
-        ssn->flags |= STREAMTCP_FLAG_TRIGGER_RAW_REASSEMBLY;
     }
 }
 
index f2bbf277e5f2888087e95c776358e41d83988731..d8aaad15f08a30b2aec07b053c6f62c1bc096b73 100644 (file)
@@ -101,7 +101,7 @@ TcpSegment *StreamTcpGetSegment(ThreadVars *, TcpReassemblyThreadCtx *);
 void StreamTcpReturnStreamSegments(TcpStream *);
 void StreamTcpSegmentReturntoPool(TcpSegment *);
 
-void StreamTcpReassembleTriggerRawReassembly(TcpSession *);
+void StreamTcpReassembleTriggerRawReassembly(TcpSession *, int direction);
 
 void StreamTcpPruneSession(Flow *, uint8_t);
 int StreamTcpReassembleDepthReached(Packet *p);