ENIPTransaction *tx;
if (input == NULL && AppLayerParserStateIssetFlag(pstate,
- APP_LAYER_PARSER_EOF))
+ APP_LAYER_PARSER_EOF_TS|APP_LAYER_PARSER_EOF_TC))
{
SCReturnStruct(APP_LAYER_OK);
} else if (input == NULL && input_len != 0) {
FtpState *state = (FtpState *)ftp_state;
void *ptmp;
- if (input == NULL && AppLayerParserStateIssetFlag(pstate, APP_LAYER_PARSER_EOF)) {
+ if (input == NULL && AppLayerParserStateIssetFlag(pstate, APP_LAYER_PARSER_EOF_TS)) {
SCReturnStruct(APP_LAYER_OK);
} else if (input == NULL || input_len == 0) {
SCReturnStruct(APP_LAYER_ERROR);
}
}
- if (input_len && AppLayerParserStateIssetFlag(pstate, APP_LAYER_PARSER_EOF)) {
+ const bool eof_flag = flags & STREAM_TOSERVER ?
+ AppLayerParserStateIssetFlag(pstate, APP_LAYER_PARSER_EOF_TS) != 0 :
+ AppLayerParserStateIssetFlag(pstate, APP_LAYER_PARSER_EOF_TC) != 0;
+ if (input_len && eof_flag) {
ret = FileCloseFile(ftpdata_state->files, (uint8_t *) NULL, 0, flags);
ftpdata_state->state = FTPDATA_STATE_FINISHED;
}
}
/* if the TCP connection is closed, then close the HTTP connection */
- if (AppLayerParserStateIssetFlag(pstate, APP_LAYER_PARSER_EOF) &&
+ if (AppLayerParserStateIssetFlag(pstate, APP_LAYER_PARSER_EOF_TS) &&
!(hstate->flags & HTP_FLAG_STATE_CLOSED_TS))
{
htp_connp_req_close(hstate->connp, &ts);
}
/* if we the TCP connection is closed, then close the HTTP connection */
- if (AppLayerParserStateIssetFlag(pstate, APP_LAYER_PARSER_EOF) &&
+ if (AppLayerParserStateIssetFlag(pstate, APP_LAYER_PARSER_EOF_TC) &&
!(hstate->flags & HTP_FLAG_STATE_CLOSED_TC))
{
htp_connp_close(hstate->connp, &ts);
ModbusTransaction *tx;
ModbusHeader header;
- if (input == NULL && AppLayerParserStateIssetFlag(pstate, APP_LAYER_PARSER_EOF)) {
+ if (input == NULL && AppLayerParserStateIssetFlag(pstate, APP_LAYER_PARSER_EOF_TS)) {
SCReturnStruct(APP_LAYER_OK);
} else if (input == NULL || input_len == 0) {
SCReturnStruct(APP_LAYER_ERROR);
ModbusState *modbus = (ModbusState *) state;
ModbusTransaction *tx;
- if (input == NULL && AppLayerParserStateIssetFlag(pstate, APP_LAYER_PARSER_EOF)) {
+ if (input == NULL && AppLayerParserStateIssetFlag(pstate, APP_LAYER_PARSER_EOF_TC)) {
SCReturnStruct(APP_LAYER_OK);
} else if (input == NULL || input_len == 0) {
SCReturnStruct(APP_LAYER_ERROR);
/***** General *****/
+static inline void SetEOFFlags(AppLayerParserState *pstate, const uint8_t flags)
+{
+ if ((flags & (STREAM_EOF|STREAM_TOSERVER)) == (STREAM_EOF|STREAM_TOSERVER)) {
+ SCLogDebug("setting APP_LAYER_PARSER_EOF_TS");
+ AppLayerParserStateSetFlag(pstate, APP_LAYER_PARSER_EOF_TS);
+ } else if ((flags & (STREAM_EOF|STREAM_TOCLIENT)) == (STREAM_EOF|STREAM_TOCLIENT)) {
+ SCLogDebug("setting APP_LAYER_PARSER_EOF_TC");
+ AppLayerParserStateSetFlag(pstate, APP_LAYER_PARSER_EOF_TC);
+ }
+}
+
/** \retval int -1 in case of unrecoverable error. App-layer tracking stops for this flow.
* \retval int 0 ok: we did not update app_progress
* \retval int 1 ok: we updated app_progress */
goto error;
}
- if (flags & STREAM_EOF)
- AppLayerParserStateSetFlag(pstate, APP_LAYER_PARSER_EOF);
+ SetEOFFlags(pstate, flags);
alstate = f->alstate;
if (alstate == NULL) {
if (pstate == NULL)
goto end;
- AppLayerParserStateSetFlag(pstate, APP_LAYER_PARSER_EOF);
+ AppLayerParserStateSetFlag(pstate, APP_LAYER_PARSER_EOF_TS|APP_LAYER_PARSER_EOF_TC);
end:
SCReturn;
#include "util-config.h"
/* Flags for AppLayerParserState. */
-#define APP_LAYER_PARSER_EOF BIT_U8(0)
+// flag available BIT_U8(0)
#define APP_LAYER_PARSER_NO_INSPECTION BIT_U8(1)
#define APP_LAYER_PARSER_NO_REASSEMBLY BIT_U8(2)
#define APP_LAYER_PARSER_NO_INSPECTION_PAYLOAD BIT_U8(3)
#define APP_LAYER_PARSER_BYPASS_READY BIT_U8(4)
+#define APP_LAYER_PARSER_EOF_TS BIT_U8(5)
+#define APP_LAYER_PARSER_EOF_TC BIT_U8(6)
/* Flags for AppLayerParserProtoCtx. */
#define APP_LAYER_PARSER_OPT_ACCEPT_GAPS BIT_U32(0)
{
SCEnter();
- if (input == NULL && AppLayerParserStateIssetFlag(pstate, APP_LAYER_PARSER_EOF)) {
+ if (input == NULL &&
+ ((direction == 0 && AppLayerParserStateIssetFlag(pstate, APP_LAYER_PARSER_EOF_TS)) ||
+ (direction == 1 && AppLayerParserStateIssetFlag(pstate, APP_LAYER_PARSER_EOF_TC)))) {
SCReturnStruct(APP_LAYER_OK);
} else if (input == NULL || input_len == 0) {
SCReturnStruct(APP_LAYER_ERROR);
ssl_state->f = f;
if (input == NULL &&
- AppLayerParserStateIssetFlag(pstate, APP_LAYER_PARSER_EOF)) {
+ ((direction == 0 && AppLayerParserStateIssetFlag(pstate, APP_LAYER_PARSER_EOF_TS)) ||
+ (direction == 1 && AppLayerParserStateIssetFlag(pstate, APP_LAYER_PARSER_EOF_TC)))) {
/* flag session as finished if APP_LAYER_PARSER_EOF is set */
ssl_state->flags |= SSL_AL_FLAG_STATE_FINISHED;
SCReturnStruct(APP_LAYER_OK);
}
/* flag session as finished if APP_LAYER_PARSER_EOF is set */
- if (AppLayerParserStateIssetFlag(pstate, APP_LAYER_PARSER_EOF)) {
+ if (AppLayerParserStateIssetFlag(pstate, APP_LAYER_PARSER_EOF_TS) &&
+ AppLayerParserStateIssetFlag(pstate, APP_LAYER_PARSER_EOF_TC)) {
SCLogDebug("SSL_AL_FLAG_STATE_FINISHED");
ssl_state->flags |= SSL_AL_FLAG_STATE_FINISHED;
}
SCLogNotice("Parsing template request: len=%"PRIu32, input_len);
if (input == NULL) {
- if (AppLayerParserStateIssetFlag(pstate, APP_LAYER_PARSER_EOF)) {
+ if (AppLayerParserStateIssetFlag(pstate, APP_LAYER_PARSER_EOF_TS)) {
/* This is a signal that the stream is done. Do any
* cleanup if needed. Usually nothing is required here. */
SCReturnStruct(APP_LAYER_OK);
/* Likely connection closed, we can just return here. */
if ((input == NULL || input_len == 0) &&
- AppLayerParserStateIssetFlag(pstate, APP_LAYER_PARSER_EOF)) {
+ AppLayerParserStateIssetFlag(pstate, APP_LAYER_PARSER_EOF_TC)) {
SCReturnStruct(APP_LAYER_OK);
}
/* Likely connection closed, we can just return here. */
if ((input == NULL || input_len == 0) &&
- AppLayerParserStateIssetFlag(pstate, APP_LAYER_PARSER_EOF)) {
+ AppLayerParserStateIssetFlag(pstate, APP_LAYER_PARSER_EOF_TS)) {
SCReturnStruct(APP_LAYER_OK);
}
memset(&p->ts, 0, sizeof(struct timeval));
TimeGet(&p->ts);
- AppLayerParserSetEOF(f->alparser);
-
return p;
error:
if ((tx_logged_old & (1<<logger->logger_id)) == 0) {
SCLogDebug("alproto match %d, logging tx_id %"PRIu64, logger->alproto, tx_id);
- if (!(AppLayerParserStateIssetFlag(f->alparser,
- APP_LAYER_PARSER_EOF))) {
+ const bool ts_eof = AppLayerParserStateIssetFlag(f->alparser,
+ APP_LAYER_PARSER_EOF_TS) != 0;
+ const bool tc_eof = AppLayerParserStateIssetFlag(f->alparser,
+ APP_LAYER_PARSER_EOF_TC) != 0;
+ SCLogDebug("pcap_cnt %"PRIu64", tx_id %"PRIu64" logger %d. EOFs TS %s TC %s",
+ p->pcap_cnt, tx_id, logger->logger_id,
+ ts_eof ? "true" : "false", tc_eof ? "true" : "false");
+
+ if (!(ts_eof && tc_eof)) {
if (logger->LogCondition) {
int r = logger->LogCondition(tv, p, alstate, tx, tx_id);
if (r == FALSE) {
(void) AppLayerParserParse(NULL, alp_tctx, f, f->alproto, flags, isolatedBuffer, alnext - albuffer);
free(isolatedBuffer);
flags &= ~(STREAM_START);
- if (f->alparser && AppLayerParserStateIssetFlag(f->alparser, APP_LAYER_PARSER_EOF)) {
+ if (f->alparser &&
+ (((flags & STREAM_TOSERVER) != 0 &&
+ AppLayerParserStateIssetFlag(f->alparser, APP_LAYER_PARSER_EOF_TS)) ||
+ ((flags & STREAM_TOCLIENT) != 0 &&
+ AppLayerParserStateIssetFlag(f->alparser, APP_LAYER_PARSER_EOF_TC)))) {
//no final chunk
alsize = 0;
break;