83 memset(op, 0x00,
sizeof(*op));
122 if (t->
id * 2ULL > UINT32_MAX) {
141 const uint64_t tx_id,
AppLayerTxData *txd,
const bool tx_complete,
const bool ts_ready,
142 const bool tc_ready,
const bool ts_eof,
const bool tc_eof,
const bool eof)
145 uint8_t opposing_dir;
146 bool packet_dir_ready;
147 const bool opposing_dir_ready = eof;
148 bool opposing_tx_ready;
150 packet_dir = STREAM_TOSERVER;
151 opposing_dir = STREAM_TOCLIENT;
152 packet_dir_ready = eof | ts_ready | ts_eof;
153 opposing_tx_ready = tc_ready;
155 packet_dir = STREAM_TOCLIENT;
156 opposing_dir = STREAM_TOSERVER;
157 packet_dir_ready = eof | tc_ready | tc_eof;
158 opposing_tx_ready = ts_ready;
163 SCLogDebug(
"eof %d ts_ready %d ts_eof %d", eof, ts_ready, ts_eof);
164 SCLogDebug(
"eof %d tc_ready %d tc_eof %d", eof, tc_ready, tc_eof);
166 SCLogDebug(
"packet dir %s opposing %s packet_dir_ready %d opposing_dir_ready %d",
167 packet_dir == STREAM_TOSERVER ?
"TOSERVER" :
"TOCLIENT",
168 opposing_dir == STREAM_TOSERVER ?
"TOSERVER" :
"TOCLIENT", packet_dir_ready,
171 AppLayerGetFileState app_files =
174 AppLayerGetFileState app_files_opposing =
180 bool opposing_finished =
181 ffc_opposing == NULL || (ffc_opposing->
head == NULL && opposing_tx_ready);
182 SCLogDebug(
"opposing_finished %d ffc_opposing %p ffc_opposing->head %p opposing_tx_ready %d",
183 opposing_finished, ffc_opposing, ffc_opposing ? ffc_opposing->
head : NULL,
186 if (ffc || ffc_opposing)
187 SCLogDebug(
"pcap_cnt %" PRIu64
" flow %p tx %p tx_id %" PRIu64
188 " ffc %p ffc_opposing %p tx_complete %d",
189 p->
pcap_cnt, f, tx, tx_id, ffc, ffc_opposing, tx_complete);
194 SCLogDebug(
"tx: calling files: ffc %p head %p file_close %d file_trunc %d", ffc, ffc->
head,
195 file_close, file_trunc);
196 if (filedata_td && txd->files_opened > txd->files_stored)
198 file_close, file_trunc, packet_dir);
199 if (file_td && txd->files_opened > txd->files_logged)
201 tv, file_td, p, ffc, tx, tx_id, txd, file_close, file_trunc, packet_dir);
204 if (opposing_dir_ready && ffc_opposing != NULL) {
207 opposing_finished =
true;
208 SCLogDebug(
"tx: calling for opposing direction files: file_close:%s file_trunc:%s",
209 file_close ?
"true" :
"false", file_trunc ?
"true" :
"false");
210 if (filedata_td && txd->files_opened > txd->files_stored)
212 opposing_dir, file_close, file_trunc, opposing_dir);
213 if (file_td && txd->files_opened > txd->files_logged)
214 OutputFileLogFfc(
tv, file_td, p, ffc_opposing, tx, tx_id, txd, file_close, file_trunc,
218 const bool tx_done = packet_dir_ready && opposing_finished;
219 SCLogDebug(
"tx_done %d packet_dir_ready %d opposing_finished %d", tx_done, packet_dir_ready,
223 const bool is_file_tx = (ffc != NULL || ffc_opposing != NULL);
224 if (!is_file_tx || tx_done) {
225 SCLogDebug(
"is_file_tx %d tx_done %d", is_file_tx, tx_done);
228 SCLogDebug(
"setting LOGGER_FILE => %08x", txd->logged.flags);
232 SCLogDebug(
"setting LOGGER_FILEDATA => %08x", txd->logged.flags);
235 SCLogDebug(
"pcap_cnt %" PRIu64
" flow %p tx %p tx_id %" PRIu64
236 " NOT SETTING FILE FLAGS ffc %p ffc_opposing %p tx_complete %d",
237 p->
pcap_cnt, f, tx, tx_id, ffc, ffc_opposing, tx_complete);
242 Flow *f,
void *tx,
const uint64_t tx_id)
251 while (logger && store) {
262 logger = logger->
next;
277 void *alstate,
void *tx,
const uint64_t tx_id,
const AppProto alproto,
const bool eof,
278 const int tx_progress_ts,
const int tx_progress_tc,
struct Ctx *ctx)
284 while (logger && store) {
288 SCLogDebug(
"logger %p, Alproto %d LogCondition %p, ts_log_progress %d "
289 "tc_log_progress %d",
296 tx_id, logger->
logger_id, eof ?
"true" :
"false");
304 SCLogDebug(
"conditions not met, not logging");
308 if (tx_progress_tc < logger->tc_log_progress) {
309 SCLogDebug(
"progress not far enough, not logging");
313 if (tx_progress_ts < logger->ts_log_progress) {
314 SCLogDebug(
"progress not far enough, not logging");
329 logger = logger->
next;
343 SCLogDebug(
"not pseudo, no app update: skip");
346 SCLogDebug(
"pseudo, or app update: run output");
351 const uint8_t ipproto = f->
proto;
356 const bool file_logging_active = (op_thread_data->
file || op_thread_data->
filedata);
357 if (!file_logging_active) {
367 if (alstate == NULL) {
372 if (logger_expectation == 0) {
373 SCLogDebug(
"bail: logger_expectation %u. LOGGER_FILE %u LOGGER_FILEDATA %u",
385 const bool eof = last_pseudo || (ts_eof && tc_eof);
386 SCLogDebug(
"eof %d last_pseudo %d ts_eof %d tc_eof %d", eof, last_pseudo, ts_eof, tc_eof);
390 SCLogDebug(
"ts_disrupt_flags %02x tc_disrupt_flags %02x", ts_disrupt_flags, tc_disrupt_flags);
393 uint64_t max_id = tx_id;
399 SCLogDebug(
"pcap_cnt %" PRIu64
": tx_id %" PRIu64
" total_txs %" PRIu64, p->
pcap_cnt, tx_id,
404 memset(&state, 0,
sizeof(state));
406 const int complete_ts =
408 const int complete_tc =
411 AppLayerGetTxIterTuple ires = IterFunc(ipproto, alproto, alstate, tx_id, total_txs, &state);
412 if (ires.tx_ptr == NULL)
414 void *
const tx = ires.tx_ptr;
416 SCLogDebug(
"STARTING tx_id %" PRIu64
", tx %p", tx_id, tx);
418 const int tx_progress_ts =
420 const int tx_progress_tc =
422 const bool tx_complete = (tx_progress_ts == complete_ts && tx_progress_tc == complete_tc);
424 SCLogDebug(
"file_thread_data %p filedata_thread_data %p", op_thread_data->
file,
436 if (file_logging_active) {
437 if (AppLayerParserIsFileTx(txd)) {
439 const bool ts_ready = (tx_progress_ts == complete_ts);
440 const bool tc_ready = (tx_progress_tc == complete_tc);
441 SCLogDebug(
"ts_ready %d tc_ready %d", ts_ready, tc_ready);
443 const bool eval_files = ts_ready | tc_ready | tx_complete | ts_eof | tc_eof | eof;
445 SCLogDebug(
"eval_files: %u, ts_ready %u, tc_ready %u, tx_complete %u, ts_eof %u, "
447 eval_files, ts_ready, tc_ready, tx_complete, ts_eof, tc_eof, eof);
448 SCLogDebug(
"txd->file_tx & pkt_dir: %02x & %02x -> %02x", txd->file_tx, pkt_dir,
449 (txd->file_tx & pkt_dir));
454 if (eval_files || AppLayerParserIsFileTxInDir(txd, pkt_dir)) {
455 OutputTxLogFiles(
tv, op_thread_data->
file, op_thread_data->
filedata, p, f, tx,
456 tx_id, txd, tx_complete, ts_ready, tc_ready, ts_eof, tc_eof, eof);
458 }
else if (support_files) {
459 if (op_thread_data->
file) {
461 SCLogDebug(
"not a file_tx: setting LOGGER_FILE => %08x", txd->logged.flags);
465 SCLogDebug(
"not a file_tx: setting LOGGER_FILEDATA => %08x", txd->logged.flags);
469 SCLogDebug(
"logger: expect %08x, have %08x", logger_expectation, txd->logged.flags);
472 OutputTxLogList0(
tv, op_thread_data, p, f, tx, tx_id);
473 if (list[alproto] == NULL)
477 SCLogDebug(
"tx %p/%" PRIu64
" txd %p: log_flags %x logger_expectation %x", tx, tx_id, txd,
478 txd->config.log_flags, logger_expectation);
482 txd->logged.flags |= logger_expectation;
486 if (txd->logged.flags == logger_expectation) {
492 SCLogDebug(
"logger: expect %08x, have %08x", logger_expectation, txd->logged.flags);
495 struct Ctx ctx = { .
tx_logged = txd->logged.flags, .tx_logged_old = txd->logged.flags };
498 OutputTxLogCallLoggers(
tv, op_thread_data, logger, store, p, f, alstate, tx, tx_id, alproto,
499 eof, tx_progress_ts, tx_progress_tc, &ctx);
514 if (!gap && ctx.
tx_logged == logger_expectation) {
531 SCLogDebug(
"updating log tx_id %"PRIu64, max_id);
547 memset(td, 0x00,
sizeof(*td));
550 SCLogDebug(
"OutputTxLogThreadInit happy (*data %p)", *data);
560 memset(
ts, 0x00,
sizeof(*
ts));
563 ts->thread_data = retptr;
565 if (td->
store[alproto] == NULL) {
569 while (tmp->
next != NULL)
578 logger = logger->
next;
584 FatalError(
"failed to set up file thread data");
589 FatalError(
"failed to set up filedata thread data");
606 while (logger && store) {
614 logger = logger->
next;
618 if (op_thread_data->
file) {
629 static void OutputTxLogExitPrintStats(
ThreadVars *
tv,
void *thread_data)
637 while (logger && store) {
642 logger = logger->
next;
648 static uint32_t OutputTxLoggerGetActiveCount(
void)
673 OutputTxLogExitPrintStats, OutputTxLog, OutputTxLoggerGetActiveCount);
683 logger = next_logger;
685 list[alproto] = NULL;