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.
pull/8562/head
Victor Julien 3 years ago
parent 6a2fdc456b
commit d79a926085

@ -344,6 +344,8 @@ static int EveStreamLogger(ThreadVars *tv, void *thread_data, const Packet *p)
jb_append_string(js, "state_update");
if (p->tcpvars.stream_pkt_flags & STREAM_PKT_FLAG_DUP_ACK)
jb_append_string(js, "dup_ack");
if (p->tcpvars.stream_pkt_flags & STREAM_PKT_FLAG_DSACK)
jb_append_string(js, "dsack");
jb_close(js);
}
jb_close(js);

@ -307,6 +307,7 @@ typedef struct TcpSession_ {
#define STREAM_PKT_FLAG_WINDOWUPDATE BIT_U16(5)
#define STREAM_PKT_FLAG_EVENTSET BIT_U16(6)
#define STREAM_PKT_FLAG_DUP_ACK BIT_U16(7)
#define STREAM_PKT_FLAG_DSACK BIT_U16(8)
#define STREAM_PKT_FLAG_SET(p, f) (p)->tcpvars.stream_pkt_flags |= (f)

@ -259,12 +259,35 @@ 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));
STREAM_PKT_FLAG_SET(p, STREAM_PKT_FLAG_DSACK);
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));
STREAM_PKT_FLAG_SET(p, STREAM_PKT_FLAG_DSACK);
}
goto next;
}
if (SEQ_LEQ(re, stream->last_ack)) {
SCLogDebug("record before last_ack");

Loading…
Cancel
Save