Beispiel #1
0
static int mod_init( void )
{
	/* bind the ACC API */
	if (acc_load_api(&accb)<0) {
		LM_ERR("cannot bind to ACC API\n");
		return -1;
	}

	/* parse the extra string, if any */
	if (diameter_extra_str
			&& (diameter_extra=accb.parse_extra(diameter_extra_str))==0 ) {
		LM_ERR("failed to parse diameter_extra param\n");
		return -1;
	}

	memset(&_acc_diameter_engine, 0, sizeof(acc_engine_t));

	if(diameter_flag != -1)
		_acc_diameter_engine.acc_flag	   = diameter_flag;
	if(diameter_missed_flag != -1)
		_acc_diameter_engine.missed_flag = diameter_missed_flag;
	_acc_diameter_engine.acc_req     = acc_diameter_send_request;
	_acc_diameter_engine.acc_init    = acc_diameter_init;
	memcpy(_acc_diameter_engine.name, "diameter", 8);
	if(accb.register_engine(&_acc_diameter_engine)<0)
	{
		LM_ERR("cannot register ACC DIAMETER engine\n");
		return -1;
	}

	return 0;
}
Beispiel #2
0
static int mod_init( void )
{
	if (radius_config==NULL || radius_config[0]=='\0') {
		LM_ERR("radius config file not set\n");
		return -1;
	}

	/* bind the ACC API */
	if (acc_load_api(&accb)<0) {
		LM_ERR("cannot bind to ACC API\n");
		return -1;
	}

	/* parse the extra string, if any */
	if (rad_extra_str && (rad_extra=accb.parse_extra(rad_extra_str))==0 ) {
		LM_ERR("failed to parse rad_extra param\n");
		return -1;
	}

	memset(&_acc_radius_engine, 0, sizeof(acc_engine_t));

	if(radius_flag != -1)
		_acc_radius_engine.acc_flag	   = 1<<radius_flag;
	if(radius_missed_flag != -1)
		_acc_radius_engine.missed_flag = 1<<radius_missed_flag;
	_acc_radius_engine.acc_req     = acc_radius_send_request;
	_acc_radius_engine.acc_init    = acc_radius_init;
	memcpy(_acc_radius_engine.name, "radius", 6);
	if(accb.register_engine(&_acc_radius_engine)<0)
	{
		LM_ERR("cannot register ACC RADIUS engine\n");
		return -1;
	}

	return 0;
}
Beispiel #3
0
static int w_acc_radius_request(struct sip_msg *rq, char *comment, char *foo)
{
	return accb.exec(rq, &_acc_radius_engine, (acc_param_t*)comment);
}
Beispiel #4
0
int acc_radius_send_request(struct sip_msg *req, acc_info_t *inf)
{
	int attr_cnt;
	VALUE_PAIR *send;
	uint32_t av_type;
	int offset;
	int i;
	int m=0;
	int o=0;
	int rc_result=-1;
	double tsecmicro;
	char smicrosec[18];
	
	send=NULL;

	attr_cnt = accb.get_core_attrs( req, inf->varr, inf->iarr, inf->tarr );
	/* not interested in the last 2 values */
	attr_cnt -= 2;

	av_type = rad_status( req, inf->env->code); /* RADIUS status */
	ADD_RAD_AVPAIR( RA_ACCT_STATUS_TYPE, &av_type, -1);

	av_type = rd_vals[RV_SIP_SESSION].v; /* session*/
	ADD_RAD_AVPAIR( RA_SERVICE_TYPE, &av_type, -1);

	av_type = (uint32_t)inf->env->code; /* status=integer */
	ADD_RAD_AVPAIR( RA_SIP_RESPONSE_CODE, &av_type, -1);

	av_type = req->REQ_METHOD; /* method */
	ADD_RAD_AVPAIR( RA_SIP_METHOD, &av_type, -1);

	// Event Time Stamp with Microseconds
        if(rad_time_mode==1){
                gettimeofday(&inf->env->tv, NULL);
                tsecmicro=inf->env->tv.tv_sec+((double)inf->env->tv.tv_usec/1000000.0);
                //radius client doesn t support double so convert it
                sprintf(smicrosec,"%17.6f",tsecmicro);
                ADD_RAD_AVPAIR(RA_TIME_STAMP, &smicrosec, -1);
        }else{
                av_type = (uint32_t)inf->env->ts;
                ADD_RAD_AVPAIR(RA_TIME_STAMP, &av_type, -1);
        }


	/* add extra also */
	o = accb.get_extra_attrs(rad_extra, req, inf->varr+attr_cnt,
			inf->iarr+attr_cnt, inf->tarr+attr_cnt);
	attr_cnt += o;
	m = attr_cnt;


	/* add the values for the vector - start from 1 instead of
	 * 0 to skip the first value which is the METHOD as string */
	offset = RA_STATIC_MAX-1;
	for( i=1; i<attr_cnt; i++) {
		switch (inf->tarr[i]) {
			case TYPE_STR:
				ADD_RAD_AVPAIR(offset+i, inf->varr[i].s, inf->varr[i].len);
				break;
			case TYPE_INT:
				ADD_RAD_AVPAIR(offset+i, &(inf->iarr[i]), -1);
				break;
			default:
				break;
		}
	}

	/* call-legs attributes also get inserted */
	if ( inf->leg_info ) {
		offset += attr_cnt;
		attr_cnt = accb.get_leg_attrs(inf->leg_info,req,inf->varr,inf->iarr,inf->tarr,1);
		do {
			for (i=0; i<attr_cnt; i++)
				ADD_RAD_AVPAIR( offset+i, inf->varr[i].s, inf->varr[i].len );
		}while ( (attr_cnt=accb.get_leg_attrs(inf->leg_info,req,inf->varr,inf->iarr,
						inf->tarr, 0))!=0 );
	}

	rc_result=rc_acct(rh, SIP_PORT, send);

        if (rc_result==ERROR_RC) {
                LM_ERR("Radius accounting - ERROR - \n");
                goto error;
        }else if(rc_result==BADRESP_RC){
                LM_ERR("Radius accounting - BAD RESPONSE \n");
                goto error;
        }else if(rc_result==TIMEOUT_RC){
                LM_ERR("Radius accounting - TIMEOUT \n");
                goto error;
        }else if(rc_result==REJECT_RC){
                LM_ERR("Radius accounting - REJECTED \n");
                goto error;
        }else if(rc_result==OK_RC){
                LM_DBG("Radius accounting - OK \n");
        }else{
        	LM_ERR("Radius accounting - Unknown response \n");
                goto error;
        }

        rc_avpair_free(send);
        /* free memory allocated by extra2strar */
        free_strar_mem( &(inf->tarr[m-o]), &(inf->varr[m-o]), o, m);
        return 1;

error:
	rc_avpair_free(send);
	/* free memory allocated by extra2strar */
	free_strar_mem( &(inf->tarr[m-o]), &(inf->varr[m-o]), o, m);
	return -1;
}
Beispiel #5
0
int acc_radius_send_request(struct sip_msg *req, acc_info_t *inf)
{
	int attr_cnt;
	VALUE_PAIR *send;
	uint32_t av_type;
	int offset;
	int i;

	send=NULL;

	attr_cnt = accb.get_core_attrs( req, inf->varr, inf->iarr, inf->tarr );
	/* not interested in the last 2 values */
	attr_cnt -= 2;

	av_type = rad_status( req, inf->env->code); /* RADIUS status */
	ADD_RAD_AVPAIR( RA_ACCT_STATUS_TYPE, &av_type, -1);

	av_type = rd_vals[RV_SIP_SESSION].v; /* session*/
	ADD_RAD_AVPAIR( RA_SERVICE_TYPE, &av_type, -1);

	av_type = (uint32_t)inf->env->code; /* status=integer */
	ADD_RAD_AVPAIR( RA_SIP_RESPONSE_CODE, &av_type, -1);

	av_type = req->REQ_METHOD; /* method */
	ADD_RAD_AVPAIR( RA_SIP_METHOD, &av_type, -1);

	/* unix time */
	av_type = (uint32_t)inf->env->ts;
	ADD_RAD_AVPAIR( RA_TIME_STAMP, &av_type, -1);

	/* add extra also */
	attr_cnt += accb.get_extra_attrs(rad_extra, req, inf->varr+attr_cnt,
				inf->iarr+attr_cnt, inf->tarr+attr_cnt);

	/* add the values for the vector - start from 1 instead of
	 * 0 to skip the first value which is the METHOD as string */
	offset = RA_STATIC_MAX-1;
	for( i=1; i<attr_cnt; i++) {
	    switch (inf->tarr[i]) {
	    case TYPE_STR:
		ADD_RAD_AVPAIR(offset+i, inf->varr[i].s, inf->varr[i].len);
		break;
	    case TYPE_INT:
		ADD_RAD_AVPAIR(offset+i, &(inf->iarr[i]), -1);
		break;
	    default:
		break;
	    }
	}

	/* call-legs attributes also get inserted */
	if ( inf->leg_info ) {
		offset += attr_cnt;
		attr_cnt = accb.get_leg_attrs(inf->leg_info,req,inf->varr,inf->iarr,inf->tarr,1);
		do {
			for (i=0; i<attr_cnt; i++)
				ADD_RAD_AVPAIR( offset+i, inf->varr[i].s, inf->varr[i].len );
		}while ( (attr_cnt=accb.get_leg_attrs(inf->leg_info,req,inf->varr,inf->iarr,
					      inf->tarr, 0))!=0 );
	}

	if (rc_acct(rh, SIP_PORT, send)!=OK_RC) {
		LM_ERR("radius-ing failed\n");
		goto error;
	}
	rc_avpair_free(send);
	return 1;

error:
	rc_avpair_free(send);
	return -1;
}
Beispiel #6
0
static int w_acc_diameter_request(sip_msg_t *rq, char *comment, char *foo)
{
	return accb.exec(rq, &_acc_diameter_engine, (acc_param_t*)comment);
}
Beispiel #7
0
int acc_diameter_send_request(sip_msg_t *req, acc_info_t *inf)
{
	int attr_cnt;
	int cnt;
	AAAMessage *send = NULL;
	AAA_AVP *avp;
	struct sip_uri puri;
	str *uri;
	int ret;
	int i;
	int status;
	char tmp[2];
	unsigned int mid;
	int m;
	int o;

	attr_cnt =  accb.get_core_attrs(req, inf->varr, inf->iarr, inf->tarr);
	/* last value is not used */
	attr_cnt--;

	if ( (send=AAAInMessage(ACCOUNTING_REQUEST, AAA_APP_NASREQ))==NULL) {
		LM_ERR("failed to create new AAA request\n");
		return -1;
	}

	m = 0;
	o = 0;
	/* AVP_ACCOUNTIG_RECORD_TYPE */
	if( (status = diam_status(req, inf->env->code))<0) {
		LM_ERR("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) {
		LM_ERR("failed to create AVP:no more free memory!\n");
		goto error;
	}
	if( AAAAddAVPToMessage(send, avp, 0)!= AAA_ERR_SUCCESS) {
		LM_ERR("avp not added \n");
		AAAFreeAVP(&avp);
		goto error;
	}
	/* SIP_MSGID AVP */
	mid = req->id;
	if( (avp=AAACreateAVP(AVP_SIP_MSGID, 0, 0, (char*)(&mid),
					sizeof(mid), AVP_DUPLICATE_DATA)) == 0) {
		LM_ERR("failed to create AVP:no more free memory!\n");
		goto error;
	}
	if( AAAAddAVPToMessage(send, avp, 0)!= AAA_ERR_SUCCESS) {
		LM_ERR("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) {
		LM_ERR("failed to create AVP:no more free memory!\n");
		goto error;
	}
	if( AAAAddAVPToMessage(send, avp, 0)!= AAA_ERR_SUCCESS) {
		LM_ERR("avp not added \n");
		AAAFreeAVP(&avp);
		goto error;
	}

	/* also the extra attributes */
	o = accb.get_extra_attrs(diameter_extra, req, inf->varr+attr_cnt,
			inf->iarr+attr_cnt, inf->tarr+attr_cnt);
	attr_cnt += o;
	m = attr_cnt;

	/* add attributes */
	for(i=0; i<attr_cnt; i++) {
		if((avp=AAACreateAVP(diam_attrs[i], 0,0, inf->varr[i].s, inf->varr[i].len,
						AVP_DUPLICATE_DATA)) == 0) {
			LM_ERR("failed to create AVP: no more free memory!\n");
			goto error;
		}
		if( AAAAddAVPToMessage(send, avp, 0)!= AAA_ERR_SUCCESS) {
			LM_ERR("avp not added \n");
			AAAFreeAVP(&avp);
			goto error;
		}
	}

	/* and the leg attributes */
	if ( inf->leg_info ) {
		cnt = accb.get_leg_attrs(inf->leg_info,req,inf->varr,inf->iarr,inf->tarr,1);
		do {
			for (i=0; i<cnt; i++) {
				if((avp=AAACreateAVP(diam_attrs[attr_cnt+i], 0, 0,
								inf->varr[i].s, inf->varr[i].len, AVP_DUPLICATE_DATA)) == 0) {
					LM_ERR("failed to create AVP: no more free memory!\n");
					goto error;
				}
				if( AAAAddAVPToMessage(send, avp, 0)!= AAA_ERR_SUCCESS) {
					LM_ERR("avp not added \n");
					AAAFreeAVP(&avp);
					goto error;
				}
			}
		} while ( (attr_cnt=accb.get_leg_attrs(inf->leg_info,req,inf->varr,inf->iarr,
						inf->tarr, 0))!=0 );
	}

	if (get_uri(req, &uri) < 0) {
		LM_ERR("failed to get uri, From/To URI not found\n");
		goto error;
	}

	if (parse_uri(uri->s, uri->len, &puri) < 0) {
		LM_ERR("failed to parse 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) {
		LM_ERR("failed to create AVP:no more free memory!\n");
		goto error;
	}

	if( AAAAddAVPToMessage(send, avp, 0)!= AAA_ERR_SUCCESS) {
		LM_ERR("avp not added \n");
		AAAFreeAVP(&avp);
		goto error;
	}

	/* prepare the message to be sent over the network */
	if(AAABuildMsgBuffer(send) != AAA_ERR_SUCCESS) {
		LM_ERR("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) {
			LM_ERR("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, req->id);
	if(ret == AAA_CONN_CLOSED) {
		LM_NOTICE("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 */
		LM_ERR("message sending to the DIAMETER backend authorization "
				"server failed\n");
		goto error;
	}

	AAAFreeMessage(&send);
	/* free memory allocated by extra2strar */
	free_strar_mem( &(inf->tarr[m-o]), &(inf->varr[m-o]), o, m);
	return 1;

error:
	AAAFreeMessage(&send);
	/* free memory allocated by extra2strar */
	free_strar_mem( &(inf->tarr[m-o]), &(inf->varr[m-o]), o, m);
	return -1;
}