stream: handle retransmission of lost data packet on TIME_WAIT state

pull/141/merge
Victor Julien 14 years ago
parent 037d67cc66
commit a5d9442c2d

@ -2020,8 +2020,10 @@ static int StreamTcpPacketStateEstablished(ThreadVars *tv, Packet *p,
,ssn->client.next_win, ssn->client.window); ,ssn->client.next_win, ssn->client.window);
} else { /* implied to client */ } else { /* implied to client */
ssn->flags |= STREAMTCP_FLAG_3WHS_CONFIRMED; if (!(ssn->flags & STREAMTCP_FLAG_3WHS_CONFIRMED)) {
SCLogDebug("3whs is now confirmed by server"); ssn->flags |= STREAMTCP_FLAG_3WHS_CONFIRMED;
SCLogDebug("3whs is now confirmed by server");
}
/* Process the received packet to client */ /* Process the received packet to client */
HandleEstablishedPacketToClient(tv, ssn, p, stt, pq); HandleEstablishedPacketToClient(tv, ssn, p, stt, pq);
@ -3470,7 +3472,7 @@ 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 (TCP_GET_SEQ(p) != ssn->client.next_seq) { 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,
TCP_GET_SEQ(p), ssn->client.next_seq); TCP_GET_SEQ(p), ssn->client.next_seq);
@ -3508,16 +3510,23 @@ 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 (TCP_GET_SEQ(p) != ssn->server.next_seq) { if (TCP_GET_SEQ(p) != ssn->server.next_seq && TCP_GET_SEQ(p) != ssn->server.next_seq+1) {
SCLogDebug("ssn %p: -> SEQ mismatch, packet SEQ %" PRIu32 "" if (p->payload_len > 0 && TCP_GET_SEQ(p) == ssn->server.last_ack) {
" != %" PRIu32 " from stream", ssn, SCLogDebug("ssn %p: -> retransmission", ssn);
TCP_GET_SEQ(p), ssn->server.next_seq); retransmission = 1;
StreamTcpSetEvent(p, STREAM_TIMEWAIT_ACK_WRONG_SEQ); } else {
return -1; SCLogDebug("ssn %p: -> SEQ mismatch, packet SEQ %" PRIu32 ""
" != %" PRIu32 " from stream", ssn,
TCP_GET_SEQ(p), ssn->server.next_seq);
StreamTcpSetEvent(p, STREAM_TIMEWAIT_ACK_WRONG_SEQ);
return -1;
}
} }
if (StreamTcpValidateAck(ssn, &ssn->client, p) == -1) { if (StreamTcpValidateAck(ssn, &ssn->client, p) == -1) {
@ -3526,8 +3535,10 @@ static int StreamTcpPacketStateTimeWait(ThreadVars *tv, Packet *p,
SCReturnInt(-1); SCReturnInt(-1);
} }
StreamTcpPacketSetState(p, ssn, TCP_CLOSED); if (!retransmission) {
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; ssn->client.window = TCP_GET_WINDOW(p) << ssn->client.wscale;

Loading…
Cancel
Save