diff --git a/src/flow-timeout.c b/src/flow-timeout.c index 335ec9bf3d..8659a7402f 100644 --- a/src/flow-timeout.c +++ b/src/flow-timeout.c @@ -380,6 +380,9 @@ int FlowForceReassemblyForFlow(Flow *f, int server, int client) goto done; } PKT_SET_SRC(p2, PKT_SRC_FFR); + p2->flowflags |= FLOW_PKT_LAST_PSEUDO; + } else { + p1->flowflags |= FLOW_PKT_LAST_PSEUDO; } } else { if (server == STREAM_HAS_UNPROCESSED_SEGMENTS_NEED_ONLY_DETECTION) { @@ -388,6 +391,7 @@ int FlowForceReassemblyForFlow(Flow *f, int server, int client) goto done; } PKT_SET_SRC(p1, PKT_SRC_FFR); + p1->flowflags |= FLOW_PKT_LAST_PSEUDO; } else { /* impossible */ BUG_ON(1); diff --git a/src/flow.h b/src/flow.h index e362f8d40d..f625ada106 100644 --- a/src/flow.h +++ b/src/flow.h @@ -222,6 +222,9 @@ typedef struct AppLayerParserState_ AppLayerParserState; #define FLOW_PKT_TOCLIENT_IPONLY_SET 0x10 #define FLOW_PKT_TOSERVER_FIRST 0x20 #define FLOW_PKT_TOCLIENT_FIRST 0x40 +/** last pseudo packet in the flow. Can be used to trigger final clean, + * logging, etc. */ +#define FLOW_PKT_LAST_PSEUDO 0x80 #define FLOW_END_FLAG_STATE_NEW 0x01 #define FLOW_END_FLAG_STATE_ESTABLISHED 0x02 diff --git a/src/output-tx.c b/src/output-tx.c index 4294d40f4c..ff11b87944 100644 --- a/src/output-tx.c +++ b/src/output-tx.c @@ -260,15 +260,20 @@ static TmEcode OutputTxLog(ThreadVars *tv, Packet *p, void *thread_data) if ((tx_logged_old & (1<logger_id)) == 0) { SCLogDebug("alproto match %d, logging tx_id %"PRIu64, logger->alproto, tx_id); + const bool last_pseudo = (p->flowflags & FLOW_PKT_LAST_PSEUDO) != 0; 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", + SCLogDebug("pcap_cnt %"PRIu64", tx_id %"PRIu64" logger %d. " + "EOFs TS %s TC %s LAST PSEUDO %s", p->pcap_cnt, tx_id, logger->logger_id, - ts_eof ? "true" : "false", tc_eof ? "true" : "false"); + ts_eof ? "true" : "false", tc_eof ? "true" : "false", + last_pseudo ? "true" : "false"); - if (!(ts_eof && tc_eof)) { + if ((ts_eof && tc_eof) || last_pseudo) { + SCLogDebug("EOF, so log now"); + } else { if (logger->LogCondition) { int r = logger->LogCondition(tv, p, alstate, tx, tx_id); if (r == FALSE) {