示例#1
0
/**
 * update Granted Service Unit timers based on CCA, for onw we assume on one MSCC per session and only TIME based supported
 */
inline void update_gsu_response_timers(cdp_cc_acc_session_t* session, AAAMessage* msg) {
	AAA_AVP *avp;
	AAA_AVP_LIST mscc_avp_list;
	AAA_AVP_LIST y;
	AAA_AVP *z;

	avp = AAAFindMatchingAVP(msg, 0, AVP_Multiple_Services_Credit_Control, 0, 0);
        if (!avp) {
            LM_WARN("Trying to update GSU timers but there is no MSCC AVP in the CCA response\n");
            return;
        }
	mscc_avp_list = AAAUngroupAVPS(avp->data);
	AAA_AVP *mscc_avp = mscc_avp_list.head;

	while (mscc_avp != NULL ) {
		LM_DBG("MSCC AVP code is [%i] and data length is [%i]", mscc_avp->code, mscc_avp->data.len);
		switch (mscc_avp->code) {
			case AVP_Granted_Service_Unit:
				y = AAAUngroupAVPS(mscc_avp->data);
				z = y.head;
				while (z) {
					switch (z->code) {
					case AVP_CC_Time:
						session->reserved_units = get_4bytes(z->data.s);
						break;
					default:
						LM_DBG("ignoring AVP in GSU group with code:[%d]\n", z->code);
					}
					z = z->next;
				}
				break;
			case AVP_Validity_Time:
				session->reserved_units_validity_time = get_4bytes(mscc_avp->data.s);
				break;
			case AVP_Final_Unit_Indication:
				y = AAAUngroupAVPS(mscc_avp->data);
				z = y.head;
				while (z) {
					switch (z->code) {
						case AVP_Final_Unit_Action:
							session->fua = get_4bytes(z->data.s);
							break;
						default:
							LM_DBG("ignoring AVP in FUI group with code:[%d]\n", z->code);
					}
					z = z->next;
				}
				break;
		}
		mscc_avp = mscc_avp->next;
	}

	AAAFreeAVPList(&mscc_avp_list);
	AAAFreeAVPList(&y);
}
示例#2
0
void save_peer_applications(peer *p,AAAMessage *msg)
{
	int total_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;
	}
	for(avp=msg->avpList.head;avp;avp = avp->next)
		switch (avp->code){
			case AVP_Auth_Application_Id:
			case AVP_Acct_Application_Id:
			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);	
				break;
			case AVP_Acct_Application_Id:
				id = get_4bytes(avp->data.s);	
				add_peer_application(p,id,0,DP_ACCOUNTING);	
				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,0);				
				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,0);				
				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;
				
		}
	}	
}
示例#3
0
/**
 * Process a Capabilities Exchange Request.
 * Checks whether there are common applications.
 * \note Must be called with a lock on the peer.
 * @param p - peer identification
 * @param cer - the CER message
 * @returns the Result-Code of the operation, AAA_SUCCESS or AAA_NO_COMMON_APPLICATION
 */
int Process_CER(peer *p,AAAMessage *cer)
{
	int common_app=0;
	AAA_AVP *avp,*avp_vendor,*avp2;
	AAA_AVP_LIST group;
	int i,id,vendor;
	for(avp=cer->avpList.head;avp;avp = avp->next)
	{
		switch (avp->code){
			case AVP_Auth_Application_Id:
				id = get_4bytes(avp->data.s);	
				for(i=0;i<config->applications_cnt;i++)
					if (id == config->applications[i].id &&
						config->applications[i].vendor==0 &&
						config->applications[i].type==DP_AUTHORIZATION) common_app++;	
				break;
			case AVP_Acct_Application_Id:
				id = get_4bytes(avp->data.s);	
				for(i=0;i<config->applications_cnt;i++)
					if (id == config->applications[i].id &&
						config->applications[i].vendor==0 &&
						config->applications[i].type==DP_ACCOUNTING) common_app++;	
				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,0);				
				if (avp_vendor&&avp2){
					vendor = get_4bytes(avp_vendor->data.s);
					id = get_4bytes(avp2->data.s);
					for(i=0;i<config->applications_cnt;i++)
						if (id == config->applications[i].id &&
							config->applications[i].vendor==vendor &&
							config->applications[i].type==DP_AUTHORIZATION) common_app++;	
					
				}
				avp2 = AAAFindMatchingAVPList(group,group.head,AVP_Acct_Application_Id,0,0);				
				if (avp_vendor&&avp2){
					vendor = get_4bytes(avp_vendor->data.s);
					id = get_4bytes(avp2->data.s);
					for(i=0;i<config->applications_cnt;i++)
						if (id == config->applications[i].id &&
							config->applications[i].vendor==vendor &&
							config->applications[i].type==DP_ACCOUNTING) common_app++;	
					
				}
				AAAFreeAVPList(&group);
				break;
				
		}
	}
	
	if (common_app!=0){
		save_peer_applications(p,cer);
		return AAA_SUCCESS;
	}else 
		return AAA_NO_COMMON_APPLICATION;	
}
int get_result_code(AAAMessage* msg)
{
	AAA_AVP *avp;
	AAA_AVP_LIST list;
	list.head=0;
	list.tail=0;
	int rc=-1;
	
        if (!msg) goto error;
        
        for (avp=msg->avpList.tail;avp;avp=avp->prev)
		{
		
			if (avp->code==AVP_Result_Code)
			{
				rc = get_4bytes(avp->data.s);	
				goto finish;
			} else if (avp->code==AVP_Experimental_Result)
			{
				list=AAAUngroupAVPS(avp->data);
				for(avp=list.head;avp;avp=avp->next)
				{
					if (avp->code==AVP_IMS_Experimental_Result_Code)
						{
							rc = get_4bytes(avp->data.s);
							AAAFreeAVPList(&list);
							goto finish;
						}
			 	}
				AAAFreeAVPList(&list);			 					
			}
		}
finish:
		return rc;
error:
        LOG(L_ERR, "ERR:get_result_code(): no AAAMessage or Result Code not found\n");
        return -1;
}
示例#5
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 && avp_vendor) {
		vendor_id = get_4bytes(avp_vendor->data.s);
		app_id = get_4bytes(avp->data.s);
	}

	avp = AAAFindMatchingAVP(m, 0, AVP_Acct_Application_Id, 0, AAA_FORWARD_SEARCH);
	if (avp && avp_vendor) {
		vendor_id = get_4bytes(avp_vendor->data.s);
		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;
}