retransmission = 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 ""
- " != %" PRIu32 " from stream", ssn,
- TCP_GET_SEQ(p), ssn->client.next_seq);
- StreamTcpSetEvent(p, STREAM_LASTACK_ACK_WRONG_SEQ);
- return -1;
- }
-
if (StreamTcpValidateAck(ssn, &ssn->server, p) == -1) {
SCLogDebug("ssn %p: rejecting because of invalid ack value", ssn);
StreamTcpSetEvent(p, STREAM_LASTACK_INVALID_ACK);
}
if (!retransmission) {
- StreamTcpPacketSetState(p, ssn, TCP_CLOSED);
- SCLogDebug("ssn %p: state changed to TCP_CLOSED", ssn);
+ if (SEQ_LT(TCP_GET_SEQ(p), ssn->client.next_seq)) {
+ SCLogDebug("ssn %p: not updating state as packet is before next_seq", ssn);
+ } else 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 ""
+ " != %" PRIu32 " from stream", ssn,
+ TCP_GET_SEQ(p), ssn->client.next_seq);
+ StreamTcpSetEvent(p, STREAM_LASTACK_ACK_WRONG_SEQ);
+ return -1;
+ } else {
+ StreamTcpPacketSetState(p, ssn, TCP_CLOSED);
+ SCLogDebug("ssn %p: state changed to TCP_CLOSED", ssn);
+ }
ssn->server.window = TCP_GET_WINDOW(p) << ssn->server.wscale;
}