int acc_radius_send_request(struct sip_msg *req, acc_info_t *inf) { int attr_cnt; VALUE_PAIR *send; uint32_t av_type; int offset; int i; send=NULL; attr_cnt = accb.get_core_attrs( req, inf->varr, inf->iarr, inf->tarr ); /* not interested in the last 2 values */ attr_cnt -= 2; av_type = rad_status( req, inf->env->code); /* RADIUS status */ ADD_RAD_AVPAIR( RA_ACCT_STATUS_TYPE, &av_type, -1); av_type = rd_vals[RV_SIP_SESSION].v; /* session*/ ADD_RAD_AVPAIR( RA_SERVICE_TYPE, &av_type, -1); av_type = (uint32_t)inf->env->code; /* status=integer */ ADD_RAD_AVPAIR( RA_SIP_RESPONSE_CODE, &av_type, -1); av_type = req->REQ_METHOD; /* method */ ADD_RAD_AVPAIR( RA_SIP_METHOD, &av_type, -1); /* unix time */ av_type = (uint32_t)inf->env->ts; ADD_RAD_AVPAIR( RA_TIME_STAMP, &av_type, -1); /* add extra also */ attr_cnt += accb.get_extra_attrs(rad_extra, req, inf->varr+attr_cnt, inf->iarr+attr_cnt, inf->tarr+attr_cnt); /* add the values for the vector - start from 1 instead of * 0 to skip the first value which is the METHOD as string */ offset = RA_STATIC_MAX-1; for( i=1; i<attr_cnt; i++) { switch (inf->tarr[i]) { case TYPE_STR: ADD_RAD_AVPAIR(offset+i, inf->varr[i].s, inf->varr[i].len); break; case TYPE_INT: ADD_RAD_AVPAIR(offset+i, &(inf->iarr[i]), -1); break; default: break; } } /* call-legs attributes also get inserted */ if ( inf->leg_info ) { offset += attr_cnt; attr_cnt = accb.get_leg_attrs(inf->leg_info,req,inf->varr,inf->iarr,inf->tarr,1); do { for (i=0; i<attr_cnt; i++) ADD_RAD_AVPAIR( offset+i, inf->varr[i].s, inf->varr[i].len ); }while ( (attr_cnt=accb.get_leg_attrs(inf->leg_info,req,inf->varr,inf->iarr, inf->tarr, 0))!=0 ); } if (rc_acct(rh, SIP_PORT, send)!=OK_RC) { LM_ERR("radius-ing failed\n"); goto error; } rc_avpair_free(send); return 1; error: rc_avpair_free(send); return -1; }
int acc_radius_send_request(struct sip_msg *req, acc_info_t *inf) { int attr_cnt; VALUE_PAIR *send; uint32_t av_type; int offset; int i; int m=0; int o=0; int rc_result=-1; double tsecmicro; char smicrosec[18]; send=NULL; attr_cnt = accb.get_core_attrs( req, inf->varr, inf->iarr, inf->tarr ); /* not interested in the last 2 values */ attr_cnt -= 2; av_type = rad_status( req, inf->env->code); /* RADIUS status */ ADD_RAD_AVPAIR( RA_ACCT_STATUS_TYPE, &av_type, -1); av_type = rd_vals[RV_SIP_SESSION].v; /* session*/ ADD_RAD_AVPAIR( RA_SERVICE_TYPE, &av_type, -1); av_type = (uint32_t)inf->env->code; /* status=integer */ ADD_RAD_AVPAIR( RA_SIP_RESPONSE_CODE, &av_type, -1); av_type = req->REQ_METHOD; /* method */ ADD_RAD_AVPAIR( RA_SIP_METHOD, &av_type, -1); // Event Time Stamp with Microseconds if(rad_time_mode==1){ gettimeofday(&inf->env->tv, NULL); tsecmicro=inf->env->tv.tv_sec+((double)inf->env->tv.tv_usec/1000000.0); //radius client doesn t support double so convert it sprintf(smicrosec,"%17.6f",tsecmicro); ADD_RAD_AVPAIR(RA_TIME_STAMP, &smicrosec, -1); }else{ av_type = (uint32_t)inf->env->ts; ADD_RAD_AVPAIR(RA_TIME_STAMP, &av_type, -1); } /* add extra also */ o = accb.get_extra_attrs(rad_extra, req, inf->varr+attr_cnt, inf->iarr+attr_cnt, inf->tarr+attr_cnt); attr_cnt += o; m = attr_cnt; /* add the values for the vector - start from 1 instead of * 0 to skip the first value which is the METHOD as string */ offset = RA_STATIC_MAX-1; for( i=1; i<attr_cnt; i++) { switch (inf->tarr[i]) { case TYPE_STR: ADD_RAD_AVPAIR(offset+i, inf->varr[i].s, inf->varr[i].len); break; case TYPE_INT: ADD_RAD_AVPAIR(offset+i, &(inf->iarr[i]), -1); break; default: break; } } /* call-legs attributes also get inserted */ if ( inf->leg_info ) { offset += attr_cnt; attr_cnt = accb.get_leg_attrs(inf->leg_info,req,inf->varr,inf->iarr,inf->tarr,1); do { for (i=0; i<attr_cnt; i++) ADD_RAD_AVPAIR( offset+i, inf->varr[i].s, inf->varr[i].len ); }while ( (attr_cnt=accb.get_leg_attrs(inf->leg_info,req,inf->varr,inf->iarr, inf->tarr, 0))!=0 ); } rc_result=rc_acct(rh, SIP_PORT, send); if (rc_result==ERROR_RC) { LM_ERR("Radius accounting - ERROR - \n"); goto error; }else if(rc_result==BADRESP_RC){ LM_ERR("Radius accounting - BAD RESPONSE \n"); goto error; }else if(rc_result==TIMEOUT_RC){ LM_ERR("Radius accounting - TIMEOUT \n"); goto error; }else if(rc_result==REJECT_RC){ LM_ERR("Radius accounting - REJECTED \n"); goto error; }else if(rc_result==OK_RC){ LM_DBG("Radius accounting - OK \n"); }else{ LM_ERR("Radius accounting - Unknown response \n"); goto error; } rc_avpair_free(send); /* free memory allocated by extra2strar */ free_strar_mem( &(inf->tarr[m-o]), &(inf->varr[m-o]), o, m); return 1; error: rc_avpair_free(send); /* free memory allocated by extra2strar */ free_strar_mem( &(inf->tarr[m-o]), &(inf->varr[m-o]), o, m); return -1; }
int acc_diameter_send_request(sip_msg_t *req, acc_info_t *inf) { int attr_cnt; int cnt; AAAMessage *send = NULL; AAA_AVP *avp; struct sip_uri puri; str *uri; int ret; int i; int status; char tmp[2]; unsigned int mid; int m; int o; attr_cnt = accb.get_core_attrs(req, inf->varr, inf->iarr, inf->tarr); /* last value is not used */ attr_cnt--; if ( (send=AAAInMessage(ACCOUNTING_REQUEST, AAA_APP_NASREQ))==NULL) { LM_ERR("failed to create new AAA request\n"); return -1; } m = 0; o = 0; /* AVP_ACCOUNTIG_RECORD_TYPE */ if( (status = diam_status(req, inf->env->code))<0) { LM_ERR("status unknown\n"); goto error; } tmp[0] = status+'0'; tmp[1] = 0; if( (avp=AAACreateAVP(AVP_Accounting_Record_Type, 0, 0, tmp, 1, AVP_DUPLICATE_DATA)) == 0) { LM_ERR("failed to create AVP:no more free memory!\n"); goto error; } if( AAAAddAVPToMessage(send, avp, 0)!= AAA_ERR_SUCCESS) { LM_ERR("avp not added \n"); AAAFreeAVP(&avp); goto error; } /* SIP_MSGID AVP */ mid = req->id; if( (avp=AAACreateAVP(AVP_SIP_MSGID, 0, 0, (char*)(&mid), sizeof(mid), AVP_DUPLICATE_DATA)) == 0) { LM_ERR("failed to create AVP:no more free memory!\n"); goto error; } if( AAAAddAVPToMessage(send, avp, 0)!= AAA_ERR_SUCCESS) { LM_ERR("avp not added \n"); AAAFreeAVP(&avp); goto error; } /* SIP Service AVP */ if( (avp=AAACreateAVP(AVP_Service_Type, 0, 0, SIP_ACCOUNTING, SERVICE_LEN, AVP_DUPLICATE_DATA)) == 0) { LM_ERR("failed to create AVP:no more free memory!\n"); goto error; } if( AAAAddAVPToMessage(send, avp, 0)!= AAA_ERR_SUCCESS) { LM_ERR("avp not added \n"); AAAFreeAVP(&avp); goto error; } /* also the extra attributes */ o = accb.get_extra_attrs(diameter_extra, req, inf->varr+attr_cnt, inf->iarr+attr_cnt, inf->tarr+attr_cnt); attr_cnt += o; m = attr_cnt; /* add attributes */ for(i=0; i<attr_cnt; i++) { if((avp=AAACreateAVP(diam_attrs[i], 0,0, inf->varr[i].s, inf->varr[i].len, AVP_DUPLICATE_DATA)) == 0) { LM_ERR("failed to create AVP: no more free memory!\n"); goto error; } if( AAAAddAVPToMessage(send, avp, 0)!= AAA_ERR_SUCCESS) { LM_ERR("avp not added \n"); AAAFreeAVP(&avp); goto error; } } /* and the leg attributes */ if ( inf->leg_info ) { cnt = accb.get_leg_attrs(inf->leg_info,req,inf->varr,inf->iarr,inf->tarr,1); do { for (i=0; i<cnt; i++) { if((avp=AAACreateAVP(diam_attrs[attr_cnt+i], 0, 0, inf->varr[i].s, inf->varr[i].len, AVP_DUPLICATE_DATA)) == 0) { LM_ERR("failed to create AVP: no more free memory!\n"); goto error; } if( AAAAddAVPToMessage(send, avp, 0)!= AAA_ERR_SUCCESS) { LM_ERR("avp not added \n"); AAAFreeAVP(&avp); goto error; } } } while ( (attr_cnt=accb.get_leg_attrs(inf->leg_info,req,inf->varr,inf->iarr, inf->tarr, 0))!=0 ); } if (get_uri(req, &uri) < 0) { LM_ERR("failed to get uri, From/To URI not found\n"); goto error; } if (parse_uri(uri->s, uri->len, &puri) < 0) { LM_ERR("failed to parse From/To URI\n"); goto error; } /* Destination-Realm AVP */ if( (avp=AAACreateAVP(AVP_Destination_Realm, 0, 0, puri.host.s, puri.host.len, AVP_DUPLICATE_DATA)) == 0) { LM_ERR("failed to create AVP:no more free memory!\n"); goto error; } if( AAAAddAVPToMessage(send, avp, 0)!= AAA_ERR_SUCCESS) { LM_ERR("avp not added \n"); AAAFreeAVP(&avp); goto error; } /* prepare the message to be sent over the network */ if(AAABuildMsgBuffer(send) != AAA_ERR_SUCCESS) { LM_ERR("message buffer not created\n"); goto error; } if(sockfd==AAA_NO_CONNECTION) { sockfd = init_mytcp(diameter_client_host, diameter_client_port); if(sockfd==AAA_NO_CONNECTION) { LM_ERR("failed to reconnect to Diameter client\n"); goto error; } } /* send the message to the DIAMETER client */ ret = tcp_send_recv(sockfd, send->buf.s, send->buf.len, rb, req->id); if(ret == AAA_CONN_CLOSED) { LM_NOTICE("connection to Diameter client closed.It will be " "reopened by the next request\n"); close(sockfd); sockfd = AAA_NO_CONNECTION; goto error; } if(ret != ACC_SUCCESS) { /* a transmission error occurred */ LM_ERR("message sending to the DIAMETER backend authorization " "server failed\n"); goto error; } AAAFreeMessage(&send); /* free memory allocated by extra2strar */ free_strar_mem( &(inf->tarr[m-o]), &(inf->varr[m-o]), o, m); return 1; error: AAAFreeMessage(&send); /* free memory allocated by extra2strar */ free_strar_mem( &(inf->tarr[m-o]), &(inf->varr[m-o]), o, m); return -1; }