core,gtp,pfcp,sgwc: avoid fatal asserts on pool and timer exhaustion

Replace ogs_assert() and ogs_fatal() with runtime checks when allocating
UE contexts, transactions, and timers.

Handle pool and timer exhaustion gracefully by logging errors, cleaning
up partially created objects, and returning NULL instead of aborting
the process, improving control-plane robustness under high load or
resource limits.

Issues: #4220, #4221
This commit is contained in:
Sukchan Lee 2025-12-30 11:49:40 +09:00
parent b4707272c1
commit c7c131f8d2
4 changed files with 107 additions and 20 deletions

View file

@ -81,7 +81,7 @@ ogs_timer_t *ogs_timer_add(
ogs_pool_alloc(&manager->pool, &timer);
if (!timer) {
ogs_fatal("ogs_pool_alloc() failed");
ogs_error("Failed to allocate timer object from pool");
return NULL;
}

View file

@ -77,7 +77,11 @@ ogs_gtp_xact_t *ogs_gtp1_xact_local_create(ogs_gtp_node_t *gnode,
ogs_assert(hdesc);
ogs_pool_id_calloc(&pool, &xact);
ogs_assert(xact);
if (!xact) {
ogs_error("Maximum number of xact[%lld] reached",
(long long)ogs_app()->pool.xact);
return NULL;
}
xact->index = ogs_pool_index(&pool, xact);
xact->gtp_version = 1;
@ -94,7 +98,12 @@ ogs_gtp_xact_t *ogs_gtp1_xact_local_create(ogs_gtp_node_t *gnode,
xact->tm_response = ogs_timer_add(
ogs_app()->timer_mgr, response_timeout,
OGS_UINT_TO_POINTER(xact->id));
ogs_assert(xact->tm_response);
if (!xact->tm_response) {
ogs_error("Maximum number of xact->tm_response[%lld] reached",
(long long)ogs_app()->pool.timer);
ogs_gtp_xact_delete(xact);
return NULL;
}
xact->response_rcount =
ogs_local_conf()->time.message.gtp.n3_response_rcount;
}
@ -102,7 +111,12 @@ ogs_gtp_xact_t *ogs_gtp1_xact_local_create(ogs_gtp_node_t *gnode,
xact->tm_holding = ogs_timer_add(
ogs_app()->timer_mgr, holding_timeout,
OGS_UINT_TO_POINTER(xact->id));
ogs_assert(xact->tm_holding);
if (!xact->tm_holding) {
ogs_error("Maximum number of xact->tm_holding[%lld] reached",
(long long)ogs_app()->pool.timer);
ogs_gtp_xact_delete(xact);
return NULL;
}
xact->holding_rcount = ogs_local_conf()->time.message.gtp.n3_holding_rcount;
ogs_list_add(&xact->gnode->local_list, xact);
@ -134,7 +148,11 @@ ogs_gtp_xact_t *ogs_gtp_xact_local_create(ogs_gtp_node_t *gnode,
ogs_assert(hdesc);
ogs_pool_id_calloc(&pool, &xact);
ogs_assert(xact);
if (!xact) {
ogs_error("Maximum number of xact[%lld] reached",
(long long)ogs_app()->pool.xact);
return NULL;
}
xact->index = ogs_pool_index(&pool, xact);
xact->gtp_version = 2;
@ -153,14 +171,24 @@ ogs_gtp_xact_t *ogs_gtp_xact_local_create(ogs_gtp_node_t *gnode,
xact->tm_response = ogs_timer_add(
ogs_app()->timer_mgr, response_timeout,
OGS_UINT_TO_POINTER(xact->id));
ogs_assert(xact->tm_response);
if (!xact->tm_response) {
ogs_error("Maximum number of xact->tm_response[%lld] reached",
(long long)ogs_app()->pool.timer);
ogs_gtp_xact_delete(xact);
return NULL;
}
xact->response_rcount =
ogs_local_conf()->time.message.gtp.n3_response_rcount,
xact->tm_holding = ogs_timer_add(
ogs_app()->timer_mgr, holding_timeout,
OGS_UINT_TO_POINTER(xact->id));
ogs_assert(xact->tm_holding);
if (!xact->tm_holding) {
ogs_error("Maximum number of xact->tm_holding[%lld] reached",
(long long)ogs_app()->pool.timer);
ogs_gtp_xact_delete(xact);
return NULL;
}
xact->holding_rcount = ogs_local_conf()->time.message.gtp.n3_holding_rcount,
xact->tm_peer = ogs_timer_add(ogs_app()->timer_mgr, peer_timeout,
@ -192,7 +220,11 @@ static ogs_gtp_xact_t *ogs_gtp_xact_remote_create(ogs_gtp_node_t *gnode, uint8_t
ogs_assert(gnode);
ogs_pool_id_calloc(&pool, &xact);
ogs_assert(xact);
if (!xact) {
ogs_error("Maximum number of xact[%lld] reached",
(long long)ogs_app()->pool.xact);
return NULL;
}
xact->index = ogs_pool_index(&pool, xact);
xact->gtp_version = gtp_version;
@ -204,14 +236,24 @@ static ogs_gtp_xact_t *ogs_gtp_xact_remote_create(ogs_gtp_node_t *gnode, uint8_t
xact->tm_response = ogs_timer_add(
ogs_app()->timer_mgr, response_timeout,
OGS_UINT_TO_POINTER(xact->id));
ogs_assert(xact->tm_response);
if (!xact->tm_response) {
ogs_error("Maximum number of xact->tm_response[%lld] reached",
(long long)ogs_app()->pool.timer);
ogs_gtp_xact_delete(xact);
return NULL;
}
xact->response_rcount =
ogs_local_conf()->time.message.gtp.n3_response_rcount,
xact->tm_holding = ogs_timer_add(
ogs_app()->timer_mgr, holding_timeout,
OGS_UINT_TO_POINTER(xact->id));
ogs_assert(xact->tm_holding);
if (!xact->tm_holding) {
ogs_error("Maximum number of xact->tm_holding[%lld] reached",
(long long)ogs_app()->pool.timer);
ogs_gtp_xact_delete(xact);
return NULL;
}
xact->holding_rcount = ogs_local_conf()->time.message.gtp.n3_holding_rcount,
xact->tm_peer = ogs_timer_add(ogs_app()->timer_mgr, peer_timeout,

View file

@ -75,7 +75,11 @@ ogs_pfcp_xact_t *ogs_pfcp_xact_local_create(ogs_pfcp_node_t *node,
ogs_assert(node);
ogs_pool_id_calloc(&pool, &xact);
ogs_assert(xact);
if (!xact) {
ogs_error("Maximum number of xact[%lld] reached",
(long long)ogs_app()->pool.xact);
return NULL;
}
xact->index = ogs_pool_index(&pool, xact);
xact->org = OGS_PFCP_LOCAL_ORIGINATOR;
@ -87,21 +91,36 @@ ogs_pfcp_xact_t *ogs_pfcp_xact_local_create(ogs_pfcp_node_t *node,
xact->tm_response = ogs_timer_add(
ogs_app()->timer_mgr, response_timeout,
OGS_UINT_TO_POINTER(xact->id));
ogs_assert(xact->tm_response);
if (!xact->tm_response) {
ogs_error("Maximum number of xact->tm_response[%lld] reached",
(long long)ogs_app()->pool.timer);
ogs_pfcp_xact_delete(xact);
return NULL;
}
xact->response_rcount =
ogs_local_conf()->time.message.pfcp.n1_response_rcount;
xact->tm_holding = ogs_timer_add(
ogs_app()->timer_mgr, holding_timeout,
OGS_UINT_TO_POINTER(xact->id));
ogs_assert(xact->tm_holding);
if (!xact->tm_holding) {
ogs_error("Maximum number of xact->tm_holding[%lld] reached",
(long long)ogs_app()->pool.timer);
ogs_pfcp_xact_delete(xact);
return NULL;
}
xact->holding_rcount =
ogs_local_conf()->time.message.pfcp.n1_holding_rcount;
xact->tm_delayed_commit = ogs_timer_add(
ogs_app()->timer_mgr, delayed_commit_timeout,
OGS_UINT_TO_POINTER(xact->id));
ogs_assert(xact->tm_delayed_commit);
if (!xact->tm_delayed_commit) {
ogs_error("Maximum number of xact->tm_delayed_commit[%lld] reached",
(long long)ogs_app()->pool.timer);
ogs_pfcp_xact_delete(xact);
return NULL;
}
ogs_list_add(xact->org == OGS_PFCP_LOCAL_ORIGINATOR ?
&xact->node->local_list : &xact->node->remote_list, xact);
@ -124,7 +143,11 @@ static ogs_pfcp_xact_t *ogs_pfcp_xact_remote_create(
ogs_assert(node);
ogs_pool_id_calloc(&pool, &xact);
ogs_assert(xact);
if (!xact) {
ogs_error("Maximum number of xact[%lld] reached",
(long long)ogs_app()->pool.xact);
return NULL;
}
xact->index = ogs_pool_index(&pool, xact);
xact->org = OGS_PFCP_REMOTE_ORIGINATOR;
@ -134,21 +157,36 @@ static ogs_pfcp_xact_t *ogs_pfcp_xact_remote_create(
xact->tm_response = ogs_timer_add(
ogs_app()->timer_mgr, response_timeout,
OGS_UINT_TO_POINTER(xact->id));
ogs_assert(xact->tm_response);
if (!xact->tm_response) {
ogs_error("Maximum number of xact->tm_response[%lld] reached",
(long long)ogs_app()->pool.timer);
ogs_pfcp_xact_delete(xact);
return NULL;
}
xact->response_rcount =
ogs_local_conf()->time.message.pfcp.n1_response_rcount;
xact->tm_holding = ogs_timer_add(
ogs_app()->timer_mgr, holding_timeout,
OGS_UINT_TO_POINTER(xact->id));
ogs_assert(xact->tm_holding);
if (!xact->tm_holding) {
ogs_error("Maximum number of xact->tm_holding[%lld] reached",
(long long)ogs_app()->pool.timer);
ogs_pfcp_xact_delete(xact);
return NULL;
}
xact->holding_rcount =
ogs_local_conf()->time.message.pfcp.n1_holding_rcount;
xact->tm_delayed_commit = ogs_timer_add(
ogs_app()->timer_mgr, delayed_commit_timeout,
OGS_UINT_TO_POINTER(xact->id));
ogs_assert(xact->tm_delayed_commit);
if (!xact->tm_delayed_commit) {
ogs_error("Maximum number of xact->tm_delayed_commit[%lld] reached",
(long long)ogs_app()->pool.timer);
ogs_pfcp_xact_delete(xact);
return NULL;
}
ogs_list_add(xact->org == OGS_PFCP_LOCAL_ORIGINATOR ?
&xact->node->local_list : &xact->node->remote_list, xact);

View file

@ -201,7 +201,10 @@ sgwc_ue_t *sgwc_ue_add_by_message(ogs_gtp2_message_t *message)
if (sgwc_ue)
sgwc_ue_remove(sgwc_ue);
sgwc_ue = sgwc_ue_add(req->imsi.data, req->imsi.len);
ogs_assert(sgwc_ue);
if (!sgwc_ue) {
ogs_error("sgwc_ue_add() failed");
return NULL;
}
return sgwc_ue;
}
@ -214,7 +217,11 @@ sgwc_ue_t *sgwc_ue_add(uint8_t *imsi, int imsi_len)
ogs_assert(imsi_len);
ogs_pool_id_calloc(&sgwc_ue_pool, &sgwc_ue);
ogs_assert(sgwc_ue);
if (!sgwc_ue) {
ogs_error("Maximum number of sgwc_ue[%lld] reached",
(long long)ogs_global_conf()->max.ue);
return NULL;
}
/* Set SGW-S11-TEID */
ogs_pool_alloc(&sgwc_s11_teid_pool, &sgwc_ue->sgw_s11_teid_node);