From: Victor Julien Date: Sat, 6 Apr 2013 15:52:44 +0000 (+0200) Subject: stream: intro function for SYN/ACK state update X-Git-Tag: suricata-2.0beta1~187 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=b8078742c3da82164202621a72810aa15cdbc6d6;p=thirdparty%2Fsuricata.git stream: intro function for SYN/ACK state update As the TCP SSN state can be updated from several points in the state machine on accepting a SYN/ACK, move the update logic into a separate function. --- diff --git a/src/stream-tcp.c b/src/stream-tcp.c index e70479bc1a..46c86000dd 100644 --- a/src/stream-tcp.c +++ b/src/stream-tcp.c @@ -906,6 +906,83 @@ static int StreamTcpPacketStateNone(ThreadVars *tv, Packet *p, return 0; } +/** \internal + * \brief Update SSN after receiving a valid SYN/ACK + */ +static void StreamTcp3whsSynAckUpdate(TcpSession *ssn, Packet *p) { + if (ssn->state != TCP_SYN_RECV) { + /* update state */ + StreamTcpPacketSetState(p, ssn, TCP_SYN_RECV); + SCLogDebug("ssn %p: =~ ssn state is now TCP_SYN_RECV", ssn); + } + /* sequence number & window */ + ssn->server.isn = TCP_GET_SEQ(p); + STREAMTCP_SET_RA_BASE_SEQ(&ssn->server, ssn->server.isn); + ssn->server.next_seq = ssn->server.isn + 1; + + ssn->client.window = TCP_GET_WINDOW(p); + SCLogDebug("ssn %p: window %" PRIu32 "", ssn, ssn->server.window); + + /* Set the timestamp values used to validate the timestamp of + * received packets.*/ + if ((p->tcpvars.ts != NULL) && + (ssn->client.flags & STREAMTCP_STREAM_FLAG_TIMESTAMP)) + { + ssn->server.last_ts = TCP_GET_TSVAL(p); + SCLogDebug("ssn %p: ssn->server.last_ts %" PRIu32" " + "ssn->client.last_ts %" PRIu32"", ssn, + ssn->server.last_ts, ssn->client.last_ts); + ssn->flags |= STREAMTCP_FLAG_TIMESTAMP; + ssn->server.last_pkt_ts = p->ts.tv_sec; + if (ssn->server.last_ts == 0) + ssn->server.flags |= STREAMTCP_STREAM_FLAG_ZERO_TIMESTAMP; + } else { + ssn->client.last_ts = 0; + ssn->server.last_ts = 0; + ssn->client.flags &= ~STREAMTCP_STREAM_FLAG_ZERO_TIMESTAMP; + } + + ssn->client.last_ack = TCP_GET_ACK(p); + ssn->server.last_ack = ssn->server.isn + 1; + + /** check for the presense of the ws ptr to determine if we + * support wscale at all */ + if ((ssn->flags & STREAMTCP_FLAG_SERVER_WSCALE) && + (p->tcpvars.ws != NULL)) + { + ssn->client.wscale = TCP_GET_WSCALE(p); + } else { + ssn->client.wscale = 0; + } + + if ((ssn->flags & STREAMTCP_FLAG_CLIENT_SACKOK) && + TCP_GET_SACKOK(p) == 1) { + ssn->flags |= STREAMTCP_FLAG_SACKOK; + SCLogDebug("ssn %p: SACK permitted for session", ssn); + } + + ssn->server.next_win = ssn->server.last_ack + ssn->server.window; + ssn->client.next_win = ssn->client.last_ack + ssn->client.window; + SCLogDebug("ssn %p: ssn->server.next_win %" PRIu32 "", ssn, + ssn->server.next_win); + SCLogDebug("ssn %p: ssn->client.next_win %" PRIu32 "", ssn, + ssn->client.next_win); + SCLogDebug("ssn %p: ssn->server.isn %" PRIu32 ", " + "ssn->server.next_seq %" PRIu32 ", " + "ssn->server.last_ack %" PRIu32 " " + "(ssn->client.last_ack %" PRIu32 ")", ssn, + ssn->server.isn, ssn->server.next_seq, + ssn->server.last_ack, ssn->client.last_ack); + + /* unset the 4WHS flag as we received this SYN/ACK as part of a + * (so far) valid 3WHS */ + if (ssn->flags & STREAMTCP_FLAG_4WHS) + SCLogDebug("ssn %p: STREAMTCP_FLAG_4WHS unset, normal SYN/ACK" + " so considering 3WHS", ssn); + + ssn->flags &=~ STREAMTCP_FLAG_4WHS; +} + /** * \brief Function to handle the TCP_SYN_SENT state. The function handles * SYN, SYN/ACK, RST packets and correspondingly changes the connection @@ -1065,76 +1142,7 @@ static int StreamTcpPacketStateSynSent(ThreadVars *tv, Packet *p, return -1; } - /* update state */ - StreamTcpPacketSetState(p, ssn, TCP_SYN_RECV); - SCLogDebug("ssn %p: =~ ssn state is now TCP_SYN_RECV", ssn); - - /* sequence number & window */ - ssn->server.isn = TCP_GET_SEQ(p); - STREAMTCP_SET_RA_BASE_SEQ(&ssn->server, ssn->server.isn); - ssn->server.next_seq = ssn->server.isn + 1; - - ssn->client.window = TCP_GET_WINDOW(p); - SCLogDebug("ssn %p: window %" PRIu32 "", ssn, ssn->server.window); - - /* Set the timestamp values used to validate the timestamp of - * received packets.*/ - if ((p->tcpvars.ts != NULL) && - (ssn->client.flags & STREAMTCP_STREAM_FLAG_TIMESTAMP)) - { - ssn->server.last_ts = TCP_GET_TSVAL(p); - SCLogDebug("ssn %p: ssn->server.last_ts %" PRIu32" " - "ssn->client.last_ts %" PRIu32"", ssn, - ssn->server.last_ts, ssn->client.last_ts); - ssn->flags |= STREAMTCP_FLAG_TIMESTAMP; - ssn->server.last_pkt_ts = p->ts.tv_sec; - if (ssn->server.last_ts == 0) - ssn->server.flags |= STREAMTCP_STREAM_FLAG_ZERO_TIMESTAMP; - } else { - ssn->client.last_ts = 0; - ssn->server.last_ts = 0; - ssn->client.flags &= ~STREAMTCP_STREAM_FLAG_ZERO_TIMESTAMP; - } - - ssn->client.last_ack = TCP_GET_ACK(p); - ssn->server.last_ack = ssn->server.isn + 1; - - /** check for the presense of the ws ptr to determine if we - * support wscale at all */ - if ((ssn->flags & STREAMTCP_FLAG_SERVER_WSCALE) && - (p->tcpvars.ws != NULL)) - { - ssn->client.wscale = TCP_GET_WSCALE(p); - } else { - ssn->client.wscale = 0; - } - - if ((ssn->flags & STREAMTCP_FLAG_CLIENT_SACKOK) && - TCP_GET_SACKOK(p) == 1) { - ssn->flags |= STREAMTCP_FLAG_SACKOK; - SCLogDebug("ssn %p: SACK permitted for session", ssn); - } - - ssn->server.next_win = ssn->server.last_ack + ssn->server.window; - ssn->client.next_win = ssn->client.last_ack + ssn->client.window; - SCLogDebug("ssn %p: ssn->server.next_win %" PRIu32 "", ssn, - ssn->server.next_win); - SCLogDebug("ssn %p: ssn->client.next_win %" PRIu32 "", ssn, - ssn->client.next_win); - SCLogDebug("ssn %p: ssn->server.isn %" PRIu32 ", " - "ssn->server.next_seq %" PRIu32 ", " - "ssn->server.last_ack %" PRIu32 " " - "(ssn->client.last_ack %" PRIu32 ")", ssn, - ssn->server.isn, ssn->server.next_seq, - ssn->server.last_ack, ssn->client.last_ack); - - /* unset the 4WHS flag as we received this SYN/ACK as part of a - * (so far) valid 3WHS */ - if (ssn->flags & STREAMTCP_FLAG_4WHS) - SCLogDebug("ssn %p: STREAMTCP_FLAG_4WHS unset, normal SYN/ACK" - " so considering 3WHS", ssn); - - ssn->flags &=~ STREAMTCP_FLAG_4WHS; + StreamTcp3whsSynAckUpdate(ssn, p); } else if (p->tcph->th_flags & TH_SYN) { SCLogDebug("ssn %p: SYN packet on state SYN_SENT... resent", ssn);