]> git.ipfire.org Git - thirdparty/suricata.git/commitdiff
stream: set next_seq before last_ack
authorVictor Julien <vjulien@oisf.net>
Wed, 15 Feb 2023 10:56:01 +0000 (11:56 +0100)
committerVictor Julien <vjulien@oisf.net>
Fri, 24 Feb 2023 09:45:26 +0000 (10:45 +0100)
next_seq sometimes depends on last_ack in cases of packet loss
catch up, so first update it.

Bug: #5877.

src/stream-tcp.c

index 89790511ae3c06001f27f1846225e32c9433f92c..de6c41903df7d041225a3c79b261f57d3f004fa6 100644 (file)
@@ -2414,12 +2414,11 @@ static int StreamTcpPacketStateSynRecv(
                 StreamTcpHandleTimestamp(ssn, p);
             }
 
+            ssn->client.next_seq = TCP_GET_SEQ(p) + p->payload_len;
             StreamTcpUpdateLastAck(ssn, &ssn->server, TCP_GET_ACK(p));
 
-            ssn->client.next_seq = TCP_GET_SEQ(p) + p->payload_len;
             SCLogDebug("ssn %p: ACK for missing data: ssn->client.next_seq %u", ssn, ssn->client.next_seq);
             ssn->server.window = TCP_GET_WINDOW(p) << ssn->server.wscale;
-
             ssn->server.next_win = ssn->server.last_ack + ssn->server.window;
 
             if (ssn->flags & STREAMTCP_FLAG_MIDSTREAM) {
@@ -3175,9 +3174,6 @@ static int StreamTcpHandleFin(ThreadVars *tv, StreamTcpThread *stt, TcpSession *
                     ssn->client.next_seq);
         ssn->server.window = TCP_GET_WINDOW(p) << ssn->server.wscale;
 
-        if (p->tcph->th_flags & TH_ACK)
-            StreamTcpUpdateLastAck(ssn, &ssn->server, TCP_GET_ACK(p));
-
         if (ssn->flags & STREAMTCP_FLAG_TIMESTAMP) {
             StreamTcpHandleTimestamp(ssn, p);
         }
@@ -3187,6 +3183,9 @@ static int StreamTcpHandleFin(ThreadVars *tv, StreamTcpThread *stt, TcpSession *
         if (SEQ_LT(ssn->server.next_seq, TCP_GET_ACK(p)))
             ssn->server.next_seq = TCP_GET_ACK(p);
 
+        if (p->tcph->th_flags & TH_ACK)
+            StreamTcpUpdateLastAck(ssn, &ssn->server, TCP_GET_ACK(p));
+
         StreamTcpReassembleHandleSegment(tv, stt->ra_ctx, ssn, &ssn->client, p);
 
         SCLogDebug("ssn %p: =+ next SEQ %" PRIu32 ", last ACK %" PRIu32 "",
@@ -3223,9 +3222,6 @@ static int StreamTcpHandleFin(ThreadVars *tv, StreamTcpThread *stt, TcpSession *
                     ssn->server.next_seq);
         ssn->client.window = TCP_GET_WINDOW(p) << ssn->client.wscale;
 
-        if (p->tcph->th_flags & TH_ACK)
-            StreamTcpUpdateLastAck(ssn, &ssn->client, TCP_GET_ACK(p));
-
         if (ssn->flags & STREAMTCP_FLAG_TIMESTAMP) {
             StreamTcpHandleTimestamp(ssn, p);
         }
@@ -3235,6 +3231,9 @@ static int StreamTcpHandleFin(ThreadVars *tv, StreamTcpThread *stt, TcpSession *
         if (SEQ_LT(ssn->client.next_seq, TCP_GET_ACK(p)))
             ssn->client.next_seq = TCP_GET_ACK(p);
 
+        if (p->tcph->th_flags & TH_ACK)
+            StreamTcpUpdateLastAck(ssn, &ssn->client, TCP_GET_ACK(p));
+
         StreamTcpReassembleHandleSegment(tv, stt->ra_ctx, ssn, &ssn->server, p);
 
         SCLogDebug("ssn %p: =+ next SEQ %" PRIu32 ", last ACK %" PRIu32 "",
@@ -3335,8 +3334,6 @@ static int StreamTcpPacketStateFinWait1(
                 ssn->server.window = TCP_GET_WINDOW(p) << ssn->server.wscale;
             }
 
-            StreamTcpUpdateLastAck(ssn, &ssn->server, TCP_GET_ACK(p));
-
             if (ssn->flags & STREAMTCP_FLAG_TIMESTAMP) {
                 StreamTcpHandleTimestamp(ssn, p);
             }
@@ -3350,6 +3347,8 @@ static int StreamTcpPacketStateFinWait1(
                 StreamTcpUpdateNextSeq(ssn, &ssn->client, (ssn->client.next_seq + p->payload_len));
             }
 
+            StreamTcpUpdateLastAck(ssn, &ssn->server, TCP_GET_ACK(p));
+
             StreamTcpReassembleHandleSegment(tv, stt->ra_ctx, ssn, &ssn->client, p);
 
             SCLogDebug("ssn %p: =+ next SEQ %" PRIu32 ", last ACK "
@@ -3391,8 +3390,6 @@ static int StreamTcpPacketStateFinWait1(
                 ssn->client.window = TCP_GET_WINDOW(p) << ssn->client.wscale;
             }
 
-            StreamTcpUpdateLastAck(ssn, &ssn->client, TCP_GET_ACK(p));
-
             if (ssn->flags & STREAMTCP_FLAG_TIMESTAMP) {
                 StreamTcpHandleTimestamp(ssn, p);
             }
@@ -3452,9 +3449,6 @@ static int StreamTcpPacketStateFinWait1(
                 ssn->server.window = TCP_GET_WINDOW(p) << ssn->server.wscale;
             }
 
-            if (p->tcph->th_flags & TH_ACK)
-                StreamTcpUpdateLastAck(ssn, &ssn->server, TCP_GET_ACK(p));
-
             if (ssn->flags & STREAMTCP_FLAG_TIMESTAMP) {
                 StreamTcpHandleTimestamp(ssn, p);
             }
@@ -3468,6 +3462,9 @@ static int StreamTcpPacketStateFinWait1(
                 StreamTcpUpdateNextSeq(ssn, &ssn->client, (ssn->client.next_seq + p->payload_len));
             }
 
+            if (p->tcph->th_flags & TH_ACK)
+                StreamTcpUpdateLastAck(ssn, &ssn->server, TCP_GET_ACK(p));
+
             StreamTcpReassembleHandleSegment(tv, stt->ra_ctx, ssn, &ssn->client, p);
 
             SCLogDebug("ssn %p: =+ next SEQ %" PRIu32 ", last ACK "
@@ -3507,9 +3504,6 @@ static int StreamTcpPacketStateFinWait1(
                 ssn->client.window = TCP_GET_WINDOW(p) << ssn->client.wscale;
             }
 
-            if (p->tcph->th_flags & TH_ACK)
-                StreamTcpUpdateLastAck(ssn, &ssn->client, TCP_GET_ACK(p));
-
             if (ssn->flags & STREAMTCP_FLAG_TIMESTAMP) {
                 StreamTcpHandleTimestamp(ssn, p);
             }
@@ -3523,6 +3517,9 @@ static int StreamTcpPacketStateFinWait1(
                 StreamTcpUpdateNextSeq(ssn, &ssn->server, (ssn->server.next_seq + p->payload_len));
             }
 
+            if (p->tcph->th_flags & TH_ACK)
+                StreamTcpUpdateLastAck(ssn, &ssn->client, TCP_GET_ACK(p));
+
             StreamTcpReassembleHandleSegment(tv, stt->ra_ctx, ssn, &ssn->server, p);
 
             SCLogDebug("ssn %p: =+ next SEQ %" PRIu32 ", last ACK "
@@ -3589,8 +3586,6 @@ static int StreamTcpPacketStateFinWait1(
                 }
             }
 
-            StreamTcpUpdateLastAck(ssn, &ssn->server, TCP_GET_ACK(p));
-
             if (ssn->flags & STREAMTCP_FLAG_TIMESTAMP) {
                 StreamTcpHandleTimestamp(ssn, p);
             }
@@ -3604,6 +3599,8 @@ static int StreamTcpPacketStateFinWait1(
                 StreamTcpUpdateNextSeq(ssn, &ssn->client, (ssn->client.next_seq + p->payload_len));
             }
 
+            StreamTcpUpdateLastAck(ssn, &ssn->server, TCP_GET_ACK(p));
+
             StreamTcpSackUpdatePacket(&ssn->server, p);
 
             /* update next_win */
@@ -3656,8 +3653,6 @@ static int StreamTcpPacketStateFinWait1(
                 ssn->client.window = TCP_GET_WINDOW(p) << ssn->client.wscale;
             }
 
-            StreamTcpUpdateLastAck(ssn, &ssn->client, TCP_GET_ACK(p));
-
             if (ssn->flags & STREAMTCP_FLAG_TIMESTAMP) {
                 StreamTcpHandleTimestamp(ssn, p);
             }
@@ -3671,6 +3666,8 @@ static int StreamTcpPacketStateFinWait1(
                 StreamTcpUpdateNextSeq(ssn, &ssn->server, (ssn->server.next_seq + p->payload_len));
             }
 
+            StreamTcpUpdateLastAck(ssn, &ssn->client, TCP_GET_ACK(p));
+
             StreamTcpSackUpdatePacket(&ssn->client, p);
 
             /* update next_win */
@@ -3785,9 +3782,6 @@ static int StreamTcpPacketStateFinWait2(
                 ssn->server.window = TCP_GET_WINDOW(p) << ssn->server.wscale;
             }
 
-            if (p->tcph->th_flags & TH_ACK)
-                StreamTcpUpdateLastAck(ssn, &ssn->server, TCP_GET_ACK(p));
-
             if (ssn->flags & STREAMTCP_FLAG_TIMESTAMP) {
                 StreamTcpHandleTimestamp(ssn, p);
             }
@@ -3797,6 +3791,9 @@ static int StreamTcpPacketStateFinWait2(
             if (SEQ_LT(ssn->server.next_seq, TCP_GET_ACK(p)))
                 ssn->server.next_seq = TCP_GET_ACK(p);
 
+            if (p->tcph->th_flags & TH_ACK)
+                StreamTcpUpdateLastAck(ssn, &ssn->server, TCP_GET_ACK(p));
+
             StreamTcpReassembleHandleSegment(tv, stt->ra_ctx, ssn, &ssn->client, p);
 
             SCLogDebug("ssn %p: =+ next SEQ %" PRIu32 ", last ACK "
@@ -3839,9 +3836,6 @@ static int StreamTcpPacketStateFinWait2(
                 ssn->client.window = TCP_GET_WINDOW(p) << ssn->client.wscale;
             }
 
-            if (p->tcph->th_flags & TH_ACK)
-                StreamTcpUpdateLastAck(ssn, &ssn->client, TCP_GET_ACK(p));
-
             if (ssn->flags & STREAMTCP_FLAG_TIMESTAMP) {
                 StreamTcpHandleTimestamp(ssn, p);
             }
@@ -3851,6 +3845,9 @@ static int StreamTcpPacketStateFinWait2(
             if (SEQ_LT(ssn->client.next_seq, TCP_GET_ACK(p)))
                 ssn->client.next_seq = TCP_GET_ACK(p);
 
+            if (p->tcph->th_flags & TH_ACK)
+                StreamTcpUpdateLastAck(ssn, &ssn->client, TCP_GET_ACK(p));
+
             StreamTcpReassembleHandleSegment(tv, stt->ra_ctx, ssn, &ssn->server, p);
             SCLogDebug("ssn %p: =+ next SEQ %" PRIu32 ", last ACK "
                     "%" PRIu32 "", ssn, ssn->server.next_seq,
@@ -3903,8 +3900,6 @@ static int StreamTcpPacketStateFinWait2(
                 ssn->server.window = TCP_GET_WINDOW(p) << ssn->server.wscale;
             }
 
-            StreamTcpUpdateLastAck(ssn, &ssn->server, TCP_GET_ACK(p));
-
             if (ssn->flags & STREAMTCP_FLAG_TIMESTAMP) {
                 StreamTcpHandleTimestamp(ssn, p);
             }
@@ -3913,6 +3908,8 @@ static int StreamTcpPacketStateFinWait2(
                 StreamTcpUpdateNextSeq(ssn, &ssn->client, (ssn->client.next_seq + p->payload_len));
             }
 
+            StreamTcpUpdateLastAck(ssn, &ssn->server, TCP_GET_ACK(p));
+
             StreamTcpSackUpdatePacket(&ssn->server, p);
 
             /* update next_win */
@@ -3957,8 +3954,6 @@ static int StreamTcpPacketStateFinWait2(
                 ssn->client.window = TCP_GET_WINDOW(p) << ssn->client.wscale;
             }
 
-            StreamTcpUpdateLastAck(ssn, &ssn->client, TCP_GET_ACK(p));
-
             if (ssn->flags & STREAMTCP_FLAG_TIMESTAMP) {
                 StreamTcpHandleTimestamp(ssn, p);
             }
@@ -3967,6 +3962,8 @@ static int StreamTcpPacketStateFinWait2(
                 StreamTcpUpdateNextSeq(ssn, &ssn->server, (ssn->server.next_seq + p->payload_len));
             }
 
+            StreamTcpUpdateLastAck(ssn, &ssn->client, TCP_GET_ACK(p));
+
             StreamTcpSackUpdatePacket(&ssn->client, p);
 
             /* update next_win */
@@ -4076,8 +4073,6 @@ static int StreamTcpPacketStateClosing(
                 ssn->client.window = TCP_GET_WINDOW(p) << ssn->client.wscale;
             }
 
-            StreamTcpUpdateLastAck(ssn, &ssn->server, TCP_GET_ACK(p));
-
             if (ssn->flags & STREAMTCP_FLAG_TIMESTAMP) {
                 StreamTcpHandleTimestamp(ssn, p);
             }
@@ -4086,6 +4081,8 @@ static int StreamTcpPacketStateClosing(
             if (SEQ_LT(ssn->server.next_seq, TCP_GET_ACK(p)))
                 ssn->server.next_seq = TCP_GET_ACK(p);
 
+            StreamTcpUpdateLastAck(ssn, &ssn->server, TCP_GET_ACK(p));
+
             StreamTcpReassembleHandleSegment(tv, stt->ra_ctx, ssn, &ssn->client, p);
             SCLogDebug("ssn %p: =+ next SEQ %" PRIu32 ", last ACK "
                     "%" PRIu32 "", ssn, ssn->client.next_seq,
@@ -4121,8 +4118,6 @@ static int StreamTcpPacketStateClosing(
                 ssn->client.window = TCP_GET_WINDOW(p) << ssn->client.wscale;
             }
 
-            StreamTcpUpdateLastAck(ssn, &ssn->client, TCP_GET_ACK(p));
-
             if (ssn->flags & STREAMTCP_FLAG_TIMESTAMP) {
                 StreamTcpHandleTimestamp(ssn, p);
             }
@@ -4132,6 +4127,8 @@ static int StreamTcpPacketStateClosing(
             if (SEQ_LT(ssn->client.next_seq, TCP_GET_ACK(p)))
                 ssn->client.next_seq = TCP_GET_ACK(p);
 
+            StreamTcpUpdateLastAck(ssn, &ssn->client, TCP_GET_ACK(p));
+
             StreamTcpReassembleHandleSegment(tv, stt->ra_ctx, ssn, &ssn->server, p);
             SCLogDebug("StreamTcpPacketStateClosing (%p): =+ next SEQ "
                     "%" PRIu32 ", last ACK %" PRIu32 "", ssn,
@@ -4245,9 +4242,6 @@ static int StreamTcpPacketStateCloseWait(
             if (!retransmission)
                 ssn->server.window = TCP_GET_WINDOW(p) << ssn->server.wscale;
 
-            if (p->tcph->th_flags & TH_ACK)
-                StreamTcpUpdateLastAck(ssn, &ssn->server, TCP_GET_ACK(p));
-
             if (ssn->flags & STREAMTCP_FLAG_TIMESTAMP) {
                 StreamTcpHandleTimestamp(ssn, p);
             }
@@ -4257,6 +4251,9 @@ static int StreamTcpPacketStateCloseWait(
             if (SEQ_LT(ssn->server.next_seq, TCP_GET_ACK(p)))
                 ssn->server.next_seq = TCP_GET_ACK(p);
 
+            if (p->tcph->th_flags & TH_ACK)
+                StreamTcpUpdateLastAck(ssn, &ssn->server, TCP_GET_ACK(p));
+
             StreamTcpReassembleHandleSegment(tv, stt->ra_ctx, ssn, &ssn->client, p);
             SCLogDebug("ssn %p: =+ next SEQ %" PRIu32 ", last ACK "
                     "%" PRIu32 "", ssn, ssn->client.next_seq,
@@ -4297,9 +4294,6 @@ static int StreamTcpPacketStateCloseWait(
                 ssn->client.window = TCP_GET_WINDOW(p) << ssn->client.wscale;
             }
 
-            if (p->tcph->th_flags & TH_ACK)
-                StreamTcpUpdateLastAck(ssn, &ssn->client, TCP_GET_ACK(p));
-
             if (ssn->flags & STREAMTCP_FLAG_TIMESTAMP) {
                 StreamTcpHandleTimestamp(ssn, p);
             }
@@ -4309,6 +4303,9 @@ static int StreamTcpPacketStateCloseWait(
             if (SEQ_LT(ssn->client.next_seq, TCP_GET_ACK(p)))
                 ssn->client.next_seq = TCP_GET_ACK(p);
 
+            if (p->tcph->th_flags & TH_ACK)
+                StreamTcpUpdateLastAck(ssn, &ssn->client, TCP_GET_ACK(p));
+
             StreamTcpReassembleHandleSegment(tv, stt->ra_ctx, ssn, &ssn->server, p);
             SCLogDebug("ssn %p: =+ next SEQ %" PRIu32 ", last ACK "
                     "%" PRIu32 "", ssn, ssn->server.next_seq,
@@ -4361,8 +4358,6 @@ static int StreamTcpPacketStateCloseWait(
                 ssn->server.window = TCP_GET_WINDOW(p) << ssn->server.wscale;
             }
 
-            StreamTcpUpdateLastAck(ssn, &ssn->server, TCP_GET_ACK(p));
-
             if (ssn->flags & STREAMTCP_FLAG_TIMESTAMP) {
                 StreamTcpHandleTimestamp(ssn, p);
             }
@@ -4375,6 +4370,8 @@ static int StreamTcpPacketStateCloseWait(
             if (SEQ_EQ(TCP_GET_SEQ(p),ssn->client.next_seq))
                 StreamTcpUpdateNextSeq(ssn, &ssn->client, (ssn->client.next_seq + p->payload_len));
 
+            StreamTcpUpdateLastAck(ssn, &ssn->server, TCP_GET_ACK(p));
+
             StreamTcpReassembleHandleSegment(tv, stt->ra_ctx, ssn, &ssn->client, p);
             SCLogDebug("ssn %p: =+ next SEQ %" PRIu32 ", last ACK "
                     "%" PRIu32 "", ssn, ssn->client.next_seq,
@@ -4413,8 +4410,6 @@ static int StreamTcpPacketStateCloseWait(
                 ssn->client.window = TCP_GET_WINDOW(p) << ssn->client.wscale;
             }
 
-            StreamTcpUpdateLastAck(ssn, &ssn->client, TCP_GET_ACK(p));
-
             if (ssn->flags & STREAMTCP_FLAG_TIMESTAMP) {
                 StreamTcpHandleTimestamp(ssn, p);
             }
@@ -4427,6 +4422,8 @@ static int StreamTcpPacketStateCloseWait(
             if (SEQ_EQ(TCP_GET_SEQ(p),ssn->server.next_seq))
                 StreamTcpUpdateNextSeq(ssn, &ssn->server, (ssn->server.next_seq + p->payload_len));
 
+            StreamTcpUpdateLastAck(ssn, &ssn->client, TCP_GET_ACK(p));
+
             StreamTcpReassembleHandleSegment(tv, stt->ra_ctx, ssn, &ssn->server, p);
             SCLogDebug("ssn %p: =+ next SEQ %" PRIu32 ", last ACK "
                     "%" PRIu32 "", ssn, ssn->server.next_seq,
@@ -4537,8 +4534,6 @@ static int StreamTcpPacketStateLastAck(
                 ssn->server.window = TCP_GET_WINDOW(p) << ssn->server.wscale;
             }
 
-            StreamTcpUpdateLastAck(ssn, &ssn->server, TCP_GET_ACK(p));
-
             if (ssn->flags & STREAMTCP_FLAG_TIMESTAMP) {
                 StreamTcpHandleTimestamp(ssn, p);
             }
@@ -4548,6 +4543,8 @@ static int StreamTcpPacketStateLastAck(
             if (SEQ_LT(ssn->server.next_seq, TCP_GET_ACK(p)))
                 ssn->server.next_seq = TCP_GET_ACK(p);
 
+            StreamTcpUpdateLastAck(ssn, &ssn->server, TCP_GET_ACK(p));
+
             StreamTcpReassembleHandleSegment(tv, stt->ra_ctx, ssn, &ssn->client, p);
             SCLogDebug("ssn %p: =+ next SEQ %" PRIu32 ", last ACK "
                     "%" PRIu32 "", ssn, ssn->client.next_seq,
@@ -4653,8 +4650,6 @@ static int StreamTcpPacketStateTimeWait(
                 ssn->server.window = TCP_GET_WINDOW(p) << ssn->server.wscale;
             }
 
-            StreamTcpUpdateLastAck(ssn, &ssn->server, TCP_GET_ACK(p));
-
             if (ssn->flags & STREAMTCP_FLAG_TIMESTAMP) {
                 StreamTcpHandleTimestamp(ssn, p);
             }
@@ -4664,6 +4659,8 @@ static int StreamTcpPacketStateTimeWait(
             if (SEQ_LT(ssn->server.next_seq, TCP_GET_ACK(p)))
                 ssn->server.next_seq = TCP_GET_ACK(p);
 
+            StreamTcpUpdateLastAck(ssn, &ssn->server, TCP_GET_ACK(p));
+
             StreamTcpReassembleHandleSegment(tv, stt->ra_ctx, ssn, &ssn->client, p);
             SCLogDebug("ssn %p: =+ next SEQ %" PRIu32 ", last ACK "
                     "%" PRIu32 "", ssn, ssn->client.next_seq,
@@ -4702,8 +4699,6 @@ static int StreamTcpPacketStateTimeWait(
                 ssn->client.window = TCP_GET_WINDOW(p) << ssn->client.wscale;
             }
 
-            StreamTcpUpdateLastAck(ssn, &ssn->client, TCP_GET_ACK(p));
-
             if (ssn->flags & STREAMTCP_FLAG_TIMESTAMP) {
                 StreamTcpHandleTimestamp(ssn, p);
             }
@@ -4713,6 +4708,8 @@ static int StreamTcpPacketStateTimeWait(
             if (SEQ_LT(ssn->client.next_seq, TCP_GET_ACK(p)))
                 ssn->client.next_seq = TCP_GET_ACK(p);
 
+            StreamTcpUpdateLastAck(ssn, &ssn->client, TCP_GET_ACK(p));
+
             StreamTcpReassembleHandleSegment(tv, stt->ra_ctx, ssn, &ssn->server, p);
             SCLogDebug("ssn %p: =+ next SEQ %" PRIu32 ", last ACK "
                     "%" PRIu32 "", ssn, ssn->server.next_seq,