[SMF] Gx: Add Destination-Host AVP to CCR (#1458)

Catch Origin-Host during CCA and set it as Destination-Host during
subsequent CCRs. This way we ensure UPDATE/TERMINATION Requests are sent
back explicitly to the same Diameter peer. Moreover, it seems
freediameter relies on this AVP to properly send the message over the
correct SCTP association when several diameter peers are available.
This commit is contained in:
Pau Espin 2022-03-28 15:00:28 +02:00 committed by GitHub
parent 4b8d3a845a
commit acd6610508
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 23 additions and 0 deletions

View File

@ -26,6 +26,8 @@ static struct disp_hdl *hdl_gx_rar = NULL;
struct sess_state {
os0_t gx_sid; /* Gx Session-Id */
os0_t peer_host; /* Peer Host */
#define MAX_CC_REQUEST_NUMBER 32
smf_sess_t *sess;
ogs_gtp_xact_t *xact[MAX_CC_REQUEST_NUMBER];
@ -63,6 +65,9 @@ static void state_cleanup(struct sess_state *sess_data, os0_t sid, void *opaque)
if (sess_data->gx_sid)
ogs_free(sess_data->gx_sid);
if (sess_data->peer_host)
ogs_free(sess_data->peer_host);
ogs_thread_mutex_lock(&sess_state_mutex);
ogs_pool_free(&sess_state_pool, sess_data);
ogs_thread_mutex_unlock(&sess_state_mutex);
@ -215,6 +220,18 @@ void smf_gx_send_ccr(smf_sess_t *sess, ogs_gtp_xact_t *xact,
ret = fd_msg_avp_add(req, MSG_BRW_LAST_CHILD, avp);
ogs_assert(ret == 0);
/* Set the Destination-Host AVP */
if (sess_data->peer_host) {
ret = fd_msg_avp_new(ogs_diam_destination_host, 0, &avp);
ogs_assert(ret == 0);
val.os.data = sess_data->peer_host;
val.os.len = strlen((char *)sess_data->peer_host);
ret = fd_msg_avp_setvalue(avp, &val);
ogs_assert(ret == 0);
ret = fd_msg_avp_add(req, MSG_BRW_LAST_CHILD, avp);
ogs_assert(ret == 0);
}
/* Set Subscription-Id */
ret = fd_msg_avp_new(ogs_diam_subscription_id, 0, &avp);
ogs_assert(ret == 0);
@ -893,6 +910,12 @@ static void smf_gx_cca_cb(void *data, struct msg **msg)
switch (hdr->avp_code) {
case AC_SESSION_ID:
case AC_ORIGIN_HOST:
if (sess_data->peer_host)
ogs_free(sess_data->peer_host);
sess_data->peer_host =
(os0_t)ogs_strdup((char *)hdr->avp_value->os.data);
ogs_assert(sess_data->peer_host);
break;
case AC_ORIGIN_REALM:
case AC_DESTINATION_REALM:
case AC_RESULT_CODE: