[AMX] Fixed a crash due to deregistration (#2021)

Fixed an issue where AMF would crash
if an implicit deregistration occurred twice.
This commit is contained in:
Sukchan Lee 2023-01-29 09:09:52 +09:00
parent f50591a8f7
commit 610b998038
3 changed files with 68 additions and 18 deletions

View File

@ -378,18 +378,18 @@ void amf_state_operational(ogs_fsm_t *s, amf_event_t *e)
ogs_sbi_xact_remove(sbi_xact);
amf_ue = amf_ue_cycle(amf_ue);
if (amf_ue) {
ogs_assert(OGS_FSM_STATE(&amf_ue->sm));
e->amf_ue = amf_ue;
e->h.sbi.message = &sbi_message;;
e->h.sbi.state = state;
ogs_fsm_dispatch(&amf_ue->sm, e);
} else {
if (!amf_ue) {
ogs_error("UE(amf_ue) Context has already been removed");
break;
}
ogs_assert(OGS_FSM_STATE(&amf_ue->sm));
e->amf_ue = amf_ue;
e->h.sbi.message = &sbi_message;;
e->h.sbi.state = state;
ogs_fsm_dispatch(&amf_ue->sm, e);
break;
CASE(OGS_SBI_SERVICE_NAME_NSMF_PDUSESSION)
@ -807,7 +807,7 @@ void amf_state_operational(ogs_fsm_t *s, amf_event_t *e)
if (ogs_nas_5gmm_decode(&nas_message, pkbuf) != OGS_OK) {
ogs_error("ogs_nas_5gmm_decode() failed");
ogs_pkbuf_free(pkbuf);
return;
break;
}
amf_ue = ran_ue->amf_ue;
@ -824,7 +824,7 @@ void amf_state_operational(ogs_fsm_t *s, amf_event_t *e)
ogs_expect(r == OGS_OK);
ogs_assert(r != OGS_ERROR);
ogs_pkbuf_free(pkbuf);
return;
break;
}
} else {
/* Here, if the AMF_UE Context is found,
@ -844,7 +844,7 @@ void amf_state_operational(ogs_fsm_t *s, amf_event_t *e)
ogs_error("[%s] nas_security_decode() failed",
amf_ue->suci);
ogs_pkbuf_free(pkbuf);
return;
break;
}
}
}
@ -909,9 +909,14 @@ void amf_state_operational(ogs_fsm_t *s, amf_event_t *e)
ogs_pkbuf_free(pkbuf);
break;
case AMF_EVENT_5GMM_TIMER:
amf_ue = e->amf_ue;
ogs_assert(amf_ue);
amf_ue = amf_ue_cycle(e->amf_ue);
if (!amf_ue) {
ogs_error("UE(amf_ue) Context has already been removed");
break;
}
ogs_assert(OGS_FSM_STATE(&amf_ue->sm));
ogs_fsm_dispatch(&amf_ue->sm, e);

View File

@ -42,6 +42,7 @@ void gmm_state_authentication(ogs_fsm_t *s, amf_event_t *e);
void gmm_state_security_mode(ogs_fsm_t *s, amf_event_t *e);
void gmm_state_initial_context_setup(ogs_fsm_t *s, amf_event_t *e);
void gmm_state_registered(ogs_fsm_t *s, amf_event_t *e);
void gmm_state_ue_context_will_remove(ogs_fsm_t *s, amf_event_t *e);
void gmm_state_exception(ogs_fsm_t *s, amf_event_t *e);
#define amf_sm_debug(__pe) \

View File

@ -60,8 +60,11 @@ void gmm_state_de_registered(ogs_fsm_t *s, amf_event_t *e)
int r, state = 0;
ogs_assert(s);
ogs_assert(e);
amf_sm_debug(e);
if (e->sess) {
sess = e->sess;
amf_ue = sess->amf_ue;
@ -289,13 +292,17 @@ void gmm_state_de_registered(ogs_fsm_t *s, amf_event_t *e)
break;
CASE(OGS_SBI_HTTP_METHOD_DELETE)
if (state != AMF_NETWORK_INITIATED_DE_REGISTERED) {
if (state == AMF_NETWORK_INITIATED_DE_REGISTERED) {
ogs_warn("[%s] AMF-UE Context Removed", amf_ue->supi);
OGS_FSM_TRAN(&amf_ue->sm,
&gmm_state_ue_context_will_remove);
} else {
r = nas_5gs_send_de_registration_accept(amf_ue);
ogs_expect(r == OGS_OK);
ogs_assert(r != OGS_ERROR);
}
PCF_AM_POLICY_CLEAR(amf_ue);
PCF_AM_POLICY_CLEAR(amf_ue);
}
break;
DEFAULT
@ -331,8 +338,11 @@ void gmm_state_registered(ogs_fsm_t *s, amf_event_t *e)
ogs_sbi_message_t *sbi_message = NULL;
ogs_assert(s);
ogs_assert(e);
amf_sm_debug(e);
if (e->sess) {
sess = e->sess;
amf_ue = sess->amf_ue;
@ -1578,6 +1588,38 @@ void gmm_state_initial_context_setup(ogs_fsm_t *s, amf_event_t *e)
}
}
void gmm_state_ue_context_will_remove(ogs_fsm_t *s, amf_event_t *e)
{
amf_ue_t *amf_ue = NULL;
amf_sess_t *sess = NULL;
ogs_assert(s);
ogs_assert(e);
amf_sm_debug(e);
if (e->sess) {
sess = e->sess;
amf_ue = sess->amf_ue;
ogs_assert(amf_ue);
} else {
amf_ue = e->amf_ue;
ogs_assert(amf_ue);
}
switch (e->h.id) {
case OGS_FSM_ENTRY_SIG:
amf_ue_remove(amf_ue);
break;
case OGS_FSM_EXIT_SIG:
break;
default:
ogs_error("Unknown event[%s]", amf_event_get_name(e));
}
}
void gmm_state_exception(ogs_fsm_t *s, amf_event_t *e)
{
int xact_count = 0, r;
@ -1589,7 +1631,9 @@ void gmm_state_exception(ogs_fsm_t *s, amf_event_t *e)
ogs_nas_5gs_message_t *nas_message = NULL;
ogs_nas_security_header_type_t h;
ogs_assert(s);
ogs_assert(e);
amf_sm_debug(e);
if (e->sess) {