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

📄 acc_mod.c

📁 用来作为linux中SIP SERVER,完成VOIP网络电话中服务器的功能
💻 C
📖 第 1 页 / 共 2 页
字号:
	if (service_type != -1)		vals[V_SIP_SESSION].v = service_type;#endif	return 0;}static int child_init(int rank){#ifdef SQL_ACC	if (acc_db_init()<0)		return -1;#endif/* DIAMETER */#ifdef DIAM_ACC	/* open TCP connection */	DBG(M_NAME": Initializing TCP connection\n");	sockfd = init_mytcp(diameter_client_host, diameter_client_port);	if(sockfd==-1) 	{		DBG(M_NAME": TCP connection not established\n");		return -1;	}	DBG(M_NAME": TCP connection established on sockfd=%d\n", sockfd);	/* every child with its buffer */	rb = (rd_buf_t*)pkg_malloc(sizeof(rd_buf_t));	if(!rb)	{		DBG("acc: mod_child_init: no more free memory\n");		return -1;	}	rb->buf = 0;#endif	return 0;}static void destroy(void){#ifdef SQL_ACC	acc_db_close();#endif#ifdef DIAM_ACC	close_tcp_connection(sockfd);#endif}static inline void acc_preparse_req(struct sip_msg *rq){	/* try to parse from for From-tag for accounted transactions; 	 * don't be worried about parsing outcome -- if it failed, 	 * we will report N/A	 */	parse_headers(rq, HDR_CALLID| HDR_FROM| HDR_TO, 0 );	parse_from_header(rq);	if (strchr(log_fmt, 'p') || strchr(log_fmt, 'D')) {		parse_orig_ruri(rq);	}}/* prepare message and transaction context for later accounting */static void acc_onreq( struct cell* t, int type, struct tmcb_params *ps ){	int tmcb_types;	if (is_acc_on(ps->req) || is_mc_on(ps->req)) {		/* install addaitional handlers */		tmcb_types =			/* report on completed transactions */			TMCB_RESPONSE_OUT |			/* account e2e acks if configured to do so */			TMCB_E2EACK_IN |			/* report on missed calls */			TMCB_ON_FAILURE_RO |			/* get incoming replies ready for processing */			TMCB_RESPONSE_IN;		if (tmb.register_tmcb( 0, t, tmcb_types, tmcb_func, 0 )<=0) {			LOG(L_ERR,"ERROR:acc:acc_onreq: cannot register additional "				"callbacks\n");			return;		}		/* do some parsing in advance */		acc_preparse_req(ps->req);		/* also, if that is INVITE, disallow silent t-drop */		if (ps->req->REQ_METHOD==METHOD_INVITE) {			DBG("DEBUG: noisy_timer set for accounting\n");			t->flags |= T_NOISY_CTIMER_FLAG;		}	}}/* is this reply of interest for accounting ? */static inline int should_acc_reply(struct cell *t, int code){	struct sip_msg *r;	r=t->uas.request;	/* validation */	if (r==0) {		LOG(L_ERR, "ERROR: acc: should_acc_reply: 0 request\n");		return 0;	}	/* negative transactions reported otherwise only if explicitly 	 * demanded */	if (!failed_transactions && code >=300) return 0;	if (!is_acc_on(r))		return 0;	if (skip_cancel(r))		return 0;	if (code < 200 && ! (early_media && code==183))		return 0;	return 1; /* seed is through, we will account this reply */}/* parse incoming replies before cloning */static inline void acc_onreply_in(struct cell *t, struct sip_msg *reply,	int code, void *param){	/* validation */	if (t->uas.request==0) {		LOG(L_ERR, "ERROR: acc: should_acc_reply: 0 request\n");		return;	}	/* don't parse replies in which we are not interested */	/* missed calls enabled ? */	if (((is_invite(t) && code>=300 && is_mc_on(t->uas.request))					|| should_acc_reply(t,code)) 				&& (reply && reply!=FAKED_REPLY)) {		parse_headers(reply, HDR_TO, 0 );	}}/* initiate a report if we previously enabled MC accounting for this t */static inline void on_missed(struct cell *t, struct sip_msg *reply,	int code, void *param ){	int reset_lmf; #ifdef SQL_ACC	int reset_dmf;#endif#ifdef RAD_ACC	int reset_rmf;#endif/* DIAMETER */#ifdef DIAM_ACC	int reset_dimf;#endif	/* validation */	if (t->uas.request==0) {		DBG("DBG: acc: on_missed: no uas.request, local t; skipping\n");		return;	}	if (is_invite(t) && code>=300) {		if (is_log_mc_on(t->uas.request)) {			acc_log_missed( t, reply, code);			reset_lmf=1;		} else reset_lmf=0;#ifdef SQL_ACC		if (is_db_mc_on(t->uas.request)) {			acc_db_missed( t, reply, code);			reset_dmf=1;		} else reset_dmf=0;#endif#ifdef RAD_ACC		if (is_rad_mc_on(t->uas.request)) {			acc_rad_missed(t, reply, code );			reset_rmf=1;		} else reset_rmf=0;#endif/* DIAMETER */#ifdef DIAM_ACC		if (is_diam_mc_on(t->uas.request)) {			acc_diam_missed(t, reply, code );			reset_dimf=1;		} else reset_dimf=0;#endif		/* we report on missed calls when the first		 * forwarding attempt fails; we do not wish to		 * report on every attempt; so we clear the flags; 		 * we do it after all reporting is over to be sure		 * that all reporting functions got a fair chance		 */		if (reset_lmf) resetflag(t->uas.request, log_missed_flag);#ifdef SQL_ACC		if (reset_dmf) resetflag(t->uas.request, db_missed_flag);#endif#ifdef RAD_ACC		if (reset_rmf) resetflag(t->uas.request, radius_missed_flag);#endif/* DIAMETER */	#ifdef DIAM_ACC		if (reset_dimf) resetflag(t->uas.request, diameter_missed_flag);#endif	}}/* initiate a report if we previously enabled accounting for this t */static inline void acc_onreply( struct cell* t, struct sip_msg *reply,	int code, void *param ){	/* validation */	if (t->uas.request==0) {		DBG("DBG: acc: onreply: no uas.request, local t; skipping\n");		return;	}	/* acc_onreply is bound to TMCB_REPLY which may be called	   from _reply, like when FR hits; we should not miss this	   event for missed calls either	*/	on_missed(t, reply, code, param );	if (!should_acc_reply(t, code)) return;	if (is_log_acc_on(t->uas.request))		acc_log_reply(t, reply, code);#ifdef SQL_ACC	if (is_db_acc_on(t->uas.request))		acc_db_reply(t, reply, code);#endif#ifdef RAD_ACC	if (is_rad_acc_on(t->uas.request))		acc_rad_reply(t, reply, code);#endif/* DIAMETER */#ifdef DIAM_ACC	if (is_diam_acc_on(t->uas.request))		acc_diam_reply(t, reply, code);#endif}static inline void acc_onack( struct cell* t , struct sip_msg *ack,	int code, void *param ){	/* only for those guys who insist on seeing ACKs as well */	if (!report_ack) return;	/* if acc enabled for flagged transaction, check if flag matches */	if (is_log_acc_on(t->uas.request)) {		acc_preparse_req(ack);		acc_log_ack(t, ack);	}#ifdef SQL_ACC	if (is_db_acc_on(t->uas.request)) {		acc_preparse_req(ack);		acc_db_ack(t, ack);	}#endif#ifdef RAD_ACC	if (is_rad_acc_on(t->uas.request)) {		acc_preparse_req(ack);		acc_rad_ack(t,ack);	}#endif/* DIAMETER */#ifdef DIAM_ACC	if (is_diam_acc_on(t->uas.request)) {		acc_preparse_req(ack);		acc_diam_ack(t,ack);	}#endif	}static void tmcb_func( struct cell* t, int type, struct tmcb_params *ps ){	if (type&TMCB_RESPONSE_OUT) {		acc_onreply( t, ps->rpl, ps->code, ps->param );	} else if (type&TMCB_E2EACK_IN) {		acc_onack( t, ps->req, ps->code, ps->param );	} else if (type&TMCB_ON_FAILURE_RO) {		on_missed( t, ps->rpl, ps->code, ps->param );	} else if (type&TMCB_RESPONSE_IN) {		acc_onreply_in( t, ps->rpl, ps->code, ps->param);	}}/* these wrappers parse all what may be needed; they don't care about * the result -- accounting functions just display "unavailable" if there * is nothing meaningful */static int w_acc_log_request(struct sip_msg *rq, char *comment, char *foo){	str txt; str phrase;	txt.s=ACC_REQUEST;	txt.len=ACC_REQUEST_LEN;	phrase.s=comment;	phrase.len=strlen(comment);	/* fix_param would be faster! */	acc_preparse_req(rq);	return acc_log_request(rq, rq->to, &txt, &phrase);}#ifdef SQL_ACCstatic int w_acc_db_request(struct sip_msg *rq, char *comment, char *table){	str phrase;	phrase.s=comment;	phrase.len=strlen(comment);	/* fix_param would be faster! */	acc_preparse_req(rq);	return acc_db_request(rq, rq->to,&phrase,table, SQL_MC_FMT );}#endif#ifdef RAD_ACCstatic int w_acc_rad_request(struct sip_msg *rq, char *comment, 				char *foo){	str phrase;	phrase.s=comment;	phrase.len=strlen(comment);	/* fix_param would be faster! */	acc_preparse_req(rq);	return acc_rad_request(rq, rq->to,&phrase);}#endif/* DIAMETER */#ifdef DIAM_ACCstatic int w_acc_diam_request(struct sip_msg *rq, char *comment, 				char *foo){	str phrase;	phrase.s=comment;	phrase.len=strlen(comment);	/* fix_param would be faster! */	acc_preparse_req(rq);	return acc_diam_request(rq, rq->to,&phrase);}#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -