📄 acc.c
字号:
A_SEPARATOR_LEN+7+A_EQ_LEN+NA_LEN); p+=A_SEPARATOR_LEN+7+A_EQ_LEN+NA_LEN; } END_loop_all_legs; } /* terminating text */ memcpy(p, A_EOL, A_EOL_LEN); p+=A_EOL_LEN; /* leading text */ p=log_msg; memcpy(p, ACC, ACC_LEN ); p+=ACC_LEN; memcpy(p, txt->s, txt->len); p+=txt->len; LOG(log_level, "%s", log_msg ); return 1;}/******************************************** * acc_missed_report ********************************************/void acc_log_missed( struct cell* t, struct sip_msg *req, struct sip_msg *reply, unsigned int code ){ str acc_text; static str leading_text={ACC_MISSED, ACC_MISSED_LEN}; get_reply_status(&acc_text, reply, code); if (acc_text.s==0) { LOG(L_ERR, "ERROR: acc_missed_report: " "get_reply_status failed\n" ); return; } acc_log_request( req, valid_to(t, reply), &leading_text, &acc_text); pkg_free(acc_text.s);}/******************************************** * acc_reply_report ********************************************/void acc_log_reply( struct cell* t, struct sip_msg *req, struct sip_msg *reply, unsigned int code ){ static str lead={ACC_ANSWERED, ACC_ANSWERED_LEN}; str code_str; code_str.s=int2str(code, &code_str.len); acc_log_request( req, valid_to(t,reply), &lead, &code_str );}/******************************************** * reports for e2e ACKs ********************************************/void acc_log_ack( struct cell* t, struct sip_msg *req, struct sip_msg *ack ){ struct hdr_field *to; static str lead={ACC_ACKED, ACC_ACKED_LEN}; str code_str; if (ack->to) to=ack->to; else to=req->to; code_str.s=int2str(t->uas.status, &code_str.len); acc_log_request(ack, to, &lead, &code_str );}/**************** SQL Support *************************/#ifdef SQL_ACC/* caution: keys need to be aligned to formatting strings */static db_key_t db_keys[ALL_LOG_FMT_LEN+3+MAX_ACC_EXTRA];static db_val_t db_vals[ALL_LOG_FMT_LEN+3+MAX_ACC_EXTRA];/* binds to the corresponding database module * returns 0 on success, -1 on error */int acc_db_bind(char* db_url){ if (bind_dbmod(db_url, &acc_dbf)<0){ LOG(L_ERR, "ERROR:acc:acc_db_init: bind_db failed\n"); return -1; } /* Check database capabilities */ if (!DB_CAPABILITY(acc_dbf, DB_CAP_INSERT)) { LOG(L_ERR, "ERROR:acc:acc_db_init: Database module does not " "implement insert function\n"); return -1; } return 0;}void acc_db_init_keys(){ struct acc_extra *extra; int i; int n; /* init the static db keys */ n = 0; /* caution: keys need to be aligned to formatting strings */ db_keys[n++] = acc_from_uri; db_keys[n++] = acc_to_uri; db_keys[n++] = acc_sip_method_col; db_keys[n++] = acc_i_uri_col; db_keys[n++] = acc_o_uri_col; db_keys[n++] = acc_sip_from_col; db_keys[n++] = acc_sip_callid_col; db_keys[n++] = acc_sip_to_col; db_keys[n++] = acc_sip_status_col; db_keys[n++] = acc_user_col; db_keys[n++] = acc_totag_col; db_keys[n++] = acc_fromtag_col; db_keys[n++] = acc_domain_col; /* init the extra db keys */ for(i=0,extra=db_extra; extra && i<MAX_ACC_EXTRA ; i++,extra=extra->next) db_keys[n++] = extra->name.s; /* time column */ db_keys[n++] = acc_time_col; /* multi leg call columns */ if (multileg_enabled) { db_keys[n++] = acc_src_col; db_keys[n++] = acc_dst_col; } /* init the values */ for(i=0; i<n; i++) { VAL_TYPE(db_vals+i)=DB_STR; VAL_NULL(db_vals+i)=0; }}/* initialize the database connection * returns 0 on success, -1 on error */int acc_db_init(char *db_url){ db_handle=acc_dbf.init(db_url); if (db_handle==0){ LOG(L_ERR, "ERROR:acc:acc_db_init: unable to connect to the " "database\n"); return -1; } acc_db_init_keys(); return 0;}/* close a db connection */void acc_db_close(){ if (db_handle && acc_dbf.close) acc_dbf.close(db_handle);}int acc_db_request( struct sip_msg *rq, struct hdr_field *to, str *phrase, char *table, char *fmt){ static str* val_arr[ALL_LOG_FMT_LEN+3+MAX_ACC_EXTRA]; static str atr_arr[ALL_LOG_FMT_LEN+3+MAX_ACC_EXTRA]; static char time_buf[20]; struct tm *tm; time_t timep; str time_str; int attr_cnt; int i; int dummy_len; leg_loop_VARS; if (skip_cancel(rq)) return 1; /* formated database columns */ attr_cnt=fmt2strar( fmt, rq, to, phrase, &dummy_len, &dummy_len, val_arr, atr_arr); if (!attr_cnt) { LOG(L_ERR, "ERROR:acc:acc_db_request: fmt2strar failed\n"); return -1; } /* extra columns */ attr_cnt += extra2strar( db_extra, rq, &dummy_len, &dummy_len, atr_arr+attr_cnt, val_arr+attr_cnt); for(i=0; i<attr_cnt; i++) VAL_STR(db_vals+i)=*val_arr[i]; /* time column */ timep = time(NULL); tm = db_localtime ? localtime(&timep) : gmtime(&timep); time_str.len = strftime(time_buf, 20, "%Y-%m-%d %H:%M:%S", tm); time_str.s = time_buf; VAL_STR( db_vals + (attr_cnt++) ) = time_str; if (acc_dbf.use_table(db_handle, table) < 0) { LOG(L_ERR, "ERROR:acc:acc_db_request: Error in use_table\n"); return -1; } if ( !multileg_enabled ) { if (acc_dbf.insert(db_handle, db_keys, db_vals, attr_cnt) < 0) { LOG(L_ERR, "ERROR:acc:acc_db_request: " "Error while inserting to database\n"); return -1; } } else { BEGIN_loop_all_legs; VAL_STR(db_vals+attr_cnt+0) = src?(src_val.s):na; VAL_STR(db_vals+attr_cnt+1) = dst?(dst_val.s):na; if (acc_dbf.insert(db_handle, db_keys, db_vals, attr_cnt+2) < 0) { LOG(L_ERR, "ERROR:acc:acc_db_request: " "Error while inserting to database\n"); return -1; } END_loop_all_legs; } return 1;}void acc_db_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_db_missed_report: " "get_reply_status failed\n" ); return; } acc_db_request(req, valid_to(t,reply), &acc_text, db_table_mc, SQL_MC_FMT); pkg_free(acc_text.s);}void acc_db_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_db_request(ack, ack->to ? ack->to : req->to, &code_str, db_table_acc, SQL_ACC_FMT);}void acc_db_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_db_request(req, valid_to(t,reply), &code_str, db_table_acc, SQL_ACC_FMT);}#endif/**************** RADIUS Support *************************/#ifdef RAD_ACCinline static UINT4 phrase2code(str *phrase){ UINT4 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;}inline UINT4 rad_status(struct sip_msg *rq, str *phrase){ int code; code=phrase2code(phrase); if (code==0) return vals[V_STATUS_FAILED].v; if ((rq->REQ_METHOD==METHOD_INVITE || rq->REQ_METHOD==METHOD_ACK) && code>=200 && code<300) return vals[V_STATUS_START].v; if ((rq->REQ_METHOD==METHOD_BYE || rq->REQ_METHOD==METHOD_CANCEL)) return vals[V_STATUS_STOP].v; return vals[V_STATUS_FAILED].v;}int acc_rad_request( struct sip_msg *rq, struct hdr_field *to, str *phrase ){ static str* val_arr[RAD_ACC_FMT_LEN+MAX_ACC_EXTRA]; static str atr_arr[RAD_ACC_FMT_LEN+MAX_ACC_EXTRA]; int attr_cnt; int extra_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; leg_loop_VARS; 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!=RAD_ACC_FMT_LEN) { LOG(L_ERR, "ERROR: acc_rad_request: fmt2strar failed\n"); goto error; } extra_attr_cnt = extra2strar( rad_extra, rq, &dummy_len, &dummy_len, atr_arr+attr_cnt, val_arr+attr_cnt); av_type=rad_status(rq, phrase); /* status */ 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; /* session*/ 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 (!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; /* 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; } } /* add extra also */ for(i=attr_cnt; i<attr_cnt+extra_attr_cnt; i++) { if (!rc_avpair_add(rh, &send, attrs[atr_arr[i].len].v, val_arr[i]->s,val_arr[i]->len, 0)) { LOG(L_ERR, "ERROR: acc_rad_request: rc_avpaid_add " "failed for extra %s {%d,%d,%d} val {%p,%d}\n", atr_arr[i].s, i, atr_arr[i].len, attrs[atr_arr[i].len].v, val_arr[i]->s, val_arr[i]->len); goto error;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -