From: Victor Julien Date: Thu, 30 Aug 2012 14:44:36 +0000 (+0200) Subject: stream/app layer: add Truncate app layer callback that is called if stream depth... X-Git-Tag: suricata-1.4beta1~52 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=869109a6a008155d16aef4d8cab51018645e37ca;p=thirdparty%2Fsuricata.git stream/app layer: add Truncate app layer callback that is called if stream depth is reached. Use it to trunc open files in HTTP. --- diff --git a/src/app-layer-htp.c b/src/app-layer-htp.c index 37230b6bd3..a7d2162369 100644 --- a/src/app-layer-htp.c +++ b/src/app-layer-htp.c @@ -2440,6 +2440,13 @@ static FileContainer *HTPStateGetFiles(void *state, uint8_t direction) { } } +static void HTPStateTruncate(void *state, uint8_t flags) { + FileContainer *fc = HTPStateGetFiles(state, flags); + if (fc != NULL) { + FileTruncateAllOpenFiles(fc); + } +} + /** * \brief Register the HTTP protocol and state handling functions to APP layer * of the engine. @@ -2472,6 +2479,8 @@ void RegisterHTPParsers(void) AppLayerDecoderEventsModuleRegister(ALPROTO_HTTP, http_decoder_event_table); + AppLayerRegisterTruncateFunc(ALPROTO_HTTP, HTPStateTruncate); + AppLayerRegisterProto(proto_name, ALPROTO_HTTP, STREAM_TOSERVER, HTPHandleRequestData); AppLayerRegisterProto(proto_name, ALPROTO_HTTP, STREAM_TOCLIENT, diff --git a/src/app-layer-parser.c b/src/app-layer-parser.c index d4f2b8b0be..be8f485048 100644 --- a/src/app-layer-parser.c +++ b/src/app-layer-parser.c @@ -632,6 +632,19 @@ void AppLayerRegisterLocalStorageFunc(uint16_t proto, return; } +void AppLayerRegisterTruncateFunc(uint16_t proto, void (*Truncate)(void *, uint8_t)) +{ + al_proto_table[proto].Truncate = Truncate; + + return; +} + +void AppLayerStreamTruncated(uint16_t proto, void *state, uint8_t flags) { + if (al_proto_table[proto].Truncate != NULL) { + al_proto_table[proto].Truncate(state, flags); + } +} + void *AppLayerGetProtocolParserLocalStorage(uint16_t proto) { if (al_proto_table[proto].LocalStorageAlloc != NULL) { @@ -966,6 +979,11 @@ int AppLayerParse(void *local_data, Flow *f, uint8_t proto, parser_state_store->id_flags |= APP_LAYER_TRANSACTION_EOF; } + /* stream truncated, inform app layer */ + if (flags & STREAM_DEPTH) { + AppLayerStreamTruncated(proto, app_layer_state, flags); + } + SCReturnInt(0); error: diff --git a/src/app-layer-parser.h b/src/app-layer-parser.h index f156517cdf..6bda0ce0af 100644 --- a/src/app-layer-parser.h +++ b/src/app-layer-parser.h @@ -54,6 +54,9 @@ typedef struct AppLayerProto_ { void (*StateTransactionFree)(void *, uint16_t); void *(*LocalStorageAlloc)(void); void (*LocalStorageFree)(void *); + + /** truncate state after a gap/depth event */ + void (*Truncate)(void *, uint8_t); FileContainer *(*StateGetFiles)(void *, uint8_t); } AppLayerProto; @@ -259,6 +262,7 @@ void AppLayerRegisterGetFilesFunc(uint16_t proto, FileContainer *(*StateGetFile)(void *, uint8_t)); void AppLayerRegisterLogger(uint16_t proto); uint16_t AppLayerGetProtoByName(const char *); +void AppLayerRegisterTruncateFunc(uint16_t proto, void (*Truncate)(void *, uint8_t)); int AppLayerParse(void *, Flow *, uint8_t, uint8_t, uint8_t *, uint32_t); diff --git a/src/stream-tcp-reassemble.c b/src/stream-tcp-reassemble.c index abea41caf2..cebea4a6a6 100644 --- a/src/stream-tcp-reassemble.c +++ b/src/stream-tcp-reassemble.c @@ -1656,6 +1656,9 @@ int StreamTcpReassembleHandleSegmentHandleData(ThreadVars *tv, TcpReassemblyThre } else { \ flag |= STREAM_TOSERVER; \ } \ + if (stream->flags & STREAMTCP_STREAM_FLAG_DEPTH_REACHED) { \ + flag |= STREAM_DEPTH; \ + } \ } #define STREAM_SET_INLINE_FLAGS(ssn, stream, p, flag) { \ @@ -1671,6 +1674,9 @@ int StreamTcpReassembleHandleSegmentHandleData(ThreadVars *tv, TcpReassemblyThre } else { \ flag |= STREAM_TOCLIENT; \ } \ + if (stream->flags & STREAMTCP_STREAM_FLAG_DEPTH_REACHED) { \ + flag |= STREAM_DEPTH; \ + } \ } static void StreamTcpSetupMsg(TcpSession *ssn, TcpStream *stream, Packet *p, diff --git a/src/stream.h b/src/stream.h index 024ecb2aef..49b796c5aa 100644 --- a/src/stream.h +++ b/src/stream.h @@ -30,7 +30,8 @@ #define STREAM_EOF 0x02 #define STREAM_TOSERVER 0x04 #define STREAM_TOCLIENT 0x08 -#define STREAM_GAP 0x10 +#define STREAM_GAP 0x10 /* data gap encountered */ +#define STREAM_DEPTH 0x20 /* depth reached */ /** size of the data chunks sent to the app layer parser. */ #define MSG_DATA_SIZE 4024 /* 4096 - 72 (size of rest of the struct) */ diff --git a/src/util-file.c b/src/util-file.c index dc25167b34..5486d8aa15 100644 --- a/src/util-file.c +++ b/src/util-file.c @@ -853,3 +853,16 @@ void FileStoreAllFiles(FileContainer *fc) { } } +void FileTruncateAllOpenFiles(FileContainer *fc) { + File *ptr = NULL; + + SCEnter(); + + if (fc != NULL) { + for (ptr = fc->head; ptr != NULL; ptr = ptr->next) { + if (ptr->state == FILE_STATE_OPENED) { + FileCloseFilePtr(ptr, NULL, 0, FILE_TRUNCATED); + } + } + } +} diff --git a/src/util-file.h b/src/util-file.h index b0858450e8..e2d485c4ac 100644 --- a/src/util-file.h +++ b/src/util-file.h @@ -184,4 +184,6 @@ void FileStoreAllFiles(FileContainer *); void FileStoreAllFilesForTx(FileContainer *, uint16_t); void FileStoreFileById(FileContainer *fc, uint16_t); +void FileTruncateAllOpenFiles(FileContainer *); + #endif /* __UTIL_FILE_H__ */