From: Victor Julien Date: Tue, 21 Feb 2023 09:47:13 +0000 (+0100) Subject: stream: D-SACK detection and logging X-Git-Tag: suricata-6.0.11~57 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=fee655bae6f0b9e7071437f4b2e37d68f5242537;p=thirdparty%2Fsuricata.git stream: D-SACK detection and logging 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) --- diff --git a/src/stream-tcp-sack.c b/src/stream-tcp-sack.c index cb60c525b9..9b99828ec5 100644 --- a/src/stream-tcp-sack.c +++ b/src/stream-tcp-sack.c @@ -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");