Fix P-GW crashed without PCRF (#402)

This commit is contained in:
Sukchan Lee 2020-04-17 21:36:26 -04:00
parent 2b69283a81
commit 3feddd5424
6 changed files with 82 additions and 4 deletions

View File

@ -69,6 +69,7 @@ int ogs_diam_init(int mode, const char *conffile, ogs_diam_config_t *fd_config);
void ogs_diam_final(void);
int ogs_diam_config_init(ogs_diam_config_t *fd_config);
bool ogs_diam_peer_connected(void);
int fd_avp_search_avp ( struct avp * groupedavp,
struct dict_object * what, struct avp ** avp );

View File

@ -27,6 +27,7 @@ libdiameter_common_sources = files('''
message.c
logger.c
config.c
util.c
init.c
'''.split())

View File

@ -0,0 +1,47 @@
/*
* Copyright (C) 2019 by Sukchan Lee <acetcom@gmail.com>
*
* 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 "ogs-diameter-common.h"
bool ogs_diam_peer_connected(void)
{
struct fd_list *li;
bool connected = false;
CHECK_POSIX( pthread_rwlock_rdlock(&fd_g_peers_rw) );
for (li = fd_g_peers.next; li != &fd_g_peers; li = li->next) {
struct peer_hdr *p = (struct peer_hdr *)li->o;
int state = fd_peer_get_state(p);
ogs_assert(p);
ogs_assert(p->info.pi_diamid);
ogs_assert(p->info.pi_diamidlen);
if (state == STATE_OPEN) {
ogs_debug("'%s' STATE is OPEN", p->info.pi_diamid);
connected = true;
} else {
ogs_debug("'%s' STATE[%d] is NOT open ", p->info.pi_diamid, state);
}
}
CHECK_POSIX( pthread_rwlock_unlock(&fd_g_peers_rw) );
return connected;
}

View File

@ -122,6 +122,10 @@ void mme_s11_handle_create_session_response(
}
if (cause_value != OGS_GTP_CAUSE_REQUEST_ACCEPTED) {
if (OGS_FSM_CHECK(&mme_ue->sm, emm_state_initial_context_setup)) {
nas_send_attach_reject(mme_ue,
EMM_CAUSE_NETWORK_FAILURE, ESM_CAUSE_NETWORK_FAILURE);
}
mme_send_delete_session_or_mme_ue_context_release(mme_ue);
return;
}

View File

@ -95,6 +95,11 @@ void pgw_s5c_handle_create_session_request(
cause_value = OGS_GTP_CAUSE_MANDATORY_IE_MISSING;
}
if (!ogs_diam_peer_connected()) {
ogs_error("No Diameter Peer");
cause_value = OGS_GTP_CAUSE_REMOTE_PEER_NOT_RESPONDING;
}
if (cause_value != OGS_GTP_CAUSE_REQUEST_ACCEPTED) {
ogs_gtp_send_error_message(xact, sess ? sess->sgw_s5c_teid : 0,
OGS_GTP_CREATE_SESSION_RESPONSE_TYPE, cause_value);
@ -177,7 +182,8 @@ void pgw_s5c_handle_create_session_request(
sess->uli_type = OGS_DIAM_GX_3GPP_USER_LOCATION_INFO_TYPE_ECGI;
if (uli.flags.tai) {
memcpy(&sess->tai.plmn_id, &uli.tai.plmn_id, sizeof(uli.tai.plmn_id));
memcpy(&sess->tai.plmn_id, &uli.tai.plmn_id,
sizeof(uli.tai.plmn_id));
sess->tai.tac = uli.tai.tac;
}
if (uli.flags.e_cgi) {
@ -195,6 +201,8 @@ void pgw_s5c_handle_delete_session_request(
pgw_sess_t *sess, ogs_gtp_xact_t *xact,
ogs_pkbuf_t *gtpbuf, ogs_gtp_delete_session_request_t *req)
{
uint8_t cause_value = 0;
ogs_debug("[PGW] Delete Session Request");
ogs_assert(xact);
@ -202,9 +210,17 @@ void pgw_s5c_handle_delete_session_request(
if (!sess) {
ogs_warn("No Context");
cause_value = OGS_GTP_CAUSE_CONTEXT_NOT_FOUND;
}
if (!ogs_diam_peer_connected()) {
ogs_error("No Diameter Peer");
cause_value = OGS_GTP_CAUSE_REMOTE_PEER_NOT_RESPONDING;
}
if (cause_value != OGS_GTP_CAUSE_REQUEST_ACCEPTED) {
ogs_gtp_send_error_message(xact, sess ? sess->sgw_s5c_teid : 0,
OGS_GTP_DELETE_SESSION_RESPONSE_TYPE,
OGS_GTP_CAUSE_CONTEXT_NOT_FOUND);
OGS_GTP_DELETE_SESSION_RESPONSE_TYPE, cause_value);
ogs_pkbuf_free(gtpbuf);
return;
}

View File

@ -92,6 +92,14 @@ void sgw_s5c_handle_create_session_response(ogs_gtp_xact_t *s5c_xact,
ogs_error("No Cause");
cause_value = OGS_GTP_CAUSE_MANDATORY_IE_MISSING;
}
} else {
/* Deliver PGW cause value to the MME */
ogs_warn("Cause[%d] : No Accepted", cause_value);
ogs_gtp_send_error_message(
s11_xact, sgw_ue ? sgw_ue->mme_s11_teid : 0,
OGS_GTP_CREATE_SESSION_RESPONSE_TYPE,
cause_value);
return;
}
} else {
ogs_error("No Cause");
@ -143,7 +151,8 @@ void sgw_s5c_handle_create_session_response(ogs_gtp_xact_t *s5c_xact,
if (cause_value != OGS_GTP_CAUSE_REQUEST_ACCEPTED) {
ogs_gtp_send_error_message(s11_xact, sgw_ue ? sgw_ue->mme_s11_teid : 0,
OGS_GTP_CREATE_SESSION_RESPONSE_TYPE, cause_value);
OGS_GTP_CREATE_SESSION_RESPONSE_TYPE,
cause_value);
return;
}