FileContainer *AppLayerGetFilesFromFlow(Flow *f, uint8_t direction) {
SCEnter();
+ DEBUG_ASSERT_FLOW_LOCKED(f);
+
uint16_t alproto = f->alproto;
if (alproto == ALPROTO_UNKNOWN)
uint16_t proto)
{
SCEnter();
+ DEBUG_ASSERT_FLOW_LOCKED(f);
+
int retval = 0;
AppLayerParserResult result = { NULL, NULL, 0 };
int AppLayerTransactionGetBaseId(Flow *f) {
SCEnter();
+ DEBUG_ASSERT_FLOW_LOCKED(f);
+
AppLayerParserStateStore *parser_state_store =
(AppLayerParserStateStore *)f->alparser;
extern uint8_t engine_mode;
/** \brief Get the active app layer proto from the packet
- * \param p packet pointer
+ * \param p packet pointer with a LOCKED flow
* \retval alstate void pointer to the state
* \retval proto (ALPROTO_UNKNOWN if no proto yet) */
uint16_t AppLayerGetProtoFromPacket(Packet *p) {
SCReturnUInt(ALPROTO_UNKNOWN);
}
+ DEBUG_ASSERT_FLOW_LOCKED(p->flow);
+
SCLogDebug("p->flow->alproto %"PRIu16"", p->flow->alproto);
SCReturnUInt(p->flow->alproto);
SCReturnPtr(NULL, "void");
}
+ DEBUG_ASSERT_FLOW_LOCKED(p->flow);
+
SCLogDebug("p->flow->alproto %"PRIu16"", p->flow->alproto);
SCLogDebug("p->flow %p", p->flow);
DetectAppLayerEventData *aled = (DetectAppLayerEventData *)m->ctx;
+ SCMutexLock(&f->m);
AppLayerDecoderEvents *decoder_events = AppLayerGetDecoderEventsForFlow(f);
+ SCMutexUnlock(&f->m);
if (decoder_events == NULL) {
SCReturnInt(0);
}
static StreamMsg *SigMatchSignaturesGetSmsg(Flow *f, Packet *p, uint8_t flags) {
SCEnter();
+ DEBUG_ASSERT_FLOW_LOCKED(f);
+
StreamMsg *smsg = NULL;
if (p->proto == IPPROTO_TCP && f->protoctx != NULL) {
* \internal
* \brief Forces reassembly for flows that need it.
*
- * Please note we don't use locks anywhere. This function is to be
- * called right when the engine is not doing anything.
+ * When this function is called we're running in virtually dead engine,
+ * so locking the flows is not strictly required. The reasons it is still
+ * done are:
+ * - code consistency
+ * - silence complaining profilers
+ * - allow us to aggressively check using debug valdation assertions
+ * - be robust in case of future changes
+ * - locking overhead if neglectable when no other thread fights us
*
* \param q The queue to process flows from.
*/
TcpSession *ssn;
int client_ok;
int server_ok;
-
- /* no locks needed, since the engine is virtually dead.
- * We are the kings here */
+ int tcp_needs_inspection;
/* get the topmost flow from the QUEUE */
f = q->top;
/* we need to loop through all the flows in the queue */
while (f != NULL) {
+ SCMutexLock(&f->m);
+
PACKET_RECYCLE(reassemble_p);
/* Get the tcp session for the flow */
/* \todo Also skip flows that shouldn't be inspected */
if (ssn == NULL) {
+ SCMutexUnlock(&f->m);
f = f->lnext;
continue;
}
StreamTcpReassembleProcessAppLayer(stt->ra_ctx);
}
+ if (ssn->state >= TCP_ESTABLISHED && ssn->state != TCP_CLOSED)
+ tcp_needs_inspection = 1;
+ else
+ tcp_needs_inspection = 0;
+
+ SCMutexUnlock(&f->m);
+
/* insert a pseudo packet in the toserver direction */
- if (client_ok ||
- (ssn->state >= TCP_ESTABLISHED && ssn->state != TCP_CLOSED))
+ if (client_ok || tcp_needs_inspection)
{
+ SCMutexLock(&f->m);
Packet *p = FlowForceReassemblyPseudoPacketGet(0, f, ssn, 1);
+ SCMutexUnlock(&f->m);
+
if (p == NULL) {
TmqhOutputPacketpool(NULL, reassemble_p);
return;
}
}
} /* if (ssn->client.seg_list != NULL) */
- if (server_ok ||
- (ssn->state >= TCP_ESTABLISHED && ssn->state != TCP_CLOSED))
+ if (server_ok || tcp_needs_inspection)
{
+ SCMutexLock(&f->m);
Packet *p = FlowForceReassemblyPseudoPacketGet(1, f, ssn, 1);
+ SCMutexUnlock(&f->m);
+
if (p == NULL) {
TmqhOutputPacketpool(NULL, reassemble_p);
return;
#include "util-privs.h"
#include "util-profiling.h"
#include "util-misc.h"
+#include "util-validate.h"
//#define DEBUG
{
SCEnter();
+ DEBUG_ASSERT_FLOW_LOCKED(p->flow);
+
SCLogDebug("p->pcap_cnt %"PRIu64, p->pcap_cnt);
TcpSession *ssn = (TcpSession *)p->flow->protoctx;
SCEnter();
+ DEBUG_ASSERT_FLOW_LOCKED(f);
+
f->flags |= FLOW_FILE_NO_STORE;
FileContainer *ffc = AppLayerGetFilesFromFlow(f, direction);
SCEnter();
+ DEBUG_ASSERT_FLOW_LOCKED(f);
+
f->flags |= FLOW_FILE_NO_MAGIC;
FileContainer *ffc = AppLayerGetFilesFromFlow(f, direction);