[7/7] suricata: Handle retransmitted SYN with TSval
Commit Message
Read more in the patch.
Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>
---
lfs/suricata | 1 +
...-Handle-retransmitted-SYN-with-TSval.patch | 55 +++++++++++++++++++
2 files changed, 56 insertions(+)
create mode 100644 src/patches/suricata-5.0-stream-tcp-Handle-retransmitted-SYN-with-TSval.patch
@@ -70,6 +70,7 @@ $(subst %,%_MD5,$(objects)) :
$(TARGET) : $(patsubst %,$(DIR_DL)/%,$(objects))
@$(PREBUILD)
@rm -rf $(DIR_APP) && cd $(DIR_SRC) && tar zxf $(DIR_DL)/$(DL_FILE)
+ cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/suricata-5.0-stream-tcp-Handle-retransmitted-SYN-with-TSval.patch
cd $(DIR_APP) && LDFLAGS="$(LDFLAGS)" ./configure \
--prefix=/usr \
--sysconfdir=/etc \
new file mode 100644
@@ -0,0 +1,55 @@
+From 511648b3d7a4b5a5b4d55b92dffd63fcb23903a0 Mon Sep 17 00:00:00 2001
+From: Michael Tremer <michael.tremer@ipfire.org>
+Date: Fri, 19 Nov 2021 17:17:47 +0000
+Subject: [PATCH] stream: tcp: Handle retransmitted SYN with TSval
+
+For connections that use TCP timestamps for which the first SYN packet
+does not reach the server, any replies to retransmitted SYNs will be
+tropped.
+
+This is happening in StateSynSentValidateTimestamp, where the timestamp
+value in a SYN-ACK packet must match the one from the SYN packet.
+However, since the server never received the first SYN packet, it will
+respond with an updated timestamp from any of the following SYN packets.
+
+The timestamp value inside suricata is not being updated at any time
+which should happen. This patch fixes that problem.
+
+This problem was introduced in 9f0294fadca3dcc18c919424242a41e01f3e8318.
+
+Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>
+---
+ src/stream-tcp.c | 17 +++++++++++++++++
+ 1 file changed, 17 insertions(+)
+
+diff --git a/src/stream-tcp.c b/src/stream-tcp.c
+index 1cff19fa5..af681760b 100644
+--- a/src/stream-tcp.c
++++ b/src/stream-tcp.c
+@@ -1643,6 +1643,23 @@ static int StreamTcpPacketStateSynSent(ThreadVars *tv, Packet *p,
+ "ssn->client.last_ack %"PRIu32"", ssn,
+ ssn->client.isn, ssn->client.next_seq,
+ ssn->client.last_ack);
++ } else if (PKT_IS_TOSERVER(p)) {
++ /*
++ * On retransmitted SYN packets, the timestamp value must be updated,
++ * to avoid dropping any SYN+ACK packets that respond to a retransmitted SYN
++ * with an updated timestamp in StateSynSentValidateTimestamp.
++ */
++ if ((ssn->client.flags & STREAMTCP_STREAM_FLAG_TIMESTAMP) && TCP_HAS_TS(p)) {
++ uint32_t ts_val = TCP_GET_TSVAL(p);
++
++ // Check whether packets have been received in the correct order (only ever update)
++ if (ssn->client.last_ts < ts_val) {
++ ssn->client.last_ts = ts_val;
++ ssn->client.last_pkt_ts = p->ts.tv_sec;
++ }
++
++ SCLogDebug("ssn %p: Retransmitted SYN. Updated timestamp from packet %"PRIu64, ssn, p->pcap_cnt);
++ }
+ }
+
+ /** \todo check if it's correct or set event */
+--
+2.30.2
+