stream: remove StreamTcpReassembleInlineAppLayer

Function is now unused.
pull/1315/head
Victor Julien 12 years ago
parent 97908bcd2d
commit ff2fecf590

@ -2095,339 +2095,6 @@ static void StreamTcpRemoveSegmentFromStream(TcpStream *stream, TcpSegment *seg)
stream->seg_list_tail = seg->prev; stream->seg_list_tail = seg->prev;
} }
/**
* \brief Update the stream reassembly upon receiving a data segment
*
* Reassembly is in the same direction of the packet.
*
* One of the utilities called by this function AppLayerHandleTCPData(),
* has a feature where it will call this very same function for the
* stream opposing the stream it is called with. This shouldn't cause
* any issues, since processing of each stream is independent of the
* other stream.
*
* \todo this function is too long, we need to break it up. It needs it BAD
*/
int StreamTcpReassembleInlineAppLayer(ThreadVars *tv,
TcpReassemblyThreadCtx *ra_ctx,
TcpSession *ssn, TcpStream *stream,
Packet *p)
{
SCEnter();
/* this function can be directly called by app layer protocol
* detection. */
if (stream->flags & STREAMTCP_STREAM_FLAG_NOREASSEMBLY) {
SCLogDebug("stream no reassembly flag set. Mostly called via "
"app proto detection.");
SCReturnInt(0);
}
SCLogDebug("pcap_cnt %"PRIu64", len %u", p->pcap_cnt, p->payload_len);
SCLogDebug("stream->seg_list %p", stream->seg_list);
#ifdef DEBUG
PrintList(stream->seg_list);
//PrintRawDataFp(stdout, p->payload, p->payload_len);
#endif
if (stream->seg_list == NULL) {
/* send an empty EOF msg if we have no segments but TCP state
* is beyond ESTABLISHED */
if (ssn->state > TCP_ESTABLISHED) {
SCLogDebug("sending empty eof message");
/* send EOF to app layer */
AppLayerHandleTCPData(tv, ra_ctx, p, p->flow, ssn, stream, NULL, 0,
StreamGetAppLayerFlags(ssn, stream, p));
AppLayerProfilingStore(ra_ctx->app_tctx, p);
} else {
SCLogDebug("no segments in the list to reassemble");
}
SCReturnInt(0);
}
if (stream->flags & STREAMTCP_STREAM_FLAG_GAP) {
SCReturnInt(0);
}
/* stream->ra_app_base_seq remains at stream->isn until protocol is
* detected. */
uint32_t ra_base_seq = stream->ra_app_base_seq;
uint8_t data[4096];
uint32_t data_len = 0;
uint16_t payload_offset = 0;
uint16_t payload_len = 0;
uint32_t next_seq = ra_base_seq + 1;
uint32_t data_sent = 0;
TcpSegment *seg = stream->seg_list;
SCLogDebug("ra_base_seq %u", ra_base_seq);
/* Check if we have a gap at the start of the list. If last_ack is
* bigger than the list start and the list start is bigger than
* next_seq, we know we are missing data that has been ack'd. That
* won't get retransmitted, so it's a data gap.
*/
if (!(p->flow->flags & FLOW_NO_APPLAYER_INSPECTION)) {
if (SEQ_GT(seg->seq, next_seq) && SEQ_LT(seg->seq, stream->last_ack)) {
/* send gap signal */
AppLayerHandleTCPData(tv, ra_ctx, p, p->flow, ssn, stream,
NULL, 0, StreamGetAppLayerFlags(ssn, stream, p)|STREAM_GAP);
AppLayerProfilingStore(ra_ctx->app_tctx, p);
/* set a GAP flag and make sure not bothering this stream anymore */
SCLogDebug("STREAMTCP_STREAM_FLAG_GAP set");
stream->flags |= STREAMTCP_STREAM_FLAG_GAP;
StreamTcpSetEvent(p, STREAM_REASSEMBLY_SEQ_GAP);
SCPerfCounterIncr(ra_ctx->counter_tcp_reass_gap, tv->sc_perf_pca);
#ifdef DEBUG
dbg_app_layer_gap++;
#endif
SCReturnInt(0);
}
}
/* loop through the segments and fill one or more msgs */
SCLogDebug("pre-loop seg %p", seg);
for (; seg != NULL;) {
SCLogDebug("seg %p, SEQ %"PRIu32", LEN %"PRIu16", SUM %"PRIu32,
seg, seg->seq, seg->payload_len,
(uint32_t)(seg->seq + seg->payload_len));
if (p->flow->flags & FLOW_NO_APPLAYER_INSPECTION) {
SCLogDebug("FLOW_NO_APPLAYER_INSPECTION set, breaking out");
break;
}
if (StreamTcpReturnSegmentCheck(p->flow, ssn, stream, seg) == 1) {
SCLogDebug("removing segment");
TcpSegment *next_seg = seg->next;
StreamTcpRemoveSegmentFromStream(stream, seg);
StreamTcpSegmentReturntoPool(seg);
seg = next_seg;
continue;
} else if (StreamTcpAppLayerSegmentProcessed(stream, seg)) {
TcpSegment *next_seg = seg->next;
seg = next_seg;
continue;
}
/* we've run into a sequence gap */
if (SEQ_GT(seg->seq, next_seq)) {
SCLogDebug("GAP: we expected %u, got %u. Diff %u", next_seq, seg->seq, seg->seq - next_seq);
/* don't conclude it's a gap until we see that the data
* that is missing was acked. */
if (SEQ_GT(seg->seq,stream->last_ack) && ssn->state != TCP_CLOSED)
break;
/* first, pass on data before the gap */
if (data_len > 0) {
SCLogDebug("pre GAP data");
/* process what we have so far */
AppLayerHandleTCPData(tv, ra_ctx, p, p->flow, ssn, stream,
data, data_len, StreamGetAppLayerFlags(ssn, stream, p));
AppLayerProfilingStore(ra_ctx->app_tctx, p);
data_len = 0;
}
/* see what the length of the gap is, gap length is seg->seq -
* (ra_base_seq +1) */
#ifdef DEBUG
uint32_t gap_len = seg->seq - next_seq;
SCLogDebug("expected next_seq %" PRIu32 ", got %" PRIu32 " , "
"stream->last_ack %" PRIu32 ". Seq gap %" PRIu32"",
next_seq, seg->seq, stream->last_ack, gap_len);
#endif
/* We have missed the packet and end host has ack'd it, so
* IDS should advance it's ra_base_seq and should not consider this
* packet any longer, even if it is retransmitted, as end host will
* drop it anyway */
ra_base_seq = seg->seq - 1;
/* send gap signal */
AppLayerHandleTCPData(tv, ra_ctx, p, p->flow, ssn, stream,
NULL, 0, StreamGetAppLayerFlags(ssn, stream, p)|STREAM_GAP);
AppLayerProfilingStore(ra_ctx->app_tctx, p);
data_sent += data_len;
/* set a GAP flag and make sure not bothering this stream anymore */
SCLogDebug("STREAMTCP_STREAM_FLAG_GAP set");
stream->flags |= STREAMTCP_STREAM_FLAG_GAP;
StreamTcpSetEvent(p, STREAM_REASSEMBLY_SEQ_GAP);
SCPerfCounterIncr(ra_ctx->counter_tcp_reass_gap, tv->sc_perf_pca);
#ifdef DEBUG
dbg_app_layer_gap++;
#endif
break;
}
/* if the segment ends beyond ra_base_seq we need to consider it */
if (SEQ_GT((seg->seq + seg->payload_len), (ra_base_seq + 1))) {
SCLogDebug("seg->seq %" PRIu32 ", seg->payload_len %" PRIu32 ", "
"ra_base_seq %" PRIu32 "", seg->seq,
seg->payload_len, ra_base_seq);
/* handle segments partly before ra_base_seq */
if (SEQ_GT(ra_base_seq, seg->seq)) {
payload_offset = ra_base_seq - seg->seq - 1;
payload_len = seg->payload_len - payload_offset;
if (SCLogDebugEnabled()) {
BUG_ON(payload_offset > seg->payload_len);
BUG_ON((payload_len + payload_offset) > seg->payload_len);
}
} else {
payload_offset = 0;
payload_len = seg->payload_len;
}
SCLogDebug("payload_offset is %"PRIu16", payload_len is %"PRIu16""
" and stream->next_win is %"PRIu32"", payload_offset,
payload_len, stream->next_win);
if (payload_len == 0) {
SCLogDebug("no payload_len, so bail out");
break;
}
/* copy the data into the smsg */
uint16_t copy_size = sizeof(data) - data_len;
if (copy_size > payload_len) {
copy_size = payload_len;
}
if (SCLogDebugEnabled()) {
BUG_ON(copy_size > sizeof(data));
}
SCLogDebug("copy_size is %"PRIu16"", copy_size);
memcpy(data + data_len, seg->payload + payload_offset, copy_size);
data_len += copy_size;
ra_base_seq += copy_size;
SCLogDebug("ra_base_seq %"PRIu32", data_len %"PRIu32, ra_base_seq, data_len);
/* queue the smsg if it's full */
if (data_len == sizeof(data)) {
/* process what we have so far */
AppLayerHandleTCPData(tv, ra_ctx, p, p->flow, ssn, stream,
data, data_len, StreamGetAppLayerFlags(ssn, stream, p));
AppLayerProfilingStore(ra_ctx->app_tctx, p);
data_sent += data_len;
data_len = 0;
}
/* if the payload len is bigger than what we copied, we handle the
* rest of the payload next... */
if (copy_size < payload_len) {
SCLogDebug("copy_size %" PRIu32 " < %" PRIu32 "", copy_size,
payload_len);
payload_offset += copy_size;
payload_len -= copy_size;
SCLogDebug("payload_offset is %"PRIu16", seg->payload_len is "
"%"PRIu16" and stream->last_ack is %"PRIu32"",
payload_offset, seg->payload_len, stream->last_ack);
if (SCLogDebugEnabled()) {
BUG_ON(payload_offset > seg->payload_len);
}
/* we need a while loop here as the packets theoretically can be
* 64k */
char segment_done = FALSE;
while (segment_done == FALSE) {
SCLogDebug("new msg at offset %" PRIu32 ", payload_len "
"%" PRIu32 "", payload_offset, payload_len);
data_len = 0;
copy_size = sizeof(data) - data_len;
if (copy_size > (seg->payload_len - payload_offset)) {
copy_size = (seg->payload_len - payload_offset);
}
if (SCLogDebugEnabled()) {
BUG_ON(copy_size > sizeof(data));
}
SCLogDebug("copy payload_offset %" PRIu32 ", data_len "
"%" PRIu32 ", copy_size %" PRIu32 "",
payload_offset, data_len, copy_size);
memcpy(data + data_len, seg->payload +
payload_offset, copy_size);
data_len += copy_size;
ra_base_seq += copy_size;
SCLogDebug("ra_base_seq %"PRIu32, ra_base_seq);
SCLogDebug("copied payload_offset %" PRIu32 ", "
"data_len %" PRIu32 ", copy_size %" PRIu32 "",
payload_offset, data_len, copy_size);
if (data_len == sizeof(data)) {
/* process what we have so far */
AppLayerHandleTCPData(tv, ra_ctx, p, p->flow, ssn, stream,
data, data_len, StreamGetAppLayerFlags(ssn, stream, p));
AppLayerProfilingStore(ra_ctx->app_tctx, p);
data_sent += data_len;
data_len = 0;
}
/* see if we have segment payload left to process */
if ((copy_size + payload_offset) < seg->payload_len) {
payload_offset += copy_size;
payload_len -= copy_size;
if (SCLogDebugEnabled()) {
BUG_ON(payload_offset > seg->payload_len);
}
} else {
payload_offset = 0;
segment_done = TRUE;
}
}
}
}
/* done with this segment, return it to the pool */
TcpSegment *next_seg = seg->next;
next_seq = seg->seq + seg->payload_len;
seg->flags |= SEGMENTTCP_FLAG_APPLAYER_PROCESSED;
seg = next_seg;
}
/* put the partly filled smsg in the queue to the l7 handler */
if (data_len > 0) {
SCLogDebug("data_len > 0, %u", data_len);
/* process what we have so far */
BUG_ON(data_len > sizeof(data));
AppLayerHandleTCPData(tv, ra_ctx, p, p->flow, ssn, stream,
data, data_len, StreamGetAppLayerFlags(ssn, stream, p));
AppLayerProfilingStore(ra_ctx->app_tctx, p);
data_sent += data_len;
}
if (data_sent == 0 && ssn->state > TCP_ESTABLISHED) {
SCLogDebug("sending empty eof message");
/* send EOF to app layer */
AppLayerHandleTCPData(tv, ra_ctx, p, p->flow, ssn, stream,
NULL, 0, StreamGetAppLayerFlags(ssn, stream, p));
AppLayerProfilingStore(ra_ctx->app_tctx, p);
}
/* store ra_base_seq in the stream */
if (StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(stream)) {
stream->ra_app_base_seq = ra_base_seq;
} else {
TcpSegment *tmp_seg = stream->seg_list;
while (tmp_seg != NULL) {
tmp_seg->flags &= ~SEGMENTTCP_FLAG_APPLAYER_PROCESSED;
tmp_seg = tmp_seg->next;
}
}
SCLogDebug("stream->ra_app_base_seq %u", stream->ra_app_base_seq);
SCReturnInt(0);
}
/** /**
* \brief Update the stream reassembly upon receiving a data segment * \brief Update the stream reassembly upon receiving a data segment
* *

@ -79,10 +79,6 @@ void StreamTcpReassembleFreeThreadCtx(TcpReassemblyThreadCtx *);
int StreamTcpReassembleAppLayer (ThreadVars *tv, TcpReassemblyThreadCtx *ra_ctx, int StreamTcpReassembleAppLayer (ThreadVars *tv, TcpReassemblyThreadCtx *ra_ctx,
TcpSession *ssn, TcpStream *stream, TcpSession *ssn, TcpStream *stream,
Packet *p); Packet *p);
int StreamTcpReassembleInlineAppLayer(ThreadVars *tv,
TcpReassemblyThreadCtx *ra_ctx,
TcpSession *ssn, TcpStream *stream,
Packet *p);
void StreamTcpCreateTestPacket(uint8_t *, uint8_t, uint8_t, uint8_t); void StreamTcpCreateTestPacket(uint8_t *, uint8_t, uint8_t, uint8_t);

Loading…
Cancel
Save