77 SCLogError(
"Failed to allocate OutputTx list");
128 if (t->
id * 2ULL > UINT32_MAX) {
164 const uint64_t tx_id,
AppLayerTxData *txd,
const bool tx_complete,
const bool ts_ready,
165 const bool tc_ready,
const bool ts_eof,
const bool tc_eof,
const bool eof)
168 uint8_t opposing_dir;
169 bool packet_dir_ready;
170 const bool opposing_dir_ready = eof;
171 bool opposing_tx_ready;
173 packet_dir = STREAM_TOSERVER;
174 opposing_dir = STREAM_TOCLIENT;
175 packet_dir_ready = eof | ts_ready | ts_eof;
176 opposing_tx_ready = tc_ready;
178 packet_dir = STREAM_TOCLIENT;
179 opposing_dir = STREAM_TOSERVER;
180 packet_dir_ready = eof | tc_ready | tc_eof;
181 opposing_tx_ready = ts_ready;
187 SCLogDebug(
"eof %d ts_ready %d ts_eof %d", eof, ts_ready, ts_eof);
188 SCLogDebug(
"eof %d tc_ready %d tc_eof %d", eof, tc_ready, tc_eof);
190 SCLogDebug(
"packet dir %s opposing %s packet_dir_ready %d opposing_dir_ready %d",
191 packet_dir == STREAM_TOSERVER ?
"TOSERVER" :
"TOCLIENT",
192 opposing_dir == STREAM_TOSERVER ?
"TOSERVER" :
"TOCLIENT", packet_dir_ready,
202 bool opposing_finished =
203 ffc_opposing == NULL || (ffc_opposing->
head == NULL && opposing_tx_ready);
204 SCLogDebug(
"opposing_finished %d ffc_opposing %p ffc_opposing->head %p opposing_tx_ready %d",
205 opposing_finished, ffc_opposing, ffc_opposing ? ffc_opposing->
head : NULL,
208 if (ffc || ffc_opposing)
209 SCLogDebug(
"pcap_cnt %" PRIu64
" flow %p tx %p tx_id %" PRIu64
210 " ffc %p ffc_opposing %p tx_complete %d",
216 SCLogDebug(
"tx: calling files: ffc %p head %p file_close %d file_trunc %d", ffc, ffc->
head,
217 file_close, file_trunc);
220 file_close, file_trunc, packet_dir);
223 tv, file_td,
p, ffc, tx, tx_id, txd, file_close, file_trunc, packet_dir);
226 if (opposing_dir_ready && ffc_opposing != NULL) {
229 opposing_finished =
true;
230 SCLogDebug(
"tx: calling for opposing direction files: file_close:%s file_trunc:%s",
231 file_close ?
"true" :
"false", file_trunc ?
"true" :
"false");
234 opposing_dir, file_close, file_trunc, opposing_dir);
240 const bool tx_done = packet_dir_ready && opposing_finished;
241 SCLogDebug(
"tx_done %d packet_dir_ready %d opposing_finished %d", tx_done, packet_dir_ready,
245 const bool is_file_tx = (ffc != NULL || ffc_opposing != NULL);
246 if (!is_file_tx || tx_done) {
247 SCLogDebug(
"is_file_tx %d tx_done %d", is_file_tx, tx_done);
257 SCLogDebug(
"pcap_cnt %" PRIu64
" flow %p tx %p tx_id %" PRIu64
258 " NOT SETTING FILE FLAGS ffc %p ffc_opposing %p tx_complete %d",
264 Flow *
f,
void *tx,
const uint64_t tx_id)
273 while (logger && store) {
284 logger = logger->
next;
300 const bool eof,
const int tx_progress_ts,
const int tx_progress_tc,
struct Ctx *
ctx)
306 while (logger && store) {
310 SCLogDebug(
"logger %p, Alproto %d LogCondition %p, ts_log_progress %d "
311 "tc_log_progress %d",
317 SCLogDebug(
"pcap_cnt %" PRIu64
", tx_id %" PRIu64
" logger %d. EOF %s",
321 SCLogDebug(
"logger:%s flow:%s: skip logger for wrong sub state: logger %u tx %u",
332 SCLogDebug(
"conditions not met, not logging");
336 if (tx_progress_tc < logger->tc_log_progress) {
337 SCLogDebug(
"progress not far enough, not logging");
341 if (tx_progress_ts < logger->ts_log_progress) {
342 SCLogDebug(
"progress not far enough, not logging");
357 logger = logger->
next;
378 const bool no_app_update =
382 if (no_app_update && !flush_pending) {
383 SCLogDebug(
"not pseudo, no app update: skip");
390 const bool flush_only = flush_pending && no_app_update;
398 SCLogDebug(
"pseudo, or app update: run output");
405 const uint8_t ipproto =
f->
proto;
410 const bool file_logging_active = (op_thread_data->
file || op_thread_data->
filedata);
411 if (!file_logging_active) {
421 if (alstate == NULL) {
426 if (logger_expectation == 0) {
427 SCLogDebug(
"bail: logger_expectation %u. LOGGER_FILE %u LOGGER_FILEDATA %u",
437 const bool eof = !flush_only && (last_pseudo || (ts_eof && tc_eof));
438 SCLogDebug(
"eof %d last_pseudo %d ts_eof %d tc_eof %d", eof, last_pseudo, ts_eof, tc_eof);
442 SCLogDebug(
"ts_disrupt_flags %02x tc_disrupt_flags %02x", ts_disrupt_flags, tc_disrupt_flags);
445 uint64_t max_id = tx_id;
456 memset(&state, 0,
sizeof(state));
462 void *
const tx = ires.
tx_ptr;
464 SCLogDebug(
"STARTING tx_id %" PRIu64
", tx %p", tx_id, tx);
470 const int tx_progress_ts =
472 const int tx_progress_tc =
474 const bool tx_complete = (tx_progress_ts == complete_ts && tx_progress_tc == complete_tc);
476 SCLogDebug(
"file_thread_data %p filedata_thread_data %p", op_thread_data->
file,
479 if (file_logging_active) {
482 const bool ts_ready = (tx_progress_ts == complete_ts);
483 const bool tc_ready = (tx_progress_tc == complete_tc);
484 SCLogDebug(
"ts_ready %d tc_ready %d", ts_ready, tc_ready);
486 const bool eval_files = ts_ready | tc_ready | tx_complete | ts_eof | tc_eof | eof;
488 SCLogDebug(
"eval_files: %u, ts_ready %u, tc_ready %u, tx_complete %u, ts_eof %u, "
490 eval_files, ts_ready, tc_ready, tx_complete, ts_eof, tc_eof, eof);
497 if (eval_files || ((txd->
file_tx & pkt_dir) != 0)) {
498 OutputTxLogFiles(
tv, op_thread_data->
file, op_thread_data->
filedata,
p,
f, tx,
499 tx_id, txd, tx_complete, ts_ready, tc_ready, ts_eof, tc_eof, eof);
501 }
else if (support_files) {
502 if (op_thread_data->
file) {
512 SCLogDebug(
"logger: expect %08x, have %08x", logger_expectation, txd->
logged);
517 !(tx_progress_ts == complete_ts) && !(tx_progress_tc == complete_tc) && !ts_eof &&
524 OutputTxLogList0(
tv, op_thread_data,
p,
f, tx, tx_id);
525 if (list[alproto] == NULL)
529 SCLogDebug(
"tx %p/%" PRIu64
" txd %p: log_flags %x logger_expectation %x", tx, tx_id, txd,
534 txd->
logged |= logger_expectation;
538 if (txd->
logged == logger_expectation) {
544 SCLogDebug(
"logger: expect %08x, have %08x", logger_expectation, txd->
logged);
548 SCLogDebug(
"logger: expect %08x, have %08x", logger_expectation,
ctx.tx_logged);
550 OutputTxLogCallLoggers(
tv, op_thread_data, logger, store,
p,
f, alstate, tx, tx_id, txd,
551 alproto, eof, tx_progress_ts, tx_progress_tc, &
ctx);
553 SCLogDebug(
"logger: expect %08x, have %08x", logger_expectation,
ctx.tx_logged);
554 if (
ctx.tx_logged !=
ctx.tx_logged_old) {
555 SCLogDebug(
"logger: storing %08x (was %08x)",
ctx.tx_logged,
ctx.tx_logged_old);
566 if (!gap &&
ctx.tx_logged == logger_expectation) {
567 SCLogDebug(
"no gap %d, %08x == %08x", gap,
ctx.tx_logged, logger_expectation);
583 SCLogDebug(
"updating log tx_id %"PRIu64, max_id);
602 SCLogDebug(
"OutputTxLogThreadInit happy (*data %p)", *data);
614 ts->thread_data = retptr;
616 if (td->
store[alproto] == NULL) {
620 while (tmp->
next != NULL)
629 logger = logger->
next;
635 FatalError(
"failed to set up file thread data");
640 FatalError(
"failed to set up filedata thread data");
657 while (logger && store) {
665 logger = logger->
next;
669 if (op_thread_data->
file) {
680 static uint32_t OutputTxLoggerGetActiveCount(
void)
713 FatalError(
"Failed to allocate OutputTx list");
716 OutputTxLoggerGetActiveCount);
730 logger = next_logger;
732 list[alproto] = NULL;