📄 avpops_impl.c
字号:
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 + -