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

📄 avpops_impl.c

📁 用来作为linux中SIP SERVER,完成VOIP网络电话中服务器的功能
💻 C
📖 第 1 页 / 共 2 页
字号:
			LOG(L_ERR,"ERROR:avpops:dbdelete_avps: failed to get uri\n");			goto error;		}		/* do DB delete */		res = db_delete_avp(0, (sp->flags&AVPOPS_FLAG_DOMAIN)?&empty:&uri.user,				(use_domain||(sp->flags&AVPOPS_FLAG_DOMAIN))?&uri.host:0,				dbp->sa.s, dbp->table);	} else if (sp->flags&AVPOPS_VAL_AVP) {		/* get uuid from avp */		if (get_avp_as_str( sp, &uuid)<0)		{			LOG(L_ERR,"ERROR:avpops:dbdelete_avps: failed to get uuid\n");			goto error;		}		/* do DB delete */		res = db_delete_avp( &uuid, 0, 0, dbp->sa.s, dbp->table);	} else if (sp->flags&AVPOPS_VAL_STR) {		/* use the STR value as uuid */		/* do DB delete */		res = db_delete_avp( sp->val.s, 0, 0, dbp->sa.s, dbp->table );	} else {		LOG(L_CRIT,"BUG:avpops:dbdelete_avps: invalid flag combination (%d)\n",			sp->flags);		goto error;	}	/* res ?  */	if (res<0)	{		LOG(L_ERR,"ERROR:avpops:dbdelete_avps: db_delete failed\n");		goto error;	}	return 1;error:	return -1;}int ops_write_avp(struct sip_msg* msg, struct fis_param *src,													struct fis_param *ap){	struct sip_uri uri;	int_str avp_val;	unsigned short flags;	str s_ip;	if (src->flags&AVPOPS_VAL_NONE)	{		if (src->flags&AVPOPS_USE_SRC_IP)		{			/* get data from src_ip */			if ( (s_ip.s=ip_addr2a( &msg->rcv.src_ip ))==0)			{				LOG(L_ERR,"ERROR:avpops:write_avp: cannot get src_ip\n");				goto error;			}			s_ip.len = strlen(s_ip.s);			avp_val.s = &s_ip;		} else {			/* get data from uri (from,to,ruri) */			if (src->flags&(AVPOPS_FLAG_USER|AVPOPS_FLAG_DOMAIN))			{				if (parse_source_uri( msg, src->flags, &uri)!=0 )				{					LOG(L_ERR,"ERROR:avpops:write_avp: cannot parse uri\n");					goto error;				}				if (src->flags&AVPOPS_FLAG_DOMAIN)					avp_val.s = &uri.host;				else					avp_val.s = &uri.user;			} else {				/* get whole uri */				if ( (avp_val.s=get_source_uri(msg,src->flags))==0 )				{					LOG(L_ERR,"ERROR:avpops:write_avp: cannot get uri\n");					goto error;				}			}		}		flags = AVP_VAL_STR;	} else {		avp_val = src->val;		flags = (src->flags&AVPOPS_VAL_INT)?0:AVP_VAL_STR;	}	/* set the proper flag */	flags |=  (ap->flags&AVPOPS_VAL_INT)?0:AVP_NAME_STR;	/* added the avp */	if (add_avp( flags, ap->val, avp_val)<0)		goto error;	return 1;error:	return -1;}int ops_delete_avp(struct sip_msg* msg, struct fis_param *ap){	struct usr_avp **avp_list;	struct usr_avp *avp;	struct usr_avp *avp_next;	unsigned short name_type;	int n;	n = 0;	if ( (ap->flags&AVPOPS_VAL_NONE)==0)	{		/* avp name is known ->search by name */		name_type = (((ap->flags&AVPOPS_VAL_INT))?0:AVP_NAME_STR);		while ( (avp=search_first_avp( name_type, ap->val, 0))!=0 )		{			destroy_avp( avp );			n++;			if ( !(ap->flags&AVPOPS_FLAG_ALL) )				break;		}	} else {		/* avp name is not given - we have just flags */		/* -> go through all list */		avp_list = get_avp_list();		avp = *avp_list;		for ( ; avp ; avp=avp_next )		{			avp_next = avp->next;			/* check if type match */			if ( !( (ap->flags&(AVPOPS_VAL_INT|AVPOPS_VAL_STR))==0 ||			((ap->flags&AVPOPS_VAL_INT)&&((avp->flags&AVP_NAME_STR))==0) ||			((ap->flags&AVPOPS_VAL_STR)&&(avp->flags&AVP_NAME_STR)) )  )				continue;			/* remove avp */			destroy_avp( avp );			n++;			if ( !(ap->flags&AVPOPS_FLAG_ALL) )				break;		}	}	DBG("DEBUG:avpops:remove_avps: %d avps were removed\n",n);	return n?1:-1;}#define STR_BUF_SIZE  1024static char str_buf[STR_BUF_SIZE];inline static int compose_hdr(str *name, str *val, str *hdr, int new){	char *p;	char *s;	int len;	len = name->len+2+val->len+CRLF_LEN;	if (new)	{		if ( (s=(char*)pkg_malloc(len))==0 )		{			LOG(L_ERR,"ERROR:avpops:compose_hdr: no more pkg mem\n");			return -1;		}	} else {		if ( len>STR_BUF_SIZE )			return -1;		s = str_buf;	}	p = s;	memcpy(p, name->s, name->len);	p += name->len;	*(p++) = ':';	*(p++) = ' ';	memcpy(p, val->s, val->len);	p += val->len;	memcpy(p, CRLF, CRLF_LEN);	p += CRLF_LEN;	if (len!=p-s)	{		LOG(L_CRIT,"BUG:avpops:compose_hdr: buffer overflow\n");		return -1;	}	hdr->len = len;	hdr->s = s;	return 0;}inline static int append_0(str *in, str *out){	if (in->len+1>STR_BUF_SIZE)		return -1;	memcpy( str_buf, in->s, in->len);	str_buf[in->len] = 0;	out->len = in->len;	out->s = str_buf;	return 0;}int ops_pushto_avp ( struct sip_msg* msg, struct fis_param* dst,													struct fis_param* ap){	struct lump    *anchor;	struct action  act;	struct usr_avp *avp;	unsigned short name_type;	int_str        avp_val;	str            val;	int            act_type;	int            n;	/* search for the avp */	name_type = (((ap->flags&AVPOPS_VAL_INT))?0:AVP_NAME_STR);	avp = search_first_avp( name_type, ap->val, &avp_val);	if (avp==0)	{		DBG("DEBUG:avpops:pushto_avp: no avp found\n");		return -1;	}	n = 0;	while (avp)	{		/* the avp val will be used all the time as str */		if (avp->flags&AVP_VAL_STR) {			val = *(avp_val.s);		} else {			val.s = int2str((unsigned long)avp_val.n, &val.len);		}		act_type = 0;		/* push the value into right position */		if (dst->flags&AVPOPS_USE_RURI)		{			if (dst->flags&AVPOPS_FLAG_USER)				act_type = SET_USER_T;			else if (dst->flags&AVPOPS_FLAG_DOMAIN)				act_type = SET_HOST_T;			else				act_type = SET_URI_T;			if ( avp->flags&AVP_VAL_STR && append_0( &val, &val)!=0 ) {				LOG(L_ERR,"ERROR:avpops:pushto_avp: failed to make 0 term.\n");				goto error;			}		} else if (dst->flags&(AVPOPS_USE_HDRREQ|AVPOPS_USE_HDRRPL)) {			if ( compose_hdr( dst->val.s, &val, &val,				dst->flags&AVPOPS_USE_HDRREQ)<0 )			{				LOG(L_ERR,"ERROR:avpops:pushto_avp: failed to build hdr\n");				goto error;			}		} else {			LOG(L_CRIT,"BUG:avpops:pushto_avp: destination unknown (%d)\n",				dst->flags);			goto error;		}			if ( act_type )		{			/* rewrite part of ruri */			if (n)			{				/* if is not the first modification, push the current uri as				 * branch */				if (append_branch( msg, 0, 0, 0, 0, 0)!=1 )				{					LOG(L_ERR,"ERROR:avpops:pushto_avp: append_branch action"						" failed\n");					goto error;				}			}			memset(&act, 0, sizeof(act));			act.p1_type = STRING_ST;			act.p1.string = val.s;			act.type = act_type;			if (do_action(&act, msg)<0)			{				LOG(L_ERR,"ERROR:avpops:pushto_avp: SET_XXXX_T action"					" failed\n");				goto error;			}		} else if (dst->flags==AVPOPS_USE_HDRRPL) {			/* set a header for reply */			if (add_lump_rpl( msg , val.s, val.len, LUMP_RPL_HDR )==0)			{				LOG(L_ERR,"ERROR:avpops:pushto_avp: add_lump_rpl failed\n");				goto error;			}		} else {			/* set a header for request */			if (parse_headers(msg, HDR_EOH, 0)==-1)			{				LOG(L_ERR, "ERROR:avpops:pushto_avp: message parse failed\n");				goto error;			}			anchor = anchor_lump( msg, msg->unparsed-msg->buf, 0, 0);			if (anchor==0)			{				LOG(L_ERR, "ERROR:avpops:pushto_avp: can't get anchor\n");				goto error;			}			if (insert_new_lump_before(anchor, val.s, val.len, 0)==0)			{				LOG(L_ERR, "ERROR:avpops:pushto_avp: can't insert lump\n");				goto error;			}		}		n++;		if ( !(ap->flags&AVPOPS_FLAG_ALL) )			break;		avp = search_next_avp( avp, &avp_val);	} /* end while */	DBG("DEBUG:avpops:pushto_avps: %d avps were processed\n",n);	return 1;error:	return -1;}int ops_check_avp( struct sip_msg* msg, struct fis_param* ap,													struct fis_param* val){	unsigned short    name_type;	struct usr_avp    *avp1;	struct usr_avp    *avp2;	regmatch_t        pmatch;	int_str           avp_val;	int_str           ck_val;	str               s_ip;	int               ck_flg;	int               n;	/* look if the required avp(s) is/are present */	name_type = (((ap->flags&AVPOPS_VAL_INT))?0:AVP_NAME_STR);	avp1 = search_first_avp( name_type, ap->val, &avp_val);	if (avp1==0)	{		DBG("DEBUG:avpops:check_avp: no avp found to check\n");		goto error;	}cycle1:	if (val->flags&AVPOPS_VAL_AVP)	{		/* the 2nd operator is an avp name -> get avp val */		name_type = (((val->flags&AVPOPS_VAL_INT))?0:AVP_NAME_STR);		avp2 = search_first_avp( name_type, val->val, &ck_val);		ck_flg = avp2->flags&AVP_VAL_STR?AVPOPS_VAL_STR:AVPOPS_VAL_INT;	} else {		ck_val = val->val;		ck_flg = val->flags;		avp2 = 0;	}cycle2:	/* are both values of the same type? */	if ( !( (avp1->flags&AVP_VAL_STR && ck_flg&AVPOPS_VAL_STR) ||		((avp1->flags&AVP_VAL_STR)==0 && ck_flg&AVPOPS_VAL_INT) ||		(avp1->flags&AVP_VAL_STR && ck_flg&AVPOPS_VAL_NONE)))	{		LOG(L_ERR,"ERROR:avpops:check_avp: value types don't match\n");		goto next;	}	if (avp1->flags&AVP_VAL_STR)	{		/* string values to check */		if (val->flags&AVPOPS_VAL_NONE)		{			/* value is variable */			if (val->flags&AVPOPS_USE_SRC_IP)			{				/* get value from src_ip */				if ( (s_ip.s=ip_addr2a( &msg->rcv.src_ip ))==0)				{					LOG(L_ERR,"ERROR:avpops:check_avp: cannot get src_ip\n");					goto error;				}				s_ip.len = strlen(s_ip.s);				ck_val.s = &s_ip;			} else {				/* get value from uri */				if ( (ck_val.s=get_source_uri(msg,val->flags))==0 )				{					LOG(L_ERR,"ERROR:avpops:check_avp: cannot get uri\n");					goto next;				}			}		}		DBG("DEBUG:avpops:check_avp: check <%.*s> against <%.*s> as str\n",			avp_val.s->len,avp_val.s->s,			(val->flags&AVPOPS_OP_RE)?6:ck_val.s->len,			(val->flags&AVPOPS_OP_RE)?"REGEXP":ck_val.s->s);		/* do check */		if (val->flags&AVPOPS_OP_EQ)		{			if (avp_val.s->len==ck_val.s->len)			{				if (val->flags&AVPOPS_FLAG_CI)				{					if (strncasecmp(avp_val.s->s,ck_val.s->s,ck_val.s->len)==0)						return 1;				} else {					if (strncmp(avp_val.s->s,ck_val.s->s,ck_val.s->len)==0 )						return 1;				}			}		} else if (val->flags&AVPOPS_OP_LT) {			n = (avp_val.s->len>=ck_val.s->len)?avp_val.s->len:ck_val.s->len;			if (strncasecmp(avp_val.s->s,ck_val.s->s,n)==-1)				return 1;		} else if (val->flags&AVPOPS_OP_GT) {			n = (avp_val.s->len>=ck_val.s->len)?avp_val.s->len:ck_val.s->len;			if (strncasecmp(avp_val.s->s,ck_val.s->s,n)==1)				return 1;		} else if (val->flags&AVPOPS_OP_RE) {			if (regexec((regex_t*)ck_val.s, avp_val.s->s, 1, &pmatch, 0)==0)				return 1;		} else {			LOG(L_CRIT,"BUG:avpops:check_avp: unknown operation "				"(flg=%d)\n",val->flags);		}	} else {		/* int values to check -> do check */		DBG("DEBUG:avpops:check_avp: check <%d> against <%d> as int\n",				avp_val.n, ck_val.n);		if (val->flags&AVPOPS_OP_EQ)		{			if ( avp_val.n==ck_val.n)				return 1;		} else if (val->flags&AVPOPS_OP_LT) {			if ( avp_val.n<ck_val.n)				return 1;		} else if (val->flags&AVPOPS_OP_GT) {			if ( avp_val.n>ck_val.n)				return 1;		} else {			LOG(L_CRIT,"BUG:avpops:check_avp: unknown operation "				"(flg=%d)\n",val->flags);		}	}next:	/* cycle for the second value (only if avp can have multiple vals) */	if ((val->flags&AVPOPS_VAL_AVP)&&(avp2=search_next_avp(avp2,&ck_val))!=0)	{		ck_flg = avp2->flags&AVP_VAL_STR?AVPOPS_VAL_STR:AVPOPS_VAL_INT;		goto cycle2;	/* cycle for the first value -> next avp */	} else {		avp1=(val->flags&AVPOPS_FLAG_ALL)?search_next_avp(avp1,&avp_val):0;		if (avp1)			goto cycle1;	}	DBG("DEBUG:avpops:check_avp: checked failed\n");	return -1; /* check failed */error:	return -1;}int ops_print_avp(){	struct usr_avp **avp_list;	struct usr_avp *avp;	int_str         val;	str            *name;	/* go through all list */	avp_list = get_avp_list();	avp = *avp_list;	for ( ; avp ; avp=avp->next)	{		DBG("DEBUG:avpops:print_avp: p=%p, flags=%X\n",avp, avp->flags);		if (avp->flags&AVP_NAME_STR)		{			name = get_avp_name(avp);			DBG("DEBUG:\t\t\tname=<%.*s>\n",name->len,name->s);		} else {			DBG("DEBUG:\t\t\tid=<%d>\n",avp->id);		}		get_avp_val( avp, &val);		if (avp->flags&AVP_VAL_STR)		{			DBG("DEBUG:\t\t\tval_str=<%.*s>\n",val.s->len,val.s->s);		} else {			DBG("DEBUG:\t\t\tval_int=<%d>\n",val.n);		}	}		return 1;}

⌨️ 快捷键说明

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