Exemple #1
0
/**
 * Get the first connect peer that matches the routing mechanisms.
 * - First the Destination-Host AVP value is tried if connected (the peer does not have to
 * be in the routing table at all).
 * - Then we look for a connected peer in the specific realm for the Destination-Realm AVP
 * - Then we look for the first connected peer in the default routes
 * @param m - the Diameter message to find the destination peer for
 * @returns - the connected peer or null if none connected found
 */
peer* get_routing_peer(cdp_session_t* cdp_session, AAAMessage *m) {
    str destination_realm = {0, 0}, destination_host = {0, 0};
    AAA_AVP *avp, *avp_vendor, *avp2;
    AAA_AVP_LIST group;
    peer *p;
    routing_realm *rr;
    int app_id = 0, vendor_id = 0;

    LM_DBG("getting diameter routing peer for realm: [%.*s]\n", m->dest_realm->data.len, m->dest_realm->data.s);

    app_id = m->applicationId;
    avp = AAAFindMatchingAVP(m, 0, AVP_Vendor_Specific_Application_Id, 0, AAA_FORWARD_SEARCH);
    if (avp) {
        group = AAAUngroupAVPS(avp->data);
        avp_vendor = AAAFindMatchingAVPList(group, group.head, AVP_Vendor_Id, 0, 0);
        avp2 = AAAFindMatchingAVPList(group, group.head, AVP_Auth_Application_Id, 0, 0);
        if (avp_vendor && avp2) {
            vendor_id = get_4bytes(avp_vendor->data.s);
            app_id = get_4bytes(avp2->data.s);
        }
        avp2 = AAAFindMatchingAVPList(group, group.head, AVP_Acct_Application_Id, 0, 0);
        if (avp_vendor && avp2) {
            vendor_id = get_4bytes(avp_vendor->data.s);
            app_id = get_4bytes(avp2->data.s);
        }
        AAAFreeAVPList(&group);
    }

    avp_vendor = AAAFindMatchingAVP(m, 0, AVP_Vendor_Id, 0, AAA_FORWARD_SEARCH);
    avp = AAAFindMatchingAVP(m, 0, AVP_Auth_Application_Id, 0, AAA_FORWARD_SEARCH);
    if (avp) {
        if (avp_vendor) vendor_id = get_4bytes(avp_vendor->data.s);
        else vendor_id = 0;
        app_id = get_4bytes(avp->data.s);
    }

    avp = AAAFindMatchingAVP(m, 0, AVP_Acct_Application_Id, 0, AAA_FORWARD_SEARCH);
    if (avp) {
        if (avp_vendor) vendor_id = get_4bytes(avp_vendor->data.s);
        else vendor_id = 0;
        app_id = get_4bytes(avp->data.s);
    }

    avp = AAAFindMatchingAVP(m, 0, AVP_Destination_Host, 0, AAA_FORWARD_SEARCH);
    if (avp) destination_host = avp->data;

    if (destination_host.len) {
        /* There is a destination host present in the message try and route directly there */
        p = get_peer_by_fqdn(&destination_host);
        if (p && (p->state == I_Open || p->state == R_Open) && peer_handles_application(p, app_id, vendor_id)) {
            p->last_selected = time(NULL);
            return p;
        }
        /* the destination host peer is not connected at the moment, try a normal route then */
    }

    avp = AAAFindMatchingAVP(m, 0, AVP_Destination_Realm, 0, AAA_FORWARD_SEARCH);
    if (avp) destination_realm = avp->data;

    if (!config->r_table) {
        LM_ERR("get_routing_peer(): Empty routing table.\n");
        return 0;
    }

    if (destination_realm.len) {
        /* first search for the destination realm */
        for (rr = config->r_table->realms; rr; rr = rr->next)
            if (rr->realm.len == destination_realm.len &&
                    strncasecmp(rr->realm.s, destination_realm.s, destination_realm.len) == 0)
                break;
        if (rr) {
            p = get_first_connected_route(cdp_session, rr->routes, app_id, vendor_id);
            if (p) return p;
            else LM_ERR("get_routing_peer(): No connected Route peer found for Realm <%.*s>. Trying DefaultRoutes next...\n",
                    destination_realm.len, destination_realm.s);
        }
    }
    /* if not found in the realms or no destination_realm, 
     * get the first connected host in default routes */
    LM_DBG("no routing peer found, trying default route\n");
    p = get_first_connected_route(cdp_session, config->r_table->routes, app_id, vendor_id);
    if (!p) {
        LM_ERR("get_routing_peer(): No connected DefaultRoute peer found for app_id %d and vendor id %d.\n",
                app_id, vendor_id);
    }
    return p;
}
Exemple #2
0
void save_peer_applications(peer *p,AAAMessage *msg)
{
	int total_cnt=0;
	int supported_vendor_id_avp_cnt = 0;
	AAA_AVP *avp,*avp_vendor,*avp2;
	AAA_AVP_LIST group;
	int id,vendor;

	if (p->applications) {
		shm_free(p->applications);
		p->applications = 0;
		p->applications_cnt = 0;
	}

	supported_vendor_id_avp_cnt = count_Supported_Vendor_Id_AVPS(msg);

	for(avp=msg->avpList.head;avp;avp = avp->next)

		switch (avp->code){
			case AVP_Auth_Application_Id:
				total_cnt += supported_vendor_id_avp_cnt;
				break;
			case AVP_Acct_Application_Id:
				total_cnt += supported_vendor_id_avp_cnt;
				break;
			case AVP_Vendor_Specific_Application_Id:
				total_cnt+=2;/* wasteful, but let's skip decoding */
				break;
		}
	p->applications_cnt = 0;
	p->applications = shm_malloc(sizeof(app_config)*total_cnt);
	if (!p->applications){
		LM_ERR("save_peer_applications(): Error allocating %ld bytes! No applications saved...\n",
				(long int)(sizeof(app_config)*total_cnt));
		return;
	}
	for(avp=msg->avpList.head;avp;avp = avp->next)
	{

		switch (avp->code){
			case AVP_Auth_Application_Id:
				id = get_4bytes(avp->data.s);
				add_peer_application(p,id,0,DP_AUTHORIZATION);
				avp_vendor = AAAFindMatchingAVP(msg,0,AVP_Supported_Vendor_Id,0,0);
				while (avp_vendor) {

					vendor = get_4bytes(avp_vendor->data.s);
					LM_DBG("Found Supported Vendor for Application %i: %i\n", DP_AUTHORIZATION, vendor);
					add_peer_application(p,id,vendor,DP_AUTHORIZATION);
					if (!avp_vendor->next)
						break;
					avp_vendor = AAAFindMatchingAVP(msg,avp_vendor->next,AVP_Supported_Vendor_Id,0,AAA_FORWARD_SEARCH);
				}
				break;
			case AVP_Acct_Application_Id:
				id = get_4bytes(avp->data.s);
				add_peer_application(p,id,0,DP_ACCOUNTING);
				avp_vendor = AAAFindMatchingAVP(msg,0,AVP_Supported_Vendor_Id,0,0);
				while (avp_vendor) {
					vendor = get_4bytes(avp_vendor->data.s);
					LM_DBG("Found Supported Vendor for Application %i: %i\n", DP_ACCOUNTING, vendor);
					add_peer_application(p,id,vendor,DP_ACCOUNTING);
					if (!avp_vendor->next)
						break;
					avp_vendor = AAAFindMatchingAVP(msg,avp_vendor->next,AVP_Supported_Vendor_Id,0,AAA_FORWARD_SEARCH);
				}
				break;
			case AVP_Vendor_Specific_Application_Id:
				group = AAAUngroupAVPS(avp->data);
				avp_vendor = AAAFindMatchingAVPList(group,group.head,AVP_Vendor_Id,0,0);
				avp2 = AAAFindMatchingAVPList(group,group.head,AVP_Auth_Application_Id,0,AAA_FORWARD_SEARCH);
				if (avp_vendor&&avp2){
					vendor = get_4bytes(avp_vendor->data.s);
					id = get_4bytes(avp2->data.s);
					add_peer_application(p,id,vendor,DP_AUTHORIZATION);
				}
				avp2 = AAAFindMatchingAVPList(group,group.head,AVP_Acct_Application_Id,0,AAA_FORWARD_SEARCH);
				if (avp_vendor&&avp2){
					vendor = get_4bytes(avp_vendor->data.s);
					id = get_4bytes(avp2->data.s);
					add_peer_application(p,id,vendor,DP_ACCOUNTING);
				}
				AAAFreeAVPList(&group);
				break;

		}
	}
}