applayer: pass parameter to StateAlloc

This parameter is NULL or the pointer to the previous state
for the previous protocol in the case of a protocol change,
for instance from HTTP1 to HTTP2

This way, the new protocol can use the old protocol context.
For instance, HTTP2 mimicks the HTTP1 request, to have a HTTP2
transaction with both request and response
pull/5403/head
Philippe Antoine 6 years ago committed by Victor Julien
parent ed9fed4958
commit 547d6c2d78

@ -256,7 +256,7 @@ pub type ParseFn = extern "C" fn (flow: *const Flow,
data: *const c_void,
flags: u8) -> AppLayerResult;
pub type ProbeFn = extern "C" fn (flow: *const Flow,direction: u8,input:*const u8, input_len: u32, rdir: *mut u8) -> AppProto;
pub type StateAllocFn = extern "C" fn () -> *mut c_void;
pub type StateAllocFn = extern "C" fn (*mut c_void, AppProto) -> *mut c_void;
pub type StateFreeFn = extern "C" fn (*mut c_void);
pub type StateTxFreeFn = extern "C" fn (*mut c_void, u64);
pub type StateGetTxFn = extern "C" fn (*mut c_void, u64) -> *mut c_void;

@ -284,7 +284,7 @@ pub extern "C" fn rs_template_probing_parser(
}
#[no_mangle]
pub extern "C" fn rs_template_state_new() -> *mut std::os::raw::c_void {
pub extern "C" fn rs_template_state_new(_orig_state: *mut std::os::raw::c_void, _orig_proto: AppProto) -> *mut std::os::raw::c_void {
let state = TemplateState::new();
let boxed = Box::new(state);
return unsafe { transmute(boxed) };
@ -607,4 +607,4 @@ mod test {
let r = state.parse_request(&buf[0..9]);
assert_eq!(r, AppLayerResult{ status: 1, consumed: 7, needed: 3});
}
}
}

@ -1137,7 +1137,7 @@ pub extern "C" fn rs_dcerpc_parse_response(
}
#[no_mangle]
pub unsafe extern "C" fn rs_dcerpc_state_new() -> *mut std::os::raw::c_void {
pub unsafe extern "C" fn rs_dcerpc_state_new(_orig_state: *mut std::os::raw::c_void, _orig_proto: core::AppProto) -> *mut std::os::raw::c_void {
let state = DCERPCState::new();
let boxed = Box::new(state);
transmute(boxed)

@ -308,7 +308,7 @@ pub extern "C" fn rs_dcerpc_udp_state_free(state: *mut std::os::raw::c_void) {
}
#[no_mangle]
pub unsafe extern "C" fn rs_dcerpc_udp_state_new() -> *mut std::os::raw::c_void {
pub unsafe extern "C" fn rs_dcerpc_udp_state_new(_orig_state: *mut std::os::raw::c_void, _orig_proto: core::AppProto) -> *mut std::os::raw::c_void {
let state = DCERPCUDPState::new();
let boxed = Box::new(state);
transmute(boxed)

@ -306,7 +306,7 @@ pub extern "C" fn rs_dhcp_state_tx_free(
}
#[no_mangle]
pub extern "C" fn rs_dhcp_state_new() -> *mut std::os::raw::c_void {
pub extern "C" fn rs_dhcp_state_new(_orig_state: *mut std::os::raw::c_void, _orig_proto: AppProto) -> *mut std::os::raw::c_void {
let state = DHCPState::new();
let boxed = Box::new(state);
return unsafe {

@ -714,7 +714,7 @@ pub fn probe_tcp(input: &[u8]) -> (bool, bool, bool) {
/// Returns *mut DNSState
#[no_mangle]
pub extern "C" fn rs_dns_state_new() -> *mut std::os::raw::c_void {
pub extern "C" fn rs_dns_state_new(_orig_state: *mut std::os::raw::c_void, _orig_proto: AppProto) -> *mut std::os::raw::c_void {
let state = DNSState::new();
let boxed = Box::new(state);
return unsafe{transmute(boxed)};

@ -878,7 +878,7 @@ pub extern "C" fn rs_http2_probing_parser_tc(
}
#[no_mangle]
pub extern "C" fn rs_http2_state_new() -> *mut std::os::raw::c_void {
pub extern "C" fn rs_http2_state_new(_orig_state: *mut std::os::raw::c_void, _orig_proto: AppProto) -> *mut std::os::raw::c_void {
let state = HTTP2State::new();
let boxed = Box::new(state);
return unsafe { transmute(boxed) };

@ -445,7 +445,7 @@ impl Drop for IKEV2Transaction {
/// Returns *mut IKEV2State
#[no_mangle]
pub extern "C" fn rs_ikev2_state_new() -> *mut std::os::raw::c_void {
pub extern "C" fn rs_ikev2_state_new(_orig_state: *mut std::os::raw::c_void, _orig_proto: AppProto) -> *mut std::os::raw::c_void {
let state = IKEV2State::new();
let boxed = Box::new(state);
return unsafe{std::mem::transmute(boxed)};

@ -273,7 +273,7 @@ pub fn test_weak_encryption(alg:EncryptionType) -> bool {
/// Returns *mut KRB5State
#[no_mangle]
pub extern "C" fn rs_krb5_state_new() -> *mut std::os::raw::c_void {
pub extern "C" fn rs_krb5_state_new(_orig_state: *mut std::os::raw::c_void, _orig_proto: AppProto) -> *mut std::os::raw::c_void {
let state = KRB5State::new();
let boxed = Box::new(state);
return unsafe{std::mem::transmute(boxed)};

@ -578,7 +578,7 @@ pub extern "C" fn rs_mqtt_probing_parser(
}
#[no_mangle]
pub extern "C" fn rs_mqtt_state_new() -> *mut std::os::raw::c_void {
pub extern "C" fn rs_mqtt_state_new(_orig_state: *mut std::os::raw::c_void, _orig_proto: AppProto) -> *mut std::os::raw::c_void {
let state = MQTTState::new();
let boxed = Box::new(state);
return unsafe { transmute(boxed) };

@ -1408,7 +1408,7 @@ impl NFSState {
/// Returns *mut NFSState
#[no_mangle]
pub extern "C" fn rs_nfs_state_new() -> *mut std::os::raw::c_void {
pub extern "C" fn rs_nfs_state_new(_orig_state: *mut std::os::raw::c_void, _orig_proto: AppProto) -> *mut std::os::raw::c_void {
let state = NFSState::new();
let boxed = Box::new(state);
SCLogDebug!("allocating state");

@ -175,7 +175,7 @@ impl Drop for NTPTransaction {
/// Returns *mut NTPState
#[no_mangle]
pub extern "C" fn rs_ntp_state_new() -> *mut std::os::raw::c_void {
pub extern "C" fn rs_ntp_state_new(_orig_state: *mut std::os::raw::c_void, _orig_proto: AppProto) -> *mut std::os::raw::c_void {
let state = NTPState::new();
let boxed = Box::new(state);
return unsafe{std::mem::transmute(boxed)};

@ -365,7 +365,7 @@ impl RdpState {
}
#[no_mangle]
pub extern "C" fn rs_rdp_state_new() -> *mut std::os::raw::c_void {
pub extern "C" fn rs_rdp_state_new(_orig_state: *mut std::os::raw::c_void, _orig_proto: AppProto) -> *mut std::os::raw::c_void {
let state = RdpState::new();
let boxed = Box::new(state);
return unsafe { std::mem::transmute(boxed) };

@ -518,7 +518,7 @@ export_tx_set_detect_state!(
);
#[no_mangle]
pub extern "C" fn rs_rfb_state_new() -> *mut std::os::raw::c_void {
pub extern "C" fn rs_rfb_state_new(_orig_state: *mut std::os::raw::c_void, _orig_proto: AppProto) -> *mut std::os::raw::c_void {
let state = RFBState::new();
let boxed = Box::new(state);
return unsafe { transmute(boxed) };

@ -169,7 +169,7 @@ impl Drop for SIPTransaction {
}
#[no_mangle]
pub extern "C" fn rs_sip_state_new() -> *mut std::os::raw::c_void {
pub extern "C" fn rs_sip_state_new(_orig_state: *mut std::os::raw::c_void, _orig_proto: AppProto) -> *mut std::os::raw::c_void {
let state = SIPState::new();
let boxed = Box::new(state);
return unsafe { std::mem::transmute(boxed) };

@ -1824,7 +1824,7 @@ impl SMBState {
/// Returns *mut SMBState
#[no_mangle]
pub extern "C" fn rs_smb_state_new() -> *mut std::os::raw::c_void {
pub extern "C" fn rs_smb_state_new(_orig_state: *mut std::os::raw::c_void, _orig_proto: AppProto) -> *mut std::os::raw::c_void {
let state = SMBState::new();
let boxed = Box::new(state);
SCLogDebug!("allocating state");

@ -297,7 +297,7 @@ impl<'a> Drop for SNMPTransaction<'a> {
/// Returns *mut SNMPState
#[no_mangle]
pub extern "C" fn rs_snmp_state_new() -> *mut std::os::raw::c_void {
pub extern "C" fn rs_snmp_state_new(_orig_state: *mut std::os::raw::c_void, _orig_proto: AppProto) -> *mut std::os::raw::c_void {
let state = SNMPState::new();
let boxed = Box::new(state);
return unsafe{std::mem::transmute(boxed)};

@ -428,7 +428,7 @@ pub extern "C" fn rs_ssh_state_get_event_info_by_id(
}
#[no_mangle]
pub extern "C" fn rs_ssh_state_new() -> *mut std::os::raw::c_void {
pub extern "C" fn rs_ssh_state_new(_orig_state: *mut std::os::raw::c_void, _orig_proto: AppProto) -> *mut std::os::raw::c_void {
let state = SSHState::new();
let boxed = Box::new(state);
return unsafe { transmute(boxed) };

@ -57,9 +57,9 @@ static AppLayerResult RustDCERPCUDPParse(Flow *f, void *dcerpc_state,
local_data, flags);
}
static void *RustDCERPCUDPStateNew(void)
static void *RustDCERPCUDPStateNew(void *state_orig, AppProto proto_orig)
{
return rs_dcerpc_udp_state_new();
return rs_dcerpc_udp_state_new(state_orig, proto_orig);
}
static void RustDCERPCUDPStateFree(void *s)

@ -81,9 +81,9 @@ static AppLayerResult DCERPCParseResponse(Flow *f, void *dcerpc_state,
}
}
static void *RustDCERPCStateNew(void)
static void *RustDCERPCStateNew(void *state_orig, AppProto proto_orig)
{
return rs_dcerpc_state_new();
return rs_dcerpc_state_new(state_orig, proto_orig);
}
static void DCERPCStateFree(void *s)

@ -432,7 +432,7 @@ static int DNP3ReassembleApplicationLayer(const uint8_t *input,
*
* The DNP3 state object represents a single DNP3 TCP session.
*/
static void *DNP3StateAlloc(void)
static void *DNP3StateAlloc(void *orig_state, AppProto proto_orig)
{
SCEnter();
DNP3State *dnp3;
@ -2510,7 +2510,7 @@ static int DNP3ParserTestParsePDU01(void)
0xe1, 0xc8, 0x01, 0x01, 0x00, 0x06, 0x77, 0x6e
};
DNP3State *dnp3state = DNP3StateAlloc();
DNP3State *dnp3state = DNP3StateAlloc(NULL, ALPROTO_UNKNOWN);
int pdus = DNP3HandleRequestLinkLayer(dnp3state, pkt, sizeof(pkt));
FAIL_IF(pdus < 1);
DNP3Transaction *dnp3tx = DNP3GetTx(dnp3state, 0);
@ -2549,7 +2549,7 @@ static int DNP3ParserDecodeG70V3Test(void)
0xc4, 0x8b
};
DNP3State *dnp3state = DNP3StateAlloc();
DNP3State *dnp3state = DNP3StateAlloc(NULL, ALPROTO_UNKNOWN);
FAIL_IF_NULL(dnp3state);
int bytes = DNP3HandleRequestLinkLayer(dnp3state, pkt, sizeof(pkt));
FAIL_IF(bytes != sizeof(pkt));
@ -2610,7 +2610,7 @@ static int DNP3ParserUnknownEventAlertTest(void)
DNP3FixCrc(pkt + 10, sizeof(pkt) - 10);
DNP3State *dnp3state = DNP3StateAlloc();
DNP3State *dnp3state = DNP3StateAlloc(NULL, ALPROTO_UNKNOWN);
FAIL_IF_NULL(dnp3state);
int bytes = DNP3HandleRequestLinkLayer(dnp3state, pkt, sizeof(pkt));
FAIL_IF(bytes != sizeof(pkt));

@ -159,7 +159,7 @@ static int ENIPStateGetEventInfoById(int event_id, const char **event_name,
*
* return state
*/
static void *ENIPStateAlloc(void)
static void *ENIPStateAlloc(void *orig_state, AppProto proto_orig)
{
SCLogDebug("ENIPStateAlloc");
void *s = SCMalloc(sizeof(ENIPState));

@ -833,7 +833,7 @@ static uint64_t ftp_state_memuse = 0;
static uint64_t ftp_state_memcnt = 0;
#endif
static void *FTPStateAlloc(void)
static void *FTPStateAlloc(void *orig_state, AppProto proto_orig)
{
void *s = FTPCalloc(1, sizeof(FtpState));
if (unlikely(s == NULL))
@ -1152,7 +1152,7 @@ static uint64_t ftpdata_state_memuse = 0;
static uint64_t ftpdata_state_memcnt = 0;
#endif
static void *FTPDataStateAlloc(void)
static void *FTPDataStateAlloc(void *orig_state, AppProto proto_orig)
{
void *s = FTPCalloc(1, sizeof(FtpDataState));
if (unlikely(s == NULL))

@ -340,7 +340,7 @@ static AppLayerDecoderEvents *HTPGetEvents(void *tx)
/** \brief Function to allocates the HTTP state memory and also creates the HTTP
* connection parser to be used by the HTP library
*/
static void *HTPStateAlloc(void)
static void *HTPStateAlloc(void *orig_state, AppProto proto_orig)
{
SCEnter();

@ -1394,7 +1394,7 @@ static AppLayerResult ModbusParseResponse(Flow *f,
/** \internal
* \brief Function to allocate the Modbus state memory
*/
static void *ModbusStateAlloc(void)
static void *ModbusStateAlloc(void *orig_state, AppProto proto_orig)
{
ModbusState *modbus;

@ -66,9 +66,9 @@ SCEnumCharMap nfs_decoder_event_table[] = {
{ NULL, 0 }
};
static void *NFSTCPStateAlloc(void)
static void *NFSTCPStateAlloc(void *orig_state, AppProto proto_orig)
{
return rs_nfs_state_new();
return rs_nfs_state_new(orig_state, proto_orig);
}
static void NFSTCPStateFree(void *state)

@ -63,9 +63,9 @@ SCEnumCharMap nfs_udp_decoder_event_table[] = {
{ NULL, 0 }
};
static void *NFSStateAlloc(void)
static void *NFSStateAlloc(void *orig_state, AppProto proto_orig)
{
return rs_nfs_state_new();
return rs_nfs_state_new(orig_state, proto_orig);
}
static void NFSStateFree(void *state)

@ -99,7 +99,7 @@ typedef struct AppLayerParserProtoCtx_
bool logger;
uint32_t logger_bits; /**< registered loggers for this proto */
void *(*StateAlloc)(void);
void *(*StateAlloc)(void *, AppProto);
void (*StateFree)(void *);
void (*StateTransactionFree)(void *, uint64_t);
void *(*LocalStorageAlloc)(void);
@ -396,8 +396,7 @@ uint32_t AppLayerParserGetOptionFlags(uint8_t protomap, AppProto alproto)
}
void AppLayerParserRegisterStateFuncs(uint8_t ipproto, AppProto alproto,
void *(*StateAlloc)(void),
void (*StateFree)(void *))
void *(*StateAlloc)(void *, AppProto), void (*StateFree)(void *))
{
SCEnter();
@ -1216,7 +1215,7 @@ int AppLayerParserParse(ThreadVars *tv, AppLayerParserThreadCtx *alp_tctx, Flow
alstate = f->alstate;
if (alstate == NULL) {
f->alstate = alstate = p->StateAlloc();
f->alstate = alstate = p->StateAlloc(alstate, f->alproto_orig);
if (alstate == NULL)
goto error;
SCLogDebug("alloced new app layer state %p (name %s)",
@ -1679,7 +1678,7 @@ static AppLayerResult TestProtocolParser(Flow *f, void *test_state, AppLayerPars
/** \brief Function to allocates the Test protocol state memory
*/
static void *TestProtocolStateAlloc(void)
static void *TestProtocolStateAlloc(void *orig_state, AppProto proto_orig)
{
SCEnter();
void *s = SCMalloc(sizeof(TestState));

@ -145,8 +145,7 @@ void AppLayerParserRegisterParserAcceptableDataDirection(uint8_t ipproto,
void AppLayerParserRegisterOptionFlags(uint8_t ipproto, AppProto alproto,
uint32_t flags);
void AppLayerParserRegisterStateFuncs(uint8_t ipproto, AppProto alproto,
void *(*StateAlloc)(void),
void (*StateFree)(void *));
void *(*StateAlloc)(void *, AppProto), void (*StateFree)(void *));
void AppLayerParserRegisterLocalStorageFunc(uint8_t ipproto, AppProto proto,
void *(*LocalStorageAlloc)(void),
void (*LocalStorageFree)(void *));

@ -35,7 +35,7 @@ typedef struct AppLayerParser {
uint16_t min_depth;
uint16_t max_depth;
void *(*StateAlloc)(void);
void *(*StateAlloc)(void *, AppProto);
void (*StateFree)(void *);
AppLayerParserFPtr ParseTS;

@ -1432,7 +1432,7 @@ static AppLayerResult SMTPParseServerRecord(Flow *f, void *alstate,
* \internal
* \brief Function to allocate SMTP state memory.
*/
void *SMTPStateAlloc(void)
void *SMTPStateAlloc(void *orig_state, AppProto proto_orig)
{
SMTPState *smtp_state = SCMalloc(sizeof(SMTPState));
if (unlikely(smtp_state == NULL))
@ -5154,7 +5154,7 @@ static int SMTPProcessDataChunkTest02(void){
memset(&ssn, 0, sizeof(ssn));
FLOW_INITIALIZE(&f);
f.protoctx = &ssn;
f.alstate = SMTPStateAlloc();
f.alstate = SMTPStateAlloc(NULL, ALPROTO_UNKNOWN);
MimeDecParseState *state = MimeDecInitParser(&f, NULL);
((MimeDecEntity *)state->stack->top->data)->ctnt_flags = CTNT_IS_ATTACHMENT;
state->body_begin = 1;
@ -5185,7 +5185,7 @@ static int SMTPProcessDataChunkTest03(void){
Flow f;
FLOW_INITIALIZE(&f);
f.protoctx = &ssn;
f.alstate = SMTPStateAlloc();
f.alstate = SMTPStateAlloc(NULL, ALPROTO_UNKNOWN);
MimeDecParseState *state = MimeDecInitParser(&f, NULL);
((MimeDecEntity *)state->stack->top->data)->ctnt_flags = CTNT_IS_ATTACHMENT;
int ret;
@ -5241,7 +5241,7 @@ static int SMTPProcessDataChunkTest04(void){
Flow f;
FLOW_INITIALIZE(&f);
f.protoctx = &ssn;
f.alstate = SMTPStateAlloc();
f.alstate = SMTPStateAlloc(NULL, ALPROTO_UNKNOWN);
MimeDecParseState *state = MimeDecInitParser(&f, NULL);
((MimeDecEntity *)state->stack->top->data)->ctnt_flags = CTNT_IS_ATTACHMENT;
int ret = MIME_DEC_OK;
@ -5281,7 +5281,7 @@ static int SMTPProcessDataChunkTest05(void){
int ret;
FLOW_INITIALIZE(&f);
f.protoctx = &ssn;
f.alstate = SMTPStateAlloc();
f.alstate = SMTPStateAlloc(NULL, ALPROTO_UNKNOWN);
FAIL_IF(f.alstate == NULL);
MimeDecParseState *state = MimeDecInitParser(&f, NULL);
((MimeDecEntity *)state->stack->top->data)->ctnt_flags = CTNT_IS_ATTACHMENT;

@ -174,7 +174,7 @@ typedef struct SMTPState_ {
extern SMTPConfig smtp_config;
int SMTPProcessDataChunk(const uint8_t *chunk, uint32_t len, MimeDecParseState *state);
void *SMTPStateAlloc(void);
void *SMTPStateAlloc(void *orig_state, AppProto proto_orig);
void RegisterSMTPParsers(void);
void SMTPParserCleanup(void);
void SMTPParserRegisterTests(void);

@ -2634,7 +2634,7 @@ static AppLayerResult SSLParseServerRecord(Flow *f, void *alstate, AppLayerParse
* \internal
* \brief Function to allocate the SSL state memory.
*/
static void *SSLStateAlloc(void)
static void *SSLStateAlloc(void *orig_state, AppProto proto_orig)
{
SSLState *ssl_state = SCMalloc(sizeof(SSLState));
if (unlikely(ssl_state == NULL))

@ -105,7 +105,7 @@ static void TemplateTxFree(void *txv)
SCFree(tx);
}
static void *TemplateStateAlloc(void)
static void *TemplateStateAlloc(void *orig_state, AppProto proto_orig)
{
SCLogNotice("Allocating template state.");
TemplateState *state = SCCalloc(1, sizeof(TemplateState));

@ -44,7 +44,7 @@
* be the size of a header. */
#define TFTP_MIN_FRAME_LEN 4
static void *TFTPStateAlloc(void)
static void *TFTPStateAlloc(void *orig_state, AppProto proto_orig)
{
return rs_tftp_state_alloc();
}

@ -73,7 +73,7 @@ static int DetectEngineSMTPFiledataTest01(void)
f.protoctx = (void *)&ssn;
f.proto = IPPROTO_TCP;
f.flags |= FLOW_IPV4;
f.alstate = SMTPStateAlloc();
f.alstate = SMTPStateAlloc(NULL, ALPROTO_UNKNOWN);
MimeDecParseState *state = MimeDecInitParser(&f, NULL);
((MimeDecEntity *)state->stack->top->data)->ctnt_flags = CTNT_IS_ATTACHMENT;
@ -205,7 +205,7 @@ static int DetectEngineSMTPFiledataTest03(void)
f.protoctx = (void *)&ssn;
f.proto = IPPROTO_TCP;
f.flags |= FLOW_IPV4;
f.alstate = SMTPStateAlloc();
f.alstate = SMTPStateAlloc(NULL, ALPROTO_UNKNOWN);
MimeDecParseState *state = MimeDecInitParser(&f, NULL);
((MimeDecEntity *)state->stack->top->data)->ctnt_flags = CTNT_IS_ATTACHMENT;

Loading…
Cancel
Save