From 240d821847499ac4a35b48439dbc31c65ac42a6a Mon Sep 17 00:00:00 2001 From: Spencer Sevilla Date: Tue, 24 Jan 2023 16:23:26 -0800 Subject: [PATCH] [sgwc][smf][no_upstream] check if session is active before dereferencing (#66) --- src/sgwc/context.c | 8 +++++++ src/sgwc/context.h | 3 +++ src/sgwc/s11-handler.c | 44 +++++++++++++++++++++++++++--------- src/sgwc/s5c-handler.c | 14 ++++++------ src/sgwc/sxa-handler.c | 49 ++++++++++++++++++++++++---------------- src/smf/context.c | 7 ++++++ src/smf/context.h | 2 ++ src/smf/gn-handler.c | 2 +- src/smf/gsm-sm.c | 15 +++++++++++++ src/smf/n4-handler.c | 6 ++--- src/smf/pfcp-sm.c | 4 ++-- src/smf/s5c-handler.c | 23 +++++++++++++++++-- src/smf/smf-sm.c | 51 +++++++++++++++++++++++++++--------------- 13 files changed, 165 insertions(+), 63 deletions(-) diff --git a/src/sgwc/context.c b/src/sgwc/context.c index 6dea6925b8..1ead3826f4 100644 --- a/src/sgwc/context.c +++ b/src/sgwc/context.c @@ -311,8 +311,11 @@ sgwc_sess_t *sgwc_sess_add(sgwc_ue_t *sgwc_ue, char *apn) (long long)ogs_app()->pool.sess); return NULL; } + memset(sess, 0, sizeof *sess); + sess->active = true; + ogs_pfcp_pool_init(&sess->pfcp); /* Set TEID & SEID */ @@ -443,6 +446,11 @@ int sgwc_sess_remove(sgwc_sess_t *sess) sgwc_ue = sess->sgwc_ue; ogs_assert(sgwc_ue); + if (!sess->active) { + ogs_error("sgwc_sess_remove double-free"); + } + sess->active = false; + ogs_list_remove(&sgwc_ue->sess_list, sess); ogs_hash_set(self.sgwc_sxa_seid_hash, &sess->sgwc_sxa_seid, diff --git a/src/sgwc/context.h b/src/sgwc/context.h index 063bbc4ee7..bea04051ae 100644 --- a/src/sgwc/context.h +++ b/src/sgwc/context.h @@ -95,6 +95,9 @@ typedef struct sgwc_sess_s { ogs_pfcp_node_t *pfcp_node; sgwc_ue_t *sgwc_ue; + + bool active; + } sgwc_sess_t; typedef struct sgwc_bearer_s { diff --git a/src/sgwc/s11-handler.c b/src/sgwc/s11-handler.c index a2544c25e6..ddc7611f7a 100644 --- a/src/sgwc/s11-handler.c +++ b/src/sgwc/s11-handler.c @@ -497,7 +497,7 @@ void sgwc_s11_handle_modify_bearer_request( } sess = bearer->sess; - ogs_assert(sess); + ogs_assert(sess && sess->active); ogs_list_for_each_entry(&pfcp_xact_list, pfcp_xact, tmpnode) { if (sess == pfcp_xact->data) { @@ -635,7 +635,7 @@ void sgwc_s11_handle_delete_session_request( if (cause_value == OGS_GTP2_CAUSE_REQUEST_ACCEPTED) { sess = sgwc_sess_find_by_ebi(sgwc_ue, req->linked_eps_bearer_id.u8); - if (!sess) { + if (!sess || !sess->active) { ogs_error("Unknown EPS Bearer [IMSI:%s, EBI:%d]", sgwc_ue->imsi_bcd, req->linked_eps_bearer_id.u8); cause_value = OGS_GTP2_CAUSE_CONTEXT_NOT_FOUND; @@ -675,7 +675,7 @@ void sgwc_s11_handle_delete_session_request( * Check ALL Context ********************/ ogs_assert(sgwc_ue); - ogs_assert(sess); + ogs_assert(sess && sess->active); ogs_assert(sess->gnode); ogs_debug(" MME_S11_TEID[%d] SGW_S11_TEID[%d]", sgwc_ue->mme_s11_teid, sgwc_ue->sgw_s11_teid); @@ -756,7 +756,7 @@ void sgwc_s11_handle_create_bearer_response( ogs_assert(bearer); sess = bearer->sess; - ogs_assert(sess); + ogs_assert(sess && sess->active); rv = ogs_gtp_xact_commit(s11_xact); ogs_expect(rv == OGS_OK); @@ -825,7 +825,7 @@ void sgwc_s11_handle_create_bearer_response( * Check ALL Context ********************/ ogs_assert(sgwc_ue); - ogs_assert(sess); + ogs_assert(sess && sess->active); ogs_assert(bearer); /* Correlate with SGW-S1U-TEID */ @@ -899,7 +899,6 @@ void sgwc_s11_handle_update_bearer_response( sgwc_bearer_t *bearer = NULL; ogs_gtp2_update_bearer_response_t *rsp = NULL; - ogs_assert(sgwc_ue); ogs_assert(message); rsp = &message->update_bearer_response; ogs_assert(rsp); @@ -921,11 +920,31 @@ void sgwc_s11_handle_update_bearer_response( ogs_assert(bearer); sess = bearer->sess; - ogs_assert(sess); rv = ogs_gtp_xact_commit(s11_xact); ogs_expect(rv == OGS_OK); + /************************ + * Check SGWC-UE Context + ************************/ + cause_value = OGS_GTP2_CAUSE_REQUEST_ACCEPTED; + + if (!sgwc_ue) { + ogs_error("No Context in TEID"); + cause_value = OGS_GTP2_CAUSE_CONTEXT_NOT_FOUND; + } + + if (!sess || !sess->active) { + ogs_error("No Sess Context"); + cause_value = OGS_GTP2_CAUSE_CONTEXT_NOT_FOUND; + } + + if (cause_value != OGS_GTP2_CAUSE_REQUEST_ACCEPTED) { + ogs_gtp_send_error_message(s5c_xact, sess ? sess->pgw_s5c_teid : 0, + OGS_GTP2_UPDATE_BEARER_RESPONSE_TYPE, cause_value); + return; + } + /***************************************** * Check Mandatory/Conditional IE Missing *****************************************/ @@ -984,7 +1003,7 @@ void sgwc_s11_handle_update_bearer_response( * Check ALL Context ********************/ ogs_assert(sgwc_ue); - ogs_assert(sess); + ogs_assert(sess && sess->active); ogs_debug(" MME_S11_TEID[%d] SGW_S11_TEID[%d]", sgwc_ue->mme_s11_teid, sgwc_ue->sgw_s11_teid); @@ -1044,7 +1063,7 @@ void sgwc_s11_handle_delete_bearer_response( ogs_assert(bearer); sess = bearer->sess; - ogs_assert(sess); + ogs_assert(sess && sess->active); rv = ogs_gtp_xact_commit(s11_xact); ogs_expect(rv == OGS_OK); @@ -1209,7 +1228,6 @@ void sgwc_s11_handle_downlink_data_notification_ack( bearer = s11_xact->data; ogs_assert(bearer); sess = bearer->sess; - ogs_assert(sess); rv = ogs_gtp_xact_commit(s11_xact); ogs_expect(rv == OGS_OK); @@ -1217,6 +1235,10 @@ void sgwc_s11_handle_downlink_data_notification_ack( /************************ * Check SGWC-UE Context ************************/ + if (!sess || !sess->active) { + ogs_error("No Sess Context"); + } + if (ack->cause.presence) { ogs_gtp2_cause_t *cause = ack->cause.data; ogs_assert(cause); @@ -1508,7 +1530,7 @@ void sgwc_s11_handle_bearer_resource_command( ********************/ ogs_assert(bearer); sess = bearer->sess; - ogs_assert(sess); + ogs_assert(sess && sess->active); ogs_assert(sess->gnode); ogs_assert(sgwc_ue); diff --git a/src/sgwc/s5c-handler.c b/src/sgwc/s5c-handler.c index 5acb72d3f4..b2c680cf34 100644 --- a/src/sgwc/s5c-handler.c +++ b/src/sgwc/s5c-handler.c @@ -113,7 +113,7 @@ void sgwc_s5c_handle_create_session_response( ************************/ cause_value = OGS_GTP2_CAUSE_REQUEST_ACCEPTED; - if (!sess) { + if (!sess || !sess->active) { ogs_error("No Context in TEID [Cause:%d]", session_cause); cause_value = OGS_GTP2_CAUSE_CONTEXT_NOT_FOUND; } else { @@ -354,7 +354,7 @@ void sgwc_s5c_handle_modify_bearer_response( ************************/ cause_value = OGS_GTP2_CAUSE_REQUEST_ACCEPTED; - if (!sess) { + if (!sess || !sess->active) { ogs_error("No Context in TEID [Cause:%d]", session_cause); cause_value = OGS_GTP2_CAUSE_CONTEXT_NOT_FOUND; } else { @@ -496,7 +496,7 @@ void sgwc_s5c_handle_delete_session_response( ************************/ cause_value = OGS_GTP2_CAUSE_REQUEST_ACCEPTED; - if (!sess) { + if (!sess || !sess->active) { ogs_error("No Context in TEID [Cause:%d]", session_cause); cause_value = OGS_GTP2_CAUSE_CONTEXT_NOT_FOUND; } else { @@ -578,7 +578,7 @@ void sgwc_s5c_handle_create_bearer_request( ************************/ cause_value = OGS_GTP2_CAUSE_REQUEST_ACCEPTED; - if (!sess) { + if (!sess || !sess->active) { ogs_error("No Context in TEID"); cause_value = OGS_GTP2_CAUSE_CONTEXT_NOT_FOUND; } else { @@ -697,7 +697,7 @@ void sgwc_s5c_handle_update_bearer_request( ************************/ cause_value = OGS_GTP2_CAUSE_REQUEST_ACCEPTED; - if (!sess) { + if (!sess || !sess->active) { ogs_error("No Context in TEID"); cause_value = OGS_GTP2_CAUSE_CONTEXT_NOT_FOUND; } else { @@ -809,7 +809,7 @@ void sgwc_s5c_handle_delete_bearer_request( ************************/ cause_value = OGS_GTP2_CAUSE_REQUEST_ACCEPTED; - if (!sess) { + if (!sess || !sess->active) { ogs_error("No Context in TEID"); cause_value = OGS_GTP2_CAUSE_CONTEXT_NOT_FOUND; } else { @@ -969,7 +969,7 @@ void sgwc_s5c_handle_bearer_resource_failure_indication( * * - Session could be deleted before a message is received from SMF. ************************/ - if (!sess) { + if (!sess || !sess->active) { ogs_error("No Context in TEID"); cause_value = OGS_GTP2_CAUSE_CONTEXT_NOT_FOUND; } else { diff --git a/src/sgwc/sxa-handler.c b/src/sgwc/sxa-handler.c index dac8cde420..85ad571147 100644 --- a/src/sgwc/sxa-handler.c +++ b/src/sgwc/sxa-handler.c @@ -128,7 +128,7 @@ static void sgwc_sxa_handle_session_reestablishment( sgwc_sess_t *sess, ogs_pfcp_xact_t *pfcp_xact, ogs_pfcp_session_establishment_response_t *pfcp_rsp) { - ogs_assert(sess); + ogs_assert(sess && sess->active); ogs_assert(pfcp_xact); ogs_assert(pfcp_rsp); @@ -197,7 +197,7 @@ void sgwc_sxa_handle_session_establishment_response( cause_value = OGS_GTP2_CAUSE_REQUEST_ACCEPTED; - if (!sess) { + if (!sess || !sess->active) { ogs_error("No Context"); cause_value = OGS_GTP2_CAUSE_CONTEXT_NOT_FOUND; } @@ -277,7 +277,7 @@ void sgwc_sxa_handle_session_establishment_response( return; } - ogs_assert(sess); + ogs_assert(sess && sess->active); ogs_debug(" SGW_S5C_TEID[0x%x] PGW_S5C_TEID[0x%x]", sess->sgw_s5c_teid, sess->pgw_s5c_teid); @@ -502,13 +502,19 @@ void sgwc_sxa_handle_session_modification_response( cause_value = OGS_GTP2_CAUSE_REQUEST_ACCEPTED; if (flags & OGS_PFCP_MODIFY_SESSION) { - if (!sess) { - ogs_error("No Context"); - + if (!sess || !sess->active) { + // sess pointer was expired; can we recover it from xact? sess = pfcp_xact->data; - ogs_assert(sess); - cause_value = OGS_GTP2_CAUSE_CONTEXT_NOT_FOUND; + if (!sess || !sess->active) { + ogs_error("No Context"); + cause_value = OGS_GTP2_CAUSE_CONTEXT_NOT_FOUND; + // send gtp error? + ogs_pfcp_xact_commit(pfcp_xact); + return; + } else { + ogs_warn("sess expired but pfcp_xact->sess active"); + } } sgwc_ue = sess->sgwc_ue; @@ -518,15 +524,20 @@ void sgwc_sxa_handle_session_modification_response( bearer = pfcp_xact->data; ogs_assert(bearer); - if (!sess) { - ogs_error("No Context"); - + if (!sess || !sess->active) { + // sess pointer was expired; can we recover it from bearer? sess = bearer->sess; - ogs_assert(sess); - cause_value = OGS_GTP2_CAUSE_CONTEXT_NOT_FOUND; + if (!sess || !sess->active) { + ogs_error("No Context"); + cause_value = OGS_GTP2_CAUSE_CONTEXT_NOT_FOUND; + // send gtp error? + ogs_pfcp_xact_commit(pfcp_xact); + return; + } else { + ogs_warn("sess expired but bearer->sess active"); + } } - sgwc_ue = bearer->sgwc_ue; ogs_assert(sgwc_ue); } @@ -551,7 +562,7 @@ void sgwc_sxa_handle_session_modification_response( OGS_LIST(pdr_to_create_list); - ogs_assert(sess); + ogs_assert(sess && sess->active); ogs_list_copy(&pdr_to_create_list, &pfcp_xact->pdr_to_create_list); @@ -1306,7 +1317,7 @@ void sgwc_sxa_handle_session_deletion_response( cause_value = OGS_GTP2_CAUSE_REQUEST_ACCEPTED; - if (!sess) { + if (!sess || !sess->active) { ogs_error("No Context"); cause_value = OGS_GTP2_CAUSE_CONTEXT_NOT_FOUND; } @@ -1375,7 +1386,7 @@ void sgwc_sxa_handle_session_deletion_response( return; } - ogs_assert(sess); + ogs_assert(sess && sess->active); sgwc_ue = sess->sgwc_ue; ogs_assert(sgwc_ue); @@ -1451,7 +1462,7 @@ void sgwc_sxa_handle_session_report_request( * * - Session could be deleted before a message is received from SMF. ************************/ - if (!sess) { + if (!sess || !sess->active) { ogs_error("No Context"); cause_value = OGS_PFCP_CAUSE_SESSION_CONTEXT_NOT_FOUND; } @@ -1468,7 +1479,7 @@ void sgwc_sxa_handle_session_report_request( return; } - ogs_assert(sess); + ogs_assert(sess && sess->active); sgwc_ue = sess->sgwc_ue; ogs_assert(sgwc_ue); diff --git a/src/smf/context.c b/src/smf/context.c index 179c9ff883..735ba004b9 100644 --- a/src/smf/context.c +++ b/src/smf/context.c @@ -1257,6 +1257,7 @@ smf_sess_t *smf_sess_add_by_apn(smf_ue_t *smf_ue, char *apn, uint8_t rat_type) e.sess = sess; ogs_fsm_init(&sess->sm, smf_gsm_state_initial, smf_gsm_state_final, &e); + sess->active = true; sess->smf_ue = smf_ue; ogs_list_add(&smf_ue->sess_list, sess); @@ -1471,6 +1472,7 @@ smf_sess_t *smf_sess_add_by_psi(smf_ue_t *smf_ue, uint8_t psi) e.sess = sess; ogs_fsm_init(&sess->sm, smf_gsm_state_initial, smf_gsm_state_final, &e); + sess->active = true; sess->smf_ue = smf_ue; ogs_list_add(&smf_ue->sess_list, sess); @@ -1690,6 +1692,11 @@ void smf_sess_remove(smf_sess_t *sess) ogs_list_remove(&smf_ue->sess_list, sess); + if (!sess->active) { + ogs_error("smf_sess_remove double-free"); + } + sess->active = false; + memset(&e, 0, sizeof(e)); e.sess = sess; ogs_fsm_fini(&sess->sm, &e); diff --git a/src/smf/context.h b/src/smf/context.h index 243d814691..4d0db733d2 100644 --- a/src/smf/context.h +++ b/src/smf/context.h @@ -432,6 +432,8 @@ typedef struct smf_sess_s { ogs_timer_t *timer_gx_cca; ogs_timer_t *timer_gy_cca; + bool active; + smf_ue_t *smf_ue; bool n1_released; diff --git a/src/smf/gn-handler.c b/src/smf/gn-handler.c index 41f0b9d271..6eff1d81d3 100644 --- a/src/smf/gn-handler.c +++ b/src/smf/gn-handler.c @@ -370,7 +370,7 @@ void smf_gn_handle_update_pdp_context_request( cause_value = OGS_GTP1_CAUSE_MANDATORY_IE_MISSING; } - if (!sess) { + if (!sess || !sess->active) { ogs_warn("No Context"); cause_value = OGS_GTP1_CAUSE_NON_EXISTENT; } diff --git a/src/smf/gsm-sm.c b/src/smf/gsm-sm.c index 024d06a4e1..ecd45fc2ed 100644 --- a/src/smf/gsm-sm.c +++ b/src/smf/gsm-sm.c @@ -723,6 +723,11 @@ void smf_gsm_state_wait_pfcp_establishment(ogs_fsm_t *s, smf_event_t *e) ogs_error("PFCP timeout waiting for Session Establishment Response"); if (sess->timeout_xact->epc) { + if (!sess->active) { + ogs_error("pfcp timeout: sess is not active"); + return; + } + ogs_gtp_xact_t *gtp_xact = (ogs_gtp_xact_t *) sess->timeout_xact->assoc_xact; uint8_t gtp_cause = (gtp_xact->gtp_version == 1) ? OGS_GTP1_CAUSE_NETWORK_FAILURE : @@ -1281,6 +1286,11 @@ void smf_gsm_state_operational(ogs_fsm_t *s, smf_event_t *e) ogs_error("PFCP timeout waiting for Session Establishment Response"); if (sess->timeout_xact->epc) { + if (!sess->active) { + ogs_error("pfcp timeout: sess is not active"); + return; + } + ogs_gtp_xact_t *gtp_xact = (ogs_gtp_xact_t *) sess->timeout_xact->assoc_xact; uint8_t gtp_cause = (gtp_xact->gtp_version == 1) ? OGS_GTP1_CAUSE_NETWORK_FAILURE : @@ -1470,6 +1480,11 @@ void smf_gsm_state_wait_pfcp_deletion(ogs_fsm_t *s, smf_event_t *e) ogs_error("PFCP timeout waiting for Session Deletion Response"); if (sess->timeout_xact->epc) { + if (!sess->active) { + ogs_error("pfcp timeout: sess is not active"); + return; + } + ogs_gtp_xact_t *gtp_xact = (ogs_gtp_xact_t *) sess->timeout_xact->assoc_xact; uint8_t gtp_cause = (gtp_xact->gtp_version == 1) ? OGS_GTP1_CAUSE_NETWORK_FAILURE : diff --git a/src/smf/n4-handler.c b/src/smf/n4-handler.c index f688fa581f..2e8b513ca4 100644 --- a/src/smf/n4-handler.c +++ b/src/smf/n4-handler.c @@ -277,7 +277,7 @@ void smf_5gc_n4_handle_session_modification_response( status = OGS_SBI_HTTP_STATUS_OK; - if (!sess) { + if (!sess || !sess->active) { ogs_error("No Context"); status = OGS_SBI_HTTP_STATUS_NOT_FOUND; } @@ -880,7 +880,7 @@ void smf_epc_n4_handle_session_modification_response( ogs_pfcp_xact_commit(xact); - if (!sess) { + if (!sess || !sess->active) { ogs_error("No Context"); return; } @@ -1191,7 +1191,7 @@ void smf_n4_handle_session_report_request( cause_value = OGS_PFCP_CAUSE_REQUEST_ACCEPTED; - if (!sess) { + if (!sess || !sess->active) { ogs_error("No Context"); cause_value = OGS_PFCP_CAUSE_SESSION_CONTEXT_NOT_FOUND; } diff --git a/src/smf/pfcp-sm.c b/src/smf/pfcp-sm.c index 7a74a1da82..25a54cdca1 100644 --- a/src/smf/pfcp-sm.c +++ b/src/smf/pfcp-sm.c @@ -320,7 +320,7 @@ void smf_pfcp_state_associated(ogs_fsm_t *s, smf_event_t *e) case OGS_PFCP_SESSION_ESTABLISHMENT_RESPONSE_TYPE: if (!message->h.seid_presence) ogs_error("No SEID"); - if (!sess) { + if (!sess || !sess->active) { ogs_gtp_xact_t *gtp_xact = xact->assoc_xact; ogs_error("No Session"); if (!gtp_xact) { @@ -355,7 +355,7 @@ void smf_pfcp_state_associated(ogs_fsm_t *s, smf_event_t *e) case OGS_PFCP_SESSION_DELETION_RESPONSE_TYPE: if (!message->h.seid_presence) ogs_error("No SEID"); - if (!sess) { + if (!sess || !sess->active) { ogs_gtp_xact_t *gtp_xact = xact->assoc_xact; ogs_error("No Session"); if (!gtp_xact) { diff --git a/src/smf/s5c-handler.c b/src/smf/s5c-handler.c index 48ad87ab0c..4e55787e63 100644 --- a/src/smf/s5c-handler.c +++ b/src/smf/s5c-handler.c @@ -495,7 +495,7 @@ void smf_s5c_handle_modify_bearer_request( ************************/ cause_value = OGS_GTP2_CAUSE_REQUEST_ACCEPTED; - if (!sess) { + if (!sess || !sess->active) { ogs_error("No Context"); cause_value = OGS_GTP2_CAUSE_CONTEXT_NOT_FOUND; } @@ -674,6 +674,11 @@ void smf_s5c_handle_create_bearer_response( ************************/ cause_value = OGS_GTP2_CAUSE_REQUEST_ACCEPTED; + if (!sess || !sess->active) { + ogs_error("No Context in TEID"); + cause_value = OGS_GTP2_CAUSE_CONTEXT_NOT_FOUND; + } + if (cause_value != OGS_GTP2_CAUSE_REQUEST_ACCEPTED) { ogs_assert(OGS_OK == smf_epc_pfcp_send_one_bearer_modification_request( @@ -845,6 +850,20 @@ void smf_s5c_handle_update_bearer_response( rv = ogs_gtp_xact_commit(xact); ogs_expect(rv == OGS_OK); + /************************ + * Check Session Context + ************************/ + cause_value = OGS_GTP2_CAUSE_REQUEST_ACCEPTED; + + if (!sess || !sess->active) { + ogs_error("No Context in TEID"); + cause_value = OGS_GTP2_CAUSE_CONTEXT_NOT_FOUND; + } + + if (cause_value != OGS_GTP2_CAUSE_REQUEST_ACCEPTED) { + return; + } + /***************************************** * Check Mandatory/Conditional IE Missing *****************************************/ @@ -1158,7 +1177,7 @@ void smf_s5c_handle_bearer_resource_command( ************************/ cause_value = OGS_GTP2_CAUSE_REQUEST_ACCEPTED; - if (!sess) { + if (!sess || !sess->active) { ogs_error("No Context"); cause_value = OGS_GTP2_CAUSE_CONTEXT_NOT_FOUND; } else { diff --git a/src/smf/smf-sm.c b/src/smf/smf-sm.c index aa8e362157..2c800868c1 100644 --- a/src/smf/smf-sm.c +++ b/src/smf/smf-sm.c @@ -139,10 +139,10 @@ void smf_state_operational(ogs_fsm_t *s, smf_event_t *e) if (gtp2_message.h.teid == 0) { ogs_expect(!sess); sess = smf_sess_add_by_gtp2_message(>p2_message); - if (sess) + if (sess && sess->active) OGS_SETUP_GTP_NODE(sess, smf_gnode->gnode); } - if (!sess) { + if (!sess || !sess->active) { ogs_error("No Session"); ogs_gtp2_send_error_message(gtp_xact, 0, OGS_GTP2_CREATE_SESSION_RESPONSE_TYPE, @@ -156,7 +156,7 @@ void smf_state_operational(ogs_fsm_t *s, smf_event_t *e) if (!gtp2_message.h.teid_presence) ogs_error("No TEID"); smf_metrics_inst_global_inc(SMF_METR_GLOB_CTR_S5C_RX_DELETESESSIONREQ); smf_metrics_inst_gtp_node_inc(smf_gnode->metrics, SMF_METR_GTP_NODE_CTR_S5C_RX_DELETESESSIONREQ); - if (!sess) { + if (!sess || !sess->active) { ogs_error("No Session"); ogs_gtp2_send_error_message(gtp_xact, 0, OGS_GTP2_DELETE_SESSION_RESPONSE_TYPE, @@ -183,7 +183,7 @@ void smf_state_operational(ogs_fsm_t *s, smf_event_t *e) break; case OGS_GTP2_DELETE_BEARER_RESPONSE_TYPE: if (!gtp2_message.h.teid_presence) ogs_error("No TEID"); - if (!sess) { + if (!sess || !sess->active) { /* TODO: NACK the message */ ogs_error("TODO: NACK the message"); break; @@ -247,7 +247,7 @@ void smf_state_operational(ogs_fsm_t *s, smf_event_t *e) if (sess) OGS_SETUP_GTP_NODE(sess, smf_gnode->gnode); } - if (!sess) { + if (!sess || !sess->active) { ogs_gtp1_send_error_message(gtp_xact, 0, OGS_GTP1_CREATE_PDP_CONTEXT_RESPONSE_TYPE, OGS_GTP1_CAUSE_CONTEXT_NOT_FOUND); @@ -259,7 +259,7 @@ void smf_state_operational(ogs_fsm_t *s, smf_event_t *e) case OGS_GTP1_DELETE_PDP_CONTEXT_REQUEST_TYPE: smf_metrics_inst_global_inc(SMF_METR_GLOB_CTR_GN_RX_DELETEPDPCTXREQ); smf_metrics_inst_gtp_node_inc(smf_gnode->metrics, SMF_METR_GTP_NODE_CTR_GN_RX_DELETEPDPCTXREQ); - if (!sess) { + if (!sess || !sess->active) { ogs_gtp1_send_error_message(gtp_xact, 0, OGS_GTP1_DELETE_PDP_CONTEXT_RESPONSE_TYPE, OGS_GTP1_CAUSE_NON_EXISTENT); @@ -289,7 +289,10 @@ void smf_state_operational(ogs_fsm_t *s, smf_event_t *e) ogs_assert(gx_message); sess = e->sess; - ogs_assert(sess); + if (!sess || !sess->active) { + ogs_error("Gx Message: No session context"); + break; + } switch(gx_message->cmd_code) { case OGS_DIAM_GX_CMD_CODE_CREDIT_CONTROL: @@ -324,7 +327,10 @@ void smf_state_operational(ogs_fsm_t *s, smf_event_t *e) ogs_assert(gy_message); sess = e->sess; - ogs_assert(sess); + if (!sess || !sess->active) { + ogs_error("Gy Message: No session context"); + break; + } switch(gy_message->cmd_code) { case OGS_DIAM_GY_CMD_CODE_CREDIT_CONTROL: @@ -360,10 +366,14 @@ void smf_state_operational(ogs_fsm_t *s, smf_event_t *e) case SMF_EVT_DIAMETER_TIMER: ogs_assert(e); sess = e->sess; - if (sess) { - ogs_assert(OGS_FSM_STATE(&sess->sm)); - ogs_fsm_dispatch(&sess->sm, e); + + if (!sess || !sess->active) { + ogs_error("Diameter Timer: No session context"); + break; } + + ogs_assert(OGS_FSM_STATE(&sess->sm)); + ogs_fsm_dispatch(&sess->sm, e); break; case SMF_EVT_S6B_MESSAGE: @@ -373,6 +383,11 @@ void smf_state_operational(ogs_fsm_t *s, smf_event_t *e) sess = e->sess; ogs_assert(sess); + if (!sess || !sess->active) { + ogs_error("S6b: No session context"); + break; + } + switch(s6b_message->cmd_code) { case OGS_DIAM_S6B_CMD_SESSION_TERMINATION: ogs_fsm_dispatch(&sess->sm, e); @@ -527,7 +542,7 @@ void smf_state_operational(ogs_fsm_t *s, smf_event_t *e) sess = smf_sess_find_by_sm_context_ref( sbi_message.h.resource.component[1]); - if (!sess) { + if (!sess || !sess->active) { ogs_warn("Not found [%s]", sbi_message.h.uri); smf_sbi_send_sm_context_update_error_log( stream, OGS_SBI_HTTP_STATUS_NOT_FOUND, @@ -537,7 +552,7 @@ void smf_state_operational(ogs_fsm_t *s, smf_event_t *e) DEFAULT sess = smf_sess_add_by_sbi_message(&sbi_message); - if (!sess) { + if (!sess || !sess->active) { ogs_error("smf_sess_add_by_sbi_message() failed"); smf_sbi_send_sm_context_create_error(stream, OGS_SBI_HTTP_STATUS_BAD_REQUEST, @@ -604,7 +619,7 @@ void smf_state_operational(ogs_fsm_t *s, smf_event_t *e) sess = smf_sess_find_by_sm_context_ref( sbi_message.h.resource.component[1]); - if (!sess) { + if (!sess || !sess->active) { ogs_warn("Not found [%s]", sbi_message.h.uri); ogs_assert(true == ogs_sbi_server_send_error(stream, @@ -804,7 +819,7 @@ void smf_state_operational(ogs_fsm_t *s, smf_event_t *e) ogs_sbi_xact_remove(sbi_xact); sess = smf_sess_cycle(sess); - if (!sess) { + if (!sess || !sess->active) { ogs_error("Session has already been removed"); break; } @@ -843,7 +858,7 @@ void smf_state_operational(ogs_fsm_t *s, smf_event_t *e) ogs_sbi_xact_remove(sbi_xact); sess = smf_sess_cycle(sess); - if (!sess) { + if (!sess || !sess->active) { ogs_error("Session has already been removed"); break; } @@ -1028,7 +1043,7 @@ void smf_state_operational(ogs_fsm_t *s, smf_event_t *e) ogs_assert(sess); sess = smf_sess_cycle(sess); - if (!sess) { + if (!sess || !sess->active) { ogs_error("Session has already been removed"); ogs_pkbuf_free(pkbuf); break; @@ -1051,7 +1066,7 @@ void smf_state_operational(ogs_fsm_t *s, smf_event_t *e) ogs_assert(sess); sess = smf_sess_cycle(sess); - if (!sess) { + if (!sess || !sess->active) { ogs_error("Session has already been removed"); ogs_pkbuf_free(pkbuf); break;