Split applayer and raw stream reassembly

Split stream reassembly in 2 parts: a part that sends ack'd data to the app
layer parsers as soon as it's available, and another part that queues up
data into larger chunks for raw inspection.
remotes/origin/master-1.1.x
Victor Julien 14 years ago
parent dda6d3e07b
commit 8fa5a2c025

@ -668,7 +668,9 @@ static int AppLayerDoParse(Flow *f, void *app_layer_state, AppLayerParserState *
AppLayerParserResult result = { NULL, NULL, 0 };
SCLogDebug("parser_idx %" PRIu32 "", parser_idx);
//printf("--- (%u)\n", input_len);
//PrintRawDataFp(stdout, input,input_len);
//printf("---\n");
/* invoke the parser */
int r = al_parser_table[parser_idx].AppLayerParser(f, app_layer_state,
@ -764,8 +766,10 @@ end:
SCReturnInt(0);
}
#ifdef DEBUG
uint32_t applayererrors = 0;
uint32_t applayerhttperrors = 0;
#endif
/**
* \brief Layer 7 Parsing main entry point.
@ -915,10 +919,11 @@ int AppLayerParse(Flow *f, uint8_t proto, uint8_t flags, uint8_t *input,
SCReturnInt(0);
error:
if (ssn != NULL) {
#ifdef DEBUG
applayererrors++;
if (f->alproto == ALPROTO_HTTP)
applayerhttperrors++;
#endif
/* Set the no app layer inspection flag for both
* the stream in this Flow */
FlowSetSessionNoApplayerInspectionFlag(f);

@ -898,8 +898,9 @@ static int TLSParserTest05(void) {
AppLayerParserState *parser_state = &parser_state_store->to_server;
if (!(parser_state->flags & APP_LAYER_PARSER_NO_INSPECTION) &&
!(ssn.flags & STREAMTCP_FLAG_NOCLIENT_REASSEMBLY) &&
!(ssn.flags & STREAMTCP_FLAG_NOSERVER_REASSEMBLY)) {
!(ssn.client.flags & STREAMTCP_STREAM_FLAG_NOREASSEMBLY) &&
!(ssn.server.flags & STREAMTCP_STREAM_FLAG_NOREASSEMBLY))
{
printf("The flags should be set\n");
result = 0;
goto end;
@ -993,8 +994,8 @@ static int TLSParserTest06(void) {
AppLayerParserState *parser_state = &parser_state_store->to_server;
if ((parser_state->flags & APP_LAYER_PARSER_NO_INSPECTION) ||
(ssn.flags & STREAMTCP_FLAG_NOCLIENT_REASSEMBLY) ||
(ssn.flags & STREAMTCP_FLAG_NOSERVER_REASSEMBLY)) {
(ssn.client.flags & STREAMTCP_STREAM_FLAG_NOREASSEMBLY) ||
(ssn.server.flags & STREAMTCP_STREAM_FLAG_NOREASSEMBLY)) {
printf("The flags should not be set\n");
result = 0;
goto end;
@ -1019,8 +1020,8 @@ static int TLSParserTest06(void) {
}
if (!(parser_state->flags & APP_LAYER_PARSER_NO_INSPECTION) &&
!(ssn.flags & STREAMTCP_FLAG_NOCLIENT_REASSEMBLY) &&
!(ssn.flags & STREAMTCP_FLAG_NOSERVER_REASSEMBLY)) {
!(ssn.client.flags & STREAMTCP_STREAM_FLAG_NOREASSEMBLY) &&
!(ssn.server.flags & STREAMTCP_STREAM_FLAG_NOREASSEMBLY)) {
printf("The flags should be set\n");
result = 0;
goto end;
@ -1337,8 +1338,8 @@ static int TLSParserTest08(void) {
AppLayerParserState *parser_state = &parser_state_store->to_server;
if (!(parser_state->flags & APP_LAYER_PARSER_NO_INSPECTION) &&
!(ssn.flags & STREAMTCP_FLAG_NOCLIENT_REASSEMBLY) &&
!(ssn.flags & STREAMTCP_FLAG_NOSERVER_REASSEMBLY)) {
!(ssn.client.flags & STREAMTCP_STREAM_FLAG_NOREASSEMBLY) &&
!(ssn.server.flags & STREAMTCP_STREAM_FLAG_NOREASSEMBLY)) {
printf("The flags should be set\n");
result = 0;
goto end;

@ -102,6 +102,8 @@ void *AppLayerGetProtoStateFromFlow(Flow *f) {
/** global app layer detection context */
extern AlpProtoDetectCtx alp_proto_ctx;
//#define PRINT
/**
* \brief Handle a chunk of TCP data
*
@ -131,29 +133,46 @@ int AppLayerHandleTCPData(AlpProtoDetectThreadCtx *dp_ctx, Flow *f,
alproto = f->alproto;
/* Copy some needed flags */
if (flags & STREAM_TOSERVER)
if (flags & STREAM_TOSERVER) {
f->alflags |= FLOW_AL_STREAM_TOSERVER;
else if (flags & STREAM_TOCLIENT)
SCLogDebug("STREAM_TOSERVER");
} else if (flags & STREAM_TOCLIENT) {
f->alflags |= FLOW_AL_STREAM_TOCLIENT;
SCLogDebug("STREAM_TOCLIENT");
}
if (flags & STREAM_GAP)
if (flags & STREAM_GAP) {
f->alflags |= FLOW_AL_STREAM_GAP;
if (flags & STREAM_EOF)
SCLogDebug("STREAM_GAP");
}
if (flags & STREAM_EOF) {
f->alflags |= FLOW_AL_STREAM_EOF;
SCLogDebug("STREAM_EOF");
}
SCLogDebug("data_len %u flags %02X", data_len, flags);
if (!(f->alflags & FLOW_AL_NO_APPLAYER_INSPECTION)) {
/* if we don't know the proto yet and we have received a stream
* initializer message, we run proto detection.
* We receive 2 stream init msgs (one for each direction) but we
* only run the proto detection once. */
if (alproto == ALPROTO_UNKNOWN && flags & STREAM_START) {
SCLogDebug("Stream initializer (len %" PRIu32 " (%" PRIu32 "))",
data_len, MSG_DATA_SIZE);
//printf("=> Init Stream Data -- start\n");
//PrintRawDataFp(stdout, data, data_len);
//printf("=> Init Stream Data -- end\n");
if (alproto == ALPROTO_UNKNOWN && flags & STREAM_GAP) {
ssn->flags |= STREAMTCP_FLAG_APPPROTO_DETECTION_COMPLETED;
f->alflags |= FLOW_AL_PROTO_DETECT_DONE;
SCLogDebug("ALPROTO_UNKNOWN flow %p, due to GAP in stream start", f);
StreamTcpSetSessionNoReassemblyFlag(ssn, 0);
} else if (alproto == ALPROTO_UNKNOWN && flags & STREAM_START) {
SCLogDebug("Stream initializer (len %" PRIu32 ")", data_len);
#ifdef PRINT
if (data_len > 0) {
printf("=> Init Stream Data -- start %s%s\n",
flags & STREAM_TOCLIENT ? "toclient" : "",
flags & STREAM_TOSERVER ? "toserver" : "");
PrintRawDataFp(stdout, data, data_len);
printf("=> Init Stream Data -- end\n");
}
#endif
alproto = AppLayerDetectGetProto(&alp_proto_ctx, dp_ctx,
data, data_len, f->alflags, IPPROTO_TCP);
if (alproto != ALPROTO_UNKNOWN) {
@ -166,6 +185,7 @@ int AppLayerHandleTCPData(AlpProtoDetectThreadCtx *dp_ctx, Flow *f,
r = AppLayerParse(f, alproto, f->alflags, data, data_len);
} else {
if (flags & STREAM_TOSERVER) {
SCLogDebug("alp_proto_ctx.toserver.max_len %u", alp_proto_ctx.toserver.max_len);
if (data_len >= alp_proto_ctx.toserver.max_len) {
ssn->flags |= STREAMTCP_FLAG_APPPROTO_DETECTION_COMPLETED;
f->alflags |= FLOW_AL_PROTO_DETECT_DONE;
@ -182,14 +202,17 @@ int AppLayerHandleTCPData(AlpProtoDetectThreadCtx *dp_ctx, Flow *f,
}
}
} else {
SCLogDebug("stream data (len %" PRIu32 " (%" PRIu32 ")), alproto "
"%"PRIu16" (flow %p)", data_len, MSG_DATA_SIZE,
alproto, f);
//printf("=> Stream Data -- start\n");
//PrintRawDataFp(stdout, data, data_len);
//printf("=> Stream Data -- end\n");
SCLogDebug("stream data (len %" PRIu32 " alproto "
"%"PRIu16" (flow %p)", data_len, alproto, f);
#ifdef PRINT
if (data_len > 0) {
printf("=> Stream Data -- start %s%s\n",
flags & STREAM_TOCLIENT ? "toclient" : "",
flags & STREAM_TOSERVER ? "toserver" : "");
PrintRawDataFp(stdout, data, data_len);
printf("=> Stream Data -- end\n");
}
#endif
/* if we don't have a data object here we are not getting it
* a start msg should have gotten us one */
if (alproto != ALPROTO_UNKNOWN) {
@ -198,11 +221,88 @@ int AppLayerHandleTCPData(AlpProtoDetectThreadCtx *dp_ctx, Flow *f,
SCLogDebug(" smsg not start, but no l7 data? Weird");
}
}
} else {
SCLogDebug("FLOW_AL_NO_APPLAYER_INSPECTION is set");
}
SCReturnInt(r);
}
/**
* \brief Attach a stream message to the TCP session for inspection
* in the detection engine.
*
* \param dp_ctx Thread app layer detect context
* \param smsg Stream message
*
* \retval 0 ok
* \retval -1 error
*/
int AppLayerHandleTCPMsg(AlpProtoDetectThreadCtx *dp_ctx, StreamMsg *smsg)
{
SCEnter();
SCLogDebug("smsg %p", smsg);
BUG_ON(smsg->flow == NULL);
TcpSession *ssn = smsg->flow->protoctx;
if (ssn != NULL) {
SCLogDebug("storing smsg %p in the tcp session", smsg);
/* store the smsg in the tcp stream */
if (smsg->flags & STREAM_TOSERVER) {
SCLogDebug("storing smsg in the to_server");
/* put the smsg in the stream list */
if (ssn->toserver_smsg_head == NULL) {
ssn->toserver_smsg_head = smsg;
ssn->toserver_smsg_tail = smsg;
smsg->next = NULL;
smsg->prev = NULL;
} else {
StreamMsg *cur = ssn->toserver_smsg_tail;
cur->next = smsg;
smsg->prev = cur;
smsg->next = NULL;
ssn->toserver_smsg_tail = smsg;
}
} else {
SCLogDebug("storing smsg in the to_client");
/* put the smsg in the stream list */
if (ssn->toclient_smsg_head == NULL) {
ssn->toclient_smsg_head = smsg;
ssn->toclient_smsg_tail = smsg;
smsg->next = NULL;
smsg->prev = NULL;
} else {
StreamMsg *cur = ssn->toclient_smsg_tail;
cur->next = smsg;
smsg->prev = cur;
smsg->next = NULL;
ssn->toclient_smsg_tail = smsg;
}
}
/* flow is free again */
FlowDecrUsecnt(smsg->flow);
/* dereference the flow */
smsg->flow = NULL;
} else { /* no ssn ptr */
/* if there is no ssn ptr we won't
* be inspecting this msg in detect
* so return it to the pool. */
/* flow is free again */
FlowDecrUsecnt(smsg->flow);
/* return the used message to the queue */
StreamMsgReturnToPool(smsg);
}
SCReturnInt(0);
}
/**
* \brief Handle a app layer TCP message
*

@ -27,14 +27,19 @@
#include "flow.h"
#include "decode.h"
#include "stream-tcp.h"
#include "app-layer-protos.h"
#include "app-layer-parser.h"
#include "app-layer-detect-proto.h"
#include "stream.h"
uint16_t AppLayerGetProtoFromPacket(Packet *);
void *AppLayerGetProtoStateFromPacket(Packet *);
void *AppLayerGetProtoStateFromFlow(Flow *);
int AppLayerHandleTCPData(AlpProtoDetectThreadCtx *, Flow *, TcpSession *, uint8_t *, uint32_t, uint8_t);
int AppLayerHandleTCPMsg(AlpProtoDetectThreadCtx *, StreamMsg *);
int AppLayerHandleMsg(AlpProtoDetectThreadCtx *, StreamMsg *);
int AppLayerHandleUdp(AlpProtoDetectThreadCtx *, Flow *, Packet *p);

@ -48,16 +48,17 @@ typedef struct TcpStream_ {
longer time.(RFC 1323)*/
/* reassembly */
uint32_t ra_base_seq; /**< reassembled seq. We've reassembled up to this point. */
uint32_t ra_app_base_seq; /**< reassembled seq. We've reassembled up to this point. */
uint32_t tmp_ra_app_base_seq; /**< Temporary reassembled seq, to be used until
app layer protocol has not been detected,
beacuse every smsg needs to contain all the
initial segments too */
uint32_t ra_raw_base_seq; /**< reassembled seq. We've reassembled up to this point. */
TcpSegment *seg_list; /**< list of TCP segments that are not yet (fully) used in reassembly */
uint8_t wscale; /**< wscale setting in this direction */
uint8_t os_policy; /**< target based OS policy used for reassembly and handling packets*/
uint16_t flags; /**< Flag specific to the stream e.g. Timestamp */
TcpSegment *seg_list_tail; /**< Last segment in the reassembled stream seg list*/
uint32_t tmp_ra_base_seq; /**< Temporary reassembled seq, to be used until
app layer protocol has not been detected,
beacuse every smsg needs to contain all the
initial segments too */
uint32_t reassembly_depth; /**< The depth value of a stream until when, we
will reassemble the stream */
} TcpStream;
@ -79,73 +80,57 @@ enum
TCP_CLOSED,
};
#define STREAMTCP_FLAG_MIDSTREAM 0x0001 /**< Flag for mid stream
session*/
#define STREAMTCP_FLAG_MIDSTREAM_ESTABLISHED 0x0002 /**< Flag for mid stream
established
session*/
#define STREAMTCP_FLAG_MIDSTREAM_SYNACK 0x0004 /**< Flag for mid session
when syn/ack is
received*/
#define STREAMTCP_FLAG_TIMESTAMP 0x0008 /**< Flag for TCP
Timestamp option*/
#define STREAMTCP_FLAG_SERVER_WSCALE 0x0010 /**< Server supports
wscale (even though
it can be 0) */
#define STREAMTCP_FLAG_ZERO_TIMESTAMP 0x0020 /**< Flag to indicate the
zero value of
timestamp*/
#define STREAMTCP_FLAG_NOCLIENT_REASSEMBLY 0x0040 /**< Flag to avoid stream
reassembly/app layer
inspection for the
client stream.*/
#define STREAMTCP_FLAG_NOSERVER_REASSEMBLY 0x0080 /**< Flag to avoid stream
reassembly / app layer
inspection for the
server stream.*/
#define STREAMTCP_FLAG_ASYNC 0x0100 /**< Flag to indicate
that the session is
handling asynchronous
stream.*/
#define STREAMTCP_FLAG_4WHS 0x0200 /**< Flag to indicate
we're dealing with
4WHS: SYN, SYN,
SYN/ACK, ACK
(http://www.breakingpointsystems.com/community/blog/tcp-portals-the-three-way-handshake-is-a-lie) */
#define STREAMTCP_FLAG_APPPROTO_DETECTION_COMPLETED 0x0400 /**< Flag to indicate
the app layer has
detected the app
layer protocol on
the current
TCP session */
#define STREAMTCP_FLAG_PAUSE_TOSERVER_REASSEMBLY 0x0800 /**< Flag to pause stream
reassembly / app layer
inspection for the
server stream.*/
#define STREAMTCP_FLAG_PAUSE_TOCLIENT_REASSEMBLY 0x1000 /**< Flag to pause stream
reassembly / app layer
inspection for the
client stream.*/
#define STREAMTCP_FLAG_DETECTION_EVASION_ATTEMPT 0x2000 /**< Flag to indicate
that this session
is possible trying
to evade the detection
(http://www.packetstan.com/2010/06/recently-ive-been-on-campaign-to-make.html) */
#define STREAMTCP_FLAG_TOSERVER_REASSEMBLY_STARTED 0x4000 /**< Flag to indicate
that this session
has reassembled to_server
chunks */
#define SEGMENTTCP_FLAG_PROCESSED 0x01 /**< Flag to indicate
that the current
segment has been
processed by the
reassembly code and
should be deleted
after app layer
protocol has been
detected. */
/*
* Per SESSION flags
*/
/** Flag for mid stream session */
#define STREAMTCP_FLAG_MIDSTREAM 0x0001
/** Flag for mid stream established session */
#define STREAMTCP_FLAG_MIDSTREAM_ESTABLISHED 0x0002
/** Flag for mid session when syn/ack is received */
#define STREAMTCP_FLAG_MIDSTREAM_SYNACK 0x0004
/** Flag for TCP Timestamp option */
#define STREAMTCP_FLAG_TIMESTAMP 0x0008
/** Server supports wscale (even though it can be 0) */
#define STREAMTCP_FLAG_SERVER_WSCALE 0x0010
/** Flag to indicate the zero value of timestamp */
#define STREAMTCP_FLAG_ZERO_TIMESTAMP 0x0020
/** Flag to indicate that the session is handling asynchronous stream.*/
#define STREAMTCP_FLAG_ASYNC 0x0040
/** Flag to indicate we're dealing with 4WHS: SYN, SYN, SYN/ACK, ACK
* (http://www.breakingpointsystems.com/community/blog/tcp-portals-the-three-way-handshake-is-a-lie) */
#define STREAMTCP_FLAG_4WHS 0x0080
/** Flag to indicate the app layer has detected the app layer protocol on
* the current TCP session */
#define STREAMTCP_FLAG_APPPROTO_DETECTION_COMPLETED 0x0100
/** Flag to indicate that this session is possible trying to evade the detection
* (http://www.packetstan.com/2010/06/recently-ive-been-on-campaign-to-make.html) */
#define STREAMTCP_FLAG_DETECTION_EVASION_ATTEMPT 0x0200
/** Flag to indicate that this stream direction has reassembled chunks */
#define STREAMTCP_FLAG_TOSERVER_REASSEMBLY_STARTED 0x0400
/*
* Per STREAM flags
*/
/** stream is in a gap state */
#define STREAMTCP_STREAM_FLAG_GAP 0x01
/** Flag to avoid stream reassembly/app layer inspection for the stream */
#define STREAMTCP_STREAM_FLAG_NOREASSEMBLY 0x02
/** Flag to pause stream reassembly / app layer inspection for the stream.*/
#define STREAMTCP_STREAM_FLAG_PAUSE_REASSEMBLY 0x04
/*
* Per SEGMENT flags
*/
/** Flag to indicate that the current segment has been processed by the
* reassembly code and should be deleted after app layer protocol has been
* detected. */
#define SEGMENTTCP_FLAG_RAW_PROCESSED 0x01
/** App Layer reassembly code is done with this segment */
#define SEGMENTTCP_FLAG_APPLAYER_PROCESSED 0x02
#define PAWS_24DAYS 2073600 /**< 24 days in seconds */
@ -162,6 +147,14 @@ enum
#define SEQ_GT(a,b) ((int32_t)((a) - (b)) > 0)
#define SEQ_GEQ(a,b) ((int32_t)((a) - (b)) >= 0)
#define STREAMTCP_SET_RA_BASE_SEQ(stream, seq) { \
do { \
(stream)->ra_raw_base_seq = (seq); \
(stream)->ra_app_base_seq = (seq); \
(stream)->tmp_ra_app_base_seq = (seq); \
} while(0); \
}
typedef struct TcpSession_ {
uint8_t state;
uint16_t flags;

File diff suppressed because it is too large Load Diff

@ -615,8 +615,7 @@ static int StreamTcpPacketStateNone(ThreadVars *tv, Packet *p,
/* set the sequence numbers and window */
ssn->client.isn = TCP_GET_SEQ(p);
ssn->client.ra_base_seq = ssn->client.isn;
ssn->client.tmp_ra_base_seq = ssn->client.isn;
STREAMTCP_SET_RA_BASE_SEQ(&ssn->client, ssn->client.isn);
ssn->client.next_seq = ssn->client.isn + 1;
/*Set the stream timestamp value, if packet has timestamp option
@ -670,15 +669,13 @@ static int StreamTcpPacketStateNone(ThreadVars *tv, Packet *p,
/* sequence number & window */
ssn->server.isn = TCP_GET_SEQ(p);
ssn->server.ra_base_seq = ssn->server.isn;
ssn->server.tmp_ra_base_seq = ssn->server.isn;
STREAMTCP_SET_RA_BASE_SEQ(&ssn->server, ssn->server.isn);
ssn->server.next_seq = ssn->server.isn + 1;
ssn->server.window = TCP_GET_WINDOW(p);
SCLogDebug("ssn %p: server window %u", ssn, ssn->server.window);
ssn->client.isn = TCP_GET_ACK(p) - 1;
ssn->client.ra_base_seq = ssn->client.isn;
ssn->client.tmp_ra_base_seq = ssn->client.isn;
STREAMTCP_SET_RA_BASE_SEQ(&ssn->client, ssn->client.isn);
ssn->client.next_seq = ssn->client.isn + 1;
ssn->client.last_ack = TCP_GET_ACK(p);
@ -752,8 +749,7 @@ static int StreamTcpPacketStateNone(ThreadVars *tv, Packet *p,
/* set the sequence numbers and window */
ssn->client.isn = TCP_GET_SEQ(p) - 1;
ssn->client.ra_base_seq = ssn->client.isn;
ssn->client.tmp_ra_base_seq = ssn->client.isn;
STREAMTCP_SET_RA_BASE_SEQ(&ssn->client, ssn->client.isn);
ssn->client.next_seq = TCP_GET_SEQ(p) + p->payload_len;
ssn->client.window = TCP_GET_WINDOW(p);
ssn->client.last_ack = TCP_GET_SEQ(p);
@ -762,8 +758,7 @@ static int StreamTcpPacketStateNone(ThreadVars *tv, Packet *p,
ssn, ssn->client.isn, ssn->client.next_seq);
ssn->server.isn = TCP_GET_ACK(p) - 1;
ssn->server.ra_base_seq = ssn->server.isn;
ssn->server.tmp_ra_base_seq = ssn->server.isn;
STREAMTCP_SET_RA_BASE_SEQ(&ssn->server, ssn->server.isn);
ssn->server.next_seq = ssn->server.isn + 1;
ssn->server.last_ack = TCP_GET_ACK(p);
ssn->server.next_win = ssn->server.last_ack;
@ -874,8 +869,7 @@ static int StreamTcpPacketStateSynSent(ThreadVars *tv, Packet *p,
* check the SYN/ACK pkt with that.
*/
ssn->server.isn = TCP_GET_SEQ(p);
ssn->server.ra_base_seq = ssn->server.isn;
ssn->server.tmp_ra_base_seq = ssn->server.isn;
STREAMTCP_SET_RA_BASE_SEQ(&ssn->server, ssn->server.isn);
ssn->server.next_seq = ssn->server.isn + 1;
/* Set the stream timestamp value, if packet has timestamp
@ -941,8 +935,7 @@ static int StreamTcpPacketStateSynSent(ThreadVars *tv, Packet *p,
/* sequence number & window */
ssn->client.isn = TCP_GET_SEQ(p);
ssn->client.ra_base_seq = ssn->client.isn;
ssn->client.tmp_ra_base_seq = ssn->client.isn;
STREAMTCP_SET_RA_BASE_SEQ(&ssn->client, ssn->client.isn);
ssn->client.next_seq = ssn->client.isn + 1;
ssn->server.window = TCP_GET_WINDOW(p);
@ -1020,8 +1013,7 @@ static int StreamTcpPacketStateSynSent(ThreadVars *tv, Packet *p,
/* sequence number & window */
ssn->server.isn = TCP_GET_SEQ(p);
ssn->server.ra_base_seq = ssn->server.isn;
ssn->server.tmp_ra_base_seq = ssn->server.isn;
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);
@ -1117,8 +1109,7 @@ static int StreamTcpPacketStateSynSent(ThreadVars *tv, Packet *p,
/* Set the server side parameters */
ssn->server.isn = TCP_GET_ACK(p) - 1;
ssn->server.ra_base_seq = ssn->server.isn;
ssn->server.tmp_ra_base_seq = ssn->server.isn;
STREAMTCP_SET_RA_BASE_SEQ(&ssn->server, ssn->server.isn);
ssn->server.next_seq = ssn->server.isn + 1;
ssn->server.last_ack = ssn->server.next_seq;
ssn->server.next_win = ssn->server.last_ack;
@ -1444,69 +1435,60 @@ static int HandleEstablishedPacketToServer(ThreadVars *tv, TcpSession *ssn, Pack
if (!(SEQ_GEQ(TCP_GET_SEQ(p), ssn->client.last_ack))) {
if (ssn->flags & STREAMTCP_FLAG_ASYNC) {
SCLogDebug("ssn %p: server => Asynchrouns stream, packet SEQ"
" %" PRIu32 ", payload size %" PRIu32 " (%" PRIu32 "),"
" ssn->client.last_ack %" PRIu32 ", ssn->client.next_win"
"%" PRIu32"(%"PRIu32") (ssn->client.ra_base_seq %"PRIu32")",
ssn, TCP_GET_SEQ(p), p->payload_len, TCP_GET_SEQ(p)
+p->payload_len, ssn->client.last_ack, ssn->client.next_win,
TCP_GET_SEQ(p) + p->payload_len - ssn->client.next_win,
ssn->client.ra_base_seq);
/*update the last_ack to current seq number as the session is
async and other stream is not updating it anymore :(*/
"%" PRIu32"(%"PRIu32")", ssn, TCP_GET_SEQ(p),
p->payload_len, TCP_GET_SEQ(p) + p->payload_len,
ssn->client.last_ack, ssn->client.next_win,
TCP_GET_SEQ(p) + p->payload_len - ssn->client.next_win);
/* update the last_ack to current seq number as the session is
* async and other stream is not updating it anymore :( */
ssn->client.last_ack = TCP_GET_SEQ(p);
} else if (SEQ_EQ(ssn->client.next_seq, TCP_GET_SEQ(p)) &&
(stream_config.async_oneside == TRUE) &&
(ssn->flags & STREAMTCP_FLAG_MIDSTREAM)) {
SCLogDebug("ssn %p: server => Asynchronous stream, packet SEQ."
" %" PRIu32 ", payload size %" PRIu32 " (%" PRIu32 "), "
"ssn->client.last_ack %" PRIu32 ", ssn->client.next_win "
"%" PRIu32 "(%"PRIu32") (ssn->client.ra_base_seq %"PRIu32")"
, ssn, TCP_GET_SEQ(p), p->payload_len, TCP_GET_SEQ(p)
+p->payload_len, ssn->client.last_ack, ssn->client.next_win,
TCP_GET_SEQ(p) + p->payload_len - ssn->client.next_win,
ssn->client.ra_base_seq);
"%" PRIu32 "(%"PRIu32")", ssn, TCP_GET_SEQ(p),
p->payload_len, TCP_GET_SEQ(p) + p->payload_len,
ssn->client.last_ack, ssn->client.next_win,
TCP_GET_SEQ(p) + p->payload_len - ssn->client.next_win);
/*it seems we missed SYN and SYN/ACK packets of this session.
/* it seems we missed SYN and SYN/ACK packets of this session.
* Update the last_ack to current seq number as the session
* is async and other stream is not updating it anymore :(*/
* is async and other stream is not updating it anymore :( */
ssn->client.last_ack = TCP_GET_SEQ(p);
ssn->flags |= STREAMTCP_FLAG_ASYNC;
} else if (SEQ_EQ(ssn->client.last_ack, (ssn->client.isn + 1)) &&
(stream_config.async_oneside == TRUE) &&
(ssn->flags & STREAMTCP_FLAG_MIDSTREAM)) {
SCLogDebug("ssn %p: server => Asynchronous stream, packet SEQ"
" %" PRIu32 ", payload size %" PRIu32 " (%" PRIu32 "), "
"ssn->client.last_ack %" PRIu32 ", ssn->client.next_win "
"%" PRIu32 "(%"PRIu32") (ssn->client.ra_base_seq %"PRIu32")"
, ssn, TCP_GET_SEQ(p), p->payload_len, TCP_GET_SEQ(p)
+p->payload_len, ssn->client.last_ack, ssn->client.next_win,
TCP_GET_SEQ(p) + p->payload_len - ssn->client.next_win,
ssn->client.ra_base_seq);
"%" PRIu32 "(%"PRIu32")", ssn, TCP_GET_SEQ(p),
p->payload_len, TCP_GET_SEQ(p) + p->payload_len,
ssn->client.last_ack, ssn->client.next_win,
TCP_GET_SEQ(p) + p->payload_len - ssn->client.next_win);
/*it seems we missed SYN and SYN/ACK packets of this session.
/* it seems we missed SYN and SYN/ACK packets of this session.
* Update the last_ack to current seq number as the session
* is async and other stream is not updating it anymore :(*/
ssn->client.last_ack = TCP_GET_SEQ(p);
ssn->flags |= STREAMTCP_FLAG_ASYNC;
} else {
SCLogDebug("ssn %p: server => SEQ before last_ack, packet SEQ"
" %" PRIu32 ", payload size %" PRIu32 " (%" PRIu32 "), "
"ssn->client.last_ack %" PRIu32 ", ssn->client.next_win "
"%" PRIu32 "(%"PRIu32") (ssn->client.ra_base_seq %"PRIu32")"
, ssn, TCP_GET_SEQ(p), p->payload_len, TCP_GET_SEQ(p)
+p->payload_len, ssn->client.last_ack, ssn->client.next_win,
TCP_GET_SEQ(p) + p->payload_len - ssn->client.next_win,
ssn->client.ra_base_seq);
"%" PRIu32 "(%"PRIu32")", ssn, TCP_GET_SEQ(p),
p->payload_len, TCP_GET_SEQ(p) + p->payload_len,
ssn->client.last_ack, ssn->client.next_win,
TCP_GET_SEQ(p) + p->payload_len - ssn->client.next_win);
return -1;
}
}
@ -1545,11 +1527,10 @@ static int HandleEstablishedPacketToServer(ThreadVars *tv, TcpSession *ssn, Pack
SCLogDebug("ssn %p: toserver => SEQ out of window, packet SEQ "
"%" PRIu32 ", payload size %" PRIu32 " (%" PRIu32 "),"
"ssn->client.last_ack %" PRIu32 ", ssn->client.next_win "
"%" PRIu32 "(%"PRIu32") (ssn->client.ra_base_seq %"PRIu32")",
ssn, TCP_GET_SEQ(p), p->payload_len, TCP_GET_SEQ(p)
+p->payload_len, ssn->client.last_ack, ssn->client.next_win,
TCP_GET_SEQ(p) + p->payload_len - ssn->client.next_win,
ssn->client.ra_base_seq);
"%" PRIu32 "(%"PRIu32")", ssn, TCP_GET_SEQ(p),
p->payload_len, TCP_GET_SEQ(p) + p->payload_len,
ssn->client.last_ack, ssn->client.next_win,
TCP_GET_SEQ(p) + p->payload_len - ssn->client.next_win);
}
return 0;
}
@ -1590,11 +1571,10 @@ static int HandleEstablishedPacketToClient(ThreadVars *tv, TcpSession *ssn, Pack
SCLogDebug("ssn %p: client => Asynchrouns stream, packet SEQ"
" %" PRIu32 ", payload size %" PRIu32 " (%" PRIu32 "),"
" ssn->client.last_ack %" PRIu32 ", ssn->client.next_win"
" %"PRIu32"(%"PRIu32") (ssn->client.ra_base_seq %"PRIu32")",
ssn, TCP_GET_SEQ(p), p->payload_len, TCP_GET_SEQ(p)
+p->payload_len, ssn->server.last_ack, ssn->server.next_win,
TCP_GET_SEQ(p) + p->payload_len - ssn->server.next_win,
ssn->server.ra_base_seq);
" %"PRIu32"(%"PRIu32")", ssn, TCP_GET_SEQ(p),
p->payload_len, TCP_GET_SEQ(p) + p->payload_len,
ssn->server.last_ack, ssn->server.next_win,
TCP_GET_SEQ(p) + p->payload_len - ssn->server.next_win);
ssn->server.last_ack = TCP_GET_SEQ(p);
@ -1639,14 +1619,14 @@ static int HandleEstablishedPacketToClient(ThreadVars *tv, TcpSession *ssn, Pack
SCLogDebug("ssn %p: client => SEQ out of window, packet SEQ"
"%" PRIu32 ", payload size %" PRIu32 " (%" PRIu32 "),"
" ssn->server.last_ack %" PRIu32 ", ssn->server.next_win "
"%" PRIu32 "(%"PRIu32") (ssn->server.ra_base_seq %"PRIu32")",
ssn, TCP_GET_SEQ(p), p->payload_len, TCP_GET_SEQ(p) +
p->payload_len, ssn->server.last_ack, ssn->server.next_win,
TCP_GET_SEQ(p) + p->payload_len - ssn->server.next_win,
ssn->server.ra_base_seq);
"%" PRIu32 "(%"PRIu32")", ssn, TCP_GET_SEQ(p),
p->payload_len, TCP_GET_SEQ(p) + p->payload_len,
ssn->server.last_ack, ssn->server.next_win,
TCP_GET_SEQ(p) + p->payload_len - ssn->server.next_win);
}
return 0;
}
/**
* \brief Function to handle the TCP_ESTABLISHED state. The function handles
* ACK, FIN, RST packets and correspondingly changes the connection
@ -3225,8 +3205,8 @@ static int ValidTimestamp (TcpSession *ssn, Packet *p)
*/
void StreamTcpSetSessionNoReassemblyFlag (TcpSession *ssn, char direction)
{
direction ? (ssn->flags |= STREAMTCP_FLAG_NOSERVER_REASSEMBLY) :
(ssn->flags |= STREAMTCP_FLAG_NOCLIENT_REASSEMBLY);
direction ? (ssn->server.flags |= STREAMTCP_STREAM_FLAG_NOREASSEMBLY) :
(ssn->client.flags |= STREAMTCP_STREAM_FLAG_NOREASSEMBLY);
}
#ifdef UNITTESTS
@ -7019,9 +6999,9 @@ static int StreamTcpTest37(void) {
goto end;
}
if (((TcpSession *)p->flow->protoctx)->client.tmp_ra_base_seq != 3) {
if (((TcpSession *)p->flow->protoctx)->client.ra_raw_base_seq != 3) {
printf("the ssn->client.next_seq should be 3, but it is %"PRIu32"\n",
((TcpSession *)p->flow->protoctx)->client.tmp_ra_base_seq);
((TcpSession *)p->flow->protoctx)->client.ra_raw_base_seq);
goto end;
}

@ -35,8 +35,6 @@
/** size of the data chunks sent to the app layer parser. */
#define MSG_DATA_SIZE 2048
#define STREAMQUEUE_FLAG_INIT 0x01
typedef struct StreamMsg_ {
uint32_t id; /**< unique stream id */
uint8_t flags; /**< msg flags */
@ -65,9 +63,7 @@ typedef struct StreamMsgQueue_ {
StreamMsg *top;
StreamMsg *bot;
uint16_t len;
// SCMutex mutex_q;
// SCCondT cond_q;
uint8_t flags;
//uint8_t flags;
#ifdef DBG_PERF
uint16_t dbg_maxlen;
#endif /* DBG_PERF */

Loading…
Cancel
Save