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

📄 acc.c

📁 SIP Express Router, Linux下的SIP代理服务器,小巧实用,开发测试VoIP设备和应用的必备.
💻 C
📖 第 1 页 / 共 2 页
字号:
{	str code_str;	code_str.s=int2str(t->uas.status, &code_str.len);	acc_db_request(ack, ack->to ? ack->to : t->uas.request->to,			&code_str, db_table_acc, SQL_ACC_FMT);}void acc_db_reply(  struct cell* t , struct sip_msg *reply,	unsigned int code ){	str code_str;	code_str.s=int2str(code, &code_str.len);	acc_db_request(t->uas.request, 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 ){	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;}void acc_rad_missed( struct cell* t, 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(t->uas.request, valid_to(t,reply), &acc_text);	pkg_free(acc_text.s);}void acc_rad_ack(  struct cell* t , 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 : t->uas.request->to,			&code_str);}void acc_rad_reply(  struct cell* t , struct sip_msg *reply,	unsigned int code ){	str code_str;	code_str.s=int2str(code, &code_str.len);	acc_rad_request(t->uas.request, 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 (rq->REQ_METHOD==METHOD_OTHER/*MESSAGE */ && code>=200 && code <=300)  		return AAA_ACCT_EVENT;		return -1;}int acc_diam_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;	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!=(sizeof(DIAM_ACC_FMT)-1)) 	{		LOG(L_ERR, "ERROR: acc_diam_request: fmt2strar failed\n");		return -1;	}		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;		}	}			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 *reply, unsigned int code ){	str acc_text;	get_reply_status(&acc_text, reply, code);	acc_diam_request(t->uas.request, valid_to(t,reply), &acc_text);}void acc_diam_ack( struct cell* t, 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 : t->uas.request->to,			&code_str);}void acc_diam_reply( struct cell* t , struct sip_msg *reply, unsigned int code ){	str code_str;	code_str.s=int2str(code, &code_str.len);	acc_diam_request(t->uas.request, valid_to(t, reply), &code_str);}#endif

⌨️ 快捷键说明

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