fix: Add the exception handling (#804)

When UE/gNB repeatedly sends NGAP message repeatedly, AMF crashed.
Exception routines have been added to resolve this issue.
This commit is contained in:
Sukchan Lee 2021-02-15 12:17:33 -05:00
parent 9b5cc4a568
commit b6bcbac3e3
20 changed files with 159 additions and 41 deletions

View File

@ -86,7 +86,7 @@ static void recalculate_pool_size(void)
self.pool.pfcp_node = self.pool.nf;
#define MAX_NUM_OF_NF_SERVICE 16 /* Num of NF Service per NF Instance */
#define MAX_NUM_OF_SBI_MESSAGE 8 /* Num of HTTP(s) Request/Response per NF */
#define MAX_NUM_OF_SBI_MESSAGE 4 /* Num of HTTP(s) Request/Response per NF */
#define MAX_NUM_OF_NF_SUBSCRIPTION 4 /* Num of Subscription per NF */
self.pool.nf_service = self.pool.nf * MAX_NUM_OF_NF_SERVICE;
self.pool.sbi_message = self.pool.nf * MAX_NUM_OF_SBI_MESSAGE;

View File

@ -1022,7 +1022,7 @@ ogs_sbi_xact_t *ogs_sbi_xact_add(
ogs_assert(sbi_object);
ogs_pool_alloc(&xact_pool, &xact);
ogs_assert(xact);
if (!xact) return NULL;
memset(xact, 0, sizeof(ogs_sbi_xact_t));
xact->target_nf_type = target_nf_type;

View File

@ -164,8 +164,7 @@ ogs_sbi_request_t *ogs_sbi_request_new(void)
ogs_sbi_request_t *request = NULL;
ogs_pool_alloc(&request_pool, &request);
ogs_assert(request);
if (!request) return NULL;
memset(request, 0, sizeof(ogs_sbi_request_t));
request->http.params = ogs_hash_make();
@ -221,7 +220,7 @@ ogs_sbi_request_t *ogs_sbi_build_request(ogs_sbi_message_t *message)
ogs_assert(message);
request = ogs_sbi_request_new();
ogs_assert(request);
if (!request) return NULL;
ogs_assert(message->h.method);
request->h.method = ogs_strdup(message->h.method);

View File

@ -267,7 +267,6 @@ ogs_sbi_request_t *ogs_nnrf_nfm_build_register(
message.NFProfile = NFProfile;
request = ogs_sbi_build_request(&message);
ogs_assert(request);
ogs_sbi_nnrf_free_nf_profile(NFProfile);
@ -306,7 +305,6 @@ ogs_sbi_request_t *ogs_nnrf_nfm_build_update(ogs_sbi_nf_instance_t *nf_instance)
message.PatchItemList = PatchItemList;
request = ogs_sbi_build_request(&message);
ogs_assert(request);
OpenAPI_list_free(PatchItemList);
@ -330,7 +328,6 @@ ogs_sbi_request_t *ogs_nnrf_nfm_build_de_register(
message.h.resource.component[1] = nf_instance->id;
request = ogs_sbi_build_request(&message);
ogs_assert(request);
return request;
}
@ -383,7 +380,6 @@ ogs_sbi_request_t *ogs_nnrf_nfm_build_status_subscribe(
message.SubscriptionData = SubscriptionData;
request = ogs_sbi_build_request(&message);
ogs_assert(request);
ogs_free(SubscriptionData->nf_status_notification_uri);
ogs_free(SubscriptionData);
@ -408,7 +404,6 @@ ogs_sbi_request_t *ogs_nnrf_nfm_build_status_unsubscribe(
message.h.resource.component[1] = subscription->id;
request = ogs_sbi_build_request(&message);
ogs_assert(request);
return request;
}
@ -433,7 +428,6 @@ ogs_sbi_request_t *ogs_nnrf_disc_build_discover(
message.param.requester_nf_type = requester_nf_type;
request = ogs_sbi_build_request(&message);
ogs_assert(request);
return request;
}

View File

@ -148,7 +148,10 @@ void ogs_nnrf_nfm_send_nf_register(ogs_sbi_nf_instance_t *nf_instance)
ogs_assert(client);
request = ogs_nnrf_nfm_build_register(nf_instance);
ogs_assert(request);
if (!request) {
ogs_error("ogs_nnrf_nfm_send_nf_register() failed");
return;
}
ogs_sbi_client_send_request(client, client->cb, request, nf_instance);
}
@ -162,7 +165,10 @@ void ogs_nnrf_nfm_send_nf_update(ogs_sbi_nf_instance_t *nf_instance)
ogs_assert(client);
request = ogs_nnrf_nfm_build_update(nf_instance);
ogs_assert(request);
if (!request) {
ogs_error("ogs_nnrf_nfm_send_nf_update() failed");
return;
}
ogs_sbi_client_send_request(client, client->cb, request, nf_instance);
}
@ -176,7 +182,10 @@ void ogs_nnrf_nfm_send_nf_de_register(ogs_sbi_nf_instance_t *nf_instance)
ogs_assert(client);
request = ogs_nnrf_nfm_build_de_register(nf_instance);
ogs_assert(request);
if (!request) {
ogs_error("ogs_nnrf_nfm_send_nf_de_register() failed");
return;
}
ogs_sbi_client_send_request(client, client->cb, request, nf_instance);
}
@ -199,7 +208,11 @@ void ogs_nnrf_nfm_send_nf_status_subscribe(ogs_sbi_client_t *client,
subscription->subscr_cond.nf_type = subscr_cond_nf_type;
request = ogs_nnrf_nfm_build_status_subscribe(subscription);
ogs_assert(request);
if (!request) {
ogs_error("ogs_nnrf_nfm_send_nf_status_subscribe() failed");
ogs_sbi_subscription_remove(subscription);
return;
}
ogs_sbi_client_send_request(client, client->cb, request, subscription);
}
@ -214,7 +227,10 @@ void ogs_nnrf_nfm_send_nf_status_unsubscribe(
ogs_assert(client);
request = ogs_nnrf_nfm_build_status_unsubscribe(subscription);
ogs_assert(request);
if (!request) {
ogs_error("ogs_nnrf_nfm_send_nf_status_unsubscribe() failed");
return;
}
ogs_sbi_client_send_request(client, client->cb, request, subscription);
}

View File

@ -38,7 +38,7 @@ amf_event_t *amf_event_new(amf_event_e id)
amf_event_t *e = NULL;
ogs_pool_alloc(&pool, &e);
ogs_assert(e);
if (!e) return NULL;
memset(e, 0, sizeof(*e));
e->id = id;

View File

@ -203,14 +203,18 @@ int ngap_send_to_nas(ran_ue_t *ran_ue,
OGS_NAS_EXTENDED_PROTOCOL_DISCRIMINATOR_5GMM) {
int rv;
e = amf_event_new(AMF_EVT_5GMM_MESSAGE);
ogs_assert(e);
if (!e) {
ogs_error("ngap_send_to_nas() failed");
ogs_pkbuf_free(nasbuf);
return OGS_ERROR;
}
e->ran_ue = ran_ue;
e->ngap.code = procedureCode;
e->nas.type = security_header_type.type;
e->pkbuf = nasbuf;
rv = ogs_queue_push(ogs_app()->queue, e);
if (rv != OGS_OK) {
ogs_warn("ogs_queue_push() failed:%d", (int)rv);
ogs_warn("ngap_send_to_nas() failed:%d", (int)rv);
ogs_pkbuf_free(e->pkbuf);
amf_event_free(e);
}
@ -220,12 +224,14 @@ int ngap_send_to_nas(ran_ue_t *ran_ue,
amf_ue_t *amf_ue = ran_ue->amf_ue;
if (!amf_ue) {
ogs_error("No UE Context");
ogs_pkbuf_free(nasbuf);
return OGS_ERROR;
}
return ngap_send_to_5gsm(amf_ue, nasbuf);
} else {
ogs_error("Unknown NAS Protocol discriminator 0x%02x",
h->extended_protocol_discriminator);
ogs_pkbuf_free(nasbuf);
return OGS_ERROR;
}
}

View File

@ -132,13 +132,19 @@ void amf_ue_sbi_discover_and_send(
xact = ogs_sbi_xact_add(target_nf_type, &amf_ue->sbi,
(ogs_sbi_build_f)build, amf_ue, data,
amf_timer_sbi_client_wait_expire);
ogs_assert(xact);
if (!xact) {
ogs_error("amf_ue_sbi_discover_and_send() failed");
nas_5gs_send_gmm_reject_from_sbi(
amf_ue, OGS_SBI_HTTP_STATUS_GATEWAY_TIMEOUT);
return;
}
if (ogs_sbi_discover_and_send(xact,
(ogs_fsm_handler_t)amf_nf_state_registered, client_cb) != true) {
ogs_error("amf_ue_sbi_discover_and_send() failed");
nas_5gs_send_gmm_reject_from_sbi(
amf_ue, OGS_SBI_HTTP_STATUS_GATEWAY_TIMEOUT);
return;
}
}
@ -155,15 +161,21 @@ void amf_sess_sbi_discover_and_send(OpenAPI_nf_type_e target_nf_type,
xact = ogs_sbi_xact_add(target_nf_type, &sess->sbi,
(ogs_sbi_build_f)build, sess, data,
amf_timer_sbi_client_wait_expire);
ogs_assert(xact);
if (!xact) {
ogs_error("amf_sess_sbi_discover_and_send() failed");
nas_5gs_send_back_5gsm_message_from_sbi(
sess, OGS_SBI_HTTP_STATUS_GATEWAY_TIMEOUT);
return;
}
xact->state = state;
if (ogs_sbi_discover_and_send(xact,
(ogs_fsm_handler_t)amf_nf_state_registered, client_cb) != true) {
ogs_error("amf_sess_sbi_discover_and_send() failed");
nas_5gs_send_back_5gsm_message_from_sbi(
sess, OGS_SBI_HTTP_STATUS_GATEWAY_TIMEOUT);
return;
}
}

View File

@ -137,7 +137,14 @@ static void sbi_timer_send_event(int timer_id, void *data)
break;
case AMF_TIMER_SBI_CLIENT_WAIT:
e = amf_event_new(AMF_EVT_SBI_TIMER);
ogs_assert(e);
if (!e) {
ogs_sbi_xact_t *sbi_xact = data;
ogs_assert(sbi_xact);
ogs_error("sbi_timer_send_event() failed");
ogs_sbi_xact_remove(sbi_xact);
return;
}
e->timer_id = timer_id;
e->sbi.data = data;
break;
@ -193,6 +200,7 @@ static void gmm_timer_event_send(
ogs_assert(amf_ue);
e = amf_event_new(AMF_EVT_5GMM_TIMER);
ogs_assert(e);
e->timer_id = timer_id;
e->amf_ue = amf_ue;
@ -238,6 +246,7 @@ void amf_timer_ng_holding_timer_expire(void *data)
ran_ue = data;
e = amf_event_new(AMF_EVT_NGAP_TIMER);
ogs_assert(e);
e->timer_id = AMF_TIMER_NG_HOLDING;
e->ran_ue = ran_ue;

View File

@ -131,15 +131,22 @@ void ausf_sbi_discover_and_send(OpenAPI_nf_type_e target_nf_type,
xact = ogs_sbi_xact_add(target_nf_type, &ausf_ue->sbi,
(ogs_sbi_build_f)build, ausf_ue, data,
ausf_timer_sbi_client_wait_expire);
ogs_assert(xact);
if (!xact) {
ogs_error("ausf_sbi_discover_and_send() failed");
ogs_sbi_server_send_error(stream,
OGS_SBI_HTTP_STATUS_GATEWAY_TIMEOUT, NULL,
"Cannot discover", ausf_ue->suci);
return;
}
xact->assoc_stream = stream;
if (ogs_sbi_discover_and_send(xact,
(ogs_fsm_handler_t)ausf_nf_state_registered, client_cb) != true) {
ogs_error("ausf_sbi_discover_and_send() failed");
ogs_sbi_server_send_error(stream,
OGS_SBI_HTTP_STATUS_GATEWAY_TIMEOUT, NULL,
"Cannot discover", ausf_ue->suci);
return;
}
}

View File

@ -53,12 +53,24 @@ static void sbi_timer_send_event(int timer_id, void *data)
case AUSF_TIMER_NF_INSTANCE_NO_HEARTBEAT:
case AUSF_TIMER_NF_INSTANCE_VALIDITY:
case AUSF_TIMER_SUBSCRIPTION_VALIDITY:
case AUSF_TIMER_SBI_CLIENT_WAIT:
e = ausf_event_new(AUSF_EVT_SBI_TIMER);
ogs_assert(e);
e->timer_id = timer_id;
e->sbi.data = data;
break;
case AUSF_TIMER_SBI_CLIENT_WAIT:
e = ausf_event_new(AUSF_EVT_SBI_TIMER);
if (!e) {
ogs_sbi_xact_t *sbi_xact = data;
ogs_assert(sbi_xact);
ogs_error("sbi_timer_send_event() failed");
ogs_sbi_xact_remove(sbi_xact);
return;
}
e->timer_id = timer_id;
e->sbi.data = data;
break;
default:
ogs_fatal("Unknown timer id[%d]", timer_id);
ogs_assert_if_reached();

View File

@ -207,14 +207,18 @@ int s1ap_send_to_nas(enb_ue_t *enb_ue,
if (h->protocol_discriminator == OGS_NAS_PROTOCOL_DISCRIMINATOR_EMM) {
int rv;
e = mme_event_new(MME_EVT_EMM_MESSAGE);
ogs_assert(e);
if (!e) {
ogs_error("s1ap_send_to_nas() failed");
ogs_pkbuf_free(nasbuf);
return OGS_ERROR;
}
e->enb_ue = enb_ue;
e->s1ap_code = procedureCode;
e->nas_type = security_header_type.type;
e->pkbuf = nasbuf;
rv = ogs_queue_push(ogs_app()->queue, e);
if (rv != OGS_OK) {
ogs_warn("ogs_queue_push() failed:%d", (int)rv);
ogs_warn("s1ap_send_to_nas() failed:%d", (int)rv);
ogs_pkbuf_free(e->pkbuf);
mme_event_free(e);
}
@ -224,12 +228,14 @@ int s1ap_send_to_nas(enb_ue_t *enb_ue,
mme_ue_t *mme_ue = enb_ue->mme_ue;
if (!mme_ue) {
ogs_error("No UE Context");
ogs_pkbuf_free(nasbuf);
return OGS_ERROR;
}
return s1ap_send_to_esm(mme_ue, nasbuf, security_header_type.type);
} else {
ogs_error("Unknown/Unimplemented NAS Protocol discriminator 0x%02x",
h->protocol_discriminator);
ogs_pkbuf_free(nasbuf);
return OGS_ERROR;
}
}

View File

@ -137,7 +137,7 @@ static bool pcf_sbi_discover_and_send(OpenAPI_nf_type_e target_nf_type,
xact = ogs_sbi_xact_add(target_nf_type, sbi_object,
build, context, data,
pcf_timer_sbi_client_wait_expire);
ogs_assert(xact);
if (!xact) return false;
xact->assoc_stream = stream;
@ -151,9 +151,11 @@ void pcf_ue_sbi_discover_and_send(OpenAPI_nf_type_e target_nf_type,
{
if (pcf_sbi_discover_and_send(target_nf_type, &pcf_ue->sbi, stream,
(ogs_sbi_build_f)build, pcf_ue, data) != true) {
ogs_error("pcf_ue_sbi_discover_and_send() failed");
ogs_sbi_server_send_error(stream,
OGS_SBI_HTTP_STATUS_GATEWAY_TIMEOUT, NULL,
"Cannot discover", pcf_ue->supi);
return;
}
}
@ -163,8 +165,10 @@ void pcf_sess_sbi_discover_and_send(OpenAPI_nf_type_e target_nf_type,
{
if (pcf_sbi_discover_and_send(target_nf_type, &sess->sbi, stream,
(ogs_sbi_build_f)build, sess, data) != true) {
ogs_error("pcf_sess_sbi_discover_and_send() failed");
ogs_sbi_server_send_error(stream,
OGS_SBI_HTTP_STATUS_GATEWAY_TIMEOUT, NULL,
"Cannot discover", NULL);
return;
}
}

View File

@ -53,12 +53,24 @@ static void sbi_timer_send_event(int timer_id, void *data)
case PCF_TIMER_NF_INSTANCE_NO_HEARTBEAT:
case PCF_TIMER_NF_INSTANCE_VALIDITY:
case PCF_TIMER_SUBSCRIPTION_VALIDITY:
case PCF_TIMER_SBI_CLIENT_WAIT:
e = pcf_event_new(PCF_EVT_SBI_TIMER);
ogs_assert(e);
e->timer_id = timer_id;
e->sbi.data = data;
break;
case PCF_TIMER_SBI_CLIENT_WAIT:
e = pcf_event_new(PCF_EVT_SBI_TIMER);
if (!e) {
ogs_sbi_xact_t *sbi_xact = data;
ogs_assert(sbi_xact);
ogs_error("sbi_timer_send_event() failed");
ogs_sbi_xact_remove(sbi_xact);
return;
}
e->timer_id = timer_id;
e->sbi.data = data;
break;
default:
ogs_fatal("Unknown timer id[%d]", timer_id);
ogs_assert_if_reached();

View File

@ -138,16 +138,23 @@ void smf_sbi_discover_and_send(OpenAPI_nf_type_e target_nf_type,
xact = ogs_sbi_xact_add(target_nf_type, &sess->sbi,
(ogs_sbi_build_f)build, sess, data,
smf_timer_sbi_client_wait_expire);
ogs_assert(xact);
if (!xact) {
ogs_error("smf_sbi_discover_and_send() failed");
ogs_sbi_server_send_error(stream,
OGS_SBI_HTTP_STATUS_GATEWAY_TIMEOUT, NULL,
"Cannot discover", smf_ue->supi);
return;
}
xact->assoc_stream = stream;
if (ogs_sbi_discover_and_send(xact,
(ogs_fsm_handler_t)smf_nf_state_registered, client_cb) != true) {
ogs_error("smf_sbi_discover_and_send() failed");
ogs_sbi_server_send_error(stream,
OGS_SBI_HTTP_STATUS_GATEWAY_TIMEOUT, NULL,
"Cannot discover", smf_ue->supi);
return;
}
}
@ -168,7 +175,10 @@ void smf_namf_comm_send_n1_n2_message_transfer(
xact = ogs_sbi_xact_add(OpenAPI_nf_type_AMF, &sess->sbi,
(ogs_sbi_build_f)smf_namf_comm_build_n1_n2_message_transfer,
sess, param, smf_timer_sbi_client_wait_expire);
ogs_assert(xact);
if (!xact) {
ogs_error("smf_namf_comm_send_n1_n2_message_transfer() failed");
return;
}
xact->state = param->state;

View File

@ -68,13 +68,25 @@ static void timer_send_event(int timer_id, void *data)
case SMF_TIMER_NF_INSTANCE_NO_HEARTBEAT:
case SMF_TIMER_NF_INSTANCE_VALIDITY:
case SMF_TIMER_SUBSCRIPTION_VALIDITY:
case SMF_TIMER_SBI_CLIENT_WAIT:
case SMF_TIMER_RELEASE_HOLDING:
e = smf_event_new(SMF_EVT_SBI_TIMER);
ogs_assert(e);
e->timer_id = timer_id;
e->sbi.data = data;
break;
case SMF_TIMER_SBI_CLIENT_WAIT:
e = smf_event_new(SMF_EVT_SBI_TIMER);
if (!e) {
ogs_sbi_xact_t *sbi_xact = data;
ogs_assert(sbi_xact);
ogs_error("timer_send_event() failed");
ogs_sbi_xact_remove(sbi_xact);
return;
}
e->timer_id = timer_id;
e->sbi.data = data;
break;
default:
ogs_fatal("Unknown timer id[%d]", timer_id);
ogs_assert_if_reached();

View File

@ -141,15 +141,22 @@ void udm_sbi_discover_and_send(OpenAPI_nf_type_e target_nf_type,
xact = ogs_sbi_xact_add(target_nf_type, &udm_ue->sbi,
(ogs_sbi_build_f)build, udm_ue, data,
udm_timer_sbi_client_wait_expire);
ogs_assert(xact);
if (!xact) {
ogs_error("udm_sbi_discover_and_send() failed");
ogs_sbi_server_send_error(stream,
OGS_SBI_HTTP_STATUS_GATEWAY_TIMEOUT, NULL,
"Cannot discover", udm_ue->suci);
return;
}
xact->assoc_stream = stream;
if (ogs_sbi_discover_and_send(xact,
(ogs_fsm_handler_t)udm_nf_state_registered, client_cb) != true) {
ogs_error("udm_sbi_discover_and_send() failed");
ogs_sbi_server_send_error(stream,
OGS_SBI_HTTP_STATUS_GATEWAY_TIMEOUT, NULL,
"Cannot discover", udm_ue->suci);
return;
}
}

View File

@ -53,12 +53,24 @@ static void sbi_timer_send_event(int timer_id, void *data)
case UDM_TIMER_NF_INSTANCE_NO_HEARTBEAT:
case UDM_TIMER_NF_INSTANCE_VALIDITY:
case UDM_TIMER_SUBSCRIPTION_VALIDITY:
case UDM_TIMER_SBI_CLIENT_WAIT:
e = udm_event_new(UDM_EVT_SBI_TIMER);
ogs_assert(e);
e->timer_id = timer_id;
e->sbi.data = data;
break;
case UDM_TIMER_SBI_CLIENT_WAIT:
e = udm_event_new(UDM_EVT_SBI_TIMER);
if (!e) {
ogs_sbi_xact_t *sbi_xact = data;
ogs_assert(sbi_xact);
ogs_error("sbi_timer_send_event() failed");
ogs_sbi_xact_remove(sbi_xact);
return;
}
e->timer_id = timer_id;
e->sbi.data = data;
break;
default:
ogs_fatal("Unknown timer id[%d]", timer_id);
ogs_assert_if_reached();

View File

@ -62,8 +62,8 @@ Vagrant.configure("2") do |config|
# information on available options.
config.vm.provider "virtualbox" do |vb|
# Customize the amount of memory on the VM:
vb.memory = "1024"
vb.cpus = "1"
vb.memory = "3072"
vb.cpus = "2"
end
# Enable provisioning with a shell script. Additional provisioners such as

View File

@ -62,7 +62,7 @@ Vagrant.configure("2") do |config|
config.vm.provider "virtualbox" do |vb|
# Customize the amount of memory on the VM:
vb.memory = "3072"
vb.cpus = "1"
vb.cpus = "2"
end
# Enable provisioning with a shell script. Additional provisioners such as