static void radius_log(struct ast_event *event) { int result = ERROR_RC; VALUE_PAIR *send = NULL; struct ast_cel_event_record record = { .version = AST_CEL_EVENT_RECORD_VERSION, }; if (ast_cel_fill_record(event, &record)) { return; } if (build_radius_record(&send, &record)) { ast_debug(1, "Unable to create RADIUS record. CEL not recorded!\n"); goto return_cleanup; } result = rc_acct(rh, 0, send); if (result != OK_RC) { ast_log(LOG_ERROR, "Failed to record Radius CEL record!\n"); } return_cleanup: if (send) { rc_avpair_free(send); } }
int process(void *rh, VALUE_PAIR *send, int acct, int nas_port, int send_info) { VALUE_PAIR *received = NULL; char buf[BUF_LEN]; RC_AAA_CTX *ctx = NULL; const unsigned char *p; int i, j; received = NULL; if (acct == 0) { i = rc_aaa_ctx(rh, &ctx, nas_port, send, &received, NULL, 1, PW_ACCESS_REQUEST); if (received != NULL) { printf("%s", rc_avpair_log(rh, received, buf, BUF_LEN)); rc_avpair_free(received); } if (ctx) { if (send_info) { printf("Request-Info-Secret = %s\n", rc_aaa_ctx_get_secret(ctx)); printf("Request-Info-Vector = "); p = rc_aaa_ctx_get_vector(ctx); for (j=0; j<AUTH_VECTOR_LEN; j++) { printf("%.2x", (unsigned)p[j]); } printf("\n"); } rc_aaa_ctx_free(ctx); } } else { i = rc_acct(rh, nas_port, send); } return (i == OK_RC) ? 0 : 1; }
static void *do_monitor(void *data) { int result = ERROR_RC; char cdr_full_path[256]; DIR *cdr_dir; VALUE_PAIR *resend = NULL; struct dirent *dir_s = NULL; int count = 0; // times of resend int wait_time = 0; for(;;){ sleep(1); /* sleep 1 minute */ /* Open dir */ if((cdr_dir=opendir(cdr_directory)) == NULL){ ast_log(LOG_ERROR,"Failed to open %s\n",cdr_directory); } else { /* open */ while((dir_s=readdir(cdr_dir))!=NULL) { if(!strcmp(dir_s->d_name,".") || !strcmp(dir_s->d_name,"..")) continue; memset(cdr_full_path,0,sizeof(cdr_full_path)); snprintf(cdr_full_path,sizeof(cdr_full_path),"%s/%s",cdr_directory,dir_s->d_name); resend = get_avp(cdr_full_path); if(resend){ result = rc_acct(rh,0,resend); }else{ ast_log(LOG_ERROR, "get avp return null!"); } if(result != OK_RC){ ast_log(LOG_ERROR, "Failed to re-record Radius CDR record!\n"); if(resend){ ast_avpair_free(resend); resend = NULL; } count++; wait_time = count * 60; // reterval to resend cdr record: 60s, 120s,180s,240s...... ast_log(LOG_DEBUG,"----------wait_time:%d-----------\n", wait_time); break; }else{ ast_log(LOG_DEBUG,"----------cdr_full_path:%s send OK!-----------\n", cdr_full_path); wait_time = 0; count = 0; if(remove(cdr_full_path) != 0) ast_log(LOG_WARNING,"Failed to delete %s\n",cdr_full_path); } if(resend){ ast_avpair_free(resend); resend = NULL; } } closedir(cdr_dir); } if (wait_time > 0) { ast_log(LOG_DEBUG,"if-wait_time>0----------wait_time:%d-----------\n", wait_time); sleep(wait_time); } } return NULL; }
int process(void *rh, VALUE_PAIR * send, int acct, int nas_port) { VALUE_PAIR *received; char msg[PW_MAX_MSG_SIZE]; char buf[BUF_LEN]; int i, fd; fd = rc_tls_fd(rh); if (fd >= 0) { dup(fd); close(fd); } received = NULL; if (acct == 0) { i = rc_auth(rh, nas_port, send, &received, msg); if (i != OK_RC) { fprintf(stderr, "tls-restart: error sending 1 (ok)\n"); } i = rc_auth(rh, nas_port, send, &received, msg); if (i != OK_RC) { fprintf(stderr, "tls-restart: error sending 2\n"); exit(2); } if (received != NULL) { printf("%s", rc_avpair_log(rh, received, buf, BUF_LEN)); rc_avpair_free(received); } } else { i = rc_acct(rh, nas_port, send); } return (i == OK_RC) ? 0 : 1; }
switch_status_t mod_xml_radius_accounting_end(switch_core_session_t *session){ VALUE_PAIR *send = NULL; uint32_t service = PW_STATUS_STOP; rc_handle *new_handle = NULL; switch_xml_t fields = NULL, conditions = NULL; switch_channel_t *channel = switch_core_session_get_channel(session); if (GLOBAL_DEBUG ) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "mod_xml_radius: starting accounting stop\n"); switch_core_session_execute_application(session, "info", NULL); } /* If there are conditions defined, and none of them pass, then skip this accounting */ if ((conditions = switch_xml_child(globals.acct_start_configs, "conditions")) != NULL && mod_xml_radius_check_conditions(channel, conditions) != SWITCH_STATUS_SUCCESS ) { goto end; } if ( mod_xml_radius_new_handle(&new_handle, globals.acct_end_configs) != SWITCH_STATUS_SUCCESS || new_handle == NULL ) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to create new accounting_end handle for call: %s\n", switch_channel_get_variable(channel, "uuid")); goto end; } if ((fields = switch_xml_child(globals.acct_end_configs, "fields")) == NULL ) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Could not find 'fields' section in config file.\n"); goto end; } if ( mod_xml_radius_add_params(session, NULL, new_handle, &send, fields) != SWITCH_STATUS_SUCCESS ) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to add params to rc_handle\n"); goto end; } if (rc_avpair_add(new_handle, &send, PW_ACCT_STATUS_TYPE, &service, -1, 0) == NULL) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "mod_xml_radius: failed to add option to handle\n"); goto end; } if (rc_acct(new_handle, 0, send) == OK_RC) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "mod_xml_radius: Accounting Stop success\n"); } else { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "mod_xml_radius: Accounting Stop failed\n"); } end: if ( send ) { rc_avpair_free(send); send = NULL; } if ( new_handle) { rc_destroy(new_handle); new_handle = NULL; } return SWITCH_STATUS_SUCCESS; }
static int radius_log(struct ast_cdr *cdr) { int result = ERROR_RC; VALUE_PAIR *send = NULL; if (build_radius_record(&send, cdr)) { if (option_debug) ast_log(LOG_DEBUG, "Unable to create RADIUS record. CDR not recorded!\n"); return result; } result = rc_acct(rh, 0, send); if (result != OK_RC) ast_log(LOG_ERROR, "Failed to record Radius CDR record!\n"); return result; }
int send_acct_func(struct sip_msg* msg, str *s) { int i, index = -1; VALUE_PAIR *send = NULL; if (!rh) { if (init_radius_handle()) { LM_ERR("invalid radius handle\n"); return -1; } } //LM_DBG("*******************************************\n"); for (i = 0; i < set_size; i++) { if (sets[i]->set_name.len == s->len && !strncmp(sets[i]->set_name.s, s->s, s->len)) index = i; } if (index == -1) { LM_ERR("set not found\n"); return -1; } if (make_send_message(msg, index, &send) < 0) { LM_ERR("make message failed\n"); return -1; } if (rc_acct(rh, SIP_PORT, send) != OK_RC){ if (send) rc_avpair_free(send); LM_ERR("radius accounting message failed to send\n"); //LM_DBG("*******************************************\n"); return -1; } LM_DBG("radius accounting message sent\n"); // LM_DBG("*******************************************\n"); return 1; }
/* skip leading text and begin with first item's * separator ", " which will be overwritten by the * leading text later * */ static int log_request(struct sip_msg* rq, str* ouri, struct hdr_field* to, unsigned int code, time_t req_time) { VALUE_PAIR *send; UINT4 av_type; send = NULL; if (skip_cancel(rq)) return 1; if (fmt2rad(log_fmt, rq, ouri, to, code, &send, req_time) < 0) goto error; /* Add Acct-Status-Type attribute */ av_type = rad_status(rq, code); if (!rc_avpair_add(rh, &send, ATTRID(attrs[A_ACCT_STATUS_TYPE].v), &av_type, -1, VENDOR(attrs[A_ACCT_STATUS_TYPE].v))) { ERR("Add Status-Type\n"); goto error; } /* Add Service-Type attribute */ av_type = (service_type != -1) ? service_type : vals[V_SIP_SESSION].v; if (!rc_avpair_add(rh, &send, ATTRID(attrs[A_SERVICE_TYPE].v), &av_type, -1, VENDOR(attrs[A_SERVICE_TYPE].v))) { ERR("add STATUS_TYPE\n"); goto error; } /* Add User-Name attribute */ if (add_user_name(rq, rh, &send) < 0) goto error; /* Send the request out */ if (rc_acct(rh, SIP_PORT, send) != OK_RC) { ERR("RADIUS accounting request failed\n"); goto error; } rc_avpair_free(send); return 1; error: rc_avpair_free(send); return -1; }
static int radius_log(struct ast_cdr *cdr) { int result = ERROR_RC; VALUE_PAIR *tosend = NULL; if (build_radius_record(&tosend, cdr)) { ast_debug(1, "Unable to create RADIUS record. CDR not recorded!\n"); goto return_cleanup; } result = rc_acct(rh, 0, tosend); if (result != OK_RC) { ast_log(LOG_ERROR, "Failed to record Radius CDR record!\n"); } return_cleanup: if (tosend) { rc_avpair_free(tosend); } return result; }
static void radius_log(struct ast_event *event) { int result = ERROR_RC; VALUE_PAIR *send = NULL; int ret = 0; char cdr_full_path[256]; struct ast_cel_event_record record = { .version = AST_CEL_EVENT_RECORD_VERSION, }; if (ast_cel_fill_record(event, &record)) { return; } if (build_radius_record(&send, &record)) { ast_debug(1, "Unable to create RADIUS record. CEL not recorded!\n"); goto return_cleanup; } result = rc_acct(rh, 0, send); if (result != OK_RC) { ast_log(LOG_ERROR, "Failed to record Radius CEL record! unique_id=%s\n", record.unique_id); /* file name */ if(record.unique_id && (!ast_strlen_zero(record.unique_id))){ snprintf(cdr_full_path,sizeof(cdr_full_path),"%s/%s",cdr_dir_tmp,record.unique_id); /* write cdr to file if rc_acct failed */ ret = save_avp_to_file(cdr_full_path,record.unique_id,send); if(!ret){ ast_log(LOG_ERROR,"Failed to write cdr to file! unique_id=%s\n", record.unique_id); } } goto return_cleanup; } return_cleanup: if (send) { rc_avpair_free(send); } }
/** * @param[in] session Session * @param[in] status Accounting status (PW_STATUS_START, PW_STATUS_STOP, PW_STATUS_ALIVE) * @param[in] cause Accounting termination cause (used only in case of PW_STATUS_STOP) * @param[in] req Accounting request data. */ static zrad_status_t zrad_acct_request(rc_handle *radh, const zrad_acct_req_t *req) { zrad_status_t ret; VALUE_PAIR *request_attrs = NULL; int success = rc_avpair_add(radh, &request_attrs, PW_CALLING_STATION_ID, req->calling_station_id, -1, 0) && rc_avpair_add(radh, &request_attrs, PW_ACCT_AUTHENTIC, &req->authentic, -1, 0) && rc_avpair_add(radh, &request_attrs, PW_FRAMED_IP_ADDRESS, &req->framed_ip_addr, -1, 0) && rc_avpair_add(radh, &request_attrs, PW_USER_NAME, req->username, -1, 0) && rc_avpair_add(radh, &request_attrs, PW_ACCT_SESSION_ID, req->session_id, -1, 0) && rc_avpair_add(radh, &request_attrs, PW_NAS_IDENTIFIER, req->nas_id, -1, 0) && rc_avpair_add(radh, &request_attrs, PW_ACCT_INPUT_OCTETS, &req->octets_down, -1, 0) && rc_avpair_add(radh, &request_attrs, PW_ACCT_INPUT_PACKETS, &req->packets_down, -1, 0) && rc_avpair_add(radh, &request_attrs, PW_ACCT_OUTPUT_OCTETS, &req->octets_up, -1, 0) && rc_avpair_add(radh, &request_attrs, PW_ACCT_OUTPUT_PACKETS, &req->packets_down, -1, 0) && (!req->gigawords_down || rc_avpair_add(radh, &request_attrs, PW_ACCT_OUTPUT_GIGAWORDS, &req->gigawords_up, -1, 0)) && (!req->gigawords_down || rc_avpair_add(radh, &request_attrs, PW_ACCT_INPUT_GIGAWORDS, &req->gigawords_down, -1, 0)) && rc_avpair_add(radh, &request_attrs, PW_ACCT_STATUS_TYPE, &req->status, -1, 0); if (success && PW_STATUS_STOP == req->status) { success = success && rc_avpair_add(radh, &request_attrs, PW_ACCT_SESSION_TIME, &req->session_time, -1, 0) && rc_avpair_add(radh, &request_attrs, PW_ACCT_TERMINATE_CAUSE, &req->term_cause, -1, 0); } if (likely(success)) { ret = (zrad_status_t) rc_acct(radh, 0, request_attrs); } else { ret = ZRAD_OTHER; } if (likely(request_attrs)) rc_avpair_free(request_attrs); return ret; }
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; }
/* Radius implementation for the send_message callback */ int rad_send_message(aaa_conn* rh, aaa_message* request, aaa_message** reply) { char msg[4096]; VALUE_PAIR *vp; DICT_ATTR *attr; int result; if (!rh) { LM_ERR("invalid aaa connection argument\n"); return -1; } if (!request) { LM_ERR("invalid argument\n"); return -1; } if (request->type == AAA_AUTH) { *reply = (aaa_message*) pkg_malloc (sizeof(aaa_message)); if (!(*reply)) { LM_ERR("no pkg memory left \n"); return -1; } (*reply)->type = AAA_RECV; (*reply)->avpair = NULL; (*reply)->last_found = NULL; result = rc_auth(rh, SIP_PORT, (VALUE_PAIR*) request->avpair, (VALUE_PAIR**)(void*)&(*reply)->avpair, msg); if (result == OK_RC) { attr = rc_dict_findattr(rh, "SIP-AVP"); if (attr) { vp = (*reply)->avpair; for(; (vp = rc_avpair_get(vp, attr->value, 0)); vp = vp->next) if (extract_avp(vp)) { LM_ERR("extract_avp failed\n"); return -1; } return 0; } else { LM_ERR("SIP-AVP was not found in the radius dictionary\n"); return -1; } } else if (result == REJECT_RC) { LM_DBG("rc_auth function succeded with result REJECT_RC\n"); return result; } else { LM_ERR("rc_auth function failed\n"); return -1; } } if (request->type == AAA_ACCT) { return rc_acct(rh, SIP_PORT, (VALUE_PAIR*) request->avpair); } LM_ERR("send message failure\n"); 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; 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 main (int argc, char **argv) { int result = ERROR_RC; VALUE_PAIR *send = NULL; UINT4 client_port; int c; VALUE_PAIR *vp; DICT_VALUE *dval; char *username, *service, *fproto, *type; char *path_radiusclient_conf = RC_CONFIG_FILE; char *ttyn = NULL; rc_handle *rh; extern char *optarg; pname = (pname = strrchr(argv[0],'/'))?pname+1:argv[0]; rc_openlog(pname); while ((c = getopt(argc,argv,"f:i:hV")) > 0) { switch(c) { case 'f': path_radiusclient_conf = optarg; break; case 'i': ttyn = optarg; break; case 'V': version(); break; case 'h': usage(); break; default: exit(ERROR_RC); break; } } if ((rh = rc_read_config(path_radiusclient_conf)) == NULL) exit(ERROR_RC); if (rc_read_dictionary(rh, rc_conf_str(rh, "dictionary")) != 0) exit (ERROR_RC); if (rc_read_mapfile(rh, rc_conf_str(rh, "mapfile")) != 0) exit (ERROR_RC); if (ttyn != NULL) { client_port = rc_map2id(rh, ttyn); } else { /* we take stdout here, because stdin is usually connected * to our input file */ if ((ttyn = ttyname(1)) != NULL) { client_port = rc_map2id(rh, ttyn); } else { client_port = 0; } } if ((send = rc_avpair_readin(rh, stdin))) { username = service = type = "(unknown)"; fproto = NULL; if ((vp = rc_avpair_get(send, PW_ACCT_STATUS_TYPE, 0)) != NULL) if ((dval = rc_dict_getval(rh, vp->lvalue, vp->name)) != NULL) { type = dval->name; } if ((vp = rc_avpair_get(send, PW_USER_NAME, 0)) != NULL) username = vp->strvalue; if ((vp = rc_avpair_get(send, PW_SERVICE_TYPE, 0)) != NULL) if ((dval = rc_dict_getval(rh, vp->lvalue, vp->name)) != NULL) { service = dval->name; } if (vp && (vp->lvalue == PW_FRAMED) && ((vp = rc_avpair_get(send, PW_FRAMED_PROTOCOL, 0)) != NULL)) if ((dval = rc_dict_getval(rh, vp->lvalue, vp->name)) != NULL) { fproto = dval->name; } result = rc_acct(rh, client_port, send); if (result == OK_RC) { fprintf(stderr, SC_ACCT_OK); rc_log(LOG_NOTICE, "accounting OK, type %s, username %s, service %s%s%s", type, username, service,(fproto)?"/":"", (fproto)?fproto:""); } else { fprintf(stderr, SC_ACCT_FAILED, result); rc_log(LOG_NOTICE, "accounting FAILED, type %s, username %s, service %s%s%s", type, username, service,(fproto)?"/":"", (fproto)?fproto:""); } rc_avpair_free(send); } exit (result); }
static switch_status_t my_on_reporting(switch_core_session_t *session) { switch_xml_t cdr = NULL; switch_channel_t *channel = switch_core_session_get_channel(session); rc_handle *rad_config; switch_status_t retval = SWITCH_STATUS_TERM; VALUE_PAIR *send = NULL; uint32_t client_port = 0; uint32_t framed_addr = 0; uint32_t status_type = PW_STATUS_STOP; switch_time_t callstartdate = 0; switch_time_t callanswerdate = 0; switch_time_t callenddate = 0; switch_time_t calltransferdate = 0; switch_time_t billusec = 0; uint32_t billsec = 0; char *uuid_str; switch_time_exp_t tm; char buffer[32] = ""; if (globals.shutdown) { return SWITCH_STATUS_FALSE; } if (channel) { const char *disable_flag = switch_channel_get_variable(channel, "disable_radius_stop"); if (switch_true(disable_flag)) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "[mod_radius_cdr] Not Sending RADIUS Stop\n"); return SWITCH_STATUS_SUCCESS; } } switch_thread_rwlock_rdlock(globals.rwlock); switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "[mod_radius_cdr] Entering my_on_reporting\n"); rad_config = my_radius_init(); if (rad_config == NULL) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "[mod_radius_cdr] Error initializing radius, session not logged.\n"); goto end; } if (switch_ivr_generate_xml_cdr(session, &cdr) == SWITCH_STATUS_SUCCESS) { uuid_str = switch_core_session_get_uuid(session); } else { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "[mod_radius_cdr] Error Generating Data!\n"); goto end; } /* Create the radius packet */ /* Set Status Type */ if (rc_avpair_add(rad_config, &send, PW_ACCT_STATUS_TYPE, &status_type, -1, 0) == NULL) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "failed adding Acct-Session-ID: %s\n", uuid_str); rc_destroy(rad_config); goto end; } if (rc_avpair_add(rad_config, &send, PW_ACCT_SESSION_ID, uuid_str, -1, 0) == NULL) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "failed adding Acct-Session-ID: %s\n", uuid_str); rc_destroy(rad_config); goto end; } /* Add VSAs */ if (channel) { switch_call_cause_t cause; switch_caller_profile_t *profile; cause = switch_channel_get_cause(channel); if (rc_avpair_add(rad_config, &send, PW_FS_HANGUPCAUSE, &cause, -1, PW_FS_PEC) == NULL) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "failed adding Freeswitch-Hangupcause: %d\n", cause); rc_destroy(rad_config); goto end; } profile = switch_channel_get_caller_profile(channel); if (profile) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "[mod_radius_cdr] Calculating billable time\n"); /* calculate billable time */ callstartdate = profile->times->created; callanswerdate = profile->times->answered; calltransferdate = profile->times->transferred; callenddate = profile->times->hungup; if (switch_channel_test_flag(channel, CF_ANSWERED)) { if (callstartdate && callanswerdate) { if (callenddate) billusec = callenddate - callanswerdate; else if (calltransferdate) billusec = calltransferdate - callanswerdate; } } else if (switch_channel_test_flag(channel, CF_TRANSFER)) { if (callanswerdate && calltransferdate) billusec = calltransferdate - callanswerdate; } billsec = (billusec / 1000000); switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "[mod_radius_cdr] Finished calculating billable time\n"); if (profile->username) { if (rc_avpair_add(rad_config, &send, PW_USER_NAME, (void *) profile->username, -1, 0) == NULL) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "failed adding User-Name: %s\n", profile->username); rc_destroy(rad_config); goto end; } } if (profile->caller_id_number) { if (rc_avpair_add(rad_config, &send, PW_FS_SRC, (void *) profile->caller_id_number, -1, PW_FS_PEC) == NULL) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "failed adding Freeswitch-Src: %s\n", profile->caller_id_number); rc_destroy(rad_config); goto end; } } if (profile->caller_id_name) { if (rc_avpair_add(rad_config, &send, PW_FS_CLID, (void *) profile->caller_id_name, -1, PW_FS_PEC) == NULL) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "failed adding Freeswitch-CLID: %s\n", profile->caller_id_name); rc_destroy(rad_config); goto end; } } if (profile->destination_number) { if (rc_avpair_add(rad_config, &send, PW_FS_DST, (void *) profile->destination_number, -1, PW_FS_PEC) == NULL) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "failed adding Freeswitch-Dst: %s\n", profile->destination_number); rc_destroy(rad_config); goto end; } } if (profile->dialplan) { if (rc_avpair_add(rad_config, &send, PW_FS_DIALPLAN, (void *) profile->dialplan, -1, PW_FS_PEC) == NULL) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "failed adding Freeswitch-Dialplan: %s\n", profile->dialplan); rc_destroy(rad_config); goto end; } } if (profile->network_addr) { inet_pton(AF_INET, (void *) profile->network_addr, &framed_addr); framed_addr = htonl(framed_addr); if (rc_avpair_add(rad_config, &send, PW_FRAMED_IP_ADDRESS, &framed_addr, -1, 0) == NULL) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "failed adding Framed-IP-Address: %s\n", profile->network_addr); rc_destroy(rad_config); goto end; } } if (profile->rdnis) { if (rc_avpair_add(rad_config, &send, PW_FS_RDNIS, (void *) profile->rdnis, -1, PW_FS_PEC) == NULL) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "failed adding Freeswitch-RDNIS: %s\n", profile->rdnis); rc_destroy(rad_config); goto end; } } if (profile->context) { if (rc_avpair_add(rad_config, &send, PW_FS_CONTEXT, (void *) profile->context, -1, PW_FS_PEC) == NULL) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "failed adding Freeswitch-Context: %s\n", profile->context); rc_destroy(rad_config); goto end; } } if (profile->ani) { if (rc_avpair_add(rad_config, &send, PW_FS_ANI, (void *) profile->ani, -1, PW_FS_PEC) == NULL) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "failed adding Freeswitch-ANI: %s\n", profile->ani); rc_destroy(rad_config); goto end; } } if (profile->aniii) { if (rc_avpair_add(rad_config, &send, PW_FS_ANIII, (void *) profile->aniii, -1, PW_FS_PEC) == NULL) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "failed adding Freeswitch-ANIII: %s\n", profile->aniii); rc_destroy(rad_config); goto end; } } if (profile->source) { if (rc_avpair_add(rad_config, &send, PW_FS_SOURCE, (void *) profile->source, -1, PW_FS_PEC) == NULL) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "failed adding Freeswitch-Source: %s\n", profile->source); rc_destroy(rad_config); goto end; } } if (profile->caller_extension && profile->caller_extension->last_application && profile->caller_extension->last_application->application_name) { if (rc_avpair_add(rad_config, &send, PW_FS_LASTAPP, (void *) profile->caller_extension->last_application->application_name, -1, PW_FS_PEC) == NULL) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "failed adding Freeswitch-Lastapp: %s\n", profile->source); rc_destroy(rad_config); goto end; } } if (rc_avpair_add(rad_config, &send, PW_FS_BILLUSEC, &billusec, -1, PW_FS_PEC) == NULL) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "failed adding Freeswitch-Billusec: %u\n", (uint32_t) billusec); rc_destroy(rad_config); goto end; } if (callstartdate > 0) { switch_time_exp_lt(&tm, callstartdate); switch_snprintf(buffer, sizeof(buffer), "%04u-%02u-%02uT%02u:%02u:%02u.%06u%+03d%02d", tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec, tm.tm_usec, tm.tm_gmtoff / 3600, tm.tm_gmtoff % 3600); if (rc_avpair_add(rad_config, &send, PW_FS_CALLSTARTDATE, &buffer, -1, PW_FS_PEC) == NULL) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "failed adding Freeswitch-Callstartdate: %s\n", buffer); rc_destroy(rad_config); goto end; } } if (callanswerdate > 0) { switch_time_exp_lt(&tm, callanswerdate); switch_snprintf(buffer, sizeof(buffer), "%04u-%02u-%02uT%02u:%02u:%02u.%06u%+03d%02d", tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec, tm.tm_usec, tm.tm_gmtoff / 3600, tm.tm_gmtoff % 3600); if (rc_avpair_add(rad_config, &send, PW_FS_CALLANSWERDATE, &buffer, -1, PW_FS_PEC) == NULL) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "failed adding Freeswitch-Callanswerdate: %s\n", buffer); rc_destroy(rad_config); goto end; } } if (calltransferdate > 0) { switch_time_exp_lt(&tm, calltransferdate); switch_snprintf(buffer, sizeof(buffer), "%04u-%02u-%02uT%02u:%02u:%02u.%06u%+03d%02d", tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec, tm.tm_usec, tm.tm_gmtoff / 3600, tm.tm_gmtoff % 3600); if (rc_avpair_add(rad_config, &send, PW_FS_CALLTRANSFERDATE, &buffer, -1, PW_FS_PEC) == NULL) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "failed adding Freeswitch-Calltransferdate: %s\n", buffer); rc_destroy(rad_config); goto end; } } if (callenddate > 0) { switch_time_exp_lt(&tm, callenddate); switch_snprintf(buffer, sizeof(buffer), "%04u-%02u-%02uT%02u:%02u:%02u.%06u%+03d%02d", tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec, tm.tm_usec, tm.tm_gmtoff / 3600, tm.tm_gmtoff % 3600); if (rc_avpair_add(rad_config, &send, PW_FS_CALLENDDATE, &buffer, -1, PW_FS_PEC) == NULL) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "failed adding Freeswitch-Callenddate: %s\n", buffer); rc_destroy(rad_config); goto end; } } if (rc_avpair_add(rad_config, &send, PW_ACCT_SESSION_TIME, &billsec, -1, 0) == NULL) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "failed adding Acct-Session-Time: %u\n", billsec); rc_destroy(rad_config); goto end; } { const char *direction_str = profile->direction == SWITCH_CALL_DIRECTION_INBOUND ? "inbound" : "outbound"; if (rc_avpair_add(rad_config, &send, PW_FS_DIRECTION, (void *) direction_str, -1, PW_FS_PEC) == NULL) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "failed adding Freeswitch-Direction: %s\n", direction_str); rc_destroy(rad_config); goto end; } } } else { /* no profile, can't create data to send */ switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "profile == NULL\n"); } } if (rc_acct(rad_config, client_port, send) == OK_RC) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "RADIUS Accounting OK\n"); retval = SWITCH_STATUS_SUCCESS; } else { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "RADIUS Accounting Failed\n"); retval = SWITCH_STATUS_TERM; } rc_avpair_free(send); rc_destroy(rad_config); end: switch_xml_free(cdr); switch_thread_rwlock_unlock(globals.rwlock); return (retval); }
int acc_rad_request( struct sip_msg *req ) { int attr_cnt; VALUE_PAIR *send; UINT4 av_type; int offset; int i; int m; int o; send=NULL; attr_cnt = core2strar( req, val_arr, int_arr, type_arr ); /* not interested in the last 2 values */ attr_cnt -= 2; av_type = rad_status( req, acc_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 = (UINT4)acc_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 = (UINT4)acc_env.ts; ADD_RAD_AVPAIR( RA_TIME_STAMP, &av_type, -1); /* add extra also */ o = extra2strar(rad_extra, req, val_arr+attr_cnt, int_arr+attr_cnt, type_arr+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 (type_arr[i]) { case TYPE_STR: ADD_RAD_AVPAIR(offset+i, val_arr[i].s, val_arr[i].len); break; case TYPE_INT: ADD_RAD_AVPAIR(offset+i, &(int_arr[i]), -1); break; default: break; } } /* call-legs attributes also get inserted */ if ( leg_info ) { offset += attr_cnt; attr_cnt = legs2strar(leg_info,req,val_arr,int_arr,type_arr,1); do { for (i=0; i<attr_cnt; i++) ADD_RAD_AVPAIR( offset+i, val_arr[i].s, val_arr[i].len ); }while ( (attr_cnt=legs2strar(leg_info,req,val_arr,int_arr, type_arr, 0))!=0 ); } if (rc_acct(rh, SIP_PORT, send)!=OK_RC) { LM_ERR("radius-ing failed\n"); goto error; } rc_avpair_free(send); /* free memory allocated by extra2strar */ free_strar_mem( &(type_arr[m-o]), &(val_arr[m-o]), o, m); return 1; error: rc_avpair_free(send); /* free memory allocated by extra2strar */ free_strar_mem( &(type_arr[m-o]), &(val_arr[m-o]), o, m); return -1; }
/** * Send radius accounting packet. * @param[in] sess Session * @param[in] status Accounting status (PW_STATUS_START, PW_STATUS_STOP, PW_STATUS_ALIVE) * @param[in] cause Accounting termination cause (used only in case of PW_STATUS_STOP) * @return Zero on success (one of *_RC codes). */ static int session_accounting(struct zsession *sess, uint32_t status, uint32_t term_cause) { int ret = OTHER_RC; VALUE_PAIR *request_attrs = NULL; rc_handle *rh = zinst()->radh; struct in_addr ip_addr; char ip_str[INET_ADDRSTRLEN]; uint64_t traff_down = atomic_load_explicit(&sess->traff_down, memory_order_acquire); uint64_t traff_up = atomic_load_explicit(&sess->traff_up, memory_order_acquire); uint32_t octets_down = (uint32_t) (traff_down % UINT32_MAX); uint32_t octets_up = (uint32_t) (traff_up % UINT32_MAX); uint32_t packets_down = atomic_load_explicit(&sess->packets_down, memory_order_acquire) % UINT32_MAX; uint32_t packets_up = atomic_load_explicit(&sess->packets_up, memory_order_acquire) % UINT32_MAX; uint32_t gigawords_down = 0; uint32_t gigawords_up = 0; char session_id[255]; snprintf(session_id, sizeof(session_id), "%s-%" PRIu32, sess->client->login, sess->ip); ip_addr.s_addr = htonl(sess->ip); if (unlikely(NULL == inet_ntop(AF_INET, &ip_addr, ip_str, sizeof(ip_str)))) { goto end; } if (unlikely(NULL == rc_avpair_add(rh, &request_attrs, PW_CALLING_STATION_ID, ip_str, -1, 0))) { goto end; } if (unlikely(NULL == rc_avpair_add(rh, &request_attrs, PW_FRAMED_IP_ADDRESS, &sess->ip, -1, 0))) { goto end; } if (unlikely(NULL == rc_avpair_add(rh, &request_attrs, PW_USER_NAME, sess->client->login, -1, 0))) { goto end; } if (unlikely(NULL == rc_avpair_add(rh, &request_attrs, PW_ACCT_SESSION_ID, session_id, -1, 0))) { goto end; } if (unlikely(NULL == rc_avpair_add(rh, &request_attrs, PW_NAS_IDENTIFIER, zcfg()->radius_nas_identifier, -1, 0))) { goto end; } if (PW_STATUS_STOP == status) { if (unlikely(NULL == rc_avpair_add(rh, &request_attrs, PW_ACCT_TERMINATE_CAUSE, &term_cause, -1, 0))) { goto end; } } if (unlikely(NULL == rc_avpair_add(rh, &request_attrs, PW_ACCT_STATUS_TYPE, &status, -1, 0))) { goto end; } if (unlikely(NULL == rc_avpair_add(rh, &request_attrs, PW_ACCT_INPUT_OCTETS, &octets_down, -1, 0))) { goto end; } if (unlikely(NULL == rc_avpair_add(rh, &request_attrs, PW_ACCT_INPUT_PACKETS, &packets_down, -1, 0))) { goto end; } if (unlikely(NULL == rc_avpair_add(rh, &request_attrs, PW_ACCT_OUTPUT_OCTETS, &octets_up, -1, 0))) { goto end; } if (unlikely(NULL == rc_avpair_add(rh, &request_attrs, PW_ACCT_OUTPUT_PACKETS, &packets_down, -1, 0))) { goto end; } if (unlikely(UINT32_MAX < traff_down)) { gigawords_down = (uint32_t) (traff_down / UINT32_MAX); if (unlikely(NULL == rc_avpair_add(rh, &request_attrs, PW_ACCT_INPUT_GIGAWORDS, &gigawords_down, -1, 0))) { goto end; } } if (unlikely(UINT32_MAX < traff_up)) { gigawords_up = (uint32_t) (traff_up / UINT32_MAX); if (unlikely(NULL == rc_avpair_add(rh, &request_attrs, PW_ACCT_OUTPUT_GIGAWORDS, &gigawords_up, -1, 0))) { goto end; } } ret = rc_acct(rh, 0, request_attrs); if (unlikely(OK_RC != ret)) { ZERO_LOG(LOG_ERR, "radius accounting failed %s (code:%d)", ip_str, ret); goto end; } atomic_fetch_sub_explicit(&sess->traff_down, traff_down, memory_order_release); atomic_fetch_sub_explicit(&sess->traff_up, traff_up, memory_order_release); atomic_fetch_sub_explicit(&sess->packets_down, packets_down, memory_order_release); atomic_fetch_sub_explicit(&sess->packets_up, packets_up, memory_order_release); end: if (request_attrs) { rc_avpair_free(request_attrs); } return ret; }
int acc_rad_request( struct sip_msg *rq, struct hdr_field *to, str *phrase ) { str* val_arr[ALL_LOG_FMT_LEN+1]; str atr_arr[ALL_LOG_FMT_LEN+1]; int attr_cnt; VALUE_PAIR *send; UINT4 av_type; int i; int dummy_len; str* user; str* realm; str user_name; struct sip_uri puri; struct to_body* from; #ifdef _OBSO char nullcode="00000"; char ccode[6]; char *c; #endif send=NULL; if (skip_cancel(rq)) return 1; attr_cnt=fmt2strar( RAD_ACC_FMT, rq, to, phrase, &dummy_len, &dummy_len, val_arr, atr_arr); if (attr_cnt!=(sizeof(RAD_ACC_FMT)-1)) { LOG(L_ERR, "ERROR: acc_rad_request: fmt2strar failed\n"); goto error; } av_type=rad_status(rq, phrase); if (!rc_avpair_add(rh, &send, attrs[A_ACCT_STATUS_TYPE].v, &av_type, -1, 0)) { LOG(L_ERR, "ERROR: acc_rad_request: add STATUS_TYPE\n"); goto error; } av_type=vals[V_SIP_SESSION].v; if (!rc_avpair_add(rh, &send, attrs[A_SERVICE_TYPE].v, &av_type, -1, 0)) { LOG(L_ERR, "ERROR: acc_rad_request: add STATUS_TYPE\n"); goto error; } av_type=phrase2code(phrase); /* status=integer */ /* if (phrase.len<3) c=nullcode; else { memcpy(ccode, phrase.s, 3); ccode[3]=0;c=nullcode;} */ if (!rc_avpair_add(rh, &send, attrs[A_SIP_RESPONSE_CODE].v, &av_type, -1, 0)) { LOG(L_ERR, "ERROR: acc_rad_request: add RESPONSE_CODE\n"); goto error; } av_type=rq->REQ_METHOD; if (!rc_avpair_add(rh, &send, attrs[A_SIP_METHOD].v, &av_type, -1, 0)) { LOG(L_ERR, "ERROR: acc_rad_request: add SIP_METHOD\n"); goto error; } /* Handle User-Name as a special case */ user=cred_user(rq); /* try to take it from credentials */ if (user) { realm = cred_realm(rq); if (realm) { user_name.len = user->len+1+realm->len; user_name.s = pkg_malloc(user_name.len); if (!user_name.s) { LOG(L_ERR, "ERROR: acc_rad_request: no memory\n"); goto error; } memcpy(user_name.s, user->s, user->len); user_name.s[user->len] = '@'; memcpy(user_name.s+user->len+1, realm->s, realm->len); if (!rc_avpair_add(rh, &send, attrs[A_USER_NAME].v, user_name.s, user_name.len, 0)) { LOG(L_ERR, "ERROR: acc_rad_request: rc_avpaid_add " "failed for %d\n", attrs[A_USER_NAME].v ); pkg_free(user_name.s); goto error; } pkg_free(user_name.s); } else { user_name.len = user->len; user_name.s = user->s; if (!rc_avpair_add(rh, &send, attrs[A_USER_NAME].v, user_name.s, user_name.len, 0)) { LOG(L_ERR, "ERROR: acc_rad_request: rc_avpaid_add " "failed for %d\n", attrs[A_USER_NAME].v ); goto error; } } } else { /* from from uri */ if (rq->from && (from=get_from(rq)) && from->uri.len) { if (parse_uri(from->uri.s, from->uri.len, &puri) < 0 ) { LOG(L_ERR, "ERROR: acc_rad_request: Bad From URI\n"); goto error; } user_name.len = puri.user.len+1+puri.host.len; user_name.s = pkg_malloc(user_name.len); if (!user_name.s) { LOG(L_ERR, "ERROR: acc_rad_request: no memory\n"); goto error; } memcpy(user_name.s, puri.user.s, puri.user.len); user_name.s[puri.user.len] = '@'; memcpy(user_name.s+puri.user.len+1, puri.host.s, puri.host.len); if (!rc_avpair_add(rh, &send, attrs[A_USER_NAME].v, user_name.s, user_name.len, 0)) { LOG(L_ERR, "ERROR: acc_rad_request: rc_avpaid_add " "failed for %d\n", attrs[A_USER_NAME].v ); pkg_free(user_name.s); goto error; } pkg_free(user_name.s); } else { user_name.len = na.len; user_name.s = na.s; if (!rc_avpair_add(rh, &send, attrs[A_USER_NAME].v, user_name.s, user_name.len, 0)) { LOG(L_ERR, "ERROR: acc_rad_request: rc_avpaid_add " "failed for %d\n", attrs[A_USER_NAME].v ); goto error; } } } /* Remaining attributes from rad_attr vector */ for(i=0; i<attr_cnt; i++) { if (!rc_avpair_add(rh, &send, attrs[rad_attr[i]].v, val_arr[i]->s,val_arr[i]->len, 0)) { LOG(L_ERR, "ERROR: acc_rad_request: rc_avpaid_add " "failed for %s\n", attrs[rad_attr[i]].n ); goto error; } } if (rc_acct(rh, SIP_PORT, send)!=OK_RC) { LOG(L_ERR, "ERROR: acc_rad_request: radius-ing failed\n"); goto error; } rc_avpair_free(send); return 1; error: rc_avpair_free(send); return -1; }