/** * Send a Capabilities Exchange Answer. * 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 * @param result_code - the Result-Code to send * @param sock - socket to send through */ void Snd_CEA(peer *p,AAAMessage *cer,int result_code,int sock) { AAAMessage *cea; unsigned int ip; struct sockaddr_in addr; socklen_t addrlen; char x[6]; cea = AAANewMessage(Code_CE,0,0,cer); if (!cea) goto done; addrlen = sizeof(struct sockaddr_in); if (getsockname(sock,(struct sockaddr*) &addr, &addrlen) == -1) { LOG(L_ERR,"ERROR:Snd_CEA(): Error on finding local host address > %s\n",strerror(errno)); }else{ set_2bytes(x,1); ip = htonl(addr.sin_addr.s_addr); set_4bytes(x+2,ip); AAACreateAndAddAVPToMessage(cea,AVP_Host_IP_Address,AAA_AVP_FLAG_MANDATORY,0,x,6); } set_4bytes(x,config->vendor_id); AAACreateAndAddAVPToMessage(cea,AVP_Vendor_Id,AAA_AVP_FLAG_MANDATORY,0,x,4); AAACreateAndAddAVPToMessage(cea,AVP_Product_Name,AAA_AVP_FLAG_MANDATORY,0,config->product_name.s,config->product_name.len); set_4bytes(x,result_code); AAACreateAndAddAVPToMessage(cea,AVP_Result_Code,AAA_AVP_FLAG_MANDATORY,0,x,4); Snd_CE_add_applications(cea,p); peer_send(p,sock,cea,1); done: AAAFreeMessage(&cer); }
/** * Send a Capability Exchange Request. * \note Must be called with a lock on the peer. * @param p - the peer to send to */ void I_Snd_CER(peer *p) { AAAMessage *cer=0; // AAA_AVP *avp; unsigned long ip; struct sockaddr_in addr; socklen_t addrlen; char x[6]; cer = AAANewMessage(Code_CE,0,0,0); if (!cer) return; cer->hopbyhopId = next_hopbyhop(); cer->endtoendId = next_endtoend(); addrlen = sizeof(struct sockaddr_in); if (getsockname(p->I_sock,(struct sockaddr*) &addr, &addrlen) == -1) { LOG(L_ERR,"ERROR:I_Snd_CER(): Error on finding local host address > %s\n",strerror(errno)); }else{ set_2bytes(x,1); ip = htonl(addr.sin_addr.s_addr); set_4bytes(x+2,ip); AAACreateAndAddAVPToMessage(cer,AVP_Host_IP_Address,AAA_AVP_FLAG_MANDATORY,0,x,6); } set_4bytes(x,config->vendor_id); AAACreateAndAddAVPToMessage(cer,AVP_Vendor_Id,AAA_AVP_FLAG_MANDATORY,0,x,4); AAACreateAndAddAVPToMessage(cer,AVP_Product_Name,AAA_AVP_FLAG_MANDATORY,0,config->product_name.s,config->product_name.len); Snd_CE_add_applications(cer,p); // peer_send(p,p->I_sock,cer,1); peer_send_msg(p,cer); }
/** * Send a Capabilities Exchange Answer. * 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 * @param result_code - the Result-Code to send * @param sock - socket to send through */ void Snd_CEA(peer *p,AAAMessage *cer,int result_code,int sock) { AAAMessage *cea; unsigned int ip; union { struct sockaddr addr; struct sockaddr_in in; struct sockaddr_in6 in6; } addr_u ; socklen_t addrlen; char x[18]; cea = AAANewMessage(Code_CE,0,0,cer); if (!cea) goto done; addrlen = sizeof(addr_u); if (getsockname(sock, &(addr_u.addr), &addrlen) == -1) { LM_ERR("Snd_CEA(): Error on finding local host address > %s\n",strerror(errno)); }else{ switch(addr_u.addr.sa_family){ case AF_INET: set_2bytes(x,1); ip = htonl(addr_u.in.sin_addr.s_addr); set_4bytes(x+2,ip); AAACreateAndAddAVPToMessage(cea,AVP_Host_IP_Address,AAA_AVP_FLAG_MANDATORY,0,x,6); break; case AF_INET6: set_2bytes(x,2); memcpy(x+2,addr_u.in6.sin6_addr.s6_addr,16); AAACreateAndAddAVPToMessage(cea,AVP_Host_IP_Address,AAA_AVP_FLAG_MANDATORY,0,x,18); break; default: LM_ERR("Snd_CEA(): unknown address type with family %d\n",addr_u.addr.sa_family); } } set_4bytes(x,config->vendor_id); AAACreateAndAddAVPToMessage(cea,AVP_Vendor_Id,AAA_AVP_FLAG_MANDATORY,0,x,4); AAACreateAndAddAVPToMessage(cea,AVP_Product_Name,AAA_AVP_FLAG_MANDATORY,0,config->product_name.s,config->product_name.len); set_4bytes(x,result_code); AAACreateAndAddAVPToMessage(cea,AVP_Result_Code,AAA_AVP_FLAG_MANDATORY,0,x,4); Snd_CE_add_applications(cea,p); peer_send(p,sock,cea,1); done: AAAFreeMessage(&cer); }
/** * Send a Capability Exchange Request. * \note Must be called with a lock on the peer. * @param p - the peer to send to */ void I_Snd_CER(peer *p) { AAAMessage *cer=0; // AAA_AVP *avp; unsigned long ip; union { struct sockaddr addr; struct sockaddr_in in; struct sockaddr_in6 in6; } addr_u ; socklen_t addrlen; char x[18]; cer = AAANewMessage(Code_CE,0,0,0); if (!cer) return; cer->hopbyhopId = next_hopbyhop(); cer->endtoendId = next_endtoend(); addrlen = sizeof(addr_u); if (getsockname(p->I_sock,&(addr_u.addr), &addrlen) == -1) { LM_ERR("I_Snd_CER(): Error on finding local host address > %s\n",strerror(errno)); }else{ switch(addr_u.addr.sa_family){ case AF_INET: set_2bytes(x,1); ip = htonl(addr_u.in.sin_addr.s_addr); set_4bytes(x+2,ip); AAACreateAndAddAVPToMessage(cer,AVP_Host_IP_Address,AAA_AVP_FLAG_MANDATORY,0,x,6); break; case AF_INET6: set_2bytes(x,2); memcpy(x+2,addr_u.in6.sin6_addr.s6_addr,16); AAACreateAndAddAVPToMessage(cer,AVP_Host_IP_Address,AAA_AVP_FLAG_MANDATORY,0,x,18); break; default: LM_ERR("I_Snd_CER(): unknown address type with family %d\n",addr_u.addr.sa_family); } } set_4bytes(x,config->vendor_id); AAACreateAndAddAVPToMessage(cer,AVP_Vendor_Id,AAA_AVP_FLAG_MANDATORY,0,x,4); AAACreateAndAddAVPToMessage(cer,AVP_Product_Name,AAA_AVP_FLAG_MANDATORY,0,config->product_name.s,config->product_name.len); Snd_CE_add_applications(cer,p); // peer_send(p,p->I_sock,cer,1); peer_send_msg(p,cer); }
void Send_ASA(cdp_session_t* s, AAAMessage* msg) { AAAMessage *asa; char x[4]; AAA_AVP *avp; LOG(L_INFO,"Send_ASA(): sending ASA\n"); if (!s) { //send an ASA for UNKNOWN_SESSION_ID - use AAASendMessage() // msg is the ASR received asa = AAANewMessage(IMS_ASA,0,0,msg); if (!asa) return; set_4bytes(x,AAA_SUCCESS); AAACreateAndAddAVPToMessage(asa,AVP_Result_Code,AAA_AVP_FLAG_MANDATORY,0,x,4); AAASendMessage(asa,0,0); }else{ // send... many cases... maybe not needed. // for now we do the same asa = AAANewMessage(IMS_ASA,0,0,msg); if (!asa) return; set_4bytes(x,AAA_SUCCESS); AAACreateAndAddAVPToMessage(asa,AVP_Result_Code,AAA_AVP_FLAG_MANDATORY,0,x,4); avp = AAAFindMatchingAVP(msg,0,AVP_Origin_Host,0,0); if (avp) { // This is because AAASendMessage is not going to find a route to the // the PCRF because TS 29.214 says no Destination-Host and no Auth-Application-Id // in the ASA LOG(L_INFO,"sending ASA to peer %.*s\n",avp->data.len,avp->data.s); peer *p; p = get_peer_by_fqdn(&avp->data); if (!peer_send_msg(p,asa)) { if (asa) AAAFreeMessage(&asa); //needed in frequency } else LOG(L_INFO,"success sending ASA\n"); }else if (!AAASendMessage(asa,0,0)) { LOG(L_ERR,"Send_ASA() : error sending ASA\n"); } } }
/** * Adds the Applications to a Capability Exchange message. * \note Must be called with a lock on the peer. * @param msg - the message to add to (request/answer) * @param p - the peer to add applications from */ static inline void Snd_CE_add_applications(AAAMessage *msg,peer *p) { int i; app_config *app; char x[4]; AAA_AVP *avp1,*avp2; AAA_AVP_LIST list; str group; list.head=0;list.tail=0; for(i=0;i<config->applications_cnt;i++){ app = config->applications+i; if (app->vendor==0){ set_4bytes(x,app->id); AAACreateAndAddAVPToMessage(msg, (app->type==DP_AUTHORIZATION?AVP_Auth_Application_Id:AVP_Acct_Application_Id), AAA_AVP_FLAG_MANDATORY,0,x,4); }else{ set_4bytes(x,app->vendor); avp1 = AAACreateAVP(AVP_Vendor_Id,AAA_AVP_FLAG_MANDATORY,0,x,4, AVP_DUPLICATE_DATA); AAAAddAVPToList(&list,avp1); set_4bytes(x,app->id); avp2 = AAACreateAVP((app->type==DP_AUTHORIZATION?AVP_Auth_Application_Id:AVP_Acct_Application_Id), AAA_AVP_FLAG_MANDATORY,0,x,4,AVP_DUPLICATE_DATA); AAAAddAVPToList(&list,avp2); group = AAAGroupAVPS(list); AAAFreeAVPList(&list); AAACreateAndAddAVPToMessage(msg, AVP_Vendor_Specific_Application_Id, AAA_AVP_FLAG_MANDATORY,0,group.s,group.len); shm_free(group.s); } } for(i=0;i<config->supported_vendors_cnt;i++){ set_4bytes(x,config->supported_vendors[i]); AAACreateAndAddAVPToMessage(msg,AVP_Supported_Vendor_Id,AAA_AVP_FLAG_MANDATORY,0,x,4); } }
/** * Sends a Diameter Watch-dog Answer. * \note Must be called with a lock on the peer. * @param p - the peer that the DWR was received from * @param dwr - the DWR message * @param result_code - the Result-Code to attach to DWA * @param sock - socket to send on */ void Snd_DWA(peer *p,AAAMessage *dwr,int result_code,int sock) { AAAMessage *dwa; char x[4]; dwa = AAANewMessage(Code_DW,0,0,dwr); if (!dwa) goto done; set_4bytes(x,result_code); AAACreateAndAddAVPToMessage(dwa,AVP_Result_Code,AAA_AVP_FLAG_MANDATORY,0,x,4); peer_send_msg(p,dwa); done: AAAFreeMessage(&dwr); }
/** * Sends a Disconnect Peer Request. * \note Must be called with a lock on the peer. * @param p - the peer to send to */ void Snd_DPR(peer *p) { AAAMessage *dpr=0; char x[4]; dpr = AAANewMessage(Code_DP,0,0,0); if (!dpr) return; dpr->hopbyhopId = next_hopbyhop(); dpr->endtoendId = next_endtoend(); set_4bytes(x,0/*busy*/); AAACreateAndAddAVPToMessage(dpr,AVP_Disconnect_Cause,AAA_AVP_FLAG_MANDATORY,0,x,4); if (p->state==I_Open) peer_send_msg(p,dpr); else peer_send_msg(p,dpr); }