]> git.ipfire.org Git - thirdparty/suricata.git/commitdiff
stream: handle case where Suricata sees 3whs-ACK but server doesn't. Bug #523.
authorVictor Julien <victor@inliniac.net>
Thu, 16 Aug 2012 10:41:53 +0000 (12:41 +0200)
committerVictor Julien <victor@inliniac.net>
Thu, 16 Aug 2012 10:41:53 +0000 (12:41 +0200)
src/stream-tcp-private.h
src/stream-tcp.c

index 385c48a0627b5e80702c34db3b6cdf03ae996b8b..bf16625862afeea03307aae19b0ab54001e566bf 100644 (file)
@@ -119,6 +119,11 @@ enum
 /** Flag for triggering RAW reassembly before the size limit is reached or
     the stream reaches EOF. */
 #define STREAMTCP_FLAG_TRIGGER_RAW_REASSEMBLY       0x1000
+/** 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
+ *  event. */
+#define STREAMTCP_FLAG_3WHS_CONFIRMED               0x2000
 
 /*
  * Per STREAM flags
index 4ea3d4823ba18cd803fe4033af653c1467bd6eb1..01a132faf8f2bc19015ed5de806be8a644d3cc75 100644 (file)
@@ -1957,9 +1957,19 @@ static int StreamTcpPacketStateEstablished(ThreadVars *tv, Packet *p,
             return -1;
         }
 
-        /* a resend of a SYN while we are established already -- fishy */
-        StreamTcpSetEvent(p, STREAM_EST_SYNACK_RESEND);
-        return -1;
+        if (ssn->flags & STREAMTCP_FLAG_3WHS_CONFIRMED) {
+            /* a resend of a SYN while we are established already -- fishy */
+            StreamTcpSetEvent(p, STREAM_EST_SYNACK_RESEND);
+            return -1;
+        }
+
+        SCLogDebug("ssn %p: SYN/ACK packet on state ESTABLISHED... resent. "
+                "Likely due server not receiving final ACK in 3whs", ssn);
+
+        /* resetting state to TCP_SYN_RECV as we should get another ACK now */
+        StreamTcpPacketSetState(p, ssn, TCP_SYN_RECV);
+        SCLogDebug("ssn %p: =~ ssn state is now reset to TCP_SYN_RECV", ssn);
+        return 0;
 
     } else if (p->tcph->th_flags & TH_SYN) {
         SCLogDebug("ssn %p: SYN packet on state ESTABLISED... resent", ssn);
@@ -2006,6 +2016,8 @@ static int StreamTcpPacketStateEstablished(ThreadVars *tv, Packet *p,
                     ,ssn->client.next_win, ssn->client.window);
 
         } else { /* implied to client */
+            ssn->flags |= STREAMTCP_FLAG_3WHS_CONFIRMED;
+            SCLogDebug("3whs is now confirmed by server");
 
             /* Process the received packet to client */
             HandleEstablishedPacketToClient(tv, ssn, p, stt, pq);