} \
}
+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
* \brief Function to handle the TCP_CLOSED or NONE state. The function handles
SCLogDebug("ssn %p: pkt (%" PRIu32 ") is to server: SEQ "
"%" PRIu32 ", ACK %" PRIu32 "", ssn, p->payload_len,
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)))
{
SCLogDebug("ssn %p: -> SEQ mismatch, packet SEQ %" PRIu32 ""
return -1;
}
- StreamTcpPacketSetState(p, ssn, TCP_TIME_WAIT);
- ssn->client.flags |= STREAMTCP_STREAM_FLAG_CLOSE_INITIATED;
- SCLogDebug("ssn %p: state changed to TCP_TIME_WAIT", ssn);
+ if (!retransmission) {
+ StreamTcpPacketSetState(p, ssn, TCP_TIME_WAIT);
+ 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));
SCLogDebug("ssn %p: pkt (%" PRIu32 ") is to client: SEQ "
"%" PRIu32 ", ACK %" PRIu32 "", ssn, p->payload_len,
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)))
{
SCLogDebug("ssn %p: -> SEQ mismatch, packet SEQ %" PRIu32 ""
return -1;
}
- StreamTcpPacketSetState(p, ssn, TCP_TIME_WAIT);
- ssn->server.flags |= STREAMTCP_STREAM_FLAG_CLOSE_INITIATED;
- SCLogDebug("ssn %p: state changed to TCP_TIME_WAIT", ssn);
+ if (!retransmission) {
+ StreamTcpPacketSetState(p, ssn, TCP_TIME_WAIT);
+ 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));
SCLogDebug("ssn %p: pkt (%" PRIu32 ") is to server: SEQ "
"%" PRIu32 ", ACK %" PRIu32 "", ssn, p->payload_len,
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)))
{
SCLogDebug("ssn %p: -> SEQ mismatch, packet SEQ %" PRIu32 ""
return -1;
}
- StreamTcpPacketSetState(p, ssn, TCP_CLOSING);
- ssn->client.flags |= STREAMTCP_STREAM_FLAG_CLOSE_INITIATED;
- SCLogDebug("ssn %p: state changed to TCP_CLOSING", ssn);
+ if (!retransmission) {
+ StreamTcpPacketSetState(p, ssn, TCP_CLOSING);
+ 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));
"%" PRIu32 ", ACK %" PRIu32 "", ssn, p->payload_len,
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)))
{
SCLogDebug("ssn %p: -> SEQ mismatch, packet SEQ %" PRIu32 ""
return -1;
}
- StreamTcpPacketSetState(p, ssn, TCP_CLOSING);
- ssn->server.flags |= STREAMTCP_STREAM_FLAG_CLOSE_INITIATED;
- SCLogDebug("ssn %p: state changed to TCP_CLOSING", ssn);
+ if (!retransmission) {
+ StreamTcpPacketSetState(p, ssn, TCP_CLOSING);
+ 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));
SCLogDebug("ssn %p: pkt (%" PRIu32 ") is to server: SEQ "
"%" PRIu32 ", ACK %" PRIu32 "", ssn, p->payload_len,
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) {
SCLogDebug("ssn %p: rejecting because of invalid ack value", ssn);
return -1;
}
- if (SEQ_LEQ(TCP_GET_SEQ(p) + p->payload_len, ssn->client.next_win) ||
- (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);
+ if (!retransmission) {
+ if (SEQ_LEQ(TCP_GET_SEQ(p) + p->payload_len, ssn->client.next_win) ||
+ (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);
+
+ 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) {
- StreamTcpPacketSetState(p, ssn, TCP_FIN_WAIT2);
- SCLogDebug("ssn %p: state changed to TCP_FIN_WAIT2", ssn);
+ 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->client.next_seq);
- StreamTcpSetEvent(p, STREAM_FIN1_ACK_WRONG_SEQ);
- 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));
if (ssn->flags & STREAMTCP_FLAG_TIMESTAMP) {
"%" PRIu32 ", ACK %" PRIu32 "", ssn, p->payload_len,
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) {
SCLogDebug("ssn %p: rejecting because of invalid ack value", ssn);
StreamTcpSetEvent(p, STREAM_FIN1_INVALID_ACK);
return -1;
}
- if (SEQ_LEQ(TCP_GET_SEQ(p) + p->payload_len, ssn->server.next_win) ||
- (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);
+ if (!retransmission) {
+ if (SEQ_LEQ(TCP_GET_SEQ(p) + p->payload_len, ssn->server.next_win) ||
+ (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);
- if (TCP_GET_SEQ(p) == ssn->server.next_seq) {
- StreamTcpPacketSetState(p, ssn, TCP_FIN_WAIT2);
- SCLogDebug("ssn %p: state changed to TCP_FIN_WAIT2", ssn);
+ if (TCP_GET_SEQ(p) == ssn->server.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->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));
SEQ_EQ(TCP_GET_ACK(p), ssn->server.last_ack)) {
SCLogDebug("ssn %p: retransmission", ssn);
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) ||
SEQ_GT(TCP_GET_SEQ(p), (ssn->client.last_ack + ssn->client.window)))
StreamTcpPacketSetState(p, ssn, TCP_TIME_WAIT);
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));
SEQ_EQ(TCP_GET_ACK(p), ssn->client.last_ack)) {
SCLogDebug("ssn %p: retransmission", ssn);
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) ||
SEQ_GT(TCP_GET_SEQ(p), (ssn->server.last_ack + ssn->server.window)))
StreamTcpPacketSetState(p, ssn, TCP_TIME_WAIT);
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));
SCLogDebug("ssn %p: pkt (%" PRIu32 ") is to server: SEQ "
"%" PRIu32 ", ACK %" PRIu32 "", ssn, p->payload_len,
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) {
SCLogDebug("ssn %p: rejecting because of invalid ack value", ssn);
return -1;
}
- if (SEQ_LEQ(TCP_GET_SEQ(p) + p->payload_len, ssn->client.next_win) ||
- (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);
+ if (!retransmission) {
+ if (SEQ_LEQ(TCP_GET_SEQ(p) + p->payload_len, ssn->client.next_win) ||
+ (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);
- } else {
- SCLogDebug("ssn %p: -> SEQ mismatch, packet SEQ %" PRIu32 ""
- " != %" PRIu32 " from stream", ssn,
- TCP_GET_SEQ(p), ssn->client.next_seq);
- StreamTcpSetEvent(p, STREAM_FIN2_ACK_WRONG_SEQ);
- return -1;
- }
+ } else {
+ SCLogDebug("ssn %p: -> SEQ mismatch, packet SEQ %" PRIu32 ""
+ " != %" PRIu32 " from stream", ssn,
+ TCP_GET_SEQ(p), ssn->client.next_seq);
+ StreamTcpSetEvent(p, STREAM_FIN2_ACK_WRONG_SEQ);
+ 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));
SCLogDebug("ssn %p: pkt (%" PRIu32 ") is to client: SEQ "
"%" PRIu32 ", ACK %" PRIu32 "", ssn, p->payload_len,
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) {
SCLogDebug("ssn %p: rejecting because of invalid ack value", ssn);
return -1;
}
- if (SEQ_LEQ(TCP_GET_SEQ(p) + p->payload_len, ssn->server.next_win) ||
- (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);
- } else {
- SCLogDebug("ssn %p: -> SEQ mismatch, packet SEQ %" PRIu32 ""
- " != %" PRIu32 " from stream", ssn,
- TCP_GET_SEQ(p), ssn->server.next_seq);
- StreamTcpSetEvent(p, STREAM_FIN2_ACK_WRONG_SEQ);
- return -1;
- }
+ if (!retransmission) {
+ if (SEQ_LEQ(TCP_GET_SEQ(p) + p->payload_len, ssn->server.next_win) ||
+ (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);
+ } else {
+ SCLogDebug("ssn %p: -> SEQ mismatch, packet SEQ %" PRIu32 ""
+ " != %" PRIu32 " from stream", ssn,
+ TCP_GET_SEQ(p), ssn->server.next_seq);
+ 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));
"%" PRIu32 ", ACK %" PRIu32 "", ssn, p->payload_len,
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) {
SCLogDebug("ssn %p: -> SEQ mismatch, packet SEQ %" PRIu32 ""
" != %" PRIu32 " from stream", ssn,
"%" PRIu32 ", ACK %" PRIu32 "", ssn, p->payload_len,
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) {
SCLogDebug("ssn %p: -> SEQ mismatch, packet SEQ %" PRIu32 ""
" != %" PRIu32 " from stream", ssn,
"%" PRIu32 ", ACK %" PRIu32 "", ssn, p->payload_len,
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) ||
SEQ_GT(TCP_GET_SEQ(p), (ssn->client.last_ack + ssn->client.window)))
{
"%" PRIu32 ", ACK %" PRIu32 "", ssn, p->payload_len,
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) ||
SEQ_GT(TCP_GET_SEQ(p), (ssn->server.last_ack + ssn->server.window)))
{
"%" PRIu32 ", ACK %" PRIu32 "", ssn, p->payload_len,
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))) {
SCLogDebug("ssn %p: -> retransmission", ssn);
StreamTcpSetEvent(p, STREAM_CLOSEWAIT_PKT_BEFORE_LAST_ACK);
"%" PRIu32 ", ACK %" PRIu32 "", ssn, p->payload_len,
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))) {
SCLogDebug("ssn %p: -> retransmission", ssn);
StreamTcpSetEvent(p, STREAM_CLOSEWAIT_PKT_BEFORE_LAST_ACK);
"%" PRIu32 ", ACK %" PRIu32 "", ssn, p->payload_len,
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) {
SCLogDebug("ssn %p: -> SEQ mismatch, packet SEQ %" PRIu32 ""
" != %" PRIu32 " from stream", ssn,
"%" PRIu32 ", ACK %" PRIu32 "", ssn, p->payload_len,
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) {
SCLogDebug("ssn %p: -> SEQ mismatch, packet SEQ %" PRIu32 ""
" != %" PRIu32 " from stream", ssn,
StreamTcpPseudoPacketCreateStreamEndPacket(p, ssn, pq);
} else {
- int retransmission = 0;
-
SCLogDebug("ssn %p: pkt (%" PRIu32 ") is to client: SEQ "
"%" PRIu32 ", ACK %" PRIu32 "", ssn, p->payload_len,
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 (p->payload_len > 0 && TCP_GET_SEQ(p) == ssn->server.last_ack) {
SCLogDebug("ssn %p: -> retransmission", ssn);
- retransmission = 1;
- } 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;
+ SCReturnInt(0);
} else {
SCLogDebug("ssn %p: -> SEQ mismatch, packet SEQ %" PRIu32 ""
" != %" PRIu32 " from stream", ssn,
SCReturnInt(-1);
}
- if (!retransmission) {
- StreamTcpPacketSetState(p, ssn, TCP_CLOSED);
- SCLogDebug("ssn %p: state changed to TCP_CLOSED", ssn);
- }
+ StreamTcpPacketSetState(p, ssn, TCP_CLOSED);
+ SCLogDebug("ssn %p: state changed to TCP_CLOSED", ssn);
ssn->client.window = TCP_GET_WINDOW(p) << ssn->client.wscale;