From 0ebe372607c0f7c555b6699cba469d40a4c0e38f Mon Sep 17 00:00:00 2001 From: Victor Julien Date: Sun, 28 Nov 2021 19:20:58 +0100 Subject: [PATCH] stream: after missing segments, be liberal on RST This avoids long lasting inactive flows because in the most likely case the RST did in fact end the connection. However Suricata may still consider it to be "established". --- src/stream-tcp-list.c | 3 +++ src/stream-tcp-private.h | 1 + src/stream-tcp-reassemble.c | 9 ++++++++- src/stream-tcp.c | 4 ++++ 4 files changed, 16 insertions(+), 1 deletion(-) diff --git a/src/stream-tcp-list.c b/src/stream-tcp-list.c index 5ead97834e..7dde2b0ea9 100644 --- a/src/stream-tcp-list.c +++ b/src/stream-tcp-list.c @@ -651,6 +651,9 @@ int StreamTcpReassembleInsertSegment(ThreadVars *tv, TcpReassemblyThreadCtx *ra_ StatsIncr(tv, ra_ctx->counter_tcp_reass_data_normal_fail); StreamTcpRemoveSegmentFromStream(stream, seg); StreamTcpSegmentReturntoPool(seg); + if (res == -1) { + SCReturnInt(-ENOMEM); + } SCReturnInt(-1); } diff --git a/src/stream-tcp-private.h b/src/stream-tcp-private.h index 8f35c8264b..8cc1cfca39 100644 --- a/src/stream-tcp-private.h +++ b/src/stream-tcp-private.h @@ -283,6 +283,7 @@ typedef struct TcpSession_ { /* coccinelle: TcpSession:flags:STREAMTCP_FLAG */ uint16_t flags; uint32_t reassembly_depth; /**< reassembly depth for the stream */ + bool lossy_be_liberal; TcpStream server; TcpStream client; TcpStateQueue *queue; /**< list of SYN/ACK candidates */ diff --git a/src/stream-tcp-reassemble.c b/src/stream-tcp-reassemble.c index a986e27248..d3de6c054e 100644 --- a/src/stream-tcp-reassemble.c +++ b/src/stream-tcp-reassemble.c @@ -748,6 +748,7 @@ int StreamTcpReassembleHandleSegmentHandleData(ThreadVars *tv, TcpReassemblyThre if (seg == NULL) { SCLogDebug("segment_pool is empty"); StreamTcpSetEvent(p, STREAM_REASSEMBLY_NO_SEGMENT); + ssn->lossy_be_liberal = true; SCReturnInt(-1); } @@ -767,7 +768,12 @@ int StreamTcpReassembleHandleSegmentHandleData(ThreadVars *tv, TcpReassemblyThre APPLAYER_PROTO_DETECTION_SKIPPED); } - if (StreamTcpReassembleInsertSegment(tv, ra_ctx, stream, seg, p, TCP_GET_SEQ(p), p->payload, p->payload_len) != 0) { + int r = StreamTcpReassembleInsertSegment( + tv, ra_ctx, stream, seg, p, TCP_GET_SEQ(p), p->payload, p->payload_len); + if (r < 0) { + if (r == -ENOMEM) { + ssn->lossy_be_liberal = true; + } SCLogDebug("StreamTcpReassembleInsertSegment failed"); SCReturnInt(-1); } @@ -1204,6 +1210,7 @@ static int ReassembleUpdateAppLayer (ThreadVars *tv, StreamTcpSetEvent(p, STREAM_REASSEMBLY_SEQ_GAP); StatsIncr(tv, ra_ctx->counter_tcp_reass_gap); + ssn->lossy_be_liberal = true; /* AppLayerHandleTCPData has likely updated progress. */ const bool no_progress_update = (app_progress == STREAM_APP_PROGRESS(*stream)); diff --git a/src/stream-tcp.c b/src/stream-tcp.c index f083fe1af1..41e2473e2a 100644 --- a/src/stream-tcp.c +++ b/src/stream-tcp.c @@ -5468,6 +5468,10 @@ static int StreamTcpValidateRst(TcpSession *ssn, Packet *p) { uint8_t os_policy; + if (ssn->lossy_be_liberal) { + SCReturnInt(1); + } + if (ssn->flags & STREAMTCP_FLAG_TIMESTAMP) { if (!StreamTcpValidateTimestamp(ssn, p)) { SCReturnInt(0);