Trigger raw stream reassembly on receiving a full HTTP request or response.

remotes/origin/master-1.2.x
Victor Julien 14 years ago
parent f773942ce0
commit 16cfae2f51

@ -1831,6 +1831,9 @@ static int HTPCallbackRequest(htp_connp_t *connp) {
}
}
/* request done, do raw reassembly now to inspect state and stream
* at the same time. */
AppLayerTriggerRawStreamReassembly(hstate->f);
SCReturnInt(HOOK_OK);
}
@ -1886,6 +1889,9 @@ static int HTPCallbackResponse(htp_connp_t *connp) {
htp_tx_destroy(tx);
}
/* response done, do raw reassembly now to inspect state and stream
* at the same time. */
AppLayerTriggerRawStreamReassembly(hstate->f);
SCReturnInt(HOOK_OK);
}

@ -1218,6 +1218,30 @@ AppLayerDecoderEvents *AppLayerGetDecoderEventsForFlow(Flow *f)
return NULL;
}
/**
* \brief Trigger "raw" stream reassembly from the app layer.
*
* This way HTTP for example, can trigger raw stream inspection right
* when the full request body is received. This is often smaller than
* our raw reassembly size limit.
*
* \param f flow, for access the stream state
*/
void AppLayerTriggerRawStreamReassembly(Flow *f) {
SCEnter();
#ifdef DEBUG
BUG_ON(f == NULL);
#endif
if (f != NULL && f->protoctx != NULL) {
TcpSession *ssn = (TcpSession *)f->protoctx;
StreamTcpReassembleTriggerRawReassembly(ssn);
}
SCReturn;
}
void RegisterAppLayerParsers(void)
{
/** \todo move to general init function */

@ -291,4 +291,6 @@ uint16_t AppLayerGetStateVersion(Flow *f);
FileContainer *AppLayerGetFilesFromFlow(Flow *, uint8_t);
AppLayerDecoderEvents *AppLayerGetDecoderEventsForFlow(Flow *);
void AppLayerTriggerRawStreamReassembly(Flow *);
#endif /* __APP_LAYER_PARSER_H__ */

@ -118,6 +118,9 @@ enum
#define STREAMTCP_FLAG_CLIENT_SACKOK 0x0800
/** Flag to indicate both sides of the session permit SACK (SYN + SYN/ACK) */
#define STREAMTCP_FLAG_SACKOK 0x1000
/** Flag for triggering RAW reassembly before the size limit is reached or
the stream reaches EOF. */
#define STREAMTCP_FLAG_TRIGGER_RAW_REASSEMBLY 0x2000
/*
* Per STREAM flags

@ -1733,6 +1733,12 @@ static int StreamTcpReassembleRawCheckLimit(TcpSession *ssn, TcpStream *stream,
{
SCEnter();
if (ssn->flags & STREAMTCP_FLAG_TRIGGER_RAW_REASSEMBLY) {
SCLogDebug("reassembling now as STREAMTCP_FLAG_TRIGGER_RAW_REASSEMBLY is set");
ssn->flags &= ~STREAMTCP_FLAG_TRIGGER_RAW_REASSEMBLY;
SCReturnInt(1);
}
/* some states mean we reassemble no matter how much data we have */
if (ssn->state >= TCP_TIME_WAIT)
SCReturnInt(1);
@ -3505,6 +3511,30 @@ TcpSegment* StreamTcpGetSegment(ThreadVars *tv, TcpReassemblyThreadCtx *ra_ctx,
return seg;
}
/**
* \brief Trigger RAW stream reassembly
*
* Used by AppLayerTriggerRawStreamReassembly to trigger RAW stream
* reassembly from the applayer, for example upon completion of a
* HTTP request.
*
* Works by setting a flag in the TcpSession that is unset as soon
* as it's checked. Since everything happens when operating under
* a single lock period, no side effects are expected.
*
* \param ssn TcpSession
*/
void StreamTcpReassembleTriggerRawReassembly(TcpSession *ssn) {
#ifdef DEBUG
BUG_ON(ssn == NULL);
#endif
if (ssn != NULL) {
SCLogDebug("flagged ssn %p for immediate raw reassembly", ssn);
ssn->flags |= STREAMTCP_FLAG_TRIGGER_RAW_REASSEMBLY;
}
}
#ifdef UNITTESTS
/** unit tests and it's support functions below */
@ -6011,9 +6041,10 @@ static int StreamTcpReassembleTest38 (void) {
goto end;
}
/* Check if we have stream smsgs in queue */
if (ra_ctx->stream_q->len != 0) {
printf("there should be no stream smsgs in the queue (6): ");
/* we should now have a smsg as the http request is complete and triggered
* reassembly */
if (ra_ctx->stream_q->len != 1) {
printf("there should one stream smsg in the queue (6): ");
goto end;
}

@ -89,5 +89,7 @@ TcpSegment* StreamTcpGetSegment(ThreadVars *, TcpReassemblyThreadCtx *, uint16_t
void StreamTcpReturnStreamSegments(TcpStream *);
void StreamTcpSegmentReturntoPool(TcpSegment *);
void StreamTcpReassembleTriggerRawReassembly(TcpSession *);
#endif /* __STREAM_TCP_REASSEMBLE_H__ */

Loading…
Cancel
Save