]> git.ipfire.org Git - thirdparty/suricata.git/commitdiff
set stream_eof flag per stream, only when the stream initiates a close. Fix htp parse...
authorAnoop Saldanha <poonaatsoc@gmail.com>
Thu, 17 May 2012 08:11:23 +0000 (13:41 +0530)
committerVictor Julien <victor@inliniac.net>
Sun, 20 May 2012 12:00:08 +0000 (14:00 +0200)
src/app-layer-htp.c
src/app-layer-htp.h
src/stream-tcp-private.h
src/stream-tcp-reassemble.c
src/stream-tcp.c

index 2f2574b22c9245ac09b7120db465fde207d01df3..bac04c49e025ce6e6f93ae7f9229dde9d1b46629 100644 (file)
@@ -686,12 +686,13 @@ static int HTPHandleRequestData(Flow *f, void *htp_state,
 
     /* if the TCP connection is closed, then close the HTTP connection */
     if ((pstate->flags & APP_LAYER_PARSER_EOF) &&
-            ! (hstate->flags & HTP_FLAG_STATE_CLOSED) &&
-            ! (hstate->flags & HTP_FLAG_STATE_DATA))
-    {
-        htp_connp_close(hstate->connp, 0);
-        hstate->flags |= HTP_FLAG_STATE_CLOSED;
-        SCLogDebug("stream eof encountered, closing htp handle");
+        !(hstate->flags & HTP_FLAG_STATE_CLOSED_TS)) {
+        hstate->connp->in_status = STREAM_STATE_CLOSED;
+        // Call the parsers one last time, which will allow them
+        // to process the events that depend on stream closure
+        htp_connp_req_data(hstate->connp, 0, NULL, 0);
+        hstate->flags |= HTP_FLAG_STATE_CLOSED_TS;
+        SCLogDebug("stream eof encountered, closing htp handle for ts");
     }
 
     SCLogDebug("hstate->connp %p", hstate->connp);
@@ -766,11 +767,12 @@ static int HTPHandleResponseData(Flow *f, void *htp_state,
 
     /* if we the TCP connection is closed, then close the HTTP connection */
     if ((pstate->flags & APP_LAYER_PARSER_EOF) &&
-            ! (hstate->flags & HTP_FLAG_STATE_CLOSED) &&
-            ! (hstate->flags & HTP_FLAG_STATE_DATA))
-    {
-        htp_connp_close(hstate->connp, 0);
-        hstate->flags |= HTP_FLAG_STATE_CLOSED;
+        !(hstate->flags & HTP_FLAG_STATE_CLOSED_TC)) {
+        hstate->connp->out_status = STREAM_STATE_CLOSED;
+        // Call the parsers one last time, which will allow them
+        // to process the events that depend on stream closure
+        htp_connp_res_data(hstate->connp, 0, NULL, 0);
+        hstate->flags |= HTP_FLAG_STATE_CLOSED_TC;
     }
 
     SCLogDebug("hstate->connp %p", hstate->connp);
index 2999495fc3d13b7ad1942a9398babccdcc9371ff..2579b9229abd4c0fa4694de5f97c62020c82d149 100644 (file)
 
 #define HTP_FLAG_STATE_OPEN         0x0001    /**< Flag to indicate that HTTP
                                              connection is open */
-#define HTP_FLAG_STATE_CLOSED       0x0002    /**< Flag to indicate that HTTP
+#define HTP_FLAG_STATE_CLOSED_TS    0x0002    /**< Flag to indicate that HTTP
                                              connection is closed */
-#define HTP_FLAG_STATE_DATA         0x0004    /**< Flag to indicate that HTTP
+#define HTP_FLAG_STATE_CLOSED_TC    0x0004    /**< Flag to indicate that HTTP
+                                             connection is closed */
+#define HTP_FLAG_STATE_DATA         0x0008    /**< Flag to indicate that HTTP
                                              connection needs more data */
-#define HTP_FLAG_STATE_ERROR        0x0008    /**< Flag to indicate that an error
+#define HTP_FLAG_STATE_ERROR        0x0010    /**< Flag to indicate that an error
                                              has been occured on HTTP
                                              connection */
-#define HTP_FLAG_NEW_BODY_SET       0x0010    /**< Flag to indicate that HTTP
+#define HTP_FLAG_NEW_BODY_SET       0x0020    /**< Flag to indicate that HTTP
                                              has parsed a new body (for
                                              pcre) */
-#define HTP_FLAG_STORE_FILES_TS     0x0020
-#define HTP_FLAG_STORE_FILES_TC     0x0040
-#define HTP_FLAG_STORE_FILES_TX_TS  0x0080
-#define HTP_FLAG_STORE_FILES_TX_TC  0x0100
+#define HTP_FLAG_STORE_FILES_TS     0x0040
+#define HTP_FLAG_STORE_FILES_TC     0x0080
+#define HTP_FLAG_STORE_FILES_TX_TS  0x0100
+#define HTP_FLAG_STORE_FILES_TX_TC  0x0200
 /** flag the state that a new file has been set in this tx */
-#define HTP_FLAG_NEW_FILE_TX_TS     0x0200
+#define HTP_FLAG_NEW_FILE_TX_TS     0x0400
 /** flag the state that a new file has been set in this tx */
-#define HTP_FLAG_NEW_FILE_TX_TC     0x0400
+#define HTP_FLAG_NEW_FILE_TX_TC     0x0800
 
 enum {
     HTP_BODY_NONE = 0,                  /**< Flag to indicate the current
index fc5ff65383a21c59560a53d21886a203349061e8..385c48a0627b5e80702c34db3b6cdf03ae996b8b 100644 (file)
@@ -132,6 +132,8 @@ enum
 #define STREAMTCP_STREAM_FLAG_PAUSE_REASSEMBLY  0x04
 /** Stream has reached it's reassembly depth, all further packets are ignored */
 #define STREAMTCP_STREAM_FLAG_DEPTH_REACHED     0x08
+/** Stream has sent a FIN/RST */
+#define STREAMTCP_STREAM_FLAG_CLOSE_INITIATED   0x10
 
 /*
  * Per SEGMENT flags
index ea9c5a9f4fd03b7f7818089bc4c6cf0bce461ea7..d30b6520ab761b173a99a58eba188eda882f1632 100644 (file)
@@ -1624,7 +1624,7 @@ int StreamTcpReassembleHandleSegmentHandleData(ThreadVars *tv, TcpReassemblyThre
     if (!(ssn->flags & STREAMTCP_FLAG_APPPROTO_DETECTION_COMPLETED)) {\
         flag |= STREAM_START; \
     } \
-    if ((ssn)->state > TCP_ESTABLISHED) { \
+    if (stream->flags & STREAMTCP_STREAM_FLAG_CLOSE_INITIATED) {    \
         flag |= STREAM_EOF; \
     } \
     if ((p)->flowflags & FLOW_PKT_TOSERVER) { \
@@ -1639,7 +1639,7 @@ int StreamTcpReassembleHandleSegmentHandleData(ThreadVars *tv, TcpReassemblyThre
     if (!(ssn->flags & STREAMTCP_FLAG_APPPROTO_DETECTION_COMPLETED)) {\
         flag |= STREAM_START; \
     } \
-    if ((ssn)->state > TCP_ESTABLISHED) { \
+    if (stream->flags & STREAMTCP_STREAM_FLAG_CLOSE_INITIATED) {    \
         flag |= STREAM_EOF; \
     } \
     if ((p)->flowflags & FLOW_PKT_TOSERVER) { \
@@ -1660,7 +1660,7 @@ static void StreamTcpSetupMsg(TcpSession *ssn, TcpStream *stream, Packet *p,
         SCLogDebug("setting STREAM_START");
         smsg->flags = STREAM_START;
     }
-    if (ssn->state > TCP_ESTABLISHED) {
+    if (stream->flags & STREAMTCP_STREAM_FLAG_CLOSE_INITIATED) {
         SCLogDebug("setting STREAM_EOF");
         smsg->flags |= STREAM_EOF;
     }
@@ -1823,7 +1823,7 @@ static int StreamTcpReassembleInlineAppLayer (ThreadVars *tv,
             /* send EOF to app layer */
             STREAM_SET_INLINE_FLAGS(ssn, stream, p, flags);
             AppLayerHandleTCPData(&ra_ctx->dp_ctx, p->flow, ssn,
-                    NULL, 0, flags|STREAM_EOF);
+                    NULL, 0, flags);
             PACKET_PROFILING_APP_STORE(&ra_ctx->dp_ctx, p);
 
         } else {
@@ -2110,7 +2110,7 @@ static int StreamTcpReassembleInlineAppLayer (ThreadVars *tv,
         /* send EOF to app layer */
         STREAM_SET_INLINE_FLAGS(ssn, stream, p, flags);
         AppLayerHandleTCPData(&ra_ctx->dp_ctx, p->flow, ssn,
-                NULL, 0, flags|STREAM_EOF);
+                NULL, 0, flags);
         PACKET_PROFILING_APP_STORE(&ra_ctx->dp_ctx, p);
     }
 
@@ -2484,7 +2484,7 @@ static int StreamTcpReassembleAppLayer (ThreadVars *tv,
             /* send EOF to app layer */
             STREAM_SET_FLAGS(ssn, stream, p, flags);
             AppLayerHandleTCPData(&ra_ctx->dp_ctx, p->flow, ssn,
-                    NULL, 0, flags|STREAM_EOF);
+                    NULL, 0, flags);
             PACKET_PROFILING_APP_STORE(&ra_ctx->dp_ctx, p);
 
             SCReturnInt(0);
index f1e97bbd6f7734830e0799fbaf70bc84f8052548..c840ccabd27b958a94056c64f89b8767b26cb50b 100644 (file)
@@ -1263,11 +1263,15 @@ static int StreamTcpPacketStateSynSent(ThreadVars *tv, Packet *p,
                             SEQ_EQ(TCP_GET_ACK(p), (ssn->client.isn + 1)))
                     {
                         StreamTcpPacketSetState(p, ssn, TCP_CLOSED);
+                        ssn->server.flags |= STREAMTCP_STREAM_FLAG_CLOSE_INITIATED;
+                        ssn->client.flags |= STREAMTCP_STREAM_FLAG_CLOSE_INITIATED;
                         SCLogDebug("ssn %p: Reset received and state changed to "
                                 "TCP_CLOSED", ssn);
                     }
                 } else {
                     StreamTcpPacketSetState(p, ssn, TCP_CLOSED);
+                    ssn->server.flags |= STREAMTCP_STREAM_FLAG_CLOSE_INITIATED;
+                    ssn->client.flags |= STREAMTCP_STREAM_FLAG_CLOSE_INITIATED;
                     SCLogDebug("ssn %p: Reset received and state changed to "
                             "TCP_CLOSED", ssn);
                 }
@@ -1577,6 +1581,8 @@ static int StreamTcpPacketStateSynRecv(ThreadVars *tv, Packet *p,
 
                 if (reset == TRUE) {
                     StreamTcpPacketSetState(p, ssn, TCP_CLOSED);
+                    ssn->server.flags |= STREAMTCP_STREAM_FLAG_CLOSE_INITIATED;
+                    ssn->client.flags |= STREAMTCP_STREAM_FLAG_CLOSE_INITIATED;
                     SCLogDebug("ssn %p: Reset received and state changed to "
                                    "TCP_CLOSED", ssn);
 
@@ -2036,6 +2042,8 @@ static int StreamTcpPacketStateEstablished(ThreadVars *tv, Packet *p,
 
                 if(PKT_IS_TOSERVER(p)) {
                     StreamTcpPacketSetState(p, ssn, TCP_CLOSED);
+                    ssn->server.flags |= STREAMTCP_STREAM_FLAG_CLOSE_INITIATED;
+                    ssn->client.flags |= STREAMTCP_STREAM_FLAG_CLOSE_INITIATED;
                     SCLogDebug("ssn %p: Reset received and state changed to "
                                "TCP_CLOSED", ssn);
 
@@ -2066,6 +2074,8 @@ static int StreamTcpPacketStateEstablished(ThreadVars *tv, Packet *p,
                      * cleanup. */
                 } else {
                     StreamTcpPacketSetState(p, ssn, TCP_CLOSED);
+                    ssn->server.flags |= STREAMTCP_STREAM_FLAG_CLOSE_INITIATED;
+                    ssn->client.flags |= STREAMTCP_STREAM_FLAG_CLOSE_INITIATED;
                     SCLogDebug("ssn %p: Reset received and state changed to "
                                "TCP_CLOSED", ssn);
 
@@ -2146,6 +2156,7 @@ static int StreamTcpHandleFin(ThreadVars *tv, StreamTcpThread *stt,
         }
 
         StreamTcpPacketSetState(p, ssn, TCP_CLOSE_WAIT);
+        ssn->client.flags |= STREAMTCP_STREAM_FLAG_CLOSE_INITIATED;
         SCLogDebug("ssn %p: state changed to TCP_CLOSE_WAIT", ssn);
 
         if (SEQ_EQ(TCP_GET_SEQ(p), ssn->client.next_seq))
@@ -2193,6 +2204,7 @@ static int StreamTcpHandleFin(ThreadVars *tv, StreamTcpThread *stt,
         }
 
         StreamTcpPacketSetState(p, ssn, TCP_FIN_WAIT1);
+        ssn->server.flags |= STREAMTCP_STREAM_FLAG_CLOSE_INITIATED;
         SCLogDebug("ssn %p: state changed to TCP_FIN_WAIT1", ssn);
 
         if (SEQ_EQ(TCP_GET_SEQ(p), ssn->server.next_seq))
@@ -2414,6 +2426,7 @@ static int StreamTcpPacketStateFinWait1(ThreadVars *tv, Packet *p,
                 }
 
                 StreamTcpPacketSetState(p, ssn, TCP_TIME_WAIT);
+                ssn->client.flags |= STREAMTCP_STREAM_FLAG_CLOSE_INITIATED;
                 SCLogDebug("ssn %p: state changed to TCP_TIME_WAIT", ssn);
 
                 ssn->server.window = TCP_GET_WINDOW(p) << ssn->server.wscale;
@@ -2463,6 +2476,7 @@ static int StreamTcpPacketStateFinWait1(ThreadVars *tv, Packet *p,
                 }
 
                 StreamTcpPacketSetState(p, ssn, TCP_TIME_WAIT);
+                ssn->server.flags |= STREAMTCP_STREAM_FLAG_CLOSE_INITIATED;
                 SCLogDebug("ssn %p: state changed to TCP_TIME_WAIT", ssn);
 
                 ssn->client.window = TCP_GET_WINDOW(p) << ssn->client.wscale;
@@ -2504,6 +2518,8 @@ static int StreamTcpPacketStateFinWait1(ThreadVars *tv, Packet *p,
                 SCPerfCounterIncr(stt->counter_tcp_pseudo, tv->sc_perf_pca);
 
                 StreamTcpPacketSetState(p, ssn, TCP_CLOSED);
+                ssn->server.flags |= STREAMTCP_STREAM_FLAG_CLOSE_INITIATED;
+                ssn->client.flags |= STREAMTCP_STREAM_FLAG_CLOSE_INITIATED;
                 SCLogDebug("ssn %p: Reset received state changed to TCP_CLOSED",
                             ssn);
 
@@ -2689,6 +2705,8 @@ static int StreamTcpPacketStateFinWait2(ThreadVars *tv, Packet *p,
                 SCPerfCounterIncr(stt->counter_tcp_pseudo, tv->sc_perf_pca);
 
                 StreamTcpPacketSetState(p, ssn, TCP_CLOSED);
+                ssn->server.flags |= STREAMTCP_STREAM_FLAG_CLOSE_INITIATED;
+                ssn->client.flags |= STREAMTCP_STREAM_FLAG_CLOSE_INITIATED;
                 SCLogDebug("ssn %p: Reset received state changed to TCP_CLOSED",
                             ssn);
 
@@ -2759,6 +2777,7 @@ static int StreamTcpPacketStateFinWait2(ThreadVars *tv, Packet *p,
                 }
 
                 StreamTcpPacketSetState(p, ssn, TCP_TIME_WAIT);
+                ssn->client.flags |= STREAMTCP_STREAM_FLAG_CLOSE_INITIATED;
                 SCLogDebug("ssn %p: state changed to TCP_TIME_WAIT", ssn);
 
                 ssn->server.window = TCP_GET_WINDOW(p) << ssn->server.wscale;
@@ -2804,6 +2823,7 @@ static int StreamTcpPacketStateFinWait2(ThreadVars *tv, Packet *p,
                 }
 
                 StreamTcpPacketSetState(p, ssn, TCP_TIME_WAIT);
+                ssn->server.flags |= STREAMTCP_STREAM_FLAG_CLOSE_INITIATED;
                 SCLogDebug("ssn %p: state changed to TCP_TIME_WAIT", ssn);
 
                 ssn->client.window = TCP_GET_WINDOW(p) << ssn->client.wscale;
@@ -2956,6 +2976,8 @@ static int StreamTcpPacketStateClosing(ThreadVars *tv, Packet *p,
                 SCPerfCounterIncr(stt->counter_tcp_pseudo, tv->sc_perf_pca);
 
                 StreamTcpPacketSetState(p, ssn, TCP_CLOSED);
+                ssn->server.flags |= STREAMTCP_STREAM_FLAG_CLOSE_INITIATED;
+                ssn->client.flags |= STREAMTCP_STREAM_FLAG_CLOSE_INITIATED;
                 SCLogDebug("ssn %p: Reset received state changed to TCP_CLOSED",
                             ssn);
 
@@ -3060,6 +3082,7 @@ static int StreamTcpPacketStateCloseWait(ThreadVars *tv, Packet *p,
                 }
 
                 StreamTcpPacketSetState(p, ssn, TCP_LAST_ACK);
+                ssn->client.flags |= STREAMTCP_STREAM_FLAG_CLOSE_INITIATED;
                 SCLogDebug("ssn %p: state changed to TCP_LAST_ACK", ssn);
 
                 ssn->server.window = TCP_GET_WINDOW(p) << ssn->server.wscale;
@@ -3102,6 +3125,7 @@ static int StreamTcpPacketStateCloseWait(ThreadVars *tv, Packet *p,
                 }
 
                 StreamTcpPacketSetState(p, ssn, TCP_LAST_ACK);
+                ssn->server.flags |= STREAMTCP_STREAM_FLAG_CLOSE_INITIATED;
                 SCLogDebug("ssn %p: state changed to TCP_LAST_ACK", ssn);
 
                 ssn->client.window = TCP_GET_WINDOW(p) << ssn->client.wscale;
@@ -3232,6 +3256,8 @@ static int StreamTcpPacketStateCloseWait(ThreadVars *tv, Packet *p,
                 SCPerfCounterIncr(stt->counter_tcp_pseudo, tv->sc_perf_pca);
 
                 StreamTcpPacketSetState(p, ssn, TCP_CLOSED);
+                ssn->server.flags |= STREAMTCP_STREAM_FLAG_CLOSE_INITIATED;
+                ssn->client.flags |= STREAMTCP_STREAM_FLAG_CLOSE_INITIATED;
                 SCLogDebug("ssn %p: Reset received state changed to TCP_CLOSED",
                             ssn);
 
@@ -3355,6 +3381,8 @@ static int StreamTcpPakcetStateLastAck(ThreadVars *tv, Packet *p,
                 SCPerfCounterIncr(stt->counter_tcp_pseudo, tv->sc_perf_pca);
 
                 StreamTcpPacketSetState(p, ssn, TCP_CLOSED);
+                ssn->server.flags |= STREAMTCP_STREAM_FLAG_CLOSE_INITIATED;
+                ssn->client.flags |= STREAMTCP_STREAM_FLAG_CLOSE_INITIATED;
                 SCLogDebug("ssn %p: Reset received state changed to TCP_CLOSED",
                             ssn);
 
@@ -3522,6 +3550,8 @@ static int StreamTcpPacketStateTimeWait(ThreadVars *tv, Packet *p,
                 SCPerfCounterIncr(stt->counter_tcp_pseudo, tv->sc_perf_pca);
 
                 StreamTcpPacketSetState(p, ssn, TCP_CLOSED);
+                ssn->server.flags |= STREAMTCP_STREAM_FLAG_CLOSE_INITIATED;
+                ssn->client.flags |= STREAMTCP_STREAM_FLAG_CLOSE_INITIATED;
                 SCLogDebug("ssn %p: Reset received state changed to TCP_CLOSED",
                             ssn);
 
@@ -3715,8 +3745,13 @@ static int StreamTcpPacket (ThreadVars *tv, Packet *p, StreamTcpThread *stt,
         if (ssn->state >= TCP_ESTABLISHED) {
             p->flags |= PKT_STREAM_EST;
         }
-        if (ssn->state > TCP_ESTABLISHED) {
-            p->flags |= PKT_STREAM_EOF;
+
+        if (PKT_IS_TOSERVER(p)) {
+            if (ssn->client.flags & STREAMTCP_STREAM_FLAG_CLOSE_INITIATED)
+                p->flags |= PKT_STREAM_EOF;
+        } else {
+            if (ssn->server.flags & STREAMTCP_STREAM_FLAG_CLOSE_INITIATED)
+                p->flags |= PKT_STREAM_EOF;
         }
     }