📄 acc.c
字号:
} } /* call-legs also get inserted */ if (multileg_enabled) { BEGIN_loop_all_legs; if (!rc_avpair_add(rh, &send, attrs[A_SRC_LEG].v, src?src_val.s.s:NA,src?src_val.s.len:NA_LEN, 0)) { LOG(L_ERR, "ERROR: acc_rad_request: rc_avpaid_add " "failed for %d\n", attrs[A_SRC_LEG].v ); goto error; } if (!rc_avpair_add(rh, &send, attrs[A_DST_LEG].v, dst?dst_val.s.s:NA,dst?dst_val.s.len:NA_LEN, 0)) { LOG(L_ERR, "ERROR: acc_rad_request: rc_avpaid_add " "failed for %d\n", attrs[A_DST_LEG].v ); goto error; } END_loop_all_legs; } av_type=(UINT4)time(0); /* unix time */ if (!rc_avpair_add(rh, &send, attrs[A_TIME_STAMP].v, &av_type, -1, 0)) { LOG(L_ERR, "ERROR: acc_rad_request: add TIME_STAMP\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;}void acc_rad_missed( struct cell* t, struct sip_msg *req, struct sip_msg *reply, unsigned int code ){ str acc_text; get_reply_status(&acc_text, reply, code); if (acc_text.s==0) { LOG(L_ERR, "ERROR: acc_rad_missed_report: " "get_reply_status failed\n" ); return; } acc_rad_request( req, valid_to(t,reply), &acc_text); pkg_free(acc_text.s);}void acc_rad_ack( struct cell* t, struct sip_msg *req, struct sip_msg *ack ){ str code_str; code_str.s=int2str(t->uas.status, &code_str.len); acc_rad_request(ack, ack->to ? ack->to : req->to, &code_str);}void acc_rad_reply( struct cell* t, struct sip_msg *req, struct sip_msg *reply, unsigned int code ){ str code_str; code_str.s=int2str(code, &code_str.len); acc_rad_request( req, valid_to(t,reply), &code_str);}#endif/**************** DIAMETER Support *************************/#ifdef DIAM_ACC#ifndef RAD_ACCinline static unsigned long phrase2code(str *phrase){ unsigned long code; int i; if (phrase->len<3) return 0; code=0; for (i=0;i<3;i++) { if (!(phrase->s[i]>='0' && phrase->s[i]<'9')) return 0; code=code*10+phrase->s[i]-'0'; } return code;}#endifinline unsigned long diam_status(struct sip_msg *rq, str *phrase){ int code; code=phrase2code(phrase); if (code==0) return -1; if ((rq->REQ_METHOD==METHOD_INVITE || rq->REQ_METHOD==METHOD_ACK) && code>=200 && code<300) return AAA_ACCT_START; if ((rq->REQ_METHOD==METHOD_BYE || rq->REQ_METHOD==METHOD_CANCEL)) return AAA_ACCT_STOP; if (code>=200 && code <=300) return AAA_ACCT_EVENT; return -1;}int acc_diam_request( struct sip_msg *rq, struct hdr_field *to, str *phrase ){ static str* val_arr[DIAM_ACC_FMT_LEN+MAX_ACC_EXTRA]; static str atr_arr[DIAM_ACC_FMT_LEN+MAX_ACC_EXTRA]; int attr_cnt; int extra_attr_cnt; AAAMessage *send = NULL; AAA_AVP *avp; int i; int dummy_len; str* user; str* realm; str user_name; str value; str *uri; struct sip_uri puri; struct to_body* from; int ret, free_user_name; int status; char tmp[2]; unsigned int mid; if (skip_cancel(rq)) return 1; attr_cnt=fmt2strar( DIAM_ACC_FMT, rq, to, phrase, &dummy_len, &dummy_len, val_arr, atr_arr); if (attr_cnt!=DIAM_ACC_FMT_LEN) { LOG(L_ERR, "ERROR: acc_diam_request: fmt2strar failed\n"); return -1; } extra_attr_cnt = extra2strar( dia_extra, rq, &dummy_len, &dummy_len, atr_arr+attr_cnt, val_arr+attr_cnt); if ( (send=AAAInMessage(ACCOUNTING_REQUEST, AAA_APP_NASREQ))==NULL) { LOG(L_ERR, "ERROR: acc_diam_request: new AAA message not created\n"); return -1; } /* AVP_ACCOUNTIG_RECORD_TYPE */ if( (status = diam_status(rq, phrase))<0) { LOG(L_ERR, "ERROR: acc_diam_request: 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) { LOG(L_ERR,"ERROR: acc_diam_request: no more free memory!\n"); goto error; } if( AAAAddAVPToMessage(send, avp, 0)!= AAA_ERR_SUCCESS) { LOG(L_ERR, "ERROR: acc_diam_request: avp not added \n"); AAAFreeAVP(&avp); goto error; } /* SIP_MSGID AVP */ DBG("**ACC***** m_id=%d\n", rq->id); mid = rq->id; if( (avp=AAACreateAVP(AVP_SIP_MSGID, 0, 0, (char*)(&mid), sizeof(mid), AVP_DUPLICATE_DATA)) == 0) { LOG(L_ERR, M_NAME":diameter_authorize(): no more free memory!\n"); goto error; } if( AAAAddAVPToMessage(send, avp, 0)!= AAA_ERR_SUCCESS) { LOG(L_ERR, M_NAME":diameter_authorize(): 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) { LOG(L_ERR,"ERROR: acc_diam_request: no more free memory!\n"); goto error; } if( AAAAddAVPToMessage(send, avp, 0)!= AAA_ERR_SUCCESS) { LOG(L_ERR, "ERROR: acc_diam_request: avp not added \n"); AAAFreeAVP(&avp); goto error; } /* SIP_STATUS avp */ if( (avp=AAACreateAVP(AVP_SIP_STATUS, 0, 0, phrase->s, phrase->len, AVP_DUPLICATE_DATA)) == 0) { LOG(L_ERR,"ERROR: acc_diam_request: no more free memory!\n"); goto error; } if( AAAAddAVPToMessage(send, avp, 0)!= AAA_ERR_SUCCESS) { LOG(L_ERR, "ERROR: acc_diam_request: avp not added \n"); AAAFreeAVP(&avp); goto error; } /* SIP_METHOD avp */ value = rq->first_line.u.request.method; if( (avp=AAACreateAVP(AVP_SIP_METHOD, 0, 0, value.s, value.len, AVP_DUPLICATE_DATA)) == 0) { LOG(L_ERR,"ERROR: acc_diam_request: no more free memory!\n"); goto error; } if( AAAAddAVPToMessage(send, avp, 0)!= AAA_ERR_SUCCESS) { LOG(L_ERR, "ERROR: acc_diam_request: avp not added \n"); AAAFreeAVP(&avp); goto error; } /* Handle AVP_USER_NAME as a special case */ free_user_name = 0; 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_diam_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); free_user_name = 1; } else { user_name.len = user->len; user_name.s = user->s; } } 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_diam_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_diam_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); free_user_name = 1; } else { user_name.len = na.len; user_name.s = na.s; } } if( (avp=AAACreateAVP(AVP_User_Name, 0, 0, user_name.s, user_name.len, free_user_name?AVP_FREE_DATA:AVP_DUPLICATE_DATA)) == 0) { LOG(L_ERR,"ERROR: acc_diam_request: no more free memory!\n"); if(free_user_name) pkg_free(user_name.s); goto error; } if( AAAAddAVPToMessage(send, avp, 0)!= AAA_ERR_SUCCESS) { LOG(L_ERR, "ERROR: acc_diam_request: avp not added \n"); AAAFreeAVP(&avp); goto error; } /* Remaining attributes from diam_attr vector */ for(i=0; i<attr_cnt; i++) { if((avp=AAACreateAVP(diam_attr[i], 0,0, val_arr[i]->s, val_arr[i]->len, AVP_DUPLICATE_DATA)) == 0) { LOG(L_ERR,"ERROR: acc_diam_request: no more free memory!\n"); goto error; } if( AAAAddAVPToMessage(send, avp, 0)!= AAA_ERR_SUCCESS) { LOG(L_ERR, "ERROR: acc_diam_request: avp not added \n"); AAAFreeAVP(&avp); goto error; } } /* also the extra */ for(i=attr_cnt; i<attr_cnt+extra_attr_cnt; i++) { if((avp=AAACreateAVP(atr_arr[i].len/*AVP code*/, 0, 0, val_arr[i]->s, val_arr[i]->len, AVP_DUPLICATE_DATA)) == 0) { LOG(L_ERR,"ERROR: acc_diam_request: no more free memory!\n"); goto error; } if( AAAAddAVPToMessage(send, avp, 0)!= AAA_ERR_SUCCESS) { LOG(L_ERR, "ERROR: acc_diam_request: avp not added \n"); AAAFreeAVP(&avp); goto error; } } if (get_uri(rq, &uri) < 0) { LOG(L_ERR, "ERROR: acc_diam_request: From/To URI not found\n"); goto error; } if (parse_uri(uri->s, uri->len, &puri) < 0) { LOG(L_ERR, "ERROR: acc_diam_request: Error parsing 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) { LOG(L_ERR,"acc_diam_request: no more free memory!\n"); goto error; } if( AAAAddAVPToMessage(send, avp, 0)!= AAA_ERR_SUCCESS) { LOG(L_ERR, "acc_diam_request: avp not added \n"); AAAFreeAVP(&avp); goto error; } /* prepare the message to be sent over the network */ if(AAABuildMsgBuffer(send) != AAA_ERR_SUCCESS) { LOG(L_ERR, "ERROR: acc_diam_request: 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) { LOG(L_ERR, M_NAME":acc_diam_request: 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, rq->id); if(ret == AAA_CONN_CLOSED) { LOG(L_NOTICE, M_NAME":acc_diam_request: 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 */ { LOG(L_ERR, M_NAME":acc_diam_request: message sending to the" " DIAMETER backend authorization server failed\n"); goto error; } AAAFreeMessage(&send); return 1;error: AAAFreeMessage(&send); return -1;}void acc_diam_missed( struct cell* t, struct sip_msg *req, struct sip_msg *reply, unsigned int code ){ str acc_text; get_reply_status(&acc_text, reply, code); acc_diam_request( req, valid_to(t,reply), &acc_text);}void acc_diam_ack( struct cell* t, struct sip_msg *req, struct sip_msg *ack ){ str code_str; code_str.s=int2str(t->uas.status, &code_str.len); acc_diam_request(ack, ack->to ? ack->to : req->to, &code_str);}void acc_diam_reply( struct cell* t , struct sip_msg *req, struct sip_msg *reply, unsigned int code ){ str code_str; code_str.s=int2str(code, &code_str.len); acc_diam_request(req, valid_to(t, reply), &code_str);}#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -