From: Victor Julien Date: Thu, 16 Aug 2012 10:41:53 +0000 (+0200) Subject: stream: handle case where Suricata sees 3whs-ACK but server doesn't. Bug #523. X-Git-Tag: suricata-1.3.1~7 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=c51a3aad17778da8912bf5b971370e406881ba50;p=thirdparty%2Fsuricata.git stream: handle case where Suricata sees 3whs-ACK but server doesn't. Bug #523. --- diff --git a/src/stream-tcp-private.h b/src/stream-tcp-private.h index 385c48a062..bf16625862 100644 --- a/src/stream-tcp-private.h +++ b/src/stream-tcp-private.h @@ -119,6 +119,11 @@ enum /** Flag for triggering RAW reassembly before the size limit is reached or the stream reaches EOF. */ #define STREAMTCP_FLAG_TRIGGER_RAW_REASSEMBLY 0x1000 +/** 3WHS confirmed by server -- if suri sees 3whs ACK but server doesn't (pkt + * is lost on the way to server), SYN/ACK is retransmitted. If server sends + * normal packet we assume 3whs to be completed. Only used for SYN/ACK resend + * event. */ +#define STREAMTCP_FLAG_3WHS_CONFIRMED 0x2000 /* * Per STREAM flags diff --git a/src/stream-tcp.c b/src/stream-tcp.c index 4ea3d4823b..01a132faf8 100644 --- a/src/stream-tcp.c +++ b/src/stream-tcp.c @@ -1957,9 +1957,19 @@ static int StreamTcpPacketStateEstablished(ThreadVars *tv, Packet *p, return -1; } - /* a resend of a SYN while we are established already -- fishy */ - StreamTcpSetEvent(p, STREAM_EST_SYNACK_RESEND); - return -1; + if (ssn->flags & STREAMTCP_FLAG_3WHS_CONFIRMED) { + /* a resend of a SYN while we are established already -- fishy */ + StreamTcpSetEvent(p, STREAM_EST_SYNACK_RESEND); + return -1; + } + + SCLogDebug("ssn %p: SYN/ACK packet on state ESTABLISHED... resent. " + "Likely due server not receiving final ACK in 3whs", ssn); + + /* resetting state to TCP_SYN_RECV as we should get another ACK now */ + StreamTcpPacketSetState(p, ssn, TCP_SYN_RECV); + SCLogDebug("ssn %p: =~ ssn state is now reset to TCP_SYN_RECV", ssn); + return 0; } else if (p->tcph->th_flags & TH_SYN) { SCLogDebug("ssn %p: SYN packet on state ESTABLISED... resent", ssn); @@ -2006,6 +2016,8 @@ static int StreamTcpPacketStateEstablished(ThreadVars *tv, Packet *p, ,ssn->client.next_win, ssn->client.window); } else { /* implied to client */ + ssn->flags |= STREAMTCP_FLAG_3WHS_CONFIRMED; + SCLogDebug("3whs is now confirmed by server"); /* Process the received packet to client */ HandleEstablishedPacketToClient(tv, ssn, p, stt, pq);