void Send_ASR(cdp_session_t* s, AAAMessage* msg) { AAAMessage *asr = 0; AAA_AVP *avp = 0; peer *p = 0; char x[4]; LM_DBG("Send_ASR() : sending ASR\n"); asr = AAACreateRequest(s->application_id, IMS_ASR, Flag_Proxyable, s); if (!asr) { LM_ERR("Send_ASR(): error creating ASR!\n"); return; } set_4bytes(x, s->application_id); avp = AAACreateAVP(AVP_Auth_Application_Id, AAA_AVP_FLAG_MANDATORY, 0, x, 4, AVP_DUPLICATE_DATA); AAAAddAVPToMessage(asr, avp, asr->avpList.tail); set_4bytes(x, 3); // Not specified avp = AAACreateAVP(AVP_IMS_Abort_Cause, AAA_AVP_FLAG_MANDATORY, 0, x, 4, AVP_DUPLICATE_DATA); AAAAddAVPToMessage(asr, avp, asr->avpList.tail); //todo - add all the other avps p = get_routing_peer(s, asr); if (!p) { LM_ERR("unable to get routing peer in Send_ASR \n"); if (asr) AAAFreeMessage(&asr); //needed in frequency } if (!peer_send_msg(p, asr)) { if (asr) AAAFreeMessage(&asr); //needed in frequency } else LM_DBG("success sending ASR\n"); }
/** * 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); }
/** * Sends a Disconnect Peer Answer. * \note Must be called with a lock on the peer. * @param p - the peer to send to * @param dpr - the DPR message * @param result_code - the Result-Code to attach to DPA * @param sock - socket to send on */ void Snd_DPA(peer *p,AAAMessage *dpr,int result_code,int sock) { AAAMessage *dpa; dpa = AAANewMessage(Code_DP,0,0,dpr); if (dpa) peer_send_msg(p,dpa); AAAFreeMessage(&dpr); }
/** * 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); }
void Send_STR(cdp_session_t* s, AAAMessage* msg) { AAAMessage *str=0; AAA_AVP *avp=0; peer *p=0; char x[4]; LOG(L_DBG, "sending STR\n"); //if (msg) LOG(L_DBG,"Send_STR() : sending STR for %d, flags %#1x endtoend %u hopbyhop %u\n",msg->commandCode,msg->flags,msg->endtoendId,msg->hopbyhopId); //else LOG(L_DBG,"Send_STR() called from AAATerminateAuthSession or some other event\n"); str = AAACreateRequest(s->application_id,IMS_STR,Flag_Proxyable,s); if (!str) { LOG(L_ERR,"ERR:Send_STR(): error creating STR!\n"); return; } if(!dup_routing_avps(msg, str)){ LOG(L_ERR,"ERR:Send_STR(): error duplicating routing AVPs!\n"); AAAFreeMessage(&str); return; } if(s->vendor_id!=0 && !add_vendor_specific_application_id_group(str,s->vendor_id,s->application_id)){ LOG(L_ERR,"ERR:Send_STR(): error adding Vendor-Id-Specific-Application-Id Group!\n"); AAAFreeMessage(&str); return; } set_4bytes(x,s->application_id); avp = AAACreateAVP(AVP_Auth_Application_Id,AAA_AVP_FLAG_MANDATORY,0,x,4,AVP_DUPLICATE_DATA); AAAAddAVPToMessage(str,avp,str->avpList.tail); set_4bytes(x,4); // Diameter_administrative avp = AAACreateAVP(AVP_Termination_Cause,AAA_AVP_FLAG_MANDATORY,0,x,4,AVP_DUPLICATE_DATA); AAAAddAVPToMessage(str,avp,str->avpList.tail); //todo - add all the other avps p = get_routing_peer(str); if (!p) { LOG(L_ERR,"unable to get routing peer in Send_STR \n"); if (str) AAAFreeMessage(&str); //needed in frequency return; } //if (str) LOG(L_CRIT,"Send_STR() : sending STR %d, flags %#1x endtoend %u hopbyhop %u\n",str->commandCode,str->flags,str->endtoendId,str->hopbyhopId); if (!peer_send_msg(p,str)) { LOG(L_DBG,"Send_STR peer_send_msg return error!\n"); if (str) AAAFreeMessage(&str); //needed in frequency } else { LOG(L_DBG,"success sending STR\n"); } }
/** * 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); }
/** * 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"); } } }
void Send_STR(cdp_session_t* s, AAAMessage* msg) { AAAMessage *str = 0; AAA_AVP *avp = 0; peer *p = 0; char x[4]; LM_DBG("sending STR\n"); //if (msg) LM_DBG("Send_STR() : sending STR for %d, flags %#1x endtoend %u hopbyhop %u\n",msg->commandCode,msg->flags,msg->endtoendId,msg->hopbyhopId); //else LM_DBG("Send_STR() called from AAATerminateAuthSession or some other event\n"); str = AAACreateRequest(s->application_id, IMS_STR, Flag_Proxyable, s); if (!str) { LM_ERR("Send_STR(): error creating STR!\n"); return; } if (!dup_routing_avps(msg, str)) { LM_ERR("Send_STR(): error duplicating routing AVPs!\n"); AAAFreeMessage(&str); return; } if (s->vendor_id != 0 && !add_vendor_specific_application_id_group(str, s->vendor_id, s->application_id)) { LM_ERR("Send_STR(): error adding Vendor-Id-Specific-Application-Id Group!\n"); AAAFreeMessage(&str); return; } //Richard added this - if timers expire dest realm is not here! LM_DBG("Adding dest realm if not there already...\n"); LM_DBG("Destination realm: [%.*s] \n", s->dest_realm.len, s->dest_realm.s); /* Add Destination-Realm AVP, if not already there */ avp = AAAFindMatchingAVP(str, str->avpList.head, AVP_Destination_Realm, 0, AAA_FORWARD_SEARCH); if (!avp) { avp = AAACreateAVP(AVP_Destination_Realm, AAA_AVP_FLAG_MANDATORY, 0, s->dest_realm.s, s->dest_realm.len, AVP_DUPLICATE_DATA); AAAAddAVPToMessage(str, avp, str->avpList.tail); } set_4bytes(x, s->application_id); avp = AAACreateAVP(AVP_Auth_Application_Id, AAA_AVP_FLAG_MANDATORY, 0, x, 4, AVP_DUPLICATE_DATA); AAAAddAVPToMessage(str, avp, str->avpList.tail); set_4bytes(x, 4); // Diameter_administrative avp = AAACreateAVP(AVP_Termination_Cause, AAA_AVP_FLAG_MANDATORY, 0, x, 4, AVP_DUPLICATE_DATA); AAAAddAVPToMessage(str, avp, str->avpList.tail); //todo - add all the other avps /* we are already locked on the auth session*/ p = get_routing_peer(s, str); if (!p) { LM_ERR("unable to get routing peer in Send_STR \n"); if (str) AAAFreeMessage(&str); //needed in frequency return; } //if (str) LM_CRIT("Send_STR() : sending STR %d, flags %#1x endtoend %u hopbyhop %u\n",str->commandCode,str->flags,str->endtoendId,str->hopbyhopId); if (!peer_send_msg(p, str)) { LM_DBG("Send_STR peer_send_msg return error!\n"); if (str) AAAFreeMessage(&str); //needed in frequency } else { LM_DBG("success sending STR\n"); } }
/** * Sends a message to the peer. * \note Must be called with a lock on the peer. * @param p - peer to send to * @param msg - message to send */ void Snd_Message(peer *p, AAAMessage *msg) { AAASession *session=0; int rcode; int send_message_before_session_sm=0; LM_DBG("Snd_Message called to peer [%.*s] for %s with code %d \n", p->fqdn.len,p->fqdn.s,is_req(msg)?"request":"response",msg->commandCode); touch_peer(p); if (msg->sessionId) session = cdp_get_session(msg->sessionId->data); if (session){ LM_DBG("There is a session of type %d\n",session->type); switch (session->type){ case AUTH_CLIENT_STATEFULL: if (is_req(msg)) { auth_client_statefull_sm_process(session,AUTH_EV_SEND_REQ,msg); session = 0; } else { if (msg->commandCode == IMS_ASA){ if (!msg->res_code){ msg->res_code = AAAFindMatchingAVP(msg,0,AVP_Result_Code,0,0); } if (!msg->res_code) { auth_client_statefull_sm_process(session,AUTH_EV_SEND_ASA_UNSUCCESS,msg); session = 0; } else { rcode = get_4bytes(msg->res_code->data.s); if (rcode>=2000 && rcode<3000) { peer_send_msg(p,msg); send_message_before_session_sm=1; auth_client_statefull_sm_process(session,AUTH_EV_SEND_ASA_SUCCESS,msg); session = 0; } else { auth_client_statefull_sm_process(session,AUTH_EV_SEND_ASA_UNSUCCESS,msg); session = 0; } } }else { auth_client_statefull_sm_process(session,AUTH_EV_SEND_ANS,msg); session = 0; } } break; case AUTH_SERVER_STATEFULL: LM_DBG("this message is matched here to see what request or reply it is\n"); if (is_req(msg)) { if (msg->commandCode== IMS_ASR) { LM_DBG("ASR\n"); auth_server_statefull_sm_process(session,AUTH_EV_SEND_ASR,msg); session = 0; } else { //would be a RAR but ok! LM_DBG("other request\n"); auth_server_statefull_sm_process(session,AUTH_EV_SEND_REQ,msg); session = 0; } } else { if (msg->commandCode == IMS_STR) { LM_DBG("STA\n"); auth_server_statefull_sm_process(session,AUTH_EV_SEND_STA,msg); session = 0; } else { LM_DBG("other reply\n"); auth_server_statefull_sm_process(session,AUTH_EV_SEND_ANS,msg); session = 0; } } break; default: break; } if (session) AAASessionsUnlock(session->hash); } if (!send_message_before_session_sm) peer_send_msg(p,msg); }
/** * Sends a message to the peer. * \note Must be called with a lock on the peer. * @param p - peer to send to * @param msg - message to send */ void Snd_Message(peer *p, AAAMessage *msg) { touch_peer(p); peer_send_msg(p,msg); }