[Cx] Fix the HSS crash (#1264)
Use Visited-Network-Identifier(Cx) instead of Visited-PLMN-ID(s6a)
This commit is contained in:
parent
27b87c1110
commit
e302f727fd
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue