alert tcp any any -> any any (msg:"SURICATA STREAM ESTABLISHED SYN resend with different seq"; stream-event:est_syn_resend_diff_seq; classtype:protocol-command-decode; sid:2210027; rev:2;)
alert tcp any any -> any any (msg:"SURICATA STREAM ESTABLISHED SYN to client"; stream-event:est_syn_toclient; classtype:protocol-command-decode; sid:2210028; rev:2;)
alert tcp any any -> any any (msg:"SURICATA STREAM ESTABLISHED invalid ack"; stream-event:est_invalid_ack; classtype:protocol-command-decode; sid:2210029; rev:2;)
+
+# ACK received for Zero Window Probe segment.
+#alert tcp any any -> any any (msg:"SURICATA STREAM ESTABLISHED ack for ZWP data"; stream-event:est_invalid_ack; classtype:protocol-command-decode; sid:2210065; rev:1;)
+
alert tcp any any -> any any (msg:"SURICATA STREAM FIN invalid ack"; stream-event:fin_invalid_ack; classtype:protocol-command-decode; sid:2210030; rev:2;)
alert tcp any any -> any any (msg:"SURICATA STREAM FIN1 ack with wrong seq"; stream-event:fin1_ack_wrong_seq; classtype:protocol-command-decode; sid:2210031; rev:2;)
alert tcp any any -> any any (msg:"SURICATA STREAM FIN1 FIN with wrong seq"; stream-event:fin1_fin_wrong_seq; classtype:protocol-command-decode; sid:2210032; rev:2;)
# Depth setting reached for a stream. Very common in normal traffic, so disable by default.
#alert tcp any any -> any any (msg:"SURICATA STREAM reassembly depth reached"; stream-event:reassembly_depth_reached; classtype:protocol-command-decode; sid:2210062; rev:1;)
-# next sid 2210065
+# next sid 2210066
"ACK %" PRIu32 ", WIN %"PRIu16"", ssn, p->payload_len,
TCP_GET_SEQ(p), TCP_GET_ACK(p), TCP_GET_WINDOW(p));
- if (StreamTcpValidateAck(ssn, &(ssn->server), p) == -1) {
- SCLogDebug("ssn %p: rejecting because of invalid ack value", ssn);
- StreamTcpSetEvent(p, STREAM_EST_INVALID_ACK);
- return -1;
+ const bool has_ack = (p->tcph->th_flags & TH_ACK) != 0;
+ if (has_ack) {
+ if ((ssn->flags & STREAMTCP_FLAG_ZWP_TC) && TCP_GET_ACK(p) == ssn->server.next_seq + 1) {
+ SCLogDebug("ssn %p: accepting ACK as it ACKs the one byte from the ZWP", ssn);
+ StreamTcpSetEvent(p, STREAM_EST_ACK_ZWP_DATA);
+
+ } else if (StreamTcpValidateAck(ssn, &ssn->server, p) == -1) {
+ SCLogDebug("ssn %p: rejecting because of invalid ack value", ssn);
+ StreamTcpSetEvent(p, STREAM_EST_INVALID_ACK);
+ return -1;
+ }
}
/* check for Keep Alive */
SCLogDebug("ssn %p: zero window probe", ssn);
zerowindowprobe = 1;
STREAM_PKT_FLAG_SET(p, STREAM_PKT_FLAG_TCP_ZERO_WIN_PROBE);
+ ssn->flags |= STREAMTCP_FLAG_ZWP_TS;
+ StreamTcpReassembleHandleSegment(tv, stt->ra_ctx, ssn, &ssn->client, p);
} else if (SEQ_GEQ(TCP_GET_SEQ(p) + p->payload_len, ssn->client.next_seq)) {
StreamTcpUpdateNextSeq(ssn, &ssn->client, (TCP_GET_SEQ(p) + p->payload_len));
" ACK %" PRIu32 ", WIN %"PRIu16"", ssn, p->payload_len,
TCP_GET_SEQ(p), TCP_GET_ACK(p), TCP_GET_WINDOW(p));
- if (StreamTcpValidateAck(ssn, &ssn->client, p) == -1) {
- SCLogDebug("ssn %p: rejecting because of invalid ack value", ssn);
- StreamTcpSetEvent(p, STREAM_EST_INVALID_ACK);
- return -1;
+ const bool has_ack = (p->tcph->th_flags & TH_ACK) != 0;
+ if (has_ack) {
+ if ((ssn->flags & STREAMTCP_FLAG_ZWP_TS) && TCP_GET_ACK(p) == ssn->client.next_seq + 1) {
+ SCLogDebug("ssn %p: accepting ACK as it ACKs the one byte from the ZWP", ssn);
+ StreamTcpSetEvent(p, STREAM_EST_ACK_ZWP_DATA);
+
+ } else if (StreamTcpValidateAck(ssn, &ssn->client, p) == -1) {
+ SCLogDebug("ssn %p: rejecting because of invalid ack value", ssn);
+ StreamTcpSetEvent(p, STREAM_EST_INVALID_ACK);
+ return -1;
+ }
}
/* To get the server window value from the servers packet, when connection
SCLogDebug("ssn %p: zero window probe", ssn);
zerowindowprobe = 1;
STREAM_PKT_FLAG_SET(p, STREAM_PKT_FLAG_TCP_ZERO_WIN_PROBE);
+ ssn->flags |= STREAMTCP_FLAG_ZWP_TC;
+
+ /* accept the segment */
+ StreamTcpReassembleHandleSegment(tv, stt->ra_ctx, ssn, &ssn->server, p);
} else if (SEQ_GEQ(TCP_GET_SEQ(p) + p->payload_len, ssn->server.next_seq)) {
StreamTcpUpdateNextSeq(ssn, &ssn->server, (TCP_GET_SEQ(p) + p->payload_len));