|
|
|
|
@ -1,4 +1,4 @@
|
|
|
|
|
/* Copyright (C) 2017-2020 Open Information Security Foundation
|
|
|
|
|
/* Copyright (C) 2017-2021 Open Information Security Foundation
|
|
|
|
|
*
|
|
|
|
|
* You can copy, redistribute or modify this Program under the terms of
|
|
|
|
|
* the GNU General Public License version 2 as published by the Free
|
|
|
|
|
@ -38,7 +38,7 @@
|
|
|
|
|
* AppLayerExpectationGetDataId():
|
|
|
|
|
*
|
|
|
|
|
* ```
|
|
|
|
|
* data = (char *)FlowGetStorageById(f, AppLayerExpectationGetDataId());
|
|
|
|
|
* data = (char *)FlowGetStorageById(f, AppLayerExpectationGetFlowId());
|
|
|
|
|
* ```
|
|
|
|
|
* This storage can be used to store information that are only available in the
|
|
|
|
|
* parent connection and could be useful in the parent connection. For instance
|
|
|
|
|
@ -63,8 +63,8 @@
|
|
|
|
|
#include "util-print.h"
|
|
|
|
|
#include "queue.h"
|
|
|
|
|
|
|
|
|
|
static int g_expectation_id = -1;
|
|
|
|
|
static int g_expectation_data_id = -1;
|
|
|
|
|
static int g_ippair_expectation_id = -1;
|
|
|
|
|
static int g_flow_expectation_id = -1;
|
|
|
|
|
|
|
|
|
|
SC_ATOMIC_DECLARE(uint32_t, expectation_count);
|
|
|
|
|
|
|
|
|
|
@ -146,8 +146,10 @@ uint64_t ExpectationGetCounter(void)
|
|
|
|
|
|
|
|
|
|
void AppLayerExpectationSetup(void)
|
|
|
|
|
{
|
|
|
|
|
g_expectation_id = IPPairStorageRegister("expectation", sizeof(void *), NULL, ExpectationListFree);
|
|
|
|
|
g_expectation_data_id = FlowStorageRegister("expectation", sizeof(void *), NULL, ExpectationDataFree);
|
|
|
|
|
g_ippair_expectation_id =
|
|
|
|
|
IPPairStorageRegister("expectation", sizeof(void *), NULL, ExpectationListFree);
|
|
|
|
|
g_flow_expectation_id =
|
|
|
|
|
FlowStorageRegister("expectation", sizeof(void *), NULL, ExpectationDataFree);
|
|
|
|
|
SC_ATOMIC_INIT(expectation_count);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@ -177,7 +179,7 @@ static ExpectationList *AppLayerExpectationLookup(Flow *f, IPPair **ipp)
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return IPPairGetStorageById(*ipp, g_expectation_id);
|
|
|
|
|
return IPPairGetStorageById(*ipp, g_ippair_expectation_id);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@ -190,7 +192,7 @@ static ExpectationList *AppLayerExpectationRemove(IPPair *ipp,
|
|
|
|
|
SC_ATOMIC_SUB(expectation_count, 1);
|
|
|
|
|
exp_list->length--;
|
|
|
|
|
if (exp_list->length == 0) {
|
|
|
|
|
IPPairSetStorageById(ipp, g_expectation_id, NULL);
|
|
|
|
|
IPPairSetStorageById(ipp, g_ippair_expectation_id, NULL);
|
|
|
|
|
ExpectationListFree(exp_list);
|
|
|
|
|
exp_list = NULL;
|
|
|
|
|
}
|
|
|
|
|
@ -240,7 +242,7 @@ int AppLayerExpectationCreate(Flow *f, int direction, Port src, Port dst,
|
|
|
|
|
if (ipp == NULL)
|
|
|
|
|
goto error;
|
|
|
|
|
|
|
|
|
|
exp_list = IPPairGetStorageById(ipp, g_expectation_id);
|
|
|
|
|
exp_list = IPPairGetStorageById(ipp, g_ippair_expectation_id);
|
|
|
|
|
if (exp_list) {
|
|
|
|
|
CIRCLEQ_INSERT_HEAD(&exp_list->list, exp, entries);
|
|
|
|
|
/* In case there is already EXPECTATION_MAX_LEVEL expectations waiting to be fullfill,
|
|
|
|
|
@ -262,7 +264,7 @@ int AppLayerExpectationCreate(Flow *f, int direction, Port src, Port dst,
|
|
|
|
|
exp_list->length = 0;
|
|
|
|
|
CIRCLEQ_INIT(&exp_list->list);
|
|
|
|
|
CIRCLEQ_INSERT_HEAD(&exp_list->list, exp, entries);
|
|
|
|
|
IPPairSetStorageById(ipp, g_expectation_id, exp_list);
|
|
|
|
|
IPPairSetStorageById(ipp, g_ippair_expectation_id, exp_list);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
exp_list->length += 1;
|
|
|
|
|
@ -284,9 +286,9 @@ error:
|
|
|
|
|
*
|
|
|
|
|
* \return expectation data identifier
|
|
|
|
|
*/
|
|
|
|
|
int AppLayerExpectationGetDataId(void)
|
|
|
|
|
int AppLayerExpectationGetFlowId(void)
|
|
|
|
|
{
|
|
|
|
|
return g_expectation_data_id;
|
|
|
|
|
return g_flow_expectation_id;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
@ -324,13 +326,13 @@ AppProto AppLayerExpectationHandle(Flow *f, uint8_t flags)
|
|
|
|
|
alproto = exp->alproto;
|
|
|
|
|
f->alproto_ts = alproto;
|
|
|
|
|
f->alproto_tc = alproto;
|
|
|
|
|
void *fdata = FlowGetStorageById(f, g_expectation_data_id);
|
|
|
|
|
void *fdata = FlowGetStorageById(f, g_flow_expectation_id);
|
|
|
|
|
if (fdata) {
|
|
|
|
|
/* We already have an expectation so let's clean this one */
|
|
|
|
|
ExpectationDataFree(exp->data);
|
|
|
|
|
} else {
|
|
|
|
|
/* Transfer ownership of Expectation data to the Flow */
|
|
|
|
|
if (FlowSetStorageById(f, g_expectation_data_id, exp->data) != 0) {
|
|
|
|
|
if (FlowSetStorageById(f, g_flow_expectation_id, exp->data) != 0) {
|
|
|
|
|
SCLogDebug("Unable to set flow storage");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|