⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 acc.c

📁 性能优秀的SIP Proxy
💻 C
📖 第 1 页 / 共 3 页
字号:
				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 + -