stream: change how retransmissions are handled and detected.

pull/141/merge
Victor Julien 13 years ago
parent b621ed8423
commit e1321f9ae6

@ -20,12 +20,9 @@ alert tcp any any -> any any (msg:"SURICATA STREAM 4way handshake invalid ack";
alert tcp any any -> any any (msg:"SURICATA STREAM CLOSEWAIT ACK out of window"; stream-event:closewait_ack_out_of_window; sid:2210015; rev:1;) alert tcp any any -> any any (msg:"SURICATA STREAM CLOSEWAIT ACK out of window"; stream-event:closewait_ack_out_of_window; sid:2210015; rev:1;)
alert tcp any any -> any any (msg:"SURICATA STREAM CLOSEWAIT FIN out of window"; stream-event:closewait_fin_out_of_window; sid:2210016; rev:1;) alert tcp any any -> any any (msg:"SURICATA STREAM CLOSEWAIT FIN out of window"; stream-event:closewait_fin_out_of_window; sid:2210016; rev:1;)
alert tcp any any -> any any (msg:"SURICATA STREAM CLOSEWAIT invalid ACK"; stream-event:closewait_invalid_ack; sid:2210017; rev:1;) alert tcp any any -> any any (msg:"SURICATA STREAM CLOSEWAIT invalid ACK"; stream-event:closewait_invalid_ack; sid:2210017; rev:1;)
#alert tcp any any -> any any (msg:"SURICATA STREAM CLOSEWAIT retransmission packet before last ack"; stream-event:closewait_pkt_before_last_ack; sid:2210052; rev:2;)
alert tcp any any -> any any (msg:"SURICATA STREAM CLOSING ACK wrong seq"; stream-event:closing_ack_wrong_seq; sid:2210018; rev:1;) alert tcp any any -> any any (msg:"SURICATA STREAM CLOSING ACK wrong seq"; stream-event:closing_ack_wrong_seq; sid:2210018; rev:1;)
alert tcp any any -> any any (msg:"SURICATA STREAM CLOSING invalid ACK"; stream-event:closing_invalid_ack; sid:2210019; rev:1;) alert tcp any any -> any any (msg:"SURICATA STREAM CLOSING invalid ACK"; stream-event:closing_invalid_ack; sid:2210019; rev:1;)
alert tcp any any -> any any (msg:"SURICATA STREAM ESTABLISHED packet out of window"; stream-event:est_packet_out_of_window; sid:2210020; rev:1;) alert tcp any any -> any any (msg:"SURICATA STREAM ESTABLISHED packet out of window"; stream-event:est_packet_out_of_window; sid:2210020; rev:1;)
# "regular" retransmissions
#alert tcp any any -> any any (msg:"SURICATA STREAM ESTABLISHED retransmission packet before last ack"; stream-event:est_pkt_before_last_ack; sid:2210021; rev:2;)
alert tcp any any -> any any (msg:"SURICATA STREAM ESTABLISHED SYNACK resend"; stream-event:est_synack_resend; sid:2210022; rev:1;) alert tcp any any -> any any (msg:"SURICATA STREAM ESTABLISHED SYNACK resend"; stream-event:est_synack_resend; sid:2210022; rev:1;)
alert tcp any any -> any any (msg:"SURICATA STREAM ESTABLISHED SYNACK resend with different ACK"; stream-event:est_synack_resend_with_different_ack; sid:2210023; rev:1;) alert tcp any any -> any any (msg:"SURICATA STREAM ESTABLISHED SYNACK resend with different ACK"; stream-event:est_synack_resend_with_different_ack; sid:2210023; rev:1;)
alert tcp any any -> any any (msg:"SURICATA STREAM ESTABLISHED SYNACK resend with different seq"; stream-event:est_synack_resend_with_diff_seq; sid:2210024; rev:1;) alert tcp any any -> any any (msg:"SURICATA STREAM ESTABLISHED SYNACK resend with different seq"; stream-event:est_synack_resend_with_diff_seq; sid:2210024; rev:1;)
@ -58,9 +55,27 @@ alert tcp any any -> any any (msg:"SURICATA STREAM Packet with invalid ack"; str
alert tcp any any -> any any (msg:"SURICATA STREAM SHUTDOWN RST invalid ack"; stream-event:rst_invalid_ack; sid:2210046; rev:1;) alert tcp any any -> any any (msg:"SURICATA STREAM SHUTDOWN RST invalid ack"; stream-event:rst_invalid_ack; sid:2210046; rev:1;)
# SYN (re)send during shutdown (closing, closewait, finwait1, finwait2, lastack, timewait states) # SYN (re)send during shutdown (closing, closewait, finwait1, finwait2, lastack, timewait states)
#alert tcp any any -> any any (msg:"SURICATA STREAM SYN resend"; stream-event:shutdown_syn_resend; sid:2210049; rev:1;) #alert tcp any any -> any any (msg:"SURICATA STREAM SYN resend"; stream-event:shutdown_syn_resend; sid:2210049; rev:1;)
#alert tcp any any -> any any (msg:"SURICATA STREAM reassembly segment before base seq"; stream-event:reassembly_segment_before_base_seq; sid:2210047; rev:1;)
# Sequence gap: missing data in the reassembly engine. Usually due to packet loss. Will be very noisy on a overloaded link / sensor. # Sequence gap: missing data in the reassembly engine. Usually due to packet loss. Will be very noisy on a overloaded link / sensor.
#alert tcp any any -> any any (msg:"SURICATA STREAM reassembly sequence GAP -- missing packet(s)"; stream-event:reassembly_seq_gap; sid:2210048; rev:1;) #alert tcp any any -> any any (msg:"SURICATA STREAM reassembly sequence GAP -- missing packet(s)"; stream-event:reassembly_seq_gap; sid:2210048; rev:1;)
alert tcp any any -> any any (msg:"SURICATA STREAM reassembly overlap with different data"; stream-event:reassembly_overlap_different_data; sid:2210050; rev:1;) alert tcp any any -> any any (msg:"SURICATA STREAM reassembly overlap with different data"; stream-event:reassembly_overlap_different_data; sid:2210050; rev:1;)
# next sid 2210053
# retransmission detection
#
# The rules below match on retransmissions detected in various stages of the
# stream engine. They are all "noalert" rules that increment the counter
# tcp.retransmission.count. The last rule sid:2210054 matches if the counter
# reaches 10. Increase this number if the rule is too noisy.
#
# "regular" retransmissions, only count
alert tcp any any -> any any (msg:"SURICATA STREAM ESTABLISHED retransmission packet before last ack"; stream-event:est_pkt_before_last_ack; flowint:tcp.retransmission.count,+,1; noalert; classtype:protocol-command-decode; sid:2210021; rev:3;)
# retransmission, only count
alert tcp any any -> any any (msg:"SURICATA STREAM CLOSEWAIT retransmission packet before last ack"; stream-event:closewait_pkt_before_last_ack; flowint:tcp.retransmission.count,+,1; noalert; classtype:protocol-command-decode; sid:2210052; rev:3;)
# retransmission of pkt before reassembly window, only count
alert tcp any any -> any any (msg:"SURICATA STREAM reassembly segment before base seq (retransmission)"; stream-event:reassembly_segment_before_base_seq; flowint:tcp.retransmission.count,+,1; noalert; classtype:protocol-command-decode; sid:2210047; rev:2;)
# count "general" retransmissions
alert tcp any any -> any any (msg:"SURICATA STREAM Packet is retransmission"; stream-event:pkt_retransmission; flowint:tcp.retransmission.count,+,1; noalert; classtype:protocol-command-decode; sid:2210053; rev:1;)
# rule to alert if a stream has excessive retransmissions
alert tcp any any -> any any (msg:"SURICATA STREAM excessive retransmissions"; flowbits:isnotset,tcp.retransmission.alerted; flowint:tcp.retransmission.count,>=,10; flowbits:set,tcp.retransmission.alerted; classtype:protocol-command-decode; sid:2210054; rev:1;)
# next sid 2210055

@ -179,6 +179,7 @@ enum {
STREAM_PKT_INVALID_ACK, STREAM_PKT_INVALID_ACK,
STREAM_PKT_BROKEN_ACK, STREAM_PKT_BROKEN_ACK,
STREAM_RST_INVALID_ACK, STREAM_RST_INVALID_ACK,
STREAM_PKT_RETRANSMISSION,
STREAM_REASSEMBLY_SEGMENT_BEFORE_BASE_SEQ, STREAM_REASSEMBLY_SEGMENT_BEFORE_BASE_SEQ,
STREAM_REASSEMBLY_NO_SEGMENT, STREAM_REASSEMBLY_NO_SEGMENT,

@ -170,6 +170,7 @@ struct DetectEngineEvents_ {
{ "stream.pkt_broken_ack", STREAM_PKT_BROKEN_ACK, }, { "stream.pkt_broken_ack", STREAM_PKT_BROKEN_ACK, },
{ "stream.rst_invalid_ack", STREAM_RST_INVALID_ACK, }, { "stream.rst_invalid_ack", STREAM_RST_INVALID_ACK, },
{ "stream.shutdown_syn_resend", STREAM_SHUTDOWN_SYN_RESEND, }, { "stream.shutdown_syn_resend", STREAM_SHUTDOWN_SYN_RESEND, },
{ "stream.pkt_retransmission", STREAM_PKT_RETRANSMISSION, },
{ "stream.reassembly_segment_before_base_seq", STREAM_REASSEMBLY_SEGMENT_BEFORE_BASE_SEQ, }, { "stream.reassembly_segment_before_base_seq", STREAM_REASSEMBLY_SEGMENT_BEFORE_BASE_SEQ, },
{ "stream.reassembly_no_segment", STREAM_REASSEMBLY_NO_SEGMENT, }, { "stream.reassembly_no_segment", STREAM_REASSEMBLY_NO_SEGMENT, },
{ "stream.reassembly_seq_gap", STREAM_REASSEMBLY_SEQ_GAP, }, { "stream.reassembly_seq_gap", STREAM_REASSEMBLY_SEQ_GAP, },

@ -636,6 +636,27 @@ void StreamTcpSetOSPolicy(TcpStream *stream, Packet *p)
} \ } \
} }
static int StreamTcpPacketIsRetransmission(TcpStream *stream, Packet *p) {
if (p->payload_len == 0)
SCReturnInt(0);
/* retransmission of already ack'd data */
if (SEQ_LEQ((TCP_GET_SEQ(p) + p->payload_len), stream->last_ack)) {
StreamTcpSetEvent(p, STREAM_PKT_RETRANSMISSION);
SCReturnInt(1);
}
/* retransmission of in flight data */
if (SEQ_LEQ((TCP_GET_SEQ(p) + p->payload_len), stream->next_seq)) {
StreamTcpSetEvent(p, STREAM_PKT_RETRANSMISSION);
SCReturnInt(2);
}
SCLogDebug("seq %u payload_len %u => %u, last_ack %u", TCP_GET_SEQ(p),
p->payload_len, (TCP_GET_SEQ(p) + p->payload_len), stream->last_ack);
SCReturnInt(0);
}
/** /**
* \internal * \internal
* \brief Function to handle the TCP_CLOSED or NONE state. The function handles * \brief Function to handle the TCP_CLOSED or NONE state. The function handles
@ -2258,8 +2279,13 @@ static int StreamTcpPacketStateFinWait1(ThreadVars *tv, Packet *p,
SCLogDebug("ssn %p: pkt (%" PRIu32 ") is to server: SEQ " SCLogDebug("ssn %p: pkt (%" PRIu32 ") is to server: SEQ "
"%" PRIu32 ", ACK %" PRIu32 "", ssn, p->payload_len, "%" PRIu32 ", ACK %" PRIu32 "", ssn, p->payload_len,
TCP_GET_SEQ(p), TCP_GET_ACK(p)); TCP_GET_SEQ(p), TCP_GET_ACK(p));
int retransmission = 0;
if (SEQ_LT(TCP_GET_SEQ(p), ssn->client.next_seq) || if (StreamTcpPacketIsRetransmission(&ssn->client, p)) {
SCLogDebug("ssn %p: packet is retransmission", ssn);
retransmission = 1;
} else if (SEQ_LT(TCP_GET_SEQ(p), ssn->client.next_seq) ||
SEQ_GT(TCP_GET_SEQ(p), (ssn->client.last_ack + ssn->client.window))) SEQ_GT(TCP_GET_SEQ(p), (ssn->client.last_ack + ssn->client.window)))
{ {
SCLogDebug("ssn %p: -> SEQ mismatch, packet SEQ %" PRIu32 "" SCLogDebug("ssn %p: -> SEQ mismatch, packet SEQ %" PRIu32 ""
@ -2275,11 +2301,13 @@ static int StreamTcpPacketStateFinWait1(ThreadVars *tv, Packet *p,
return -1; return -1;
} }
StreamTcpPacketSetState(p, ssn, TCP_TIME_WAIT); if (!retransmission) {
ssn->client.flags |= STREAMTCP_STREAM_FLAG_CLOSE_INITIATED; StreamTcpPacketSetState(p, ssn, TCP_TIME_WAIT);
SCLogDebug("ssn %p: state changed to TCP_TIME_WAIT", ssn); ssn->client.flags |= STREAMTCP_STREAM_FLAG_CLOSE_INITIATED;
SCLogDebug("ssn %p: state changed to TCP_TIME_WAIT", ssn);
ssn->server.window = TCP_GET_WINDOW(p) << ssn->server.wscale; ssn->server.window = TCP_GET_WINDOW(p) << ssn->server.wscale;
}
StreamTcpUpdateLastAck(ssn, &ssn->server, TCP_GET_ACK(p)); StreamTcpUpdateLastAck(ssn, &ssn->server, TCP_GET_ACK(p));
@ -2308,8 +2336,13 @@ static int StreamTcpPacketStateFinWait1(ThreadVars *tv, Packet *p,
SCLogDebug("ssn %p: pkt (%" PRIu32 ") is to client: SEQ " SCLogDebug("ssn %p: pkt (%" PRIu32 ") is to client: SEQ "
"%" PRIu32 ", ACK %" PRIu32 "", ssn, p->payload_len, "%" PRIu32 ", ACK %" PRIu32 "", ssn, p->payload_len,
TCP_GET_SEQ(p), TCP_GET_ACK(p)); TCP_GET_SEQ(p), TCP_GET_ACK(p));
int retransmission = 0;
if (SEQ_LT(TCP_GET_SEQ(p), ssn->server.next_seq) || if (StreamTcpPacketIsRetransmission(&ssn->server, p)) {
SCLogDebug("ssn %p: packet is retransmission", ssn);
retransmission = 1;
} else if (SEQ_LT(TCP_GET_SEQ(p), ssn->server.next_seq) ||
SEQ_GT(TCP_GET_SEQ(p), (ssn->server.last_ack + ssn->server.window))) SEQ_GT(TCP_GET_SEQ(p), (ssn->server.last_ack + ssn->server.window)))
{ {
SCLogDebug("ssn %p: -> SEQ mismatch, packet SEQ %" PRIu32 "" SCLogDebug("ssn %p: -> SEQ mismatch, packet SEQ %" PRIu32 ""
@ -2325,11 +2358,13 @@ static int StreamTcpPacketStateFinWait1(ThreadVars *tv, Packet *p,
return -1; return -1;
} }
StreamTcpPacketSetState(p, ssn, TCP_TIME_WAIT); if (!retransmission) {
ssn->server.flags |= STREAMTCP_STREAM_FLAG_CLOSE_INITIATED; StreamTcpPacketSetState(p, ssn, TCP_TIME_WAIT);
SCLogDebug("ssn %p: state changed to TCP_TIME_WAIT", ssn); ssn->server.flags |= STREAMTCP_STREAM_FLAG_CLOSE_INITIATED;
SCLogDebug("ssn %p: state changed to TCP_TIME_WAIT", ssn);
ssn->client.window = TCP_GET_WINDOW(p) << ssn->client.wscale; ssn->client.window = TCP_GET_WINDOW(p) << ssn->client.wscale;
}
StreamTcpUpdateLastAck(ssn, &ssn->client, TCP_GET_ACK(p)); StreamTcpUpdateLastAck(ssn, &ssn->client, TCP_GET_ACK(p));
@ -2366,8 +2401,13 @@ static int StreamTcpPacketStateFinWait1(ThreadVars *tv, Packet *p,
SCLogDebug("ssn %p: pkt (%" PRIu32 ") is to server: SEQ " SCLogDebug("ssn %p: pkt (%" PRIu32 ") is to server: SEQ "
"%" PRIu32 ", ACK %" PRIu32 "", ssn, p->payload_len, "%" PRIu32 ", ACK %" PRIu32 "", ssn, p->payload_len,
TCP_GET_SEQ(p), TCP_GET_ACK(p)); TCP_GET_SEQ(p), TCP_GET_ACK(p));
int retransmission = 0;
if (SEQ_LT(TCP_GET_SEQ(p), ssn->client.next_seq) || if (StreamTcpPacketIsRetransmission(&ssn->client, p)) {
SCLogDebug("ssn %p: packet is retransmission", ssn);
retransmission = 1;
} else if (SEQ_LT(TCP_GET_SEQ(p), ssn->client.next_seq) ||
SEQ_GT(TCP_GET_SEQ(p), (ssn->client.last_ack + ssn->client.window))) SEQ_GT(TCP_GET_SEQ(p), (ssn->client.last_ack + ssn->client.window)))
{ {
SCLogDebug("ssn %p: -> SEQ mismatch, packet SEQ %" PRIu32 "" SCLogDebug("ssn %p: -> SEQ mismatch, packet SEQ %" PRIu32 ""
@ -2383,11 +2423,13 @@ static int StreamTcpPacketStateFinWait1(ThreadVars *tv, Packet *p,
return -1; return -1;
} }
StreamTcpPacketSetState(p, ssn, TCP_CLOSING); if (!retransmission) {
ssn->client.flags |= STREAMTCP_STREAM_FLAG_CLOSE_INITIATED; StreamTcpPacketSetState(p, ssn, TCP_CLOSING);
SCLogDebug("ssn %p: state changed to TCP_CLOSING", ssn); ssn->client.flags |= STREAMTCP_STREAM_FLAG_CLOSE_INITIATED;
SCLogDebug("ssn %p: state changed to TCP_CLOSING", ssn);
ssn->server.window = TCP_GET_WINDOW(p) << ssn->server.wscale; ssn->server.window = TCP_GET_WINDOW(p) << ssn->server.wscale;
}
StreamTcpUpdateLastAck(ssn, &ssn->server, TCP_GET_ACK(p)); StreamTcpUpdateLastAck(ssn, &ssn->server, TCP_GET_ACK(p));
@ -2417,7 +2459,13 @@ static int StreamTcpPacketStateFinWait1(ThreadVars *tv, Packet *p,
"%" PRIu32 ", ACK %" PRIu32 "", ssn, p->payload_len, "%" PRIu32 ", ACK %" PRIu32 "", ssn, p->payload_len,
TCP_GET_SEQ(p), TCP_GET_ACK(p)); TCP_GET_SEQ(p), TCP_GET_ACK(p));
if (SEQ_LT(TCP_GET_SEQ(p), ssn->server.next_seq) || int retransmission = 0;
if (StreamTcpPacketIsRetransmission(&ssn->server, p)) {
SCLogDebug("ssn %p: packet is retransmission", ssn);
retransmission = 1;
} else if (SEQ_LT(TCP_GET_SEQ(p), ssn->server.next_seq) ||
SEQ_GT(TCP_GET_SEQ(p), (ssn->server.last_ack + ssn->server.window))) SEQ_GT(TCP_GET_SEQ(p), (ssn->server.last_ack + ssn->server.window)))
{ {
SCLogDebug("ssn %p: -> SEQ mismatch, packet SEQ %" PRIu32 "" SCLogDebug("ssn %p: -> SEQ mismatch, packet SEQ %" PRIu32 ""
@ -2433,11 +2481,13 @@ static int StreamTcpPacketStateFinWait1(ThreadVars *tv, Packet *p,
return -1; return -1;
} }
StreamTcpPacketSetState(p, ssn, TCP_CLOSING); if (!retransmission) {
ssn->server.flags |= STREAMTCP_STREAM_FLAG_CLOSE_INITIATED; StreamTcpPacketSetState(p, ssn, TCP_CLOSING);
SCLogDebug("ssn %p: state changed to TCP_CLOSING", ssn); ssn->server.flags |= STREAMTCP_STREAM_FLAG_CLOSE_INITIATED;
SCLogDebug("ssn %p: state changed to TCP_CLOSING", ssn);
ssn->client.window = TCP_GET_WINDOW(p) << ssn->client.wscale; ssn->client.window = TCP_GET_WINDOW(p) << ssn->client.wscale;
}
StreamTcpUpdateLastAck(ssn, &ssn->client, TCP_GET_ACK(p)); StreamTcpUpdateLastAck(ssn, &ssn->client, TCP_GET_ACK(p));
@ -2478,6 +2528,12 @@ static int StreamTcpPacketStateFinWait1(ThreadVars *tv, Packet *p,
SCLogDebug("ssn %p: pkt (%" PRIu32 ") is to server: SEQ " SCLogDebug("ssn %p: pkt (%" PRIu32 ") is to server: SEQ "
"%" PRIu32 ", ACK %" PRIu32 "", ssn, p->payload_len, "%" PRIu32 ", ACK %" PRIu32 "", ssn, p->payload_len,
TCP_GET_SEQ(p), TCP_GET_ACK(p)); TCP_GET_SEQ(p), TCP_GET_ACK(p));
int retransmission = 0;
if (StreamTcpPacketIsRetransmission(&ssn->client, p)) {
SCLogDebug("ssn %p: packet is retransmission", ssn);
retransmission = 1;
}
if (StreamTcpValidateAck(ssn, &ssn->server, p) == -1) { if (StreamTcpValidateAck(ssn, &ssn->server, p) == -1) {
SCLogDebug("ssn %p: rejecting because of invalid ack value", ssn); SCLogDebug("ssn %p: rejecting because of invalid ack value", ssn);
@ -2485,28 +2541,30 @@ static int StreamTcpPacketStateFinWait1(ThreadVars *tv, Packet *p,
return -1; return -1;
} }
if (SEQ_LEQ(TCP_GET_SEQ(p) + p->payload_len, ssn->client.next_win) || if (!retransmission) {
(ssn->flags & STREAMTCP_FLAG_MIDSTREAM) || if (SEQ_LEQ(TCP_GET_SEQ(p) + p->payload_len, ssn->client.next_win) ||
ssn->flags & STREAMTCP_FLAG_ASYNC) (ssn->flags & STREAMTCP_FLAG_MIDSTREAM) ||
{ ssn->flags & STREAMTCP_FLAG_ASYNC)
SCLogDebug("ssn %p: seq %"PRIu32" in window, ssn->client.next_win " {
"%" PRIu32 "", ssn, TCP_GET_SEQ(p), ssn->client.next_win); SCLogDebug("ssn %p: seq %"PRIu32" in window, ssn->client.next_win "
"%" PRIu32 "", ssn, TCP_GET_SEQ(p), ssn->client.next_win);
if (TCP_GET_SEQ(p) == ssn->client.next_seq) {
StreamTcpPacketSetState(p, ssn, TCP_FIN_WAIT2);
SCLogDebug("ssn %p: state changed to TCP_FIN_WAIT2", ssn);
}
} else {
SCLogDebug("ssn %p: -> SEQ mismatch, packet SEQ %" PRIu32 ""
" != %" PRIu32 " from stream", ssn,
TCP_GET_SEQ(p), ssn->client.next_seq);
if (TCP_GET_SEQ(p) == ssn->client.next_seq) { StreamTcpSetEvent(p, STREAM_FIN1_ACK_WRONG_SEQ);
StreamTcpPacketSetState(p, ssn, TCP_FIN_WAIT2); return -1;
SCLogDebug("ssn %p: state changed to TCP_FIN_WAIT2", ssn);
} }
} else {
SCLogDebug("ssn %p: -> SEQ mismatch, packet SEQ %" PRIu32 ""
" != %" PRIu32 " from stream", ssn,
TCP_GET_SEQ(p), ssn->client.next_seq);
StreamTcpSetEvent(p, STREAM_FIN1_ACK_WRONG_SEQ); ssn->server.window = TCP_GET_WINDOW(p) << ssn->server.wscale;
return -1;
} }
ssn->server.window = TCP_GET_WINDOW(p) << ssn->server.wscale;
StreamTcpUpdateLastAck(ssn, &ssn->server, TCP_GET_ACK(p)); StreamTcpUpdateLastAck(ssn, &ssn->server, TCP_GET_ACK(p));
if (ssn->flags & STREAMTCP_FLAG_TIMESTAMP) { if (ssn->flags & STREAMTCP_FLAG_TIMESTAMP) {
@ -2542,32 +2600,41 @@ static int StreamTcpPacketStateFinWait1(ThreadVars *tv, Packet *p,
"%" PRIu32 ", ACK %" PRIu32 "", ssn, p->payload_len, "%" PRIu32 ", ACK %" PRIu32 "", ssn, p->payload_len,
TCP_GET_SEQ(p), TCP_GET_ACK(p)); TCP_GET_SEQ(p), TCP_GET_ACK(p));
int retransmission = 0;
if (StreamTcpPacketIsRetransmission(&ssn->server, p)) {
SCLogDebug("ssn %p: packet is retransmission", ssn);
retransmission = 1;
}
if (StreamTcpValidateAck(ssn, &ssn->client, p) == -1) { if (StreamTcpValidateAck(ssn, &ssn->client, p) == -1) {
SCLogDebug("ssn %p: rejecting because of invalid ack value", ssn); SCLogDebug("ssn %p: rejecting because of invalid ack value", ssn);
StreamTcpSetEvent(p, STREAM_FIN1_INVALID_ACK); StreamTcpSetEvent(p, STREAM_FIN1_INVALID_ACK);
return -1; return -1;
} }
if (SEQ_LEQ(TCP_GET_SEQ(p) + p->payload_len, ssn->server.next_win) || if (!retransmission) {
(ssn->flags & STREAMTCP_FLAG_MIDSTREAM) || if (SEQ_LEQ(TCP_GET_SEQ(p) + p->payload_len, ssn->server.next_win) ||
ssn->flags & STREAMTCP_FLAG_ASYNC) (ssn->flags & STREAMTCP_FLAG_MIDSTREAM) ||
{ ssn->flags & STREAMTCP_FLAG_ASYNC)
SCLogDebug("ssn %p: seq %"PRIu32" in window, ssn->server.next_win " {
"%" PRIu32 "", ssn, TCP_GET_SEQ(p), ssn->server.next_win); SCLogDebug("ssn %p: seq %"PRIu32" in window, ssn->server.next_win "
"%" PRIu32 "", ssn, TCP_GET_SEQ(p), ssn->server.next_win);
if (TCP_GET_SEQ(p) == ssn->server.next_seq) { if (TCP_GET_SEQ(p) == ssn->server.next_seq) {
StreamTcpPacketSetState(p, ssn, TCP_FIN_WAIT2); StreamTcpPacketSetState(p, ssn, TCP_FIN_WAIT2);
SCLogDebug("ssn %p: state changed to TCP_FIN_WAIT2", ssn); SCLogDebug("ssn %p: state changed to TCP_FIN_WAIT2", ssn);
}
} else {
SCLogDebug("ssn %p: -> SEQ mismatch, packet SEQ %" PRIu32 ""
" != %" PRIu32 " from stream", ssn,
TCP_GET_SEQ(p), ssn->server.next_seq);
StreamTcpSetEvent(p, STREAM_FIN1_ACK_WRONG_SEQ);
return -1;
} }
} else {
SCLogDebug("ssn %p: -> SEQ mismatch, packet SEQ %" PRIu32 ""
" != %" PRIu32 " from stream", ssn,
TCP_GET_SEQ(p), ssn->server.next_seq);
StreamTcpSetEvent(p, STREAM_FIN1_ACK_WRONG_SEQ);
return -1;
}
ssn->client.window = TCP_GET_WINDOW(p) << ssn->client.wscale; ssn->client.window = TCP_GET_WINDOW(p) << ssn->client.wscale;
}
StreamTcpUpdateLastAck(ssn, &ssn->client, TCP_GET_ACK(p)); StreamTcpUpdateLastAck(ssn, &ssn->client, TCP_GET_ACK(p));
@ -2679,6 +2746,9 @@ static int StreamTcpPacketStateFinWait2(ThreadVars *tv, Packet *p,
SEQ_EQ(TCP_GET_ACK(p), ssn->server.last_ack)) { SEQ_EQ(TCP_GET_ACK(p), ssn->server.last_ack)) {
SCLogDebug("ssn %p: retransmission", ssn); SCLogDebug("ssn %p: retransmission", ssn);
retransmission = 1; retransmission = 1;
} else if (StreamTcpPacketIsRetransmission(&ssn->client, p)) {
SCLogDebug("ssn %p: packet is retransmission", ssn);
retransmission = 1;
} else if (SEQ_LT(TCP_GET_SEQ(p), ssn->client.next_seq) || } else if (SEQ_LT(TCP_GET_SEQ(p), ssn->client.next_seq) ||
SEQ_GT(TCP_GET_SEQ(p), (ssn->client.last_ack + ssn->client.window))) SEQ_GT(TCP_GET_SEQ(p), (ssn->client.last_ack + ssn->client.window)))
@ -2700,9 +2770,9 @@ static int StreamTcpPacketStateFinWait2(ThreadVars *tv, Packet *p,
StreamTcpPacketSetState(p, ssn, TCP_TIME_WAIT); StreamTcpPacketSetState(p, ssn, TCP_TIME_WAIT);
ssn->client.flags |= STREAMTCP_STREAM_FLAG_CLOSE_INITIATED; ssn->client.flags |= STREAMTCP_STREAM_FLAG_CLOSE_INITIATED;
SCLogDebug("ssn %p: state changed to TCP_TIME_WAIT", ssn); SCLogDebug("ssn %p: state changed to TCP_TIME_WAIT", ssn);
}
ssn->server.window = TCP_GET_WINDOW(p) << ssn->server.wscale; ssn->server.window = TCP_GET_WINDOW(p) << ssn->server.wscale;
}
StreamTcpUpdateLastAck(ssn, &ssn->server, TCP_GET_ACK(p)); StreamTcpUpdateLastAck(ssn, &ssn->server, TCP_GET_ACK(p));
@ -2733,6 +2803,9 @@ static int StreamTcpPacketStateFinWait2(ThreadVars *tv, Packet *p,
SEQ_EQ(TCP_GET_ACK(p), ssn->client.last_ack)) { SEQ_EQ(TCP_GET_ACK(p), ssn->client.last_ack)) {
SCLogDebug("ssn %p: retransmission", ssn); SCLogDebug("ssn %p: retransmission", ssn);
retransmission = 1; retransmission = 1;
} else if (StreamTcpPacketIsRetransmission(&ssn->server, p)) {
SCLogDebug("ssn %p: packet is retransmission", ssn);
retransmission = 1;
} else if (SEQ_LT(TCP_GET_SEQ(p), ssn->server.next_seq) || } else if (SEQ_LT(TCP_GET_SEQ(p), ssn->server.next_seq) ||
SEQ_GT(TCP_GET_SEQ(p), (ssn->server.last_ack + ssn->server.window))) SEQ_GT(TCP_GET_SEQ(p), (ssn->server.last_ack + ssn->server.window)))
@ -2754,8 +2827,9 @@ static int StreamTcpPacketStateFinWait2(ThreadVars *tv, Packet *p,
StreamTcpPacketSetState(p, ssn, TCP_TIME_WAIT); StreamTcpPacketSetState(p, ssn, TCP_TIME_WAIT);
ssn->server.flags |= STREAMTCP_STREAM_FLAG_CLOSE_INITIATED; ssn->server.flags |= STREAMTCP_STREAM_FLAG_CLOSE_INITIATED;
SCLogDebug("ssn %p: state changed to TCP_TIME_WAIT", ssn); SCLogDebug("ssn %p: state changed to TCP_TIME_WAIT", ssn);
ssn->client.window = TCP_GET_WINDOW(p) << ssn->client.wscale;
} }
ssn->client.window = TCP_GET_WINDOW(p) << ssn->client.wscale;
StreamTcpUpdateLastAck(ssn, &ssn->client, TCP_GET_ACK(p)); StreamTcpUpdateLastAck(ssn, &ssn->client, TCP_GET_ACK(p));
@ -2792,6 +2866,12 @@ static int StreamTcpPacketStateFinWait2(ThreadVars *tv, Packet *p,
SCLogDebug("ssn %p: pkt (%" PRIu32 ") is to server: SEQ " SCLogDebug("ssn %p: pkt (%" PRIu32 ") is to server: SEQ "
"%" PRIu32 ", ACK %" PRIu32 "", ssn, p->payload_len, "%" PRIu32 ", ACK %" PRIu32 "", ssn, p->payload_len,
TCP_GET_SEQ(p), TCP_GET_ACK(p)); TCP_GET_SEQ(p), TCP_GET_ACK(p));
int retransmission = 0;
if (StreamTcpPacketIsRetransmission(&ssn->client, p)) {
SCLogDebug("ssn %p: packet is retransmission", ssn);
retransmission = 1;
}
if (StreamTcpValidateAck(ssn, &ssn->server, p) == -1) { if (StreamTcpValidateAck(ssn, &ssn->server, p) == -1) {
SCLogDebug("ssn %p: rejecting because of invalid ack value", ssn); SCLogDebug("ssn %p: rejecting because of invalid ack value", ssn);
@ -2799,22 +2879,24 @@ static int StreamTcpPacketStateFinWait2(ThreadVars *tv, Packet *p,
return -1; return -1;
} }
if (SEQ_LEQ(TCP_GET_SEQ(p) + p->payload_len, ssn->client.next_win) || if (!retransmission) {
(ssn->flags & STREAMTCP_FLAG_MIDSTREAM) || if (SEQ_LEQ(TCP_GET_SEQ(p) + p->payload_len, ssn->client.next_win) ||
ssn->flags & STREAMTCP_FLAG_ASYNC) (ssn->flags & STREAMTCP_FLAG_MIDSTREAM) ||
{ ssn->flags & STREAMTCP_FLAG_ASYNC)
SCLogDebug("ssn %p: seq %"PRIu32" in window, ssn->client.next_win " {
"%" PRIu32 "", ssn, TCP_GET_SEQ(p), ssn->client.next_win); SCLogDebug("ssn %p: seq %"PRIu32" in window, ssn->client.next_win "
"%" PRIu32 "", ssn, TCP_GET_SEQ(p), ssn->client.next_win);
} else { } else {
SCLogDebug("ssn %p: -> SEQ mismatch, packet SEQ %" PRIu32 "" SCLogDebug("ssn %p: -> SEQ mismatch, packet SEQ %" PRIu32 ""
" != %" PRIu32 " from stream", ssn, " != %" PRIu32 " from stream", ssn,
TCP_GET_SEQ(p), ssn->client.next_seq); TCP_GET_SEQ(p), ssn->client.next_seq);
StreamTcpSetEvent(p, STREAM_FIN2_ACK_WRONG_SEQ); StreamTcpSetEvent(p, STREAM_FIN2_ACK_WRONG_SEQ);
return -1; return -1;
} }
ssn->server.window = TCP_GET_WINDOW(p) << ssn->server.wscale; ssn->server.window = TCP_GET_WINDOW(p) << ssn->server.wscale;
}
StreamTcpUpdateLastAck(ssn, &ssn->server, TCP_GET_ACK(p)); StreamTcpUpdateLastAck(ssn, &ssn->server, TCP_GET_ACK(p));
@ -2843,6 +2925,12 @@ static int StreamTcpPacketStateFinWait2(ThreadVars *tv, Packet *p,
SCLogDebug("ssn %p: pkt (%" PRIu32 ") is to client: SEQ " SCLogDebug("ssn %p: pkt (%" PRIu32 ") is to client: SEQ "
"%" PRIu32 ", ACK %" PRIu32 "", ssn, p->payload_len, "%" PRIu32 ", ACK %" PRIu32 "", ssn, p->payload_len,
TCP_GET_SEQ(p), TCP_GET_ACK(p)); TCP_GET_SEQ(p), TCP_GET_ACK(p));
int retransmission = 0;
if (StreamTcpPacketIsRetransmission(&ssn->server, p)) {
SCLogDebug("ssn %p: packet is retransmission", ssn);
retransmission = 1;
}
if (StreamTcpValidateAck(ssn, &ssn->client, p) == -1) { if (StreamTcpValidateAck(ssn, &ssn->client, p) == -1) {
SCLogDebug("ssn %p: rejecting because of invalid ack value", ssn); SCLogDebug("ssn %p: rejecting because of invalid ack value", ssn);
@ -2850,21 +2938,23 @@ static int StreamTcpPacketStateFinWait2(ThreadVars *tv, Packet *p,
return -1; return -1;
} }
if (SEQ_LEQ(TCP_GET_SEQ(p) + p->payload_len, ssn->server.next_win) || if (!retransmission) {
(ssn->flags & STREAMTCP_FLAG_MIDSTREAM) || if (SEQ_LEQ(TCP_GET_SEQ(p) + p->payload_len, ssn->server.next_win) ||
ssn->flags & STREAMTCP_FLAG_ASYNC) (ssn->flags & STREAMTCP_FLAG_MIDSTREAM) ||
{ ssn->flags & STREAMTCP_FLAG_ASYNC)
SCLogDebug("ssn %p: seq %"PRIu32" in window, ssn->server.next_win " {
"%" PRIu32 "", ssn, TCP_GET_SEQ(p), ssn->server.next_win); SCLogDebug("ssn %p: seq %"PRIu32" in window, ssn->server.next_win "
} else { "%" PRIu32 "", ssn, TCP_GET_SEQ(p), ssn->server.next_win);
SCLogDebug("ssn %p: -> SEQ mismatch, packet SEQ %" PRIu32 "" } else {
" != %" PRIu32 " from stream", ssn, SCLogDebug("ssn %p: -> SEQ mismatch, packet SEQ %" PRIu32 ""
TCP_GET_SEQ(p), ssn->server.next_seq); " != %" PRIu32 " from stream", ssn,
StreamTcpSetEvent(p, STREAM_FIN2_ACK_WRONG_SEQ); TCP_GET_SEQ(p), ssn->server.next_seq);
return -1; StreamTcpSetEvent(p, STREAM_FIN2_ACK_WRONG_SEQ);
} return -1;
}
ssn->client.window = TCP_GET_WINDOW(p) << ssn->client.wscale; ssn->client.window = TCP_GET_WINDOW(p) << ssn->client.wscale;
}
StreamTcpUpdateLastAck(ssn, &ssn->client, TCP_GET_ACK(p)); StreamTcpUpdateLastAck(ssn, &ssn->client, TCP_GET_ACK(p));
@ -2971,6 +3061,11 @@ static int StreamTcpPacketStateClosing(ThreadVars *tv, Packet *p,
"%" PRIu32 ", ACK %" PRIu32 "", ssn, p->payload_len, "%" PRIu32 ", ACK %" PRIu32 "", ssn, p->payload_len,
TCP_GET_SEQ(p), TCP_GET_ACK(p)); TCP_GET_SEQ(p), TCP_GET_ACK(p));
if (StreamTcpPacketIsRetransmission(&ssn->client, p)) {
SCLogDebug("ssn %p: packet is retransmission", ssn);
SCReturnInt(-1);
}
if (TCP_GET_SEQ(p) != ssn->client.next_seq) { if (TCP_GET_SEQ(p) != ssn->client.next_seq) {
SCLogDebug("ssn %p: -> SEQ mismatch, packet SEQ %" PRIu32 "" SCLogDebug("ssn %p: -> SEQ mismatch, packet SEQ %" PRIu32 ""
" != %" PRIu32 " from stream", ssn, " != %" PRIu32 " from stream", ssn,
@ -3010,6 +3105,11 @@ static int StreamTcpPacketStateClosing(ThreadVars *tv, Packet *p,
"%" PRIu32 ", ACK %" PRIu32 "", ssn, p->payload_len, "%" PRIu32 ", ACK %" PRIu32 "", ssn, p->payload_len,
TCP_GET_SEQ(p), TCP_GET_ACK(p)); TCP_GET_SEQ(p), TCP_GET_ACK(p));
if (StreamTcpPacketIsRetransmission(&ssn->server, p)) {
SCLogDebug("ssn %p: packet is retransmission", ssn);
SCReturnInt(-1);
}
if (TCP_GET_SEQ(p) != ssn->server.next_seq) { if (TCP_GET_SEQ(p) != ssn->server.next_seq) {
SCLogDebug("ssn %p: -> SEQ mismatch, packet SEQ %" PRIu32 "" SCLogDebug("ssn %p: -> SEQ mismatch, packet SEQ %" PRIu32 ""
" != %" PRIu32 " from stream", ssn, " != %" PRIu32 " from stream", ssn,
@ -3135,6 +3235,11 @@ static int StreamTcpPacketStateCloseWait(ThreadVars *tv, Packet *p,
"%" PRIu32 ", ACK %" PRIu32 "", ssn, p->payload_len, "%" PRIu32 ", ACK %" PRIu32 "", ssn, p->payload_len,
TCP_GET_SEQ(p), TCP_GET_ACK(p)); TCP_GET_SEQ(p), TCP_GET_ACK(p));
if (StreamTcpPacketIsRetransmission(&ssn->client, p)) {
SCLogDebug("ssn %p: packet is retransmission", ssn);
SCReturnInt(-1);
}
if (SEQ_LT(TCP_GET_SEQ(p), ssn->client.next_seq) || if (SEQ_LT(TCP_GET_SEQ(p), ssn->client.next_seq) ||
SEQ_GT(TCP_GET_SEQ(p), (ssn->client.last_ack + ssn->client.window))) SEQ_GT(TCP_GET_SEQ(p), (ssn->client.last_ack + ssn->client.window)))
{ {
@ -3178,6 +3283,11 @@ static int StreamTcpPacketStateCloseWait(ThreadVars *tv, Packet *p,
"%" PRIu32 ", ACK %" PRIu32 "", ssn, p->payload_len, "%" PRIu32 ", ACK %" PRIu32 "", ssn, p->payload_len,
TCP_GET_SEQ(p), TCP_GET_ACK(p)); TCP_GET_SEQ(p), TCP_GET_ACK(p));
if (StreamTcpPacketIsRetransmission(&ssn->server, p)) {
SCLogDebug("ssn %p: packet is retransmission", ssn);
SCReturnInt(-1);
}
if (SEQ_LT(TCP_GET_SEQ(p), ssn->server.next_seq) || if (SEQ_LT(TCP_GET_SEQ(p), ssn->server.next_seq) ||
SEQ_GT(TCP_GET_SEQ(p), (ssn->server.last_ack + ssn->server.window))) SEQ_GT(TCP_GET_SEQ(p), (ssn->server.last_ack + ssn->server.window)))
{ {
@ -3234,6 +3344,11 @@ static int StreamTcpPacketStateCloseWait(ThreadVars *tv, Packet *p,
"%" PRIu32 ", ACK %" PRIu32 "", ssn, p->payload_len, "%" PRIu32 ", ACK %" PRIu32 "", ssn, p->payload_len,
TCP_GET_SEQ(p), TCP_GET_ACK(p)); TCP_GET_SEQ(p), TCP_GET_ACK(p));
if (StreamTcpPacketIsRetransmission(&ssn->client, p)) {
SCLogDebug("ssn %p: packet is retransmission", ssn);
SCReturnInt(-1);
}
if (p->payload_len > 0 && (SEQ_LEQ((TCP_GET_SEQ(p) + p->payload_len), ssn->client.last_ack))) { if (p->payload_len > 0 && (SEQ_LEQ((TCP_GET_SEQ(p) + p->payload_len), ssn->client.last_ack))) {
SCLogDebug("ssn %p: -> retransmission", ssn); SCLogDebug("ssn %p: -> retransmission", ssn);
StreamTcpSetEvent(p, STREAM_CLOSEWAIT_PKT_BEFORE_LAST_ACK); StreamTcpSetEvent(p, STREAM_CLOSEWAIT_PKT_BEFORE_LAST_ACK);
@ -3280,6 +3395,11 @@ static int StreamTcpPacketStateCloseWait(ThreadVars *tv, Packet *p,
"%" PRIu32 ", ACK %" PRIu32 "", ssn, p->payload_len, "%" PRIu32 ", ACK %" PRIu32 "", ssn, p->payload_len,
TCP_GET_SEQ(p), TCP_GET_ACK(p)); TCP_GET_SEQ(p), TCP_GET_ACK(p));
if (StreamTcpPacketIsRetransmission(&ssn->server, p)) {
SCLogDebug("ssn %p: packet is retransmission", ssn);
SCReturnInt(-1);
}
if (p->payload_len > 0 && (SEQ_LEQ((TCP_GET_SEQ(p) + p->payload_len), ssn->server.last_ack))) { if (p->payload_len > 0 && (SEQ_LEQ((TCP_GET_SEQ(p) + p->payload_len), ssn->server.last_ack))) {
SCLogDebug("ssn %p: -> retransmission", ssn); SCLogDebug("ssn %p: -> retransmission", ssn);
StreamTcpSetEvent(p, STREAM_CLOSEWAIT_PKT_BEFORE_LAST_ACK); StreamTcpSetEvent(p, STREAM_CLOSEWAIT_PKT_BEFORE_LAST_ACK);
@ -3406,6 +3526,11 @@ static int StreamTcpPakcetStateLastAck(ThreadVars *tv, Packet *p,
"%" PRIu32 ", ACK %" PRIu32 "", ssn, p->payload_len, "%" PRIu32 ", ACK %" PRIu32 "", ssn, p->payload_len,
TCP_GET_SEQ(p), TCP_GET_ACK(p)); TCP_GET_SEQ(p), TCP_GET_ACK(p));
if (StreamTcpPacketIsRetransmission(&ssn->client, p)) {
SCLogDebug("ssn %p: packet is retransmission", ssn);
SCReturnInt(-1);
}
if (TCP_GET_SEQ(p) != ssn->client.next_seq && TCP_GET_SEQ(p) != ssn->client.next_seq + 1) { if (TCP_GET_SEQ(p) != ssn->client.next_seq && TCP_GET_SEQ(p) != ssn->client.next_seq + 1) {
SCLogDebug("ssn %p: -> SEQ mismatch, packet SEQ %" PRIu32 "" SCLogDebug("ssn %p: -> SEQ mismatch, packet SEQ %" PRIu32 ""
" != %" PRIu32 " from stream", ssn, " != %" PRIu32 " from stream", ssn,
@ -3526,6 +3651,11 @@ static int StreamTcpPacketStateTimeWait(ThreadVars *tv, Packet *p,
"%" PRIu32 ", ACK %" PRIu32 "", ssn, p->payload_len, "%" PRIu32 ", ACK %" PRIu32 "", ssn, p->payload_len,
TCP_GET_SEQ(p), TCP_GET_ACK(p)); TCP_GET_SEQ(p), TCP_GET_ACK(p));
if (StreamTcpPacketIsRetransmission(&ssn->client, p)) {
SCLogDebug("ssn %p: packet is retransmission", ssn);
SCReturnInt(-1);
}
if (TCP_GET_SEQ(p) != ssn->client.next_seq && TCP_GET_SEQ(p) != ssn->client.next_seq+1) { if (TCP_GET_SEQ(p) != ssn->client.next_seq && TCP_GET_SEQ(p) != ssn->client.next_seq+1) {
SCLogDebug("ssn %p: -> SEQ mismatch, packet SEQ %" PRIu32 "" SCLogDebug("ssn %p: -> SEQ mismatch, packet SEQ %" PRIu32 ""
" != %" PRIu32 " from stream", ssn, " != %" PRIu32 " from stream", ssn,
@ -3564,19 +3694,19 @@ static int StreamTcpPacketStateTimeWait(ThreadVars *tv, Packet *p,
StreamTcpPseudoPacketCreateStreamEndPacket(p, ssn, pq); StreamTcpPseudoPacketCreateStreamEndPacket(p, ssn, pq);
} else { } else {
int retransmission = 0;
SCLogDebug("ssn %p: pkt (%" PRIu32 ") is to client: SEQ " SCLogDebug("ssn %p: pkt (%" PRIu32 ") is to client: SEQ "
"%" PRIu32 ", ACK %" PRIu32 "", ssn, p->payload_len, "%" PRIu32 ", ACK %" PRIu32 "", ssn, p->payload_len,
TCP_GET_SEQ(p), TCP_GET_ACK(p)); TCP_GET_SEQ(p), TCP_GET_ACK(p));
if (StreamTcpPacketIsRetransmission(&ssn->server, p)) {
SCLogDebug("ssn %p: packet is retransmission", ssn);
SCReturnInt(-1);
}
if (TCP_GET_SEQ(p) != ssn->server.next_seq && TCP_GET_SEQ(p) != ssn->server.next_seq+1) { if (TCP_GET_SEQ(p) != ssn->server.next_seq && TCP_GET_SEQ(p) != ssn->server.next_seq+1) {
if (p->payload_len > 0 && TCP_GET_SEQ(p) == ssn->server.last_ack) { if (p->payload_len > 0 && TCP_GET_SEQ(p) == ssn->server.last_ack) {
SCLogDebug("ssn %p: -> retransmission", ssn); SCLogDebug("ssn %p: -> retransmission", ssn);
retransmission = 1; SCReturnInt(0);
} else if (p->payload_len > 0 && SEQ_LEQ((TCP_GET_SEQ(p) + p->payload_len), ssn->server.last_ack)) {
SCLogDebug("ssn %p: -> retransmission", ssn);
retransmission = 1;
} else { } else {
SCLogDebug("ssn %p: -> SEQ mismatch, packet SEQ %" PRIu32 "" SCLogDebug("ssn %p: -> SEQ mismatch, packet SEQ %" PRIu32 ""
" != %" PRIu32 " from stream", ssn, " != %" PRIu32 " from stream", ssn,
@ -3592,10 +3722,8 @@ static int StreamTcpPacketStateTimeWait(ThreadVars *tv, Packet *p,
SCReturnInt(-1); SCReturnInt(-1);
} }
if (!retransmission) { StreamTcpPacketSetState(p, ssn, TCP_CLOSED);
StreamTcpPacketSetState(p, ssn, TCP_CLOSED); SCLogDebug("ssn %p: state changed to TCP_CLOSED", ssn);
SCLogDebug("ssn %p: state changed to TCP_CLOSED", ssn);
}
ssn->client.window = TCP_GET_WINDOW(p) << ssn->client.wscale; ssn->client.window = TCP_GET_WINDOW(p) << ssn->client.wscale;

Loading…
Cancel
Save