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
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);