SCReturnInt(-1);
}
+/**
+ * \brief Get 'active' tx id, meaning the lowest id that still need work.
+ *
+ * \retval id tx id
+ */
+uint64_t AppLayerTransactionGetActive(Flow *f, uint8_t flags) {
+ AppLayerProto *p = &al_proto_table[f->alproto];
+ uint64_t log_id = ((AppLayerParserStateStore *)f->alparser)->log_id;
+ uint64_t inspect_id = ((AppLayerParserStateStore *)f->alparser)->
+ inspect_id[flags & STREAM_TOSERVER ? 0 : 1];
+ if (p->logger == TRUE) {
+ return (log_id < inspect_id) ? log_id : inspect_id;
+ } else {
+ return inspect_id;
+ }
+}
+
void AppLayerTransactionUpdateLogId(Flow *f)
{
DEBUG_ASSERT_FLOW_LOCKED(f);
}
int server = 0, client = 0;
- if (FlowForceReassemblyNeedReassmbly(f, &server, &client) == 1) {
+ if (!(f->flags & FLOW_TIMEOUT_REASSEMBLY_DONE) &&
+ FlowForceReassemblyNeedReassmbly(f, &server, &client) == 1) {
FlowForceReassemblyForFlowV2(f, server, client);
return 0;
}
int FlowForceReassemblyNeedReassmbly(Flow *f, int *server, int *client) {
TcpSession *ssn;
- /* looks like we have no flows in this queue */
- if (f == NULL || (f->flags & FLOW_TIMEOUT_REASSEMBLY_DONE)) {
- return 0;
+ if (f == NULL) {
+ *server = *client = STREAM_HAS_UNPROCESSED_SEGMENTS_NONE;
+ SCReturnInt(0);
}
/* Get the tcp session for the flow */
ssn = (TcpSession *)f->protoctx;
if (ssn == NULL) {
- return 0;
+ *server = *client = STREAM_HAS_UNPROCESSED_SEGMENTS_NONE;
+ SCReturnInt(0);
}
*client = StreamNeedsReassembly(ssn, 0);
*server = STREAM_HAS_UNPROCESSED_SEGMENTS_NEED_ONLY_DETECTION;
}
+ /* if app layer still needs some love, push through */
+ if (f->alproto != ALPROTO_UNKNOWN && f->alstate != NULL &&
+ AppLayerAlprotoSupportsTxs(f->alproto))
+ {
+ uint64_t total_txs = AppLayerGetTxCnt(f->alproto, f->alstate);
+
+ if (AppLayerTransactionGetActive(f, STREAM_TOCLIENT) < total_txs) {
+ if (*server != STREAM_HAS_UNPROCESSED_SEGMENTS_NEED_REASSEMBLY)
+ *server = STREAM_HAS_UNPROCESSED_SEGMENTS_NEED_ONLY_DETECTION;
+ }
+ if (AppLayerTransactionGetActive(f, STREAM_TOSERVER) < total_txs) {
+ if (*client != STREAM_HAS_UNPROCESSED_SEGMENTS_NEED_REASSEMBLY)
+ *client = STREAM_HAS_UNPROCESSED_SEGMENTS_NEED_ONLY_DETECTION;
+ }
+ }
+
/* nothing to do */
if (*client == STREAM_HAS_UNPROCESSED_SEGMENTS_NONE &&
*server == STREAM_HAS_UNPROCESSED_SEGMENTS_NONE) {
- return 0;
+ SCReturnInt(0);
}
- return 1;
+ SCReturnInt(1);
}
/**
continue;
}
+ (void)FlowForceReassemblyNeedReassmbly(f, &server_ok, &client_ok);
+
/* ah ah! We have some unattended toserver segments */
- if ((client_ok = StreamNeedsReassembly(ssn, 0)) == STREAM_HAS_UNPROCESSED_SEGMENTS_NEED_REASSEMBLY) {
+ if (client_ok == STREAM_HAS_UNPROCESSED_SEGMENTS_NEED_REASSEMBLY) {
StreamTcpThread *stt = SC_ATOMIC_GET(stream_pseudo_pkt_stream_tm_slot->slot_data);
ssn->client.last_ack = (ssn->client.seg_list_tail->seq +
}
}
/* oh oh! We have some unattended toclient segments */
- if ((server_ok = StreamNeedsReassembly(ssn, 1)) == STREAM_HAS_UNPROCESSED_SEGMENTS_NEED_REASSEMBLY) {
+ if (server_ok == STREAM_HAS_UNPROCESSED_SEGMENTS_NEED_REASSEMBLY) {
StreamTcpThread *stt = SC_ATOMIC_GET(stream_pseudo_pkt_stream_tm_slot->slot_data);
ssn->server.last_ack = (ssn->server.seg_list_tail->seq +