]> git.ipfire.org Git - thirdparty/suricata.git/commitdiff
stream: D-SACK detection and logging
authorVictor Julien <vjulien@oisf.net>
Tue, 21 Feb 2023 09:47:13 +0000 (10:47 +0100)
committerVictor Julien <vjulien@oisf.net>
Thu, 2 Mar 2023 08:01:28 +0000 (09:01 +0100)
RFC 2883 specifies a special use of SACKs to indicate a host has
received a segment it considers a spurious retransmission.

(cherry picked from commit d79a926085ce66e0be4bb22ede1671928b6995fb)

src/stream-tcp-sack.c

index cb60c525b93c3bff98cee8eb6043dc373072374a..9b99828ec5895c834fec8b15c40e59835bcca641 100644 (file)
@@ -257,12 +257,33 @@ int StreamTcpSackUpdatePacket(TcpStream *stream, Packet *p)
     TCPOptSackRecord rec[records], *sack_rec = rec;
     memcpy(&rec, data, sizeof(TCPOptSackRecord) * records);
 
+    uint32_t first_le = 0;
+    uint32_t first_re = 0;
+
     for (int record = 0; record < records; record++) {
         const uint32_t le = SCNtohl(sack_rec->le);
         const uint32_t re = SCNtohl(sack_rec->re);
 
-        SCLogDebug("%p last_ack %u, left edge %u, right edge %u", sack_rec,
-            stream->last_ack, le, re);
+        if (!first_le)
+            first_le = le;
+        if (!first_re)
+            first_re = re;
+
+        SCLogDebug("%p last_ack %u, left edge %u, right edge %u pkt ACK %u", sack_rec,
+                stream->last_ack, le, re, TCP_GET_ACK(p));
+
+        /* RFC 2883 D-SACK */
+        if (SEQ_LT(le, TCP_GET_ACK(p))) {
+            SCLogDebug("packet: %" PRIu64 ": D-SACK? %u-%u before ACK %u", p->pcap_cnt, le, re,
+                    TCP_GET_ACK(p));
+            goto next;
+        } else if (record == 1) { // 2nd record
+            if (SEQ_GEQ(first_le, le) && SEQ_LEQ(first_re, re)) {
+                SCLogDebug("packet: %" PRIu64 ": D-SACK? %u-%u inside 2nd range %u-%u ACK %u",
+                        p->pcap_cnt, first_le, first_re, le, re, TCP_GET_ACK(p));
+            }
+            goto next;
+        }
 
         if (SEQ_LEQ(re, stream->last_ack)) {
             SCLogDebug("record before last_ack");