2021-05-29 06:56:12 +00:00
|
|
|
/*
|
2022-08-12 05:03:53 +00:00
|
|
|
* Copyright (C) 2019-2022 by Sukchan Lee <acetcom@gmail.com>
|
2021-05-29 06:56:12 +00:00
|
|
|
*
|
|
|
|
* This file is part of Open5GS.
|
|
|
|
*
|
|
|
|
* This program is free software: you can redistribute it and/or modify
|
|
|
|
* it under the terms of the GNU Affero General Public License as published by
|
|
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
|
|
* (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "sbi-path.h"
|
|
|
|
#include "nnrf-handler.h"
|
|
|
|
#include "nbsf-handler.h"
|
|
|
|
#include "npcf-handler.h"
|
|
|
|
|
|
|
|
void af_state_initial(ogs_fsm_t *s, af_event_t *e)
|
|
|
|
{
|
|
|
|
af_sm_debug(e);
|
|
|
|
|
|
|
|
ogs_assert(s);
|
|
|
|
|
|
|
|
OGS_FSM_TRAN(s, &af_state_operational);
|
|
|
|
}
|
|
|
|
|
|
|
|
void af_state_final(ogs_fsm_t *s, af_event_t *e)
|
|
|
|
{
|
|
|
|
af_sm_debug(e);
|
|
|
|
|
|
|
|
ogs_assert(s);
|
|
|
|
}
|
|
|
|
|
|
|
|
void af_state_operational(ogs_fsm_t *s, af_event_t *e)
|
|
|
|
{
|
|
|
|
int rv;
|
|
|
|
|
|
|
|
af_sess_t *sess = NULL;
|
|
|
|
|
|
|
|
ogs_sbi_stream_t *stream = NULL;
|
|
|
|
ogs_sbi_request_t *request = NULL;
|
|
|
|
|
|
|
|
ogs_sbi_nf_instance_t *nf_instance = NULL;
|
2022-09-08 13:12:01 +00:00
|
|
|
ogs_sbi_subscription_data_t *subscription_data = NULL;
|
2021-05-29 06:56:12 +00:00
|
|
|
ogs_sbi_response_t *response = NULL;
|
|
|
|
ogs_sbi_message_t message;
|
|
|
|
ogs_sbi_xact_t *sbi_xact = NULL;
|
|
|
|
|
|
|
|
af_sm_debug(e);
|
|
|
|
|
|
|
|
ogs_assert(s);
|
|
|
|
|
2022-08-12 05:03:53 +00:00
|
|
|
switch (e->h.id) {
|
2021-05-29 06:56:12 +00:00
|
|
|
case OGS_FSM_ENTRY_SIG:
|
|
|
|
break;
|
|
|
|
|
|
|
|
case OGS_FSM_EXIT_SIG:
|
|
|
|
break;
|
|
|
|
|
2022-08-12 05:03:53 +00:00
|
|
|
case OGS_EVENT_SBI_SERVER:
|
|
|
|
request = e->h.sbi.request;
|
2021-05-29 06:56:12 +00:00
|
|
|
ogs_assert(request);
|
2022-08-12 05:03:53 +00:00
|
|
|
stream = e->h.sbi.data;
|
2021-05-29 06:56:12 +00:00
|
|
|
ogs_assert(stream);
|
|
|
|
|
|
|
|
rv = ogs_sbi_parse_request(&message, request);
|
|
|
|
if (rv != OGS_OK) {
|
|
|
|
/* 'sbi_message' buffer is released in ogs_sbi_parse_request() */
|
|
|
|
ogs_error("cannot parse HTTP sbi_message");
|
2021-06-06 13:35:46 +00:00
|
|
|
ogs_assert(true ==
|
|
|
|
ogs_sbi_server_send_error(
|
|
|
|
stream, OGS_SBI_HTTP_STATUS_BAD_REQUEST,
|
2024-04-04 14:29:20 +00:00
|
|
|
NULL, "cannot parse HTTP sbi_message", NULL, NULL));
|
2021-05-29 06:56:12 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (strcmp(message.h.api.version, OGS_SBI_API_V1) != 0) {
|
|
|
|
ogs_error("Not supported version [%s]", message.h.api.version);
|
2021-06-06 13:35:46 +00:00
|
|
|
ogs_assert(true ==
|
|
|
|
ogs_sbi_server_send_error(
|
|
|
|
stream, OGS_SBI_HTTP_STATUS_BAD_REQUEST,
|
2024-04-04 14:29:20 +00:00
|
|
|
&message, "Not supported version", NULL, NULL));
|
2021-05-29 06:56:12 +00:00
|
|
|
ogs_sbi_message_free(&message);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
SWITCH(message.h.service.name)
|
|
|
|
CASE(OGS_SBI_SERVICE_NAME_NNRF_NFM)
|
|
|
|
|
|
|
|
SWITCH(message.h.resource.component[0])
|
|
|
|
CASE(OGS_SBI_RESOURCE_NAME_NF_STATUS_NOTIFY)
|
|
|
|
SWITCH(message.h.method)
|
|
|
|
CASE(OGS_SBI_HTTP_METHOD_POST)
|
2022-10-22 02:26:04 +00:00
|
|
|
ogs_nnrf_nfm_handle_nf_status_notify(stream, &message);
|
2021-05-29 06:56:12 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
DEFAULT
|
|
|
|
ogs_error("Invalid HTTP method [%s]", message.h.method);
|
2021-06-06 13:35:46 +00:00
|
|
|
ogs_assert(true ==
|
|
|
|
ogs_sbi_server_send_error(stream,
|
2021-05-29 06:56:12 +00:00
|
|
|
OGS_SBI_HTTP_STATUS_FORBIDDEN, &message,
|
2024-04-04 14:29:20 +00:00
|
|
|
"Invalid HTTP method", message.h.method, NULL));
|
2021-05-29 06:56:12 +00:00
|
|
|
END
|
|
|
|
break;
|
|
|
|
|
|
|
|
DEFAULT
|
|
|
|
ogs_error("Invalid resource name [%s]",
|
|
|
|
message.h.resource.component[0]);
|
2021-06-06 13:35:46 +00:00
|
|
|
ogs_assert(true ==
|
|
|
|
ogs_sbi_server_send_error(stream,
|
2021-05-29 06:56:12 +00:00
|
|
|
OGS_SBI_HTTP_STATUS_BAD_REQUEST, &message,
|
|
|
|
"Invalid resource name",
|
2024-04-04 14:29:20 +00:00
|
|
|
message.h.resource.component[0], NULL));
|
2021-05-29 06:56:12 +00:00
|
|
|
END
|
|
|
|
break;
|
|
|
|
|
2021-11-14 12:07:56 +00:00
|
|
|
CASE(OGS_SBI_SERVICE_NAME_NPCF_POLICYAUTHORIZATION)
|
|
|
|
SWITCH(message.h.resource.component[0])
|
|
|
|
CASE(OGS_SBI_RESOURCE_NAME_APP_SESSIONS)
|
|
|
|
af_sess_t *app_session = NULL;
|
|
|
|
|
|
|
|
if (!message.h.resource.component[1]) {
|
|
|
|
ogs_error("[%s] Unknown app session id",
|
|
|
|
message.h.resource.component[1]);
|
|
|
|
ogs_assert(true ==
|
|
|
|
ogs_sbi_server_send_error(stream,
|
|
|
|
OGS_SBI_HTTP_STATUS_NOT_FOUND,
|
|
|
|
&message, "Not found",
|
2024-04-04 14:29:20 +00:00
|
|
|
message.h.resource.component[1], NULL));
|
2021-11-14 12:07:56 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
app_session = af_sess_find_by_af_app_session_id(
|
|
|
|
message.h.resource.component[1]);
|
|
|
|
if (!app_session) {
|
|
|
|
ogs_error("[%s] Unknown app session id",
|
|
|
|
message.h.resource.component[1]);
|
|
|
|
ogs_assert(true ==
|
|
|
|
ogs_sbi_server_send_error(stream,
|
|
|
|
OGS_SBI_HTTP_STATUS_NOT_FOUND,
|
|
|
|
&message, "Not found",
|
2024-04-04 14:29:20 +00:00
|
|
|
message.h.resource.component[1], NULL));
|
2021-11-14 12:07:56 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
SWITCH(message.h.resource.component[2])
|
|
|
|
CASE(OGS_SBI_RESOURCE_NAME_TERMINATE)
|
|
|
|
ogs_assert(true ==
|
|
|
|
ogs_sbi_send_http_status_no_content(stream));
|
|
|
|
af_sess_remove(app_session);
|
|
|
|
break;
|
|
|
|
DEFAULT
|
|
|
|
ogs_error("Invalid resource name [%s]",
|
|
|
|
message.h.resource.component[2]);
|
|
|
|
ogs_assert(true ==
|
|
|
|
ogs_sbi_server_send_error(stream,
|
|
|
|
OGS_SBI_HTTP_STATUS_BAD_REQUEST, &message,
|
|
|
|
"Invalid resource name",
|
2024-04-04 14:29:20 +00:00
|
|
|
message.h.resource.component[2], NULL));
|
2021-11-14 12:07:56 +00:00
|
|
|
END
|
|
|
|
break;
|
|
|
|
DEFAULT
|
|
|
|
ogs_error("Invalid resource name [%s]",
|
|
|
|
message.h.resource.component[0]);
|
|
|
|
ogs_assert(true ==
|
|
|
|
ogs_sbi_server_send_error(stream,
|
|
|
|
OGS_SBI_HTTP_STATUS_BAD_REQUEST, &message,
|
|
|
|
"Invalid resource name",
|
2024-04-04 14:29:20 +00:00
|
|
|
message.h.resource.component[0], NULL));
|
2021-11-14 12:07:56 +00:00
|
|
|
END
|
|
|
|
break;
|
|
|
|
|
2021-05-29 06:56:12 +00:00
|
|
|
DEFAULT
|
|
|
|
ogs_error("Invalid API name [%s]", message.h.service.name);
|
2021-06-06 13:35:46 +00:00
|
|
|
ogs_assert(true ==
|
|
|
|
ogs_sbi_server_send_error(stream,
|
2021-05-29 06:56:12 +00:00
|
|
|
OGS_SBI_HTTP_STATUS_BAD_REQUEST, &message,
|
2024-04-04 14:29:20 +00:00
|
|
|
"Invalid API name", message.h.service.name, NULL));
|
2021-05-29 06:56:12 +00:00
|
|
|
END
|
|
|
|
|
|
|
|
/* In lib/sbi/server.c, notify_completed() releases 'request' buffer. */
|
|
|
|
ogs_sbi_message_free(&message);
|
|
|
|
break;
|
|
|
|
|
2022-08-12 05:03:53 +00:00
|
|
|
case OGS_EVENT_SBI_CLIENT:
|
2021-05-29 06:56:12 +00:00
|
|
|
ogs_assert(e);
|
|
|
|
|
2022-08-12 05:03:53 +00:00
|
|
|
response = e->h.sbi.response;
|
2021-05-29 06:56:12 +00:00
|
|
|
ogs_assert(response);
|
|
|
|
rv = ogs_sbi_parse_response(&message, response);
|
|
|
|
if (rv != OGS_OK) {
|
|
|
|
ogs_error("cannot parse HTTP response");
|
|
|
|
ogs_sbi_message_free(&message);
|
|
|
|
ogs_sbi_response_free(response);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (strcmp(message.h.api.version, OGS_SBI_API_V1) != 0) {
|
|
|
|
ogs_error("Not supported version [%s]", message.h.api.version);
|
|
|
|
ogs_sbi_message_free(&message);
|
|
|
|
ogs_sbi_response_free(response);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
SWITCH(message.h.service.name)
|
|
|
|
CASE(OGS_SBI_SERVICE_NAME_NNRF_NFM)
|
|
|
|
|
|
|
|
SWITCH(message.h.resource.component[0])
|
|
|
|
CASE(OGS_SBI_RESOURCE_NAME_NF_INSTANCES)
|
2022-08-12 05:03:53 +00:00
|
|
|
nf_instance = e->h.sbi.data;
|
2021-05-29 06:56:12 +00:00
|
|
|
ogs_assert(nf_instance);
|
|
|
|
ogs_assert(OGS_FSM_STATE(&nf_instance->sm));
|
|
|
|
|
2022-08-12 05:03:53 +00:00
|
|
|
e->h.sbi.message = &message;
|
2021-05-29 06:56:12 +00:00
|
|
|
ogs_fsm_dispatch(&nf_instance->sm, e);
|
|
|
|
break;
|
|
|
|
|
|
|
|
CASE(OGS_SBI_RESOURCE_NAME_SUBSCRIPTIONS)
|
2022-09-08 13:12:01 +00:00
|
|
|
subscription_data = e->h.sbi.data;
|
|
|
|
ogs_assert(subscription_data);
|
2021-05-29 06:56:12 +00:00
|
|
|
|
|
|
|
SWITCH(message.h.method)
|
|
|
|
CASE(OGS_SBI_HTTP_METHOD_POST)
|
|
|
|
if (message.res_status == OGS_SBI_HTTP_STATUS_CREATED ||
|
|
|
|
message.res_status == OGS_SBI_HTTP_STATUS_OK) {
|
2022-10-22 02:26:04 +00:00
|
|
|
ogs_nnrf_nfm_handle_nf_status_subscribe(
|
2022-09-08 13:12:01 +00:00
|
|
|
subscription_data, &message);
|
2021-05-29 06:56:12 +00:00
|
|
|
} else {
|
|
|
|
ogs_error("HTTP response error : %d",
|
|
|
|
message.res_status);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
2023-03-12 13:06:19 +00:00
|
|
|
CASE(OGS_SBI_HTTP_METHOD_PATCH)
|
|
|
|
if (message.res_status == OGS_SBI_HTTP_STATUS_OK ||
|
|
|
|
message.res_status == OGS_SBI_HTTP_STATUS_NO_CONTENT) {
|
|
|
|
ogs_nnrf_nfm_handle_nf_status_update(
|
|
|
|
subscription_data, &message);
|
|
|
|
} else {
|
|
|
|
ogs_error("[%s] HTTP response error [%d]",
|
|
|
|
subscription_data->id ?
|
|
|
|
subscription_data->id : "Unknown",
|
|
|
|
message.res_status);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
2021-05-29 06:56:12 +00:00
|
|
|
CASE(OGS_SBI_HTTP_METHOD_DELETE)
|
|
|
|
if (message.res_status == OGS_SBI_HTTP_STATUS_NO_CONTENT) {
|
2022-09-08 13:12:01 +00:00
|
|
|
ogs_sbi_subscription_data_remove(subscription_data);
|
2021-05-29 06:56:12 +00:00
|
|
|
} else {
|
2023-03-12 13:06:19 +00:00
|
|
|
ogs_error("[%s] HTTP response error [%d]",
|
|
|
|
subscription_data->id ?
|
|
|
|
subscription_data->id : "Unknown",
|
2021-05-29 06:56:12 +00:00
|
|
|
message.res_status);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
DEFAULT
|
|
|
|
ogs_error("Invalid HTTP method [%s]", message.h.method);
|
|
|
|
ogs_assert_if_reached();
|
|
|
|
END
|
|
|
|
break;
|
|
|
|
|
|
|
|
DEFAULT
|
|
|
|
ogs_error("Invalid resource name [%s]",
|
|
|
|
message.h.resource.component[0]);
|
|
|
|
ogs_assert_if_reached();
|
|
|
|
END
|
|
|
|
break;
|
|
|
|
|
|
|
|
CASE(OGS_SBI_SERVICE_NAME_NNRF_DISC)
|
|
|
|
SWITCH(message.h.resource.component[0])
|
|
|
|
CASE(OGS_SBI_RESOURCE_NAME_NF_INSTANCES)
|
2022-08-12 05:03:53 +00:00
|
|
|
sbi_xact = e->h.sbi.data;
|
2021-05-29 06:56:12 +00:00
|
|
|
ogs_assert(sbi_xact);
|
|
|
|
|
|
|
|
SWITCH(message.h.method)
|
|
|
|
CASE(OGS_SBI_HTTP_METHOD_GET)
|
|
|
|
if (message.res_status == OGS_SBI_HTTP_STATUS_OK)
|
|
|
|
af_nnrf_handle_nf_discover(sbi_xact, &message);
|
|
|
|
else
|
|
|
|
ogs_error("HTTP response error [%d]",
|
|
|
|
message.res_status);
|
|
|
|
break;
|
|
|
|
|
|
|
|
DEFAULT
|
|
|
|
ogs_error("Invalid HTTP method [%s]", message.h.method);
|
|
|
|
ogs_assert_if_reached();
|
|
|
|
END
|
|
|
|
break;
|
|
|
|
|
|
|
|
DEFAULT
|
|
|
|
ogs_error("Invalid resource name [%s]",
|
|
|
|
message.h.resource.component[0]);
|
|
|
|
ogs_assert_if_reached();
|
|
|
|
END
|
|
|
|
break;
|
|
|
|
|
|
|
|
CASE(OGS_SBI_SERVICE_NAME_NBSF_MANAGEMENT)
|
|
|
|
SWITCH(message.h.resource.component[0])
|
|
|
|
CASE(OGS_SBI_RESOURCE_NAME_PCF_BINDINGS)
|
2022-08-12 05:03:53 +00:00
|
|
|
sbi_xact = e->h.sbi.data;
|
2021-05-29 06:56:12 +00:00
|
|
|
ogs_assert(sbi_xact);
|
|
|
|
|
2022-07-21 03:41:19 +00:00
|
|
|
sbi_xact = ogs_sbi_xact_cycle(sbi_xact);
|
|
|
|
if (!sbi_xact) {
|
|
|
|
/* CLIENT_WAIT timer could remove SBI transaction
|
|
|
|
* before receiving SBI message */
|
|
|
|
ogs_error("SBI transaction has already been removed");
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2021-05-29 06:56:12 +00:00
|
|
|
sess = (af_sess_t *)sbi_xact->sbi_object;
|
|
|
|
ogs_assert(sess);
|
|
|
|
|
|
|
|
ogs_sbi_xact_remove(sbi_xact);
|
|
|
|
|
|
|
|
SWITCH(message.h.method)
|
|
|
|
CASE(OGS_SBI_HTTP_METHOD_GET)
|
|
|
|
if (message.res_status == OGS_SBI_HTTP_STATUS_OK)
|
|
|
|
af_nbsf_management_handle_pcf_binding(sess, &message);
|
|
|
|
else
|
|
|
|
ogs_error("HTTP response error [%d]",
|
|
|
|
message.res_status);
|
|
|
|
break;
|
|
|
|
|
|
|
|
DEFAULT
|
|
|
|
ogs_error("Invalid HTTP method [%s]", message.h.method);
|
|
|
|
ogs_assert_if_reached();
|
|
|
|
END
|
|
|
|
break;
|
|
|
|
DEFAULT
|
|
|
|
ogs_error("Invalid resource name [%s]",
|
|
|
|
message.h.resource.component[0]);
|
|
|
|
ogs_assert_if_reached();
|
|
|
|
END
|
|
|
|
break;
|
|
|
|
|
|
|
|
CASE(OGS_SBI_SERVICE_NAME_NPCF_POLICYAUTHORIZATION)
|
|
|
|
SWITCH(message.h.resource.component[0])
|
|
|
|
CASE(OGS_SBI_RESOURCE_NAME_APP_SESSIONS)
|
2022-08-12 05:03:53 +00:00
|
|
|
sess = e->h.sbi.data;
|
2021-05-29 06:56:12 +00:00
|
|
|
ogs_assert(sess);
|
|
|
|
|
2021-11-14 12:07:56 +00:00
|
|
|
if (message.h.resource.component[1]) {
|
|
|
|
if (message.h.resource.component[2]) {
|
|
|
|
SWITCH(message.h.resource.component[2])
|
|
|
|
CASE(OGS_SBI_RESOURCE_NAME_DELETE)
|
|
|
|
af_sess_remove(sess);
|
|
|
|
break;
|
|
|
|
DEFAULT
|
|
|
|
ogs_error("Invalid resource name [%s]",
|
|
|
|
message.h.resource.component[2]);
|
|
|
|
ogs_assert_if_reached();
|
|
|
|
END
|
|
|
|
} else {
|
|
|
|
SWITCH(message.h.method)
|
|
|
|
CASE(OGS_SBI_HTTP_METHOD_PATCH)
|
|
|
|
if (message.res_status == OGS_SBI_HTTP_STATUS_OK)
|
|
|
|
af_npcf_policyauthorization_handle_update(
|
|
|
|
sess, &message);
|
|
|
|
else
|
|
|
|
ogs_error("HTTP response error [%d]",
|
|
|
|
message.res_status);
|
|
|
|
break;
|
|
|
|
DEFAULT
|
|
|
|
ogs_error("Invalid HTTP method [%s]",
|
|
|
|
message.h.method);
|
|
|
|
ogs_assert_if_reached();
|
|
|
|
END
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
SWITCH(message.h.method)
|
|
|
|
CASE(OGS_SBI_HTTP_METHOD_POST)
|
|
|
|
if (message.res_status == OGS_SBI_HTTP_STATUS_CREATED)
|
|
|
|
af_npcf_policyauthorization_handle_create(
|
|
|
|
sess, &message);
|
|
|
|
else
|
|
|
|
ogs_error("HTTP response error [%d]",
|
|
|
|
message.res_status);
|
|
|
|
break;
|
|
|
|
DEFAULT
|
|
|
|
ogs_error("Invalid HTTP method [%s]", message.h.method);
|
|
|
|
ogs_assert_if_reached();
|
|
|
|
END
|
|
|
|
}
|
2021-05-29 06:56:12 +00:00
|
|
|
break;
|
|
|
|
DEFAULT
|
|
|
|
ogs_error("Invalid resource name [%s]",
|
|
|
|
message.h.resource.component[0]);
|
|
|
|
ogs_assert_if_reached();
|
|
|
|
END
|
|
|
|
break;
|
|
|
|
|
|
|
|
DEFAULT
|
|
|
|
ogs_error("Invalid service name [%s]", message.h.service.name);
|
|
|
|
ogs_assert_if_reached();
|
|
|
|
END
|
|
|
|
|
|
|
|
ogs_sbi_message_free(&message);
|
|
|
|
ogs_sbi_response_free(response);
|
|
|
|
break;
|
|
|
|
|
2022-08-12 05:03:53 +00:00
|
|
|
case OGS_EVENT_SBI_TIMER:
|
2021-05-29 06:56:12 +00:00
|
|
|
ogs_assert(e);
|
|
|
|
|
2022-08-12 05:03:53 +00:00
|
|
|
switch(e->h.timer_id) {
|
|
|
|
case OGS_TIMER_NF_INSTANCE_REGISTRATION_INTERVAL:
|
|
|
|
case OGS_TIMER_NF_INSTANCE_HEARTBEAT_INTERVAL:
|
|
|
|
case OGS_TIMER_NF_INSTANCE_NO_HEARTBEAT:
|
|
|
|
case OGS_TIMER_NF_INSTANCE_VALIDITY:
|
|
|
|
nf_instance = e->h.sbi.data;
|
2021-05-29 06:56:12 +00:00
|
|
|
ogs_assert(nf_instance);
|
|
|
|
ogs_assert(OGS_FSM_STATE(&nf_instance->sm));
|
|
|
|
|
|
|
|
ogs_fsm_dispatch(&nf_instance->sm, e);
|
2022-08-12 05:03:53 +00:00
|
|
|
if (OGS_FSM_CHECK(&nf_instance->sm, ogs_sbi_nf_state_exception))
|
|
|
|
ogs_error("State machine exception [%d]", e->h.timer_id);
|
2021-05-29 06:56:12 +00:00
|
|
|
break;
|
|
|
|
|
2022-08-12 05:03:53 +00:00
|
|
|
case OGS_TIMER_SUBSCRIPTION_VALIDITY:
|
2022-09-08 13:12:01 +00:00
|
|
|
subscription_data = e->h.sbi.data;
|
|
|
|
ogs_assert(subscription_data);
|
2021-05-29 06:56:12 +00:00
|
|
|
|
2021-06-06 13:35:46 +00:00
|
|
|
ogs_assert(true ==
|
2022-11-18 14:28:35 +00:00
|
|
|
ogs_nnrf_nfm_send_nf_status_subscribe(
|
|
|
|
ogs_sbi_self()->nf_instance->nf_type,
|
|
|
|
subscription_data->req_nf_instance_id,
|
|
|
|
subscription_data->subscr_cond.nf_type,
|
|
|
|
subscription_data->subscr_cond.service_name));
|
2021-05-29 06:56:12 +00:00
|
|
|
|
2023-03-12 13:06:19 +00:00
|
|
|
ogs_error("[%s] Subscription validity expired",
|
2022-09-08 13:12:01 +00:00
|
|
|
subscription_data->id);
|
|
|
|
ogs_sbi_subscription_data_remove(subscription_data);
|
2021-05-29 06:56:12 +00:00
|
|
|
break;
|
|
|
|
|
2023-03-12 13:06:19 +00:00
|
|
|
case OGS_TIMER_SUBSCRIPTION_PATCH:
|
|
|
|
subscription_data = e->h.sbi.data;
|
|
|
|
ogs_assert(subscription_data);
|
|
|
|
|
|
|
|
ogs_assert(true ==
|
|
|
|
ogs_nnrf_nfm_send_nf_status_update(subscription_data));
|
|
|
|
|
|
|
|
ogs_info("[%s] Need to update Subscription",
|
|
|
|
subscription_data->id);
|
|
|
|
break;
|
|
|
|
|
2022-08-12 05:03:53 +00:00
|
|
|
case OGS_TIMER_SBI_CLIENT_WAIT:
|
2023-02-04 12:35:12 +00:00
|
|
|
/*
|
|
|
|
* ogs_pollset_poll() receives the time of the expiration
|
|
|
|
* of next timer as an argument. If this timeout is
|
|
|
|
* in very near future (1 millisecond), and if there are
|
|
|
|
* multiple events that need to be processed by ogs_pollset_poll(),
|
|
|
|
* these could take more than 1 millisecond for processing,
|
|
|
|
* resulting in the timer already passed the expiration.
|
|
|
|
*
|
|
|
|
* In case that another NF is under heavy load and responds
|
|
|
|
* to an SBI request with some delay of a few seconds,
|
|
|
|
* it can happen that ogs_pollset_poll() adds SBI responses
|
|
|
|
* to the event list for further processing,
|
|
|
|
* then ogs_timer_mgr_expire() is called which will add
|
|
|
|
* an additional event for timer expiration. When all events are
|
|
|
|
* processed one-by-one, the SBI xact would get deleted twice
|
|
|
|
* in a row, resulting in a crash.
|
|
|
|
*
|
|
|
|
* 1. ogs_pollset_poll()
|
|
|
|
* message was received and put into an event list,
|
|
|
|
* 2. ogs_timer_mgr_expire()
|
|
|
|
* add an additional event for timer expiration
|
|
|
|
* 3. message event is processed. (free SBI xact)
|
|
|
|
* 4. timer expiration event is processed. (double-free SBI xact)
|
|
|
|
*
|
|
|
|
* To avoid double-free SBI xact,
|
|
|
|
* we need to check ogs_sbi_xact_cycle()
|
|
|
|
*/
|
|
|
|
sbi_xact = ogs_sbi_xact_cycle(e->h.sbi.data);
|
[NF] Fix double-free crash when NF is under heavy load
<nf>/init.c:<nf>_main() :
ogs_pollset_poll() receives the time of the expiration of next timer as
an argument. If this timeout is in very near future (1 millisecond),
and if there are multiple events that need to be processed by
ogs_pollset_poll(), these could take more than 1 millisecond for
processing, resulting in the timer already passed the expiration.
In case that another NF is under heavy load and responds to an SBI
request with some delay of a few seconds, it can happen that
ogs_pollset_poll() adds SBI responses to the event list for further
processing, then ogs_timer_mgr_expire() is called which will add an
additional event for timer expiration. When all events are processed
one-by-one, the SBI xact would get deleted twice in a row, resulting in
a crash.
0 __GI_abort () at ./stdlib/abort.c:107
1 0x00007f9de91693b1 in ?? () from /lib/x86_64-linux-gnu/libtalloc.so.2
2 0x00007f9de9a21745 in ogs_talloc_free (ptr=0x7f9d906c2c70, location=0x7f9de960bf41 "../lib/sbi/message.c:2423") at ../lib/core/ogs-memory.c:107
3 0x00007f9de95dbf31 in ogs_sbi_discovery_option_free (discovery_option=0x7f9d9090e670) at ../lib/sbi/message.c:2423
4 0x00007f9de95f7c47 in ogs_sbi_xact_remove (xact=0x7f9db630b630) at ../lib/sbi/context.c:1702
5 0x000055a482784846 in amf_state_operational (s=0x7f9d9488bbb0, e=0x7f9d90aecf20) at ../src/amf/amf-sm.c:604
6 0x00007f9de9a33cf0 in ogs_fsm_dispatch (fsm=0x7f9d9488bbb0, event=0x7f9d90aecf20) at ../lib/core/ogs-fsm.c:127
7 0x000055a48275b32e in amf_main (data=0x0) at ../src/amf/init.c:149
8 0x00007f9de9a249eb in thread_worker (arg=0x55a483d41d90) at ../lib/core/ogs-thread.c:67
9 0x00007f9de8fd2b43 in start_thread (arg=<optimized out>) at ./nptl/pthread_create.c:442
10 0x00007f9de9063bb4 in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:100
2022-12-21 08:57:50 +00:00
|
|
|
if (!sbi_xact) {
|
|
|
|
ogs_error("SBI transaction has already been removed");
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2021-05-29 06:56:12 +00:00
|
|
|
stream = sbi_xact->assoc_stream;
|
|
|
|
/* Here, we should not use ogs_assert(stream)
|
|
|
|
* since 'namf-comm' service has no an associated stream. */
|
|
|
|
|
|
|
|
ogs_sbi_xact_remove(sbi_xact);
|
|
|
|
|
|
|
|
ogs_error("Cannot receive SBI message");
|
|
|
|
if (stream) {
|
2021-06-06 13:35:46 +00:00
|
|
|
ogs_assert(true ==
|
|
|
|
ogs_sbi_server_send_error(stream,
|
2021-05-29 06:56:12 +00:00
|
|
|
OGS_SBI_HTTP_STATUS_GATEWAY_TIMEOUT, NULL,
|
2024-04-04 14:29:20 +00:00
|
|
|
"Cannot receive SBI message", NULL, NULL));
|
2021-05-29 06:56:12 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
ogs_error("Unknown timer[%s:%d]",
|
2022-08-12 05:03:53 +00:00
|
|
|
ogs_timer_get_name(e->h.timer_id), e->h.timer_id);
|
2021-05-29 06:56:12 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
2022-09-02 14:04:57 +00:00
|
|
|
case AF_EVENT_SBI_LOCAL:
|
2021-05-29 06:56:12 +00:00
|
|
|
ogs_assert(e);
|
|
|
|
|
|
|
|
switch(e->local_id) {
|
|
|
|
case AF_LOCAL_DISCOVER_AND_SEND:
|
2022-08-26 15:12:22 +00:00
|
|
|
af_sbi_discover_and_send(e->local.service_type, NULL,
|
2022-07-24 06:10:09 +00:00
|
|
|
e->local.build, e->sess, e->local.data);
|
2021-05-29 06:56:12 +00:00
|
|
|
break;
|
|
|
|
case AF_LOCAL_SEND_TO_PCF:
|
|
|
|
af_sbi_send_to_pcf(e->sess, e->local.data, e->local.build);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
ogs_error("Unknown local[%s:%d]",
|
|
|
|
af_local_get_name(e->local_id), e->local_id);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
ogs_error("No handler for event %s", af_event_get_name(e));
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|