[Cx] Fix the HSS crash (#1264)

Use Visited-Network-Identifier(Cx) instead of Visited-PLMN-ID(s6a)
This commit is contained in:
Sukchan Lee 2021-12-12 14:33:42 +09:00
parent 27b87c1110
commit e302f727fd
4 changed files with 52 additions and 50 deletions

View File

@ -26,7 +26,7 @@ typedef struct hss_imsi_s {
ogs_lnode_t lnode;
char *id;
ogs_plmn_id_t visited_plmn_id;
char *visited_network_identifier;
} hss_imsi_t;
typedef struct hss_impi_s {
@ -480,6 +480,9 @@ static void imsi_remove(hss_imsi_t *imsi)
ogs_hash_set(self.imsi_hash, imsi->id, strlen(imsi->id), NULL);
ogs_free(imsi->id);
ogs_assert(imsi->visited_network_identifier);
ogs_free(imsi->visited_network_identifier);
ogs_pool_free(&imsi_pool, imsi);
}
@ -631,26 +634,6 @@ static hss_impu_t *impu_find_by_impi_and_id(hss_impi_t *impi, char *id)
return NULL;
}
void hss_s6a_set_visited_plmn_id(char *imsi_bcd, ogs_plmn_id_t *visited_plmn_id)
{
hss_imsi_t *imsi = NULL;
ogs_assert(imsi_bcd);
ogs_assert(visited_plmn_id);
ogs_thread_mutex_lock(&self.cx_lock);
imsi = imsi_find_by_id(imsi_bcd);
if (!imsi) {
imsi = imsi_add(imsi_bcd);
ogs_assert(imsi);
}
memcpy(&imsi->visited_plmn_id, visited_plmn_id, OGS_PLMN_ID_LEN);
ogs_thread_mutex_unlock(&self.cx_lock);
}
void hss_cx_associate_identity(char *user_name, char *public_identity)
{
hss_impi_t *impi = NULL;
@ -698,7 +681,8 @@ bool hss_cx_identity_is_associated(char *user_name, char *public_identity)
return match_result;
}
void hss_cx_set_imsi_bcd(char *user_name, char *imsi_bcd)
void hss_cx_set_imsi_bcd(char *user_name,
char *imsi_bcd, char *visited_network_identifier)
{
hss_imsi_t *imsi = NULL;
hss_impi_t *impi = NULL;
@ -712,10 +696,18 @@ void hss_cx_set_imsi_bcd(char *user_name, char *imsi_bcd)
ogs_assert(impi);
imsi = imsi_find_by_id(imsi_bcd);
ogs_assert(imsi);
if (!imsi) {
imsi = imsi_add(imsi_bcd);
ogs_assert(imsi);
}
impi->imsi = imsi;
if (imsi->visited_network_identifier)
ogs_free(imsi->visited_network_identifier);
imsi->visited_network_identifier = ogs_strdup(visited_network_identifier);
ogs_assert(imsi->visited_network_identifier);
ogs_thread_mutex_unlock(&self.cx_lock);
}
@ -742,12 +734,12 @@ char *hss_cx_get_imsi_bcd(char *public_identity)
return imsi_bcd;
}
ogs_plmn_id_t *hss_cx_get_visited_plmn_id(char *public_identity)
char *hss_cx_get_visited_network_identifier(char *public_identity)
{
hss_impi_t *impi = NULL;
hss_impu_t *impu = NULL;
ogs_plmn_id_t *visited_plmn_id = NULL;
char *visited_network_identifier = NULL;
ogs_thread_mutex_lock(&self.cx_lock);
@ -757,12 +749,12 @@ ogs_plmn_id_t *hss_cx_get_visited_plmn_id(char *public_identity)
ogs_assert(impi);
if (impi->imsi)
visited_plmn_id = &impi->imsi->visited_plmn_id;
visited_network_identifier = impi->imsi->visited_network_identifier;
}
ogs_thread_mutex_unlock(&self.cx_lock);
return visited_plmn_id;
return visited_network_identifier;
}
char *hss_cx_get_user_name(char *public_identity)
@ -844,7 +836,8 @@ void hss_cx_set_server_name(
}
char *hss_cx_download_user_data(
char *user_name, ogs_plmn_id_t *plmn_id, ogs_ims_data_t *ims_data)
char *user_name, char *visited_network_identifier,
ogs_ims_data_t *ims_data)
{
char *user_data = NULL;
@ -855,17 +848,15 @@ char *hss_cx_download_user_data(
int i;
ogs_assert(user_name);
ogs_assert(plmn_id);
ogs_assert(visited_network_identifier);
ogs_assert(ims_data);
/* Download User-Data */
for (i = 0; i < ims_data->num_of_msisdn; i++) {
char *public_identity = NULL;
public_identity = ogs_msprintf(
"sip:%s@ims.mnc%03d.mcc%03d.3gppnetwork.org",
ims_data->msisdn[i].bcd,
ogs_plmn_id_mnc(plmn_id), ogs_plmn_id_mcc(plmn_id));
public_identity = ogs_msprintf("sip:%s@%s",
ims_data->msisdn[i].bcd, visited_network_identifier);
ogs_assert(public_identity);
hss_cx_associate_identity(user_name, public_identity);
ogs_free(public_identity);

View File

@ -70,16 +70,14 @@ int hss_db_msisdn_data(
int hss_db_ims_data(char *imsi_bcd, ogs_ims_data_t *ims_data);
void hss_s6a_set_visited_plmn_id(
char *imsi_bcd, ogs_plmn_id_t *visited_plmn_id);
void hss_cx_associate_identity(char *user_name, char *public_identity);
bool hss_cx_identity_is_associated(char *user_name, char *public_identity);
void hss_cx_set_imsi_bcd(char *user_name, char *imsi_bcd);
void hss_cx_set_imsi_bcd(char *user_name,
char *imsi_bcd, char *visited_network_identifier);
char *hss_cx_get_imsi_bcd(char *public_identity);
ogs_plmn_id_t *hss_cx_get_visited_plmn_id(char *public_identity);
char *hss_cx_get_visited_network_identifier(char *public_identity);
char *hss_cx_get_user_name(char *public_identity);
char *hss_cx_get_server_name(char *public_identity);
@ -87,7 +85,8 @@ void hss_cx_set_server_name(
char *public_identity, char *server_name, bool overwrite);
char *hss_cx_download_user_data(
char *user_name, ogs_plmn_id_t *plmn_id, ogs_ims_data_t *ims_data);
char *user_name, char *visited_network_identifier,
ogs_ims_data_t *ims_data);
#ifdef __cplusplus

View File

@ -57,6 +57,7 @@ static int hss_ogs_diam_cx_uar_cb( struct msg **msg, struct avp *avp,
char *user_name = NULL;
char *public_identity = NULL;
char *visited_network_identifier = NULL;
char *server_name = NULL;
char imsi_or_msisdn_bcd[OGS_MAX_IMSI_BCD_LEN+1];
@ -95,6 +96,16 @@ static int hss_ogs_diam_cx_uar_cb( struct msg **msg, struct avp *avp,
(char*)hdr->avp_value->os.data, hdr->avp_value->os.len);
ogs_assert(public_identity);
/* Get Visited-Network-Identifier AVP (Mandatory) */
ret = fd_msg_search_avp(qry, ogs_diam_visited_network_identifier, &avp);
ogs_assert(ret == 0);
ret = fd_msg_avp_hdr(avp, &hdr);
ogs_assert(ret == 0);
visited_network_identifier = ogs_strndup(
(char*)hdr->avp_value->os.data, hdr->avp_value->os.len);
ogs_assert(visited_network_identifier);
memset(&msisdn_data, 0, sizeof(ogs_msisdn_data_t));
rv = hss_db_msisdn_data(imsi_or_msisdn_bcd, &msisdn_data);
if (rv != OGS_OK) {
@ -113,7 +124,8 @@ static int hss_ogs_diam_cx_uar_cb( struct msg **msg, struct avp *avp,
hss_cx_associate_identity(user_name, public_identity);
/* Set IMSI for IMPI(User-Name) */
hss_cx_set_imsi_bcd(user_name, msisdn_data.imsi.bcd);
hss_cx_set_imsi_bcd(user_name,
msisdn_data.imsi.bcd, visited_network_identifier);
/* Get Server-Name by IMPU(Public-Identity) */
server_name = hss_cx_get_server_name(public_identity);
@ -160,6 +172,7 @@ static int hss_ogs_diam_cx_uar_cb( struct msg **msg, struct avp *avp,
ogs_free(user_name);
ogs_free(public_identity);
ogs_free(visited_network_identifier);
return 0;
@ -187,6 +200,7 @@ out:
ogs_free(user_name);
ogs_free(public_identity);
ogs_free(visited_network_identifier);
return 0;
}
@ -607,7 +621,7 @@ static int hss_ogs_diam_cx_sar_cb( struct msg **msg, struct avp *avp,
char *user_data = NULL;
char *imsi_bcd = NULL;
ogs_plmn_id_t *visited_plmn_id = NULL;
char *visited_network_identifier = NULL;
ogs_ims_data_t ims_data;
@ -682,10 +696,12 @@ static int hss_ogs_diam_cx_sar_cb( struct msg **msg, struct avp *avp,
goto out;
}
/* Check if Visited-PLMN-ID from S6A */
visited_plmn_id = hss_cx_get_visited_plmn_id(public_identity);
if (!visited_plmn_id) {
ogs_error("Cannot find PLMN-ID for User-Name[%s] Public-Identity[%s]",
/* Check if Visited-Network-Identifier */
visited_network_identifier =
hss_cx_get_visited_network_identifier(public_identity);
if (!visited_network_identifier) {
ogs_error("Cannot find Visted-Network-Identifier "
"for User-Name[%s] Public-Identity[%s]",
user_name, public_identity);
result_code = OGS_DIAM_CX_ERROR_IDENTITY_NOT_REGISTERED;
goto out;
@ -754,7 +770,7 @@ static int hss_ogs_diam_cx_sar_cb( struct msg **msg, struct avp *avp,
} else {
/* Set the User-Data AVP */
user_data = hss_cx_download_user_data(
user_name, visited_plmn_id, &ims_data);
user_name, visited_network_identifier, &ims_data);
ogs_assert(user_data);
ret = fd_msg_avp_new(ogs_diam_cx_user_data, 0, &avp);

View File

@ -159,8 +159,6 @@ static int hss_ogs_diam_s6a_air_cb( struct msg **msg, struct avp *avp,
ogs_assert(ret == 0);
memcpy(&visited_plmn_id, hdr->avp_value->os.data, hdr->avp_value->os.len);
hss_s6a_set_visited_plmn_id(imsi_bcd, &visited_plmn_id);
milenage_generate(opc, auth_info.amf, auth_info.k,
ogs_uint64_to_buffer(auth_info.sqn, OGS_SQN_LEN, sqn), auth_info.rand,
autn, ik, ck, ak, xres, &xres_len);
@ -322,8 +320,6 @@ static int hss_ogs_diam_s6a_ulr_cb( struct msg **msg, struct avp *avp,
ogs_assert(ret == 0);
memcpy(&visited_plmn_id, hdr->avp_value->os.data, hdr->avp_value->os.len);
hss_s6a_set_visited_plmn_id(imsi_bcd, &visited_plmn_id);
/* Set the Origin-Host, Origin-Realm, andResult-Code AVPs */
ret = fd_msg_rescode_set(ans, (char*)"DIAMETER_SUCCESS", NULL, NULL, 1);
ogs_assert(ret == 0);