- hard coded expressions elements (e.g. method==xxx) support now
rvalues as operands (e.g. uri=="sip:"+$a)
- small cleanups
... | ... |
@@ -81,6 +81,7 @@ |
81 | 81 |
#include "onsend.h" |
82 | 82 |
#include "str_hash.h" |
83 | 83 |
#include "ut.h" |
84 |
+#include "rvalue.h" |
|
84 | 85 |
|
85 | 86 |
#define RT_HASH_SIZE 8 /* route names hash */ |
86 | 87 |
|
... | ... |
@@ -333,7 +334,9 @@ int fix_expr(struct expr* exp) |
333 | 334 |
pkg_free(exp->r.param); |
334 | 335 |
exp->r.re=re; |
335 | 336 |
exp->r_type=RE_ST; |
336 |
- }else if (exp->r_type!=RE_ST && exp->r_type != AVP_ST && exp->r_type != SELECT_ST){ |
|
337 |
+ }else if (exp->r_type!=RE_ST && exp->r_type != AVP_ST |
|
338 |
+ && exp->r_type != SELECT_ST && exp->r_type!= RVE_ST |
|
339 |
+ && exp->r_type != PVAR_ST){ |
|
337 | 340 |
LOG(L_CRIT, "BUG: fix_expr : invalid type for match\n"); |
338 | 341 |
return E_BUG; |
339 | 342 |
} |
... | ... |
@@ -374,6 +377,19 @@ int fix_expr(struct expr* exp) |
374 | 377 |
return ret; |
375 | 378 |
} |
376 | 379 |
} |
380 |
+ if (exp->l_type==RVEXP_O){ |
|
381 |
+ if ((ret=fix_rval_expr(&exp->l.param))<0){ |
|
382 |
+ ERR("Unable to fix left rval expression\n"); |
|
383 |
+ return ret; |
|
384 |
+ } |
|
385 |
+ } |
|
386 |
+ if (exp->r_type==RVE_ST){ |
|
387 |
+ if ((ret=fix_rval_expr(&exp->r.param))<0){ |
|
388 |
+ ERR("Unable to fix right rval expression\n"); |
|
389 |
+ return ret; |
|
390 |
+ } |
|
391 |
+ } |
|
392 |
+ /* PVAR don't need fixing */ |
|
377 | 393 |
ret=0; |
378 | 394 |
} |
379 | 395 |
return ret; |
... | ... |
@@ -585,40 +601,67 @@ int fix_actions(struct action* a) |
585 | 601 |
* attributes. If either of the attributes if of string type then the length of |
586 | 602 |
* its value will be used. |
587 | 603 |
*/ |
588 |
-inline static int comp_num(int op, long left, int rtype, union exp_op* r) |
|
604 |
+inline static int comp_num(int op, long left, int rtype, union exp_op* r, |
|
605 |
+ struct sip_msg* msg, struct run_act_ctx* h) |
|
589 | 606 |
{ |
590 | 607 |
int_str val; |
608 |
+ pv_value_t pval; |
|
591 | 609 |
avp_t* avp; |
592 |
- long right; |
|
593 |
- |
|
594 |
- if (rtype == AVP_ST) { |
|
595 |
- avp = search_avp_by_index(r->attr->type, r->attr->name, &val, r->attr->index); |
|
596 |
- if (avp && !(avp->flags & AVP_VAL_STR)) right = val.n; |
|
597 |
- else return (op == DIFF_OP); |
|
598 |
- } else if (rtype == NUMBER_ST) { |
|
599 |
- right = r->numval; |
|
600 |
- } else { |
|
601 |
- LOG(L_CRIT, "BUG: comp_num: Invalid right operand (%d)\n", rtype); |
|
602 |
- return E_BUG; |
|
610 |
+ int right; |
|
611 |
+ |
|
612 |
+ if (unlikely(op==NO_OP)) return !(!left); |
|
613 |
+ switch(rtype){ |
|
614 |
+ case AVP_ST: |
|
615 |
+ avp = search_avp_by_index(r->attr->type, r->attr->name, |
|
616 |
+ &val, r->attr->index); |
|
617 |
+ if (avp && !(avp->flags & AVP_VAL_STR)) right = val.n; |
|
618 |
+ else return (op == DIFF_OP); |
|
619 |
+ break; |
|
620 |
+ case NUMBER_ST: |
|
621 |
+ right = r->numval; |
|
622 |
+ break; |
|
623 |
+ case RVE_ST: |
|
624 |
+ if (unlikely(rval_expr_eval_int(h, msg, &right, r->param)<0)) |
|
625 |
+ return (op == DIFF_OP); /* not found/invalid */ |
|
626 |
+ break; |
|
627 |
+ case PVAR_ST: |
|
628 |
+ memset(&pval, 0, sizeof(pv_value_t)); |
|
629 |
+ if (unlikely(pv_get_spec_value(msg, r->param, &pval)!=0)){ |
|
630 |
+ return (op == DIFF_OP); /* error, not found => false */ |
|
631 |
+ } |
|
632 |
+ if (likely(pval.flags & (PV_TYPE_INT|PV_VAL_INT))){ |
|
633 |
+ pv_value_destroy(&pval); |
|
634 |
+ right=pval.ri; |
|
635 |
+ }else{ |
|
636 |
+ pv_value_destroy(&pval); |
|
637 |
+ return (op == DIFF_OP); /* not found or invalid type */ |
|
638 |
+ } |
|
639 |
+ break; |
|
640 |
+ default: |
|
641 |
+ LOG(L_CRIT, "BUG: comp_num: Invalid right operand (%d)\n", rtype); |
|
642 |
+ return E_BUG; |
|
603 | 643 |
} |
604 | 644 |
|
605 | 645 |
switch (op){ |
606 |
- case EQUAL_OP: return (long)left == (long)right; |
|
607 |
- case DIFF_OP: return (long)left != (long)right; |
|
608 |
- case GT_OP: return (long)left > (long)right; |
|
609 |
- case LT_OP: return (long)left < (long)right; |
|
610 |
- case GTE_OP: return (long)left >= (long)right; |
|
611 |
- case LTE_OP: return (long)left <= (long)right; |
|
612 |
- default: |
|
613 |
- LOG(L_CRIT, "BUG: comp_num: unknown operator: %d\n", op); |
|
614 |
- return E_BUG; |
|
646 |
+ case EQUAL_OP: return (long)left == (long)right; |
|
647 |
+ case DIFF_OP: return (long)left != (long)right; |
|
648 |
+ case GT_OP: return (long)left > (long)right; |
|
649 |
+ case LT_OP: return (long)left < (long)right; |
|
650 |
+ case GTE_OP: return (long)left >= (long)right; |
|
651 |
+ case LTE_OP: return (long)left <= (long)right; |
|
652 |
+ default: |
|
653 |
+ LOG(L_CRIT, "BUG: comp_num: unknown operator: %d\n", op); |
|
654 |
+ return E_BUG; |
|
615 | 655 |
} |
656 |
+ return E_BUG; |
|
616 | 657 |
} |
617 | 658 |
|
618 | 659 |
/* |
619 | 660 |
* Compare given string "left" with right side of expression |
620 | 661 |
*/ |
621 |
-inline static int comp_str(int op, str* left, int rtype, union exp_op* r, struct sip_msg* msg) |
|
662 |
+inline static int comp_str(int op, str* left, int rtype, |
|
663 |
+ union exp_op* r, struct sip_msg* msg, |
|
664 |
+ struct run_act_ctx* h) |
|
622 | 665 |
{ |
623 | 666 |
str* right; |
624 | 667 |
int_str val; |
... | ... |
@@ -628,33 +671,74 @@ inline static int comp_str(int op, str* left, int rtype, union exp_op* r, struct |
628 | 671 |
char backup; |
629 | 672 |
regex_t* re; |
630 | 673 |
unsigned int l; |
674 |
+ struct rvalue* rv; |
|
675 |
+ struct rval_cache rv_cache; |
|
676 |
+ pv_value_t pval; |
|
677 |
+ int destroy_pval; |
|
631 | 678 |
|
632 | 679 |
right=0; /* warning fix */ |
633 |
- |
|
634 |
- if (rtype == AVP_ST) { |
|
635 |
- avp = search_avp_by_index(r->attr->type, r->attr->name, &val, r->attr->index); |
|
636 |
- if (avp && (avp->flags & AVP_VAL_STR)) right = &val.s; |
|
637 |
- else return (op == DIFF_OP); |
|
638 |
- } else if (rtype == SELECT_ST) { |
|
639 |
- ret = run_select(&v, r->select, msg); |
|
640 |
- if (ret != 0) return (op == DIFF_OP); /* Not found or error */ |
|
641 |
- right = &v; |
|
642 |
- } else if ((op == MATCH_OP && rtype == RE_ST)) { |
|
643 |
- } else if (op != MATCH_OP && rtype == STRING_ST) { |
|
644 |
- right = &r->str; |
|
645 |
- } else if (rtype == NUMBER_ST) { |
|
680 |
+ rv=0; |
|
681 |
+ destroy_pval=0; |
|
682 |
+ if (unlikely(op==NO_OP)) return (left->s!=0); |
|
683 |
+ switch(rtype){ |
|
684 |
+ case AVP_ST: |
|
685 |
+ avp = search_avp_by_index(r->attr->type, r->attr->name, |
|
686 |
+ &val, r->attr->index); |
|
687 |
+ if (likely(avp && (avp->flags & AVP_VAL_STR))) right = &val.s; |
|
688 |
+ else return (op == DIFF_OP); |
|
689 |
+ break; |
|
690 |
+ case SELECT_ST: |
|
691 |
+ ret = run_select(&v, r->select, msg); |
|
692 |
+ if (unlikely(ret != 0)) |
|
693 |
+ return (op == DIFF_OP); /* Not found or error */ |
|
694 |
+ right = &v; |
|
695 |
+ break; |
|
696 |
+ case RVE_ST: |
|
697 |
+ rval_cache_init(&rv_cache); |
|
698 |
+ rv=rval_expr_eval(h, msg, r->param); |
|
699 |
+ if (unlikely (rv==0)) |
|
700 |
+ return (op==DIFF_OP); /* not found or error*/ |
|
701 |
+ if (unlikely(rval_get_tmp_str(h, msg, &v, rv, 0, &rv_cache)<0)){ |
|
702 |
+ goto error; |
|
703 |
+ } |
|
704 |
+ right = &v; |
|
705 |
+ break; |
|
706 |
+ case PVAR_ST: |
|
707 |
+ memset(&pval, 0, sizeof(pv_value_t)); |
|
708 |
+ if (unlikely(pv_get_spec_value(msg, r->param, &pval)!=0)){ |
|
709 |
+ return (op == DIFF_OP); /* error, not found => false */ |
|
710 |
+ } |
|
711 |
+ destroy_pval=1; |
|
712 |
+ if (likely(pval.flags & PV_VAL_STR)){ |
|
713 |
+ right=&pval.rs; |
|
714 |
+ }else{ |
|
715 |
+ pv_value_destroy(&pval); |
|
716 |
+ return (op == DIFF_OP); /* not found or invalid type */ |
|
717 |
+ } |
|
718 |
+ break; |
|
719 |
+ case RE_ST: |
|
720 |
+ if (unlikely(op != MATCH_OP)){ |
|
721 |
+ LOG(L_CRIT, "BUG: comp_str: Bad operator %d," |
|
722 |
+ " ~= expected\n", op); |
|
723 |
+ goto error; |
|
724 |
+ } |
|
725 |
+ break; |
|
726 |
+ case STRING_ST: |
|
727 |
+ right=&r->str; |
|
728 |
+ break; |
|
729 |
+ case NUMBER_ST: |
|
646 | 730 |
/* "123" > 100 is not allowed by cfg.y rules |
647 | 731 |
* but can happen as @select or $avp evaluation |
648 | 732 |
* $test > 10 |
649 | 733 |
* the right operator MUST be number to do the conversion |
650 | 734 |
*/ |
651 |
- if (str2int(left,&l) < 0) |
|
735 |
+ if (str2int(left,&l) < 0) |
|
736 |
+ goto error; |
|
737 |
+ return comp_num(op, l, rtype, r, msg, h); |
|
738 |
+ default: |
|
739 |
+ LOG(L_CRIT, "BUG: comp_str: Bad type %d, " |
|
740 |
+ "string or RE expected\n", rtype); |
|
652 | 741 |
goto error; |
653 |
- return comp_num(op, l, rtype, r); |
|
654 |
- } else { |
|
655 |
- LOG(L_CRIT, "BUG: comp_str: Bad type %d, " |
|
656 |
- "string or RE expected\n", rtype); |
|
657 |
- goto error; |
|
658 | 742 |
} |
659 | 743 |
|
660 | 744 |
ret=-1; |
... | ... |
@@ -668,111 +752,97 @@ inline static int comp_str(int op, str* left, int rtype, union exp_op* r, struct |
668 | 752 |
ret = (strncasecmp(left->s, right->s, left->len)!=0); |
669 | 753 |
break; |
670 | 754 |
case MATCH_OP: |
671 |
- /* this is really ugly -- we put a temporary zero-terminating |
|
672 |
- * character in the original string; that's because regexps |
|
673 |
- * take 0-terminated strings and our messages are not |
|
674 |
- * zero-terminated; it should not hurt as long as this function |
|
675 |
- * is applied to content of pkg mem, which is always the case |
|
676 |
- * with calls from route{}; the same goes for fline in reply_route{}; |
|
677 |
- * |
|
678 |
- * also, the received function should always give us an extra |
|
679 |
- * character, into which we can put the 0-terminator now; |
|
680 |
- * an alternative would be allocating a new piece of memory, |
|
681 |
- * which might be too slow |
|
682 |
- * -jiri |
|
683 |
- * |
|
684 |
- * janakj: AVPs are zero terminated too so this is not problem either |
|
685 |
- */ |
|
755 |
+ /* this is really ugly -- we put a temporary zero-terminating |
|
756 |
+ * character in the original string; that's because regexps |
|
757 |
+ * take 0-terminated strings and our messages are not |
|
758 |
+ * zero-terminated; it should not hurt as long as this function |
|
759 |
+ * is applied to content of pkg mem, which is always the case |
|
760 |
+ * with calls from route{}; the same goes for fline in |
|
761 |
+ * reply_route{}; |
|
762 |
+ * |
|
763 |
+ * also, the received function should always give us an extra |
|
764 |
+ * character, into which we can put the 0-terminator now; |
|
765 |
+ * an alternative would be allocating a new piece of memory, |
|
766 |
+ * which might be too slow |
|
767 |
+ * -jiri |
|
768 |
+ * |
|
769 |
+ * janakj: AVPs are zero terminated too so this is not problem |
|
770 |
+ * either |
|
771 |
+ */ |
|
686 | 772 |
backup=left->s[left->len]; |
687 |
- if (backup) left->s[left->len]='\0'; |
|
688 |
- if (rtype == AVP_ST || rtype == SELECT_ST) { |
|
689 |
- /* For AVPs we need to compile the RE on the fly */ |
|
690 |
- re=(regex_t*)pkg_malloc(sizeof(regex_t)); |
|
691 |
- if (re==0){ |
|
692 |
- LOG(L_CRIT, "ERROR: comp_strstr: memory allocation" |
|
693 |
- " failure\n"); |
|
694 |
- left->s[left->len] = backup; |
|
695 |
- goto error; |
|
696 |
- } |
|
697 |
- if (regcomp(re, right->s, REG_EXTENDED|REG_NOSUB|REG_ICASE)) { |
|
773 |
+ left->s[left->len]='\0'; |
|
774 |
+ switch(rtype){ |
|
775 |
+ case AVP_ST: |
|
776 |
+ case SELECT_ST: |
|
777 |
+ case RVE_ST: |
|
778 |
+ case PVAR_ST: |
|
779 |
+ /* we need to compile the RE on the fly */ |
|
780 |
+ re=(regex_t*)pkg_malloc(sizeof(regex_t)); |
|
781 |
+ if (re==0){ |
|
782 |
+ LOG(L_CRIT, "ERROR: comp_strstr: memory allocation" |
|
783 |
+ " failure\n"); |
|
784 |
+ left->s[left->len] = backup; |
|
785 |
+ goto error; |
|
786 |
+ } |
|
787 |
+ if (regcomp(re, right->s, |
|
788 |
+ REG_EXTENDED|REG_NOSUB|REG_ICASE)) { |
|
789 |
+ pkg_free(re); |
|
790 |
+ left->s[left->len] = backup; |
|
791 |
+ goto error; |
|
792 |
+ } |
|
793 |
+ ret=(regexec(re, left->s, 0, 0, 0)==0); |
|
794 |
+ regfree(re); |
|
698 | 795 |
pkg_free(re); |
699 |
- left->s[left->len] = backup; |
|
796 |
+ break; |
|
797 |
+ case RE_ST: |
|
798 |
+ ret=(regexec(r->re, left->s, 0, 0, 0)==0); |
|
799 |
+ break; |
|
800 |
+ case STRING_ST: |
|
801 |
+ default: |
|
802 |
+ LOG(L_CRIT, "BUG: comp_str: Bad operator type %d, " |
|
803 |
+ "for ~= \n", rtype); |
|
700 | 804 |
goto error; |
701 |
- } |
|
702 |
- ret=(regexec(re, left->s, 0, 0, 0)==0); |
|
703 |
- regfree(re); |
|
704 |
- pkg_free(re); |
|
705 |
- } else { |
|
706 |
- ret=(regexec(r->re, left->s, 0, 0, 0)==0); |
|
707 | 805 |
} |
708 |
- if (backup) left->s[left->len] = backup; |
|
806 |
+ left->s[left->len] = backup; |
|
709 | 807 |
break; |
710 | 808 |
default: |
711 | 809 |
LOG(L_CRIT, "BUG: comp_str: unknown op %d\n", op); |
712 | 810 |
goto error; |
713 | 811 |
} |
812 |
+ if (rv){ |
|
813 |
+ rval_cache_clean(&rv_cache); |
|
814 |
+ rval_destroy(rv); |
|
815 |
+ } |
|
816 |
+ if (destroy_pval) |
|
817 |
+ pv_value_destroy(&pval); |
|
714 | 818 |
return ret; |
715 | 819 |
|
716 | 820 |
error: |
821 |
+ if (rv){ |
|
822 |
+ rval_cache_clean(&rv_cache); |
|
823 |
+ rval_destroy(rv); |
|
824 |
+ } |
|
825 |
+ if (destroy_pval) |
|
826 |
+ pv_value_destroy(&pval); |
|
717 | 827 |
return (op == DIFF_OP) ? 1 : -1; |
718 | 828 |
} |
719 | 829 |
|
720 | 830 |
|
721 | 831 |
/* eval_elem helping function, returns str op param */ |
722 |
-inline static int comp_string(int op, char* left, int rtype, union exp_op* r) |
|
832 |
+inline static int comp_string(int op, char* left, int rtype, union exp_op* r, |
|
833 |
+ struct sip_msg* msg, struct run_act_ctx* h) |
|
723 | 834 |
{ |
724 |
- int ret; |
|
725 |
- int_str val; |
|
726 |
- avp_t* avp; |
|
727 |
- char* right; |
|
728 |
- |
|
729 |
- ret=-1; |
|
730 |
- right=0; |
|
731 |
- if (rtype == AVP_ST) { |
|
732 |
- avp = search_avp_by_index(r->attr->type, r->attr->name, &val, r->attr->index); |
|
733 |
- if (avp && (avp->flags & AVP_VAL_STR)) right = val.s.s; |
|
734 |
- else return (op == DIFF_OP); |
|
735 |
- } else if (rtype == STRING_ST) { |
|
736 |
- right = r->str.s; |
|
737 |
- } |
|
738 |
- |
|
739 |
- switch(op){ |
|
740 |
- case EQUAL_OP: |
|
741 |
- if (rtype!=STRING_ST && rtype!=AVP_ST){ |
|
742 |
- LOG(L_CRIT, "BUG: comp_string: bad type %d, " |
|
743 |
- "string or attr expected\n", rtype); |
|
744 |
- goto error; |
|
745 |
- } |
|
746 |
- ret=(strcasecmp(left, right)==0); |
|
747 |
- break; |
|
748 |
- case DIFF_OP: |
|
749 |
- if (rtype!=STRING_ST && rtype!=AVP_ST){ |
|
750 |
- LOG(L_CRIT, "BUG: comp_string: bad type %d, " |
|
751 |
- "string or attr expected\n", rtype); |
|
752 |
- goto error; |
|
753 |
- } |
|
754 |
- ret=(strcasecmp(left, right)!=0); |
|
755 |
- break; |
|
756 |
- case MATCH_OP: |
|
757 |
- if (rtype!=RE_ST){ |
|
758 |
- LOG(L_CRIT, "BUG: comp_string: bad type %d, " |
|
759 |
- " RE expected\n", rtype); |
|
760 |
- goto error; |
|
761 |
- } |
|
762 |
- ret=(regexec(r->re, left, 0, 0, 0)==0); |
|
763 |
- break; |
|
764 |
- default: |
|
765 |
- LOG(L_CRIT, "BUG: comp_string: unknown op %d\n", op); |
|
766 |
- goto error; |
|
767 |
- } |
|
768 |
- return ret; |
|
769 |
- |
|
770 |
-error: |
|
771 |
- return -1; |
|
835 |
+ str s; |
|
836 |
+ |
|
837 |
+ s.s=left; |
|
838 |
+ s.len=strlen(left); |
|
839 |
+ return comp_str(op, &s, rtype, r, msg, h); |
|
772 | 840 |
} |
773 | 841 |
|
774 | 842 |
|
775 |
-inline static int comp_avp(int op, avp_spec_t* spec, int rtype, union exp_op* r, struct sip_msg* msg) |
|
843 |
+inline static int comp_avp(int op, avp_spec_t* spec, int rtype, |
|
844 |
+ union exp_op* r, struct sip_msg* msg, |
|
845 |
+ struct run_act_ctx* h) |
|
776 | 846 |
{ |
777 | 847 |
avp_t* avp; |
778 | 848 |
int_str val; |
... | ... |
@@ -781,46 +851,41 @@ inline static int comp_avp(int op, avp_spec_t* spec, int rtype, union exp_op* r, |
781 | 851 |
unsigned int uval; |
782 | 852 |
|
783 | 853 |
if (spec->type & AVP_INDEX_ALL) { |
784 |
- avp = search_first_avp(spec->type & ~AVP_INDEX_ALL, spec->name, NULL, NULL); |
|
854 |
+ avp = search_first_avp(spec->type & ~AVP_INDEX_ALL, spec->name, |
|
855 |
+ NULL, NULL); |
|
785 | 856 |
return (avp!=0); |
786 | 857 |
} |
787 | 858 |
avp = search_avp_by_index(spec->type, spec->name, &val, spec->index); |
788 | 859 |
if (!avp) return (op == DIFF_OP); |
789 | 860 |
|
790 |
- switch(op) { |
|
791 |
- case NO_OP: |
|
861 |
+ if (op==NO_OP){ |
|
792 | 862 |
if (avp->flags & AVP_VAL_STR) { |
793 | 863 |
return val.s.len!=0; |
794 | 864 |
} else { |
795 | 865 |
return val.n != 0; |
796 | 866 |
} |
797 |
- break; |
|
798 |
- |
|
799 |
- case BINOR_OP: |
|
800 |
- return (val.n | r->numval)!=0; |
|
801 |
- break; |
|
802 |
- |
|
803 |
- case BINAND_OP: |
|
804 |
- return (val.n & r->numval)!=0; |
|
805 |
- break; |
|
806 | 867 |
} |
807 |
- |
|
808 | 868 |
if (avp->flags & AVP_VAL_STR) { |
809 |
- return comp_str(op, &val.s, rtype, r, msg); |
|
869 |
+ return comp_str(op, &val.s, rtype, r, msg, h); |
|
810 | 870 |
} else { |
811 | 871 |
switch(rtype){ |
812 | 872 |
case NUMBER_ST: |
813 |
- return comp_num(op, val.n, rtype, r); |
|
873 |
+ case AVP_ST: |
|
874 |
+ case RVE_ST: |
|
875 |
+ case PVAR_ST: |
|
876 |
+ return comp_num(op, val.n, rtype, r, msg, h); |
|
877 |
+ break; |
|
814 | 878 |
case STRING_ST: |
815 | 879 |
tmp.s=r->string; |
816 | 880 |
tmp.len=strlen(r->string); |
817 | 881 |
if (str2int(&tmp, &uval)<0){ |
818 |
- LOG(L_WARN, "WARNING: comp_avp: cannot convert string value" |
|
819 |
- " to int (%s)\n", ZSW(r->string)); |
|
882 |
+ LOG(L_WARN, "WARNING: comp_avp: cannot convert" |
|
883 |
+ " string value to int (%s)\n", |
|
884 |
+ ZSW(r->string)); |
|
820 | 885 |
goto error; |
821 | 886 |
} |
822 | 887 |
num_val.numval=uval; |
823 |
- return comp_num(op, val.n, NUMBER_ST, &num_val); |
|
888 |
+ return comp_num(op, val.n, NUMBER_ST, &num_val, msg, h); |
|
824 | 889 |
case STR_ST: |
825 | 890 |
if (str2int(&r->str, &uval)<0){ |
826 | 891 |
LOG(L_WARN, "WARNING: comp_avp: cannot convert str value" |
... | ... |
@@ -828,9 +893,7 @@ inline static int comp_avp(int op, avp_spec_t* spec, int rtype, union exp_op* r, |
828 | 893 |
goto error; |
829 | 894 |
} |
830 | 895 |
num_val.numval=uval; |
831 |
- return comp_num(op, val.n, NUMBER_ST, &num_val); |
|
832 |
- case AVP_ST: |
|
833 |
- return comp_num(op, val.n, rtype, r); |
|
896 |
+ return comp_num(op, val.n, NUMBER_ST, &num_val, msg, h); |
|
834 | 897 |
default: |
835 | 898 |
LOG(L_CRIT, "BUG: comp_avp: invalid type for numeric avp " |
836 | 899 |
"comparison (%d)\n", rtype); |
... | ... |
@@ -844,7 +907,9 @@ error: |
844 | 907 |
/* |
845 | 908 |
* Left side of expression was select |
846 | 909 |
*/ |
847 |
-inline static int comp_select(int op, select_t* sel, int rtype, union exp_op* r, struct sip_msg* msg) |
|
910 |
+inline static int comp_select(int op, select_t* sel, int rtype, |
|
911 |
+ union exp_op* r, struct sip_msg* msg, |
|
912 |
+ struct run_act_ctx* h) |
|
848 | 913 |
{ |
849 | 914 |
int ret; |
850 | 915 |
str val; |
... | ... |
@@ -853,22 +918,68 @@ inline static int comp_select(int op, select_t* sel, int rtype, union exp_op* r, |
853 | 918 |
ret = run_select(&val, sel, msg); |
854 | 919 |
if (ret != 0) return (op == DIFF_OP); |
855 | 920 |
|
856 |
- switch(op) { |
|
857 |
- case NO_OP: return (val.len>0); |
|
858 |
- case BINOR_OP: |
|
859 |
- case BINAND_OP: |
|
860 |
- ERR("Binary operators cannot be used with string selects\n"); |
|
861 |
- return -1; |
|
862 |
- } |
|
863 |
- if (val.len==0) { |
|
921 |
+ if (op==NO_OP) return (val.len>0); |
|
922 |
+ if (unlikely(val.len==0)) { |
|
864 | 923 |
/* make sure the string pointer uses accessible memory range |
865 | 924 |
* the comp_str function might dereference it |
866 | 925 |
*/ |
867 | 926 |
val.s=&empty_str; |
868 | 927 |
} |
869 |
- return comp_str(op, &val, rtype, r, msg); |
|
928 |
+ return comp_str(op, &val, rtype, r, msg, h); |
|
929 |
+} |
|
930 |
+ |
|
931 |
+ |
|
932 |
+inline static int comp_rve(int op, struct rval_expr* rve, int rtype, |
|
933 |
+ union exp_op* r, struct sip_msg* msg, |
|
934 |
+ struct run_act_ctx* h) |
|
935 |
+{ |
|
936 |
+ int i; |
|
937 |
+ |
|
938 |
+ if (unlikely(rval_expr_eval_int(h, msg, &i, rve)<0)){ |
|
939 |
+ ERR("failure evaluating expression: bad type\n"); |
|
940 |
+ i=0; /* false */ |
|
941 |
+ } |
|
942 |
+ if (op==NO_OP) |
|
943 |
+ return !(!i); /* transform it into { 0, 1 } */ |
|
944 |
+ return comp_num(op, i, rtype, r, msg, h); |
|
870 | 945 |
} |
871 | 946 |
|
947 |
+ |
|
948 |
+ |
|
949 |
+inline static int comp_pvar(int op, pv_spec_t* pvs, int rtype, |
|
950 |
+ union exp_op* r, struct sip_msg* msg, |
|
951 |
+ struct run_act_ctx* h) |
|
952 |
+{ |
|
953 |
+ pv_value_t pval; |
|
954 |
+ int ret; |
|
955 |
+ |
|
956 |
+ ret=0; |
|
957 |
+ memset(&pval, 0, sizeof(pv_value_t)); |
|
958 |
+ if (unlikely(pv_get_spec_value(msg, r->param, &pval)!=0)){ |
|
959 |
+ return 0; /* error, not found => false */ |
|
960 |
+ } |
|
961 |
+ if (likely(pval.flags & PV_TYPE_INT)){ |
|
962 |
+ if (op==NO_OP) |
|
963 |
+ ret=!(!pval.ri); |
|
964 |
+ else |
|
965 |
+ ret=comp_num(op, pval.ri, rtype, r, msg, h); |
|
966 |
+ }else if ((pval.flags==PV_VAL_NONE) || |
|
967 |
+ (pval.flags & (PV_VAL_NULL|PV_VAL_EMPTY))){ |
|
968 |
+ if (op==NO_OP) |
|
969 |
+ ret=0; |
|
970 |
+ else |
|
971 |
+ ret=comp_num(op, 0, rtype, r, msg, h); |
|
972 |
+ }else{ |
|
973 |
+ ret=pval.rs.len!=0; |
|
974 |
+ if (op!=NO_OP) |
|
975 |
+ ret=comp_num(op, ret, rtype, r, msg, h); |
|
976 |
+ } |
|
977 |
+ pv_value_destroy(&pval); |
|
978 |
+ return ret; |
|
979 |
+} |
|
980 |
+ |
|
981 |
+ |
|
982 |
+ |
|
872 | 983 |
/* check_self wrapper -- it checks also for the op */ |
873 | 984 |
inline static int check_self_op(int op, str* s, unsigned short p) |
874 | 985 |
{ |
... | ... |
@@ -877,6 +988,7 @@ inline static int check_self_op(int op, str* s, unsigned short p) |
877 | 988 |
ret=check_self(s, p, 0); |
878 | 989 |
switch(op){ |
879 | 990 |
case EQUAL_OP: |
991 |
+ case MATCH_OP: |
|
880 | 992 |
break; |
881 | 993 |
case DIFF_OP: |
882 | 994 |
ret=(ret > 0) ? 0 : 1; |
... | ... |
@@ -890,7 +1002,9 @@ inline static int check_self_op(int op, str* s, unsigned short p) |
890 | 1002 |
|
891 | 1003 |
|
892 | 1004 |
/* eval_elem helping function, returns an op param */ |
893 |
-inline static int comp_ip(int op, struct ip_addr* ip, int rtype, union exp_op* r) |
|
1005 |
+inline static int comp_ip(int op, struct ip_addr* ip, int rtype, |
|
1006 |
+ union exp_op* r, struct sip_msg* msg, |
|
1007 |
+ struct run_act_ctx *ctx ) |
|
894 | 1008 |
{ |
895 | 1009 |
struct hostent* he; |
896 | 1010 |
char ** h; |
... | ... |
@@ -914,12 +1028,14 @@ inline static int comp_ip(int op, struct ip_addr* ip, int rtype, union exp_op* r |
914 | 1028 |
case AVP_ST: |
915 | 1029 |
case STRING_ST: |
916 | 1030 |
case RE_ST: |
1031 |
+ case RVE_ST: |
|
1032 |
+ case SELECT_ST: |
|
917 | 1033 |
switch(op){ |
918 | 1034 |
case EQUAL_OP: |
919 | 1035 |
case MATCH_OP: |
920 | 1036 |
/* 1: compare with ip2str*/ |
921 |
- ret=comp_string(op, ip_addr2a(ip), rtype, r); |
|
922 |
- if (ret==1) break; |
|
1037 |
+ ret=comp_string(op, ip_addr2a(ip), rtype, r, msg, ctx); |
|
1038 |
+ if (likely(ret==1)) break; |
|
923 | 1039 |
/* 2: resolve (name) & compare w/ all the ips */ |
924 | 1040 |
if (rtype==STRING_ST){ |
925 | 1041 |
he=resolvehost(r->str.s); |
... | ... |
@@ -939,17 +1055,17 @@ inline static int comp_ip(int op, struct ip_addr* ip, int rtype, union exp_op* r |
939 | 1055 |
if (unlikely((received_dns & DO_REV_DNS) && |
940 | 1056 |
((he=rev_resolvehost(ip))!=0) )){ |
941 | 1057 |
/* compare with primary host name */ |
942 |
- ret=comp_string(op, he->h_name, rtype, r); |
|
1058 |
+ ret=comp_string(op, he->h_name, rtype, r, msg, ctx); |
|
943 | 1059 |
/* compare with all the aliases */ |
944 | 1060 |
for(h=he->h_aliases; (ret!=1) && (*h); h++){ |
945 |
- ret=comp_string(op, *h, rtype, r); |
|
1061 |
+ ret=comp_string(op, *h, rtype, r, msg, ctx); |
|
946 | 1062 |
} |
947 | 1063 |
}else{ |
948 | 1064 |
ret=0; |
949 | 1065 |
} |
950 | 1066 |
break; |
951 | 1067 |
case DIFF_OP: |
952 |
- ret=(comp_ip(EQUAL_OP, ip, rtype, r) > 0) ? 0 : 1; |
|
1068 |
+ ret=(comp_ip(EQUAL_OP, ip, rtype, r, msg, ctx) > 0) ?0:1; |
|
953 | 1069 |
break; |
954 | 1070 |
default: |
955 | 1071 |
goto error_op; |
... | ... |
@@ -969,10 +1085,10 @@ inline static int comp_ip(int op, struct ip_addr* ip, int rtype, union exp_op* r |
969 | 1085 |
error_op: |
970 | 1086 |
LOG(L_CRIT, "BUG: comp_ip: invalid operator %d\n", op); |
971 | 1087 |
return -1; |
972 |
- |
|
973 | 1088 |
} |
974 | 1089 |
|
975 | 1090 |
|
1091 |
+ |
|
976 | 1092 |
/* returns: 0/1 (false/true) or -1 on error */ |
977 | 1093 |
inline static int eval_elem(struct run_act_ctx* h, struct expr* e, |
978 | 1094 |
struct sip_msg* msg) |
... | ... |
@@ -990,7 +1106,7 @@ inline static int eval_elem(struct run_act_ctx* h, struct expr* e, |
990 | 1106 |
switch(e->l_type){ |
991 | 1107 |
case METHOD_O: |
992 | 1108 |
ret=comp_str(e->op, &msg->first_line.u.request.method, |
993 |
- e->r_type, &e->r, msg); |
|
1109 |
+ e->r_type, &e->r, msg, h); |
|
994 | 1110 |
break; |
995 | 1111 |
case URI_O: |
996 | 1112 |
if(msg->new_uri.s) { |
... | ... |
@@ -1001,7 +1117,7 @@ inline static int eval_elem(struct run_act_ctx* h, struct expr* e, |
1001 | 1117 |
msg->parsed_uri.port_no:SIP_PORT); |
1002 | 1118 |
}else{ |
1003 | 1119 |
ret=comp_str(e->op, &msg->new_uri, |
1004 |
- e->r_type, &e->r, msg); |
|
1120 |
+ e->r_type, &e->r, msg, h); |
|
1005 | 1121 |
} |
1006 | 1122 |
}else{ |
1007 | 1123 |
if (e->r_type==MYSELF_ST){ |
... | ... |
@@ -1011,7 +1127,7 @@ inline static int eval_elem(struct run_act_ctx* h, struct expr* e, |
1011 | 1127 |
msg->parsed_uri.port_no:SIP_PORT); |
1012 | 1128 |
}else{ |
1013 | 1129 |
ret=comp_str(e->op, &msg->first_line.u.request.uri, |
1014 |
- e->r_type, &e->r, msg); |
|
1130 |
+ e->r_type, &e->r, msg, h); |
|
1015 | 1131 |
} |
1016 | 1132 |
} |
1017 | 1133 |
break; |
... | ... |
@@ -1032,7 +1148,7 @@ inline static int eval_elem(struct run_act_ctx* h, struct expr* e, |
1032 | 1148 |
uri.port_no?uri.port_no:SIP_PORT); |
1033 | 1149 |
}else{ |
1034 | 1150 |
ret=comp_str(e->op, &get_from(msg)->uri, |
1035 |
- e->r_type, &e->r, msg); |
|
1151 |
+ e->r_type, &e->r, msg, h); |
|
1036 | 1152 |
} |
1037 | 1153 |
break; |
1038 | 1154 |
|
... | ... |
@@ -1054,22 +1170,23 @@ inline static int eval_elem(struct run_act_ctx* h, struct expr* e, |
1054 | 1170 |
uri.port_no?uri.port_no:SIP_PORT); |
1055 | 1171 |
}else{ |
1056 | 1172 |
ret=comp_str(e->op, &get_to(msg)->uri, |
1057 |
- e->r_type, &e->r, msg); |
|
1173 |
+ e->r_type, &e->r, msg, h); |
|
1058 | 1174 |
} |
1059 | 1175 |
break; |
1060 | 1176 |
|
1061 | 1177 |
case SRCIP_O: |
1062 |
- ret=comp_ip(e->op, &msg->rcv.src_ip, e->r_type, &e->r); |
|
1178 |
+ ret=comp_ip(e->op, &msg->rcv.src_ip, e->r_type, &e->r, msg, h); |
|
1063 | 1179 |
break; |
1064 | 1180 |
|
1065 | 1181 |
case DSTIP_O: |
1066 |
- ret=comp_ip(e->op, &msg->rcv.dst_ip, e->r_type, &e->r); |
|
1182 |
+ ret=comp_ip(e->op, &msg->rcv.dst_ip, e->r_type, &e->r, msg, h); |
|
1067 | 1183 |
break; |
1068 | 1184 |
|
1069 | 1185 |
case SNDIP_O: |
1070 | 1186 |
snd_inf=get_onsend_info(); |
1071 |
- if (snd_inf && snd_inf->send_sock){ |
|
1072 |
- ret=comp_ip(e->op, &snd_inf->send_sock->address, e->r_type, &e->r); |
|
1187 |
+ if (likely(snd_inf && snd_inf->send_sock)){ |
|
1188 |
+ ret=comp_ip(e->op, &snd_inf->send_sock->address, |
|
1189 |
+ e->r_type, &e->r, msg, h); |
|
1073 | 1190 |
}else{ |
1074 | 1191 |
BUG("eval_elem: snd_ip unknown (not in a onsend_route?)\n"); |
1075 | 1192 |
} |
... | ... |
@@ -1077,9 +1194,9 @@ inline static int eval_elem(struct run_act_ctx* h, struct expr* e, |
1077 | 1194 |
|
1078 | 1195 |
case TOIP_O: |
1079 | 1196 |
snd_inf=get_onsend_info(); |
1080 |
- if (snd_inf && snd_inf->to){ |
|
1197 |
+ if (likely(snd_inf && snd_inf->to)){ |
|
1081 | 1198 |
su2ip_addr(&ip, snd_inf->to); |
1082 |
- ret=comp_ip(e->op, &ip, e->r_type, &e->r); |
|
1199 |
+ ret=comp_ip(e->op, &ip, e->r_type, &e->r, msg, h); |
|
1083 | 1200 |
}else{ |
1084 | 1201 |
BUG("eval_elem: to_ip unknown (not in a onsend_route?)\n"); |
1085 | 1202 |
} |
... | ... |
@@ -1096,20 +1213,18 @@ inline static int eval_elem(struct run_act_ctx* h, struct expr* e, |
1096 | 1213 |
break; |
1097 | 1214 |
|
1098 | 1215 |
case SRCPORT_O: |
1099 |
- ret=comp_num(e->op, (int)msg->rcv.src_port, |
|
1100 |
- e->r_type, &e->r); |
|
1216 |
+ ret=comp_num(e->op, (int)msg->rcv.src_port, e->r_type, &e->r, msg, h); |
|
1101 | 1217 |
break; |
1102 | 1218 |
|
1103 | 1219 |
case DSTPORT_O: |
1104 |
- ret=comp_num(e->op, (int)msg->rcv.dst_port, |
|
1105 |
- e->r_type, &e->r); |
|
1220 |
+ ret=comp_num(e->op, (int)msg->rcv.dst_port, e->r_type, &e->r, msg, h); |
|
1106 | 1221 |
break; |
1107 | 1222 |
|
1108 | 1223 |
case SNDPORT_O: |
1109 | 1224 |
snd_inf=get_onsend_info(); |
1110 |
- if (snd_inf && snd_inf->send_sock){ |
|
1225 |
+ if (likely(snd_inf && snd_inf->send_sock)){ |
|
1111 | 1226 |
ret=comp_num(e->op, (int)snd_inf->send_sock->port_no, |
1112 |
- e->r_type, &e->r); |
|
1227 |
+ e->r_type, &e->r, msg, h); |
|
1113 | 1228 |
}else{ |
1114 | 1229 |
BUG("eval_elem: snd_port unknown (not in a onsend_route?)\n"); |
1115 | 1230 |
} |
... | ... |
@@ -1117,39 +1232,37 @@ inline static int eval_elem(struct run_act_ctx* h, struct expr* e, |
1117 | 1232 |
|
1118 | 1233 |
case TOPORT_O: |
1119 | 1234 |
snd_inf=get_onsend_info(); |
1120 |
- if (snd_inf && snd_inf->to){ |
|
1235 |
+ if (likely(snd_inf && snd_inf->to)){ |
|
1121 | 1236 |
ret=comp_num(e->op, (int)su_getport(snd_inf->to), |
1122 |
- e->r_type, &e->r); |
|
1237 |
+ e->r_type, &e->r, msg, h); |
|
1123 | 1238 |
}else{ |
1124 | 1239 |
BUG("eval_elem: to_port unknown (not in a onsend_route?)\n"); |
1125 | 1240 |
} |
1126 | 1241 |
break; |
1127 | 1242 |
|
1128 | 1243 |
case PROTO_O: |
1129 |
- ret=comp_num(e->op, msg->rcv.proto, |
|
1130 |
- e->r_type, &e->r); |
|
1244 |
+ ret=comp_num(e->op, msg->rcv.proto, e->r_type, &e->r, msg, h); |
|
1131 | 1245 |
break; |
1132 | 1246 |
|
1133 | 1247 |
case SNDPROTO_O: |
1134 | 1248 |
snd_inf=get_onsend_info(); |
1135 |
- if (snd_inf && snd_inf->send_sock){ |
|
1249 |
+ if (likely(snd_inf && snd_inf->send_sock)){ |
|
1136 | 1250 |
ret=comp_num(e->op, snd_inf->send_sock->proto, |
1137 |
- e->r_type, &e->r); |
|
1251 |
+ e->r_type, &e->r, msg, h); |
|
1138 | 1252 |
}else{ |
1139 | 1253 |
BUG("eval_elem: snd_proto unknown (not in a onsend_route?)\n"); |
1140 | 1254 |
} |
1141 | 1255 |
break; |
1142 | 1256 |
|
1143 | 1257 |
case AF_O: |
1144 |
- ret=comp_num(e->op, (int)msg->rcv.src_ip.af, |
|
1145 |
- e->r_type, &e->r); |
|
1258 |
+ ret=comp_num(e->op, (int)msg->rcv.src_ip.af, e->r_type, &e->r, msg, h); |
|
1146 | 1259 |
break; |
1147 | 1260 |
|
1148 | 1261 |
case SNDAF_O: |
1149 | 1262 |
snd_inf=get_onsend_info(); |
1150 |
- if (snd_inf && snd_inf->send_sock){ |
|
1263 |
+ if (likely(snd_inf && snd_inf->send_sock)){ |
|
1151 | 1264 |
ret=comp_num(e->op, snd_inf->send_sock->address.af, |
1152 |
- e->r_type, &e->r); |
|
1265 |
+ e->r_type, &e->r, msg, h); |
|
1153 | 1266 |
}else{ |
1154 | 1267 |
BUG("eval_elem: snd_af unknown (not in a onsend_route?)\n"); |
1155 | 1268 |
} |
... | ... |
@@ -1157,24 +1270,30 @@ inline static int eval_elem(struct run_act_ctx* h, struct expr* e, |
1157 | 1270 |
|
1158 | 1271 |
case MSGLEN_O: |
1159 | 1272 |
if ((snd_inf=get_onsend_info())!=0){ |
1160 |
- ret=comp_num(e->op, (int)snd_inf->len, |
|
1161 |
- e->r_type, &e->r); |
|
1273 |
+ ret=comp_num(e->op, (int)snd_inf->len, e->r_type, &e->r, msg, h); |
|
1162 | 1274 |
}else{ |
1163 |
- ret=comp_num(e->op, (int)msg->len, |
|
1164 |
- e->r_type, &e->r); |
|
1275 |
+ ret=comp_num(e->op, (int)msg->len, e->r_type, &e->r, msg, h); |
|
1165 | 1276 |
} |
1166 | 1277 |
break; |
1167 | 1278 |
|
1168 | 1279 |
case RETCODE_O: |
1169 |
- ret=comp_num(e->op, h->last_retcode, e->r_type, &e->r); |
|
1280 |
+ ret=comp_num(e->op, h->last_retcode, e->r_type, &e->r, msg, h); |
|
1170 | 1281 |
break; |
1171 | 1282 |
|
1172 | 1283 |
case AVP_O: |
1173 |
- ret = comp_avp(e->op, e->l.attr, e->r_type, &e->r, msg); |
|
1284 |
+ ret = comp_avp(e->op, e->l.attr, e->r_type, &e->r, msg, h); |
|
1174 | 1285 |
break; |
1175 | 1286 |
|
1176 | 1287 |
case SELECT_O: |
1177 |
- ret = comp_select(e->op, e->l.select, e->r_type, &e->r, msg); |
|
1288 |
+ ret = comp_select(e->op, e->l.select, e->r_type, &e->r, msg, h); |
|
1289 |
+ break; |
|
1290 |
+ |
|
1291 |
+ case RVEXP_O: |
|
1292 |
+ ret = comp_rve(e->op, e->l.param, e->r_type, &e->r, msg, h); |
|
1293 |
+ break; |
|
1294 |
+ |
|
1295 |
+ case PVAR_O: |
|
1296 |
+ ret=comp_pvar(e->op, e->l.param, e->r_type, &e->r, msg, h); |
|
1178 | 1297 |
break; |
1179 | 1298 |
|
1180 | 1299 |
default: |
... | ... |
@@ -68,6 +68,27 @@ error: |
68 | 68 |
} |
69 | 69 |
|
70 | 70 |
|
71 |
+struct expr* mk_exp_rve(int op, void* left, void* right) |
|
72 |
+{ |
|
73 |
+ struct expr * e; |
|
74 |
+ e=(struct expr*)pkg_malloc(sizeof (struct expr)); |
|
75 |
+ if (e==0) goto error; |
|
76 |
+ e->type=EXP_T; |
|
77 |
+ e->op=op; |
|
78 |
+ e->l.param=mk_elem(RVEXP_O, RVE_ST, left, 0, 0); |
|
79 |
+ e->r.param=mk_elem(RVEXP_O, RVE_ST, right, 0, 0); |
|
80 |
+ if (e->l.param==0 || e->r.param==0){ |
|
81 |
+ if (e->l.param) pkg_free(e->l.param); |
|
82 |
+ if (e->r.param) pkg_free(e->r.param); |
|
83 |
+ pkg_free(e); |
|
84 |
+ goto error; |
|
85 |
+ } |
|
86 |
+ return e; |
|
87 |
+error: |
|
88 |
+ LOG(L_CRIT, "ERROR: mk_exp_rve: memory allocation failure\n"); |
|
89 |
+ return 0; |
|
90 |
+} |
|
91 |
+ |
|
71 | 92 |
struct expr* mk_elem(int op, int ltype, void* lparam, int rtype, void* rparam) |
72 | 93 |
{ |
73 | 94 |
struct expr * e; |
... | ... |
@@ -160,15 +181,48 @@ void print_expr(struct expr* exp) |
160 | 181 |
case DSTPORT_O: |
161 | 182 |
DBG("dstport"); |
162 | 183 |
break; |
163 |
- case NUMBER_O: |
|
184 |
+ case PROTO_O: |
|
185 |
+ DBG("proto"); |
|
186 |
+ break; |
|
187 |
+ case AF_O: |
|
188 |
+ DBG("af"); |
|
189 |
+ break; |
|
190 |
+ case MSGLEN_O: |
|
191 |
+ DBG("msglen"); |
|
164 | 192 |
break; |
165 | 193 |
case ACTION_O: |
166 | 194 |
break; |
167 |
- case AVP_ST: |
|
168 |
- DBG("attr"); |
|
195 |
+ case NUMBER_O: |
|
169 | 196 |
break; |
170 |
- case SELECT_ST: |
|
171 |
- DBG("select"); |
|
197 |
+ case AVP_O: |
|
198 |
+ DBG("avp"); |
|
199 |
+ break; |
|
200 |
+ case SNDIP_O: |
|
201 |
+ DBG("sndip"); |
|
202 |
+ break; |
|
203 |
+ case SNDPORT_O: |
|
204 |
+ DBG("sndport"); |
|
205 |
+ break; |
|
206 |
+ case TOIP_O: |
|
207 |
+ DBG("toip"); |
|
208 |
+ break; |
|
209 |
+ case TOPORT_O: |
|
210 |
+ DBG("toport"); |
|
211 |
+ break; |
|
212 |
+ case SNDPROTO_O: |
|
213 |
+ DBG("sndproto"); |
|
214 |
+ break; |
|
215 |
+ case SNDAF_O: |
|
216 |
+ DBG("sndaf"); |
|
217 |
+ break; |
|
218 |
+ case RETCODE_O: |
|
219 |
+ DBG("retcode"); |
|
220 |
+ break; |
|
221 |
+ case SELECT_O: |
|
222 |
+ DBG("select"); |
|
223 |
+ break; |
|
224 |
+ case RVEXP_O: |
|
225 |
+ DBG("rval"); |
|
172 | 226 |
break; |
173 | 227 |
|
174 | 228 |
default: |
... | ... |
@@ -65,7 +65,7 @@ enum { EQUAL_OP=10, MATCH_OP, GT_OP, LT_OP, GTE_OP, LTE_OP, DIFF_OP, NO_OP }; |
65 | 65 |
enum { METHOD_O=1, URI_O, FROM_URI_O, TO_URI_O, SRCIP_O, SRCPORT_O, |
66 | 66 |
DSTIP_O, DSTPORT_O, PROTO_O, AF_O, MSGLEN_O, DEFAULT_O, ACTION_O, |
67 | 67 |
NUMBER_O, AVP_O, SNDIP_O, SNDPORT_O, TOIP_O, TOPORT_O, SNDPROTO_O, |
68 |
- SNDAF_O, RETCODE_O, SELECT_O}; |
|
68 |
+ SNDAF_O, RETCODE_O, SELECT_O, PVAR_O, RVEXP_O}; |
|
69 | 69 |
|
70 | 70 |
enum { FORWARD_T=1, SEND_T, DROP_T, LOG_T, ERROR_T, ROUTE_T, EXEC_T, |
71 | 71 |
SET_HOST_T, SET_HOSTPORT_T, SET_USER_T, SET_USERPASS_T, |
... | ... |
@@ -94,8 +94,8 @@ enum { FORWARD_T=1, SEND_T, DROP_T, LOG_T, ERROR_T, ROUTE_T, EXEC_T, |
94 | 94 |
enum { NOSUBTYPE=0, STRING_ST, NET_ST, NUMBER_ST, IP_ST, RE_ST, PROXY_ST, |
95 | 95 |
EXPR_ST, ACTIONS_ST, MODEXP_ST, MODFIXUP_ST, URIHOST_ST, URIPORT_ST, |
96 | 96 |
MYSELF_ST, STR_ST, SOCKID_ST, SOCKETINFO_ST, ACTION_ST, AVP_ST, |
97 |
- SELECT_ST, /* obsolete */ |
|
98 |
- LVAL_ST, RVE_ST, |
|
97 |
+ SELECT_ST, PVAR_ST, |
|
98 |
+ LVAL_ST, RVE_ST, |
|
99 | 99 |
RETCODE_ST}; |
100 | 100 |
|
101 | 101 |
/* run flags */ |