예제 #1
0
int rx_send_aar_register(struct sip_msg *msg, AAASession* auth, saved_transaction_local_t* saved_t_data) {
    AAAMessage* aar = 0;
    int ret = 0;
    AAA_AVP* avp = 0;
    char x[4];
    str identifier;
    
    str ip;
    uint16_t ip_version;

    //we get ip and identifier for the auth session data 
    rx_authsessiondata_t* p_session_data = 0;
    p_session_data = (rx_authsessiondata_t*) auth->u.auth.generic_data;
    identifier = p_session_data->identifier;
    ip = p_session_data->ip;
    ip_version = p_session_data->ip_version;

    LM_DBG("Send AAR register\n");

    aar = cdpb.AAACreateRequest(IMS_Rx, IMS_AAR, Flag_Proxyable, auth);

    if (!aar)
        goto error;

    /*Add AVPs*/

    /* Add Auth-Application-Id AVP */
    if (!rx_add_auth_application_id_avp(aar, IMS_Rx))
        goto error;
    if (!rx_add_vendor_specific_application_id_group(aar, IMS_vendor_id_3GPP,
            IMS_Rx))
        goto error;

    /* Add Destination-Realm AVP, if not already there */
    avp = cdpb.AAAFindMatchingAVP(aar, aar->avpList.head, AVP_Destination_Realm,
            0, AAA_FORWARD_SEARCH);
    if (!avp) {
        str realm = rx_dest_realm;
        if (realm.len && !rx_add_destination_realm_avp(aar, realm))
            goto error;
    }

    /* Add Subscription ID AVP*/
    
    identifier = cscf_get_public_identity(msg);
    
    int identifier_type = AVP_Subscription_Id_Type_SIP_URI; //we only do IMPU now
    rx_add_subscription_id_avp(aar, identifier, identifier_type);

    /* Add media component description avp for register*/
    rx_add_media_component_description_avp_register(aar);

    /* Add specific action AVP's */
    rx_add_specific_action_avp(aar, 1); // CHARGING_CORRELATION_EXCHANGE
    rx_add_specific_action_avp(aar, 2); // INDICATION_OF_LOSS_OF_BEARER
    rx_add_specific_action_avp(aar, 3); // INDICATION_RECOVERY_OF_BEARER
    rx_add_specific_action_avp(aar, 4); // INDICATION_RELEASE_OF_BEARER
    rx_add_specific_action_avp(aar, 5); // INDICATION_ESTABLISHMENT_OF_BEARER (now void)
    rx_add_specific_action_avp(aar, 6); // IP-CAN_CHANGE
    rx_add_specific_action_avp(aar, 12); // ACCESS_NETWORK_INFO_REPORT

    /* Add Framed IP address AVP*/
    if (!rx_add_framed_ip_avp(&aar->avpList, ip, ip_version)) {
        LM_ERR("Unable to add framed IP AVP\n");
        goto error;
    }

    /* Add Auth lifetime AVP */LM_DBG("auth_lifetime %u\n", rx_auth_expiry); //TODO check why this is 0 all the time
    if (rx_auth_expiry) {
        set_4bytes(x, rx_auth_expiry);
        if (!rx_add_avp(aar, x, 4, AVP_Authorization_Lifetime,
                AAA_AVP_FLAG_MANDATORY, 0, AVP_DUPLICATE_DATA, __FUNCTION__))
            goto error;
    }

    if (auth)
        cdpb.AAASessionsUnlock(auth->hash);

    LM_DBG("sending AAR to PCRF\n");
    if (rx_forced_peer.len)
        ret = cdpb.AAASendMessageToPeer(aar, &rx_forced_peer,
            (void*) async_aar_reg_callback, (void*) saved_t_data);
    else
        ret = cdpb.AAASendMessage(aar, (void*) async_aar_reg_callback,
            (void*) saved_t_data);

    return ret;

error:
    LM_ERR("unexpected error\n");
    if (aar)
        cdpb.AAAFreeMessage(&aar);
    if (auth) {
        cdpb.AAASessionsUnlock(auth->hash);
        cdpb.AAADropAuthSession(auth);
        auth = 0;
    }
    return ret;
}
예제 #2
0
int rx_send_aar(struct sip_msg *req, struct sip_msg *res,
        AAASession* auth, char* direction, saved_transaction_t* saved_t_data) {

    AAAMessage* aar = 0;
    
    str identifier;
    int identifier_type;


    AAA_AVP* avp = 0;
    char x[4];
    int ret = 0;

    str ip;
    uint16_t ip_version;

    //we get ip and identifier for the auth session data 
    rx_authsessiondata_t* p_session_data = 0;
    p_session_data = (rx_authsessiondata_t*) auth->u.auth.generic_data;
    identifier = p_session_data->identifier;
    identifier_type = p_session_data->identifier_type;
    ip = p_session_data->ip;
    ip_version = p_session_data->ip_version;
    
    /* find direction for AAR (orig/term) */
    //need this to add the media component details
    enum dialog_direction dlg_direction = get_dialog_direction(direction);
    if (dlg_direction == DLG_MOBILE_UNKNOWN) {
        LM_DBG("Asked to send AAR for unknown direction.....Aborting...\n");
        goto error;
    }

    aar = cdpb.AAACreateRequest(IMS_Rx, IMS_AAR, Flag_Proxyable, auth);

    LM_DBG("Created aar request...\n");

    if (!aar)
        goto error;

    /*Adding AVPs*/

    LM_DBG("Adding auth app id AVP...\n");
    /* Add Auth-Application-Id AVP */
    if (!rx_add_auth_application_id_avp(aar, IMS_Rx))
        goto error;
    if (!rx_add_vendor_specific_application_id_group(aar, IMS_vendor_id_3GPP,
            IMS_Rx))
        goto error;

    LM_DBG("Adding dest realm if not there already...\n");
    /* Add Destination-Realm AVP, if not already there */
    avp = cdpb.AAAFindMatchingAVP(aar, aar->avpList.head, AVP_Destination_Realm,
            0, AAA_FORWARD_SEARCH);
    if (!avp) {
        str realm = rx_dest_realm;
        if (realm.len && !rx_add_destination_realm_avp(aar, realm))
            goto error;
    }

    LM_DBG("Adding AF App identifier...\n");
    /* Add AF-Application-Identifier AVP */
    str af_id = {0, 0};
    af_id = IMS_Serv_AVP_val;
    if (!rx_add_avp(aar, af_id.s, af_id.len, AVP_IMS_AF_Application_Identifier,
            AAA_AVP_FLAG_MANDATORY, IMS_vendor_id_3GPP, AVP_DUPLICATE_DATA,
            __FUNCTION__))
        goto error;

    LM_DBG("Adding service info status...\n");
    /* Add Service-Info-Status AVP, if prelimiary
     * by default(when absent): final status is considered*/
    if (!res) {
        set_4bytes(x,
                AVP_EPC_Service_Info_Status_Preliminary_Service_Information);
        if (!rx_add_avp(aar, x, 4, AVP_IMS_Service_Info_Status,
                AAA_AVP_FLAG_MANDATORY, IMS_vendor_id_3GPP, AVP_DUPLICATE_DATA,
                __FUNCTION__))
            goto error;
    }

    /* Add Auth lifetime AVP */LM_DBG("auth_lifetime %u\n", rx_auth_expiry); //TODO check why this is 0 all the time
    if (rx_auth_expiry) {
        set_4bytes(x, rx_auth_expiry);
        if (!rx_add_avp(aar, x, 4, AVP_Authorization_Lifetime,
                AAA_AVP_FLAG_MANDATORY, 0, AVP_DUPLICATE_DATA, __FUNCTION__))
            goto error;
    }

    LM_DBG("Adding subscription id...\n");

    rx_add_subscription_id_avp(aar, identifier, identifier_type);


    LM_DBG("Adding reservation priority...\n");
    /* Add Reservation Priority AVP*/
    set_4bytes(x, 0);
    if (!rx_add_avp(aar, x, 4, AVP_ETSI_Reservation_Priority,
            AAA_AVP_FLAG_VENDOR_SPECIFIC, IMS_vendor_id_ETSI,
            AVP_DUPLICATE_DATA, __FUNCTION__))
        goto error;

    LM_DBG("Adding media component...\n");
    //Note we add this AVP first as it gets the IP address which we need to create the auth session
    //Could and maybe should have a separate method that retrieves the IP from SDP - TODO

    /*---------- 2. Create and add Media-Component-Description AVP ----------*/

    /*
     *  See 3GPP TS29214
     *
     *  <Media-Component-Description> = {Media-Component-Number}
     * 								 	[Media-Sub-Component]
     * 								 	[AF-Application-Identifier]
     * 								 	[Media-Type]
     * 								 	[Max-Requested-Bandwidth-UL]
     * 									[Max-Requested-Bandwidth-DL]
     * 									[Flow-Status]
     * 									[Reservation-Priority] (Not used yet)
     * 								 	[RS-Bandwidth]
     * 									[RR-Bandwidth]
     * 									*[Codec-Data]
     */

    add_media_components(aar, req, res, dlg_direction, auth);

    LM_DBG("Adding framed ip address [%.*s]\n", ip.len, ip.s);
    /* Add Framed IP address AVP*/
    if (!rx_add_framed_ip_avp(&aar->avpList, ip, ip_version)) {
        LM_ERR("Unable to add framed IP AVP\n");
        goto error;
    }
    
    /* Add specific action AVP's */
    rx_add_specific_action_avp(aar, 1); // CHARGING_CORRELATION_EXCHANGE
    rx_add_specific_action_avp(aar, 2); // INDICATION_OF_LOSS_OF_BEARER
    rx_add_specific_action_avp(aar, 3); // INDICATION_RECOVERY_OF_BEARER
    rx_add_specific_action_avp(aar, 4); // INDICATION_RELEASE_OF_BEARER
    rx_add_specific_action_avp(aar, 5); // INDICATION_ESTABLISHMENT_OF_BEARER (now void)
    rx_add_specific_action_avp(aar, 6); // IP-CAN_CHANGE
    rx_add_specific_action_avp(aar, 12); // ACCESS_NETWORK_INFO_REPORT

    show_callsessiondata(p_session_data);
    
    LM_DBG("Unlocking AAA session...\n");

    if (auth)
        cdpb.AAASessionsUnlock(auth->hash);

    LM_DBG("sending AAR to PCRF\n");
    if (rx_forced_peer.len)
        ret = cdpb.AAASendMessageToPeer(aar, &rx_forced_peer,
            (void*) async_aar_callback, (void*) saved_t_data);
    else
        ret = cdpb.AAASendMessage(aar, (void*) async_aar_callback,
            (void*) saved_t_data);

    return ret;

error:
    LM_ERR("unexpected error\n");
    if (aar)
        cdpb.AAAFreeMessage(&aar);
    if (auth) {
        cdpb.AAASessionsUnlock(auth->hash);
        cdpb.AAADropAuthSession(auth);
        auth = 0;
    }
    return ret;
}
예제 #3
0
파일: rx_aar.c 프로젝트: halan/kamailio
/**
 * Sends the Authorization Authentication Request for Register messages
 * @param req - SIP Register msg
 * @param rx_auth_data - the returned rx auth data
 * @param ip - ip address extracted from contact to register
 * @param ip_version - AF_INET or AF_INET6
 * @returns int >0 if sent AAR successfully, otherwise 0
 */
int rx_send_aar_register(struct sip_msg *msg, AAASession* auth, str *ip,
        uint16_t *ip_version, str *aor, saved_transaction_local_t* saved_t_data) {
    AAAMessage* aar = 0;
    int ret = 0;
    AAA_AVP* avp = 0;
    char x[4];

    LM_DBG("Send AAR register\n");

    aar = cdpb.AAACreateRequest(IMS_Rx, IMS_AAR, Flag_Proxyable, auth);

    if (!aar)
        goto error;

    /*Add AVPs*/

    /* Add Auth-Application-Id AVP */
    if (!rx_add_auth_application_id_avp(aar, IMS_Rx))
        goto error;
    if (!rx_add_vendor_specific_application_id_group(aar, IMS_vendor_id_3GPP,
            IMS_Rx))
        goto error;

    /* Add Destination-Realm AVP, if not already there */
    avp = cdpb.AAAFindMatchingAVP(aar, aar->avpList.head, AVP_Destination_Realm,
            0, AAA_FORWARD_SEARCH);
    if (!avp) {
        str realm = rx_dest_realm;
        if (realm.len && !rx_add_destination_realm_avp(aar, realm))
            goto error;
    }

    /* Add Subscription ID AVP*/
    str identifier;
    cscf_get_from_uri(msg, &identifier);
    int identifier_type = AVP_Subscription_Id_Type_SIP_URI; //we only do IMPU now
    rx_add_subscription_id_avp(aar, identifier, identifier_type);

    /* Add media component description avp for register*/
    rx_add_media_component_description_avp_register(aar);

    /* Add Framed IP address AVP*/
    if (!rx_add_framed_ip_avp(&aar->avpList, *ip, *ip_version)) {
        LM_ERR("Unable to add framed IP AVP\n");
        goto error;
    }

    /* Add Auth lifetime AVP */LM_DBG("auth_lifetime %u\n", rx_auth_expiry); //TODO check why this is 0 all the time
    if (rx_auth_expiry) {
        set_4bytes(x, rx_auth_expiry);
        if (!rx_add_avp(aar, x, 4, AVP_Authorization_Lifetime,
                AAA_AVP_FLAG_MANDATORY, 0, AVP_DUPLICATE_DATA, __FUNCTION__))
            goto error;
    }

    if (auth)
        cdpb.AAASessionsUnlock(auth->hash);

    LM_DBG("sending AAR to PCRF\n");
    if (rx_forced_peer.len)
        ret = cdpb.AAASendMessageToPeer(aar, &rx_forced_peer,
            (void*) async_cdp_callback, (void*) saved_t_data);
    else
        ret = cdpb.AAASendMessage(aar, (void*) async_cdp_callback,
            (void*) saved_t_data);

    return ret;

error:
    LM_ERR("unexpected error\n");
    if (aar)
        cdpb.AAAFreeMessage(&aar);
    if (auth) {
        cdpb.AAASessionsUnlock(auth->hash);
        cdpb.AAADropAuthSession(auth);
        auth = 0;
    }
    return ret;
}
예제 #4
0
int rx_send_aar_update_no_video(AAASession* auth) {

    AAAMessage* aar = 0;
    
    str identifier;
    int identifier_type;


    AAA_AVP* avp = 0;
    char x[4];
    int ret = 0;

    str recv_ip;
    uint16_t ip_version;

    //we get ip and identifier for the auth session data 
    rx_authsessiondata_t* p_session_data = 0;
    p_session_data = (rx_authsessiondata_t*) auth->u.auth.generic_data;
    identifier = p_session_data->identifier;
    identifier_type = p_session_data->identifier_type;
    recv_ip = p_session_data->ip;
    ip_version = p_session_data->ip_version;
    
    aar = cdpb.AAACreateRequest(IMS_Rx, IMS_AAR, Flag_Proxyable, auth);

    LM_DBG("Sending AAR update to remove a video bearer\n");
    show_callsessiondata(p_session_data);

    if (!aar)
        goto error;

    /*Adding AVPs*/

    LM_DBG("Adding auth app id AVP...\n");
    /* Add Auth-Application-Id AVP */
    if (!rx_add_auth_application_id_avp(aar, IMS_Rx))
        goto error;
    if (!rx_add_vendor_specific_application_id_group(aar, IMS_vendor_id_3GPP,
            IMS_Rx))
        goto error;

    LM_DBG("Adding dest realm if not there already...\n");
    /* Add Destination-Realm AVP, if not already there */
    avp = cdpb.AAAFindMatchingAVP(aar, aar->avpList.head, AVP_Destination_Realm,
            0, AAA_FORWARD_SEARCH);
    if (!avp) {
        str realm = rx_dest_realm;
        if (realm.len && !rx_add_destination_realm_avp(aar, realm))
            goto error;
    }

    LM_DBG("Adding AF App identifier...\n");
    /* Add AF-Application-Identifier AVP */
    str af_id = {0, 0};
    af_id = IMS_Serv_AVP_val;
    if (!rx_add_avp(aar, af_id.s, af_id.len, AVP_IMS_AF_Application_Identifier,
            AAA_AVP_FLAG_MANDATORY, IMS_vendor_id_3GPP, AVP_DUPLICATE_DATA,
            __FUNCTION__))
        goto error;

    LM_DBG("Adding service info status...\n");
    /* Add Service-Info-Status AVP, if prelimiary
     * by default(when absent): final status is considered*/
    
    set_4bytes(x,
	    AVP_EPC_Service_Info_Status_Preliminary_Service_Information);
    if (!rx_add_avp(aar, x, 4, AVP_IMS_Service_Info_Status,
	    AAA_AVP_FLAG_MANDATORY, IMS_vendor_id_3GPP, AVP_DUPLICATE_DATA,
	    __FUNCTION__))
	goto error;

    /* Add Auth lifetime AVP */LM_DBG("auth_lifetime %u\n", rx_auth_expiry); //TODO check why this is 0 all the time
    if (rx_auth_expiry) {
        set_4bytes(x, rx_auth_expiry);
        if (!rx_add_avp(aar, x, 4, AVP_Authorization_Lifetime,
                AAA_AVP_FLAG_MANDATORY, 0, AVP_DUPLICATE_DATA, __FUNCTION__))
            goto error;
    }

    LM_DBG("Adding subscription id...\n");

    rx_add_subscription_id_avp(aar, identifier, identifier_type);


    LM_DBG("Adding reservation priority...\n");
    /* Add Reservation Priority AVP*/
    set_4bytes(x, 0);
    if (!rx_add_avp(aar, x, 4, AVP_ETSI_Reservation_Priority,
            AAA_AVP_FLAG_VENDOR_SPECIFIC, IMS_vendor_id_ETSI,
            AVP_DUPLICATE_DATA, __FUNCTION__))
        goto error;

    LM_DBG("Adding media component...\n");
    //Note we add this AVP first as it gets the IP address which we need to create the auth session
    //Could and maybe should have a separate method that retrieves the IP from SDP - TODO

    /*---------- 2. Create and add Media-Component-Description AVP ----------*/

    /*
     *  See 3GPP TS29214
     *
     *  <Media-Component-Description> = {Media-Component-Number}
     * 								 	[Media-Sub-Component]
     * 								 	[AF-Application-Identifier]
     * 								 	[Media-Type]
     * 								 	[Max-Requested-Bandwidth-UL]
     * 									[Max-Requested-Bandwidth-DL]
     * 									[Flow-Status]
     * 									[Reservation-Priority] (Not used yet)
     * 								 	[RS-Bandwidth]
     * 									[RR-Bandwidth]
     * 									*[Codec-Data]
     */

    add_media_components_using_current_flow_description(aar, p_session_data);

    LM_DBG("Adding framed ip address [%.*s]\n", recv_ip.len, recv_ip.s);
    /* Add Framed IP address AVP*/
    if (!rx_add_framed_ip_avp(&aar->avpList, recv_ip, ip_version)) {
        LM_ERR("Unable to add framed IP AVP\n");
        goto error;
    }
    LM_DBG("Unlocking AAA session...\n");

    if (auth)
        cdpb.AAASessionsUnlock(auth->hash);

    LM_DBG("sending AAR to PCRF\n");
    if (rx_forced_peer.len)
        ret = cdpb.AAASendMessageToPeer(aar, &rx_forced_peer,
            NULL, NULL);
    else
        ret = cdpb.AAASendMessage(aar, NULL,
            NULL);

    return ret;

error:
    LM_ERR("unexpected error\n");
    if (aar)
        cdpb.AAAFreeMessage(&aar);
    if (auth) {
        cdpb.AAASessionsUnlock(auth->hash);
        cdpb.AAADropAuthSession(auth);
        auth = 0;
    }
    return ret;
}
예제 #5
0
파일: rx_aar.c 프로젝트: halan/kamailio
AAAMessage *rx_send_aar(struct sip_msg *req, struct sip_msg *res,
        AAASession* auth, str* callid, str* ftag, str* ttag, char* direction,
        rx_authsessiondata_t **rx_authdata) {
    AAAMessage* aar = 0;
    AAAMessage* aaa = 0;
    AAA_AVP* avp = 0;
    char x[4];

    str ip;
    uint16_t ip_version;

    /* find direction for AAR (orig/term) */
    //need this to add the media component details
    enum dialog_direction dlg_direction = get_dialog_direction(direction);
    if (dlg_direction == DLG_MOBILE_UNKNOWN) {
        LM_DBG("Asked to send AAR for unknown direction.....Aborting...\n");
        goto error;
    }

    aar = cdpb.AAACreateRequest(IMS_Rx, IMS_AAR, Flag_Proxyable, auth);

    LM_DBG("Created aar request...\n");

    if (!aar)
        goto error;

    /*Adding AVPs*/

    LM_DBG("Adding auth app id AVP...\n");
    /* Add Auth-Application-Id AVP */
    if (!rx_add_auth_application_id_avp(aar, IMS_Rx))
        goto error;
    if (!rx_add_vendor_specific_application_id_group(aar, IMS_vendor_id_3GPP,
            IMS_Rx))
        goto error;

    LM_DBG("Adding dest realm if not there already...\n");
    /* Add Destination-Realm AVP, if not already there */
    avp = cdpb.AAAFindMatchingAVP(aar, aar->avpList.head, AVP_Destination_Realm,
            0, AAA_FORWARD_SEARCH);
    if (!avp) {
        str realm = rx_dest_realm;
        if (realm.len && !rx_add_destination_realm_avp(aar, realm))
            goto error;
    }

    LM_DBG("Adding AF App identifier...\n");
    /* Add AF-Application-Identifier AVP */
    str af_id = {0, 0};
    af_id = IMS_Serv_AVP_val;
    if (!rx_add_avp(aar, af_id.s, af_id.len, AVP_IMS_AF_Application_Identifier,
            AAA_AVP_FLAG_MANDATORY, IMS_vendor_id_3GPP, AVP_DUPLICATE_DATA,
            __FUNCTION__))
        goto error;

    LM_DBG("Adding service info status...\n");
    /* Add Service-Info-Status AVP, if prelimiary
     * by default(when absent): final status is considered*/
    if (!res) {
        set_4bytes(x,
                AVP_EPC_Service_Info_Status_Preliminary_Service_Information);
        if (!rx_add_avp(aar, x, 4, AVP_IMS_Service_Info_Status,
                AAA_AVP_FLAG_MANDATORY, IMS_vendor_id_3GPP, AVP_DUPLICATE_DATA,
                __FUNCTION__))
            goto error;
    }

    /* Add Auth lifetime AVP */LM_DBG("auth_lifetime %u\n", rx_auth_expiry); //TODO check why this is 0 all the time
    if (rx_auth_expiry) {
        set_4bytes(x, rx_auth_expiry);
        if (!rx_add_avp(aar, x, 4, AVP_Authorization_Lifetime,
                AAA_AVP_FLAG_MANDATORY, 0, AVP_DUPLICATE_DATA, __FUNCTION__))
            goto error;
    }

    LM_DBG("Adding subscription id...\n");
    /* Add Subscription ID AVP*/
    int identifier_type = AVP_Subscription_Id_Type_SIP_URI; //we only do IMPU now
    //to get the SIP URI I use the dlg direction - if its mo I get the from uri from the req, if its mt I get the to uri from the req
    str identifier;
    if (dlg_direction == DLG_MOBILE_ORIGINATING) {
        cscf_get_from_uri(req, &identifier);
    } else {
        cscf_get_to_uri(req, &identifier);
    }
    rx_add_subscription_id_avp(aar, identifier, identifier_type);

    LM_DBG("Adding reservation priority...\n");
    /* Add Reservation Priority AVP*/
    set_4bytes(x, 0);
    if (!rx_add_avp(aar, x, 4, AVP_ETSI_Reservation_Priority,
            AAA_AVP_FLAG_VENDOR_SPECIFIC, IMS_vendor_id_ETSI,
            AVP_DUPLICATE_DATA, __FUNCTION__))
        goto error;

    LM_DBG("Adding media component...\n");
    //Note we add this AVP first as it gets the IP address which we need to create the auth session
    //Could and maybe should have a separate method that retrieves the IP from SDP - TODO

    /*---------- 2. Create and add Media-Component-Description AVP ----------*/

    /*
     *  See 3GPP TS29214
     *
     *  <Media-Component-Description> = {Media-Component-Number}
     * 								 	[Media-Sub-Component]
     * 								 	[AF-Application-Identifier]
     * 								 	[Media-Type]
     * 								 	[Max-Requested-Bandwidth-UL]
     * 									[Max-Requested-Bandwidth-DL]
     * 									[Flow-Status]
     * 									[Reservation-Priority] (Not used yet)
     * 								 	[RS-Bandwidth]
     * 									[RR-Bandwidth]
     * 									*[Codec-Data]
     */

    add_media_components(aar, req, res, dlg_direction, &ip, &ip_version);

    LM_DBG("Adding framed ip address [%.*s]\n", ip.len, ip.s);
    /* Add Framed IP address AVP*/
    if (!rx_add_framed_ip_avp(&aar->avpList, ip, ip_version)) {
        LM_ERR("Unable to add framed IP AVP\n");
        goto error;
    }
    LM_DBG("Unlocking AAA session...\n");

    if (auth)
        cdpb.AAASessionsUnlock(auth->hash);

    LM_DBG("sending AAR to PCRF\n");
    if (rx_forced_peer.len)
        aaa = cdpb.AAASendRecvMessageToPeer(aar, &rx_forced_peer);
    else
        aaa = cdpb.AAASendRecvMessage(aar);

    return aaa;

error:
    LM_ERR("unexpected error\n");
    if (aar)
        cdpb.AAAFreeMessage(&aar);
    if (auth) {
        cdpb.AAASessionsUnlock(auth->hash);
        cdpb.AAADropAuthSession(auth);
        auth = 0;
    }
    return NULL;
}