alert tcp any any -> any any (msg:"SURICATA STREAM 3way handshake SYNACK with wrong ack"; stream-event:3whs_synack_with_wrong_ack; classtype:protocol-command-decode; sid:2210007; rev:2;)
# Excessive SYN/ACKs within a session. Limit is set in stream engine, "stream.max-synack-queued".
alert tcp any any -> any any (msg:"SURICATA STREAM 3way handshake excessive different SYN/ACKs"; stream-event:3whs_synack_flood; classtype:protocol-command-decode; sid:2210055; rev:2;)
+# Client sent an SYN packet with TCP fast open and data, but the server only ACK'd
+# the SYN, not the data, while still supporting TFO.
+alert tcp any any -> any any (msg:"SURICATA STREAM 3way handshake SYN/ACK ignored TFO data"; stream-event:3whs_synack_tfo_data_ignored; classtype:protocol-command-decode; sid:2210064; rev:1;)
alert tcp any any -> any any (msg:"SURICATA STREAM 3way handshake SYN resend different seq on SYN recv"; stream-event:3whs_syn_resend_diff_seq_on_syn_recv; classtype:protocol-command-decode; sid:2210008; rev:2;)
alert tcp any any -> any any (msg:"SURICATA STREAM 3way handshake SYN to client on SYN recv"; stream-event:3whs_syn_toclient_on_syn_recv; classtype:protocol-command-decode; sid:2210009; rev:2;)
alert tcp any any -> any any (msg:"SURICATA STREAM 3way handshake wrong seq wrong ack"; stream-event:3whs_wrong_seq_wrong_ack; classtype:protocol-command-decode; sid:2210010; rev:2;)
# Packet with FIN+SYN set
alert tcp any any -> any any (msg:"SURICATA STREAM FIN SYN reuse"; stream-event:fin_syn; classtype:protocol-command-decode; sid:2210060; rev:1;)
-# next sid 2210061
+# next sid 2210065
"stream.3whs_synack_flood",
STREAM_3WHS_SYNACK_FLOOD,
},
+ {
+ "stream.3whs_synack_tfo_data_ignored",
+ STREAM_3WHS_SYNACK_TFO_DATA_IGNORED,
+ },
{
"stream.3whs_syn_resend_diff_seq_on_syn_recv",
STREAM_3WHS_SYN_RESEND_DIFF_SEQ_ON_SYN_RECV,
STREAM_3WHS_SYNACK_TOSERVER_ON_SYN_RECV,
STREAM_3WHS_SYNACK_WITH_WRONG_ACK,
STREAM_3WHS_SYNACK_FLOOD,
+ STREAM_3WHS_SYNACK_TFO_DATA_IGNORED,
STREAM_3WHS_SYN_RESEND_DIFF_SEQ_ON_SYN_RECV,
STREAM_3WHS_SYN_TOCLIENT_ON_SYN_RECV,
STREAM_3WHS_WRONG_SEQ_WRONG_ACK,
return -1;
}
} else {
- if (!(SEQ_EQ(TCP_GET_ACK(p), ssn->client.next_seq))) {
+ if (SEQ_EQ(TCP_GET_ACK(p), ssn->client.next_seq)) {
+ SCLogDebug("ssn %p: (TFO) ACK matches next_seq, packet ACK %" PRIu32 " == "
+ "%" PRIu32 " from stream",
+ ssn, TCP_GET_ACK(p), ssn->client.next_seq);
+ } else if (SEQ_EQ(TCP_GET_ACK(p), ssn->client.isn + 1)) {
+ SCLogDebug("ssn %p: (TFO) ACK matches ISN+1, packet ACK %" PRIu32 " == "
+ "%" PRIu32 " from stream",
+ ssn, TCP_GET_ACK(p), ssn->client.isn + 1);
+ ssn->client.next_seq = ssn->client.isn;
+ SCLogDebug("ssn %p: (TFO) next_seq reset to isn (%u)", ssn, ssn->client.next_seq);
+ StreamTcpSetEvent(p, STREAM_3WHS_SYNACK_TFO_DATA_IGNORED);
+ } else {
StreamTcpSetEvent(p, STREAM_3WHS_SYNACK_WITH_WRONG_ACK);
SCLogDebug("ssn %p: (TFO) ACK mismatch, packet ACK %" PRIu32 " != "
"%" PRIu32 " from stream", ssn, TCP_GET_ACK(p),
ssn->client.next_seq);
return -1;
}
- SCLogDebug("ssn %p: (TFO) ACK match, packet ACK %" PRIu32 " == "
- "%" PRIu32 " from stream", ssn, TCP_GET_ACK(p),
- ssn->client.next_seq);
-
ssn->flags |= STREAMTCP_FLAG_TCP_FAST_OPEN;
StreamTcpPacketSetState(p, ssn, TCP_ESTABLISHED);
}