... | ... |
@@ -30,6 +30,7 @@ |
30 | 30 |
* -------- |
31 | 31 |
* 2003-01-29 s/int/enum ... more convenient for gdb (jiri) |
32 | 32 |
* 2003-03-31 added subst lumps -- they expand in ip addr, port a.s.o (andrei) |
33 |
+ * 2003-04-01 added opt (condition) lumps (andrei) |
|
33 | 34 |
*/ |
34 | 35 |
|
35 | 36 |
|
... | ... |
@@ -37,12 +38,33 @@ |
37 | 38 |
#define data_lump_h |
38 | 39 |
|
39 | 40 |
|
40 |
-enum lump_op { LUMP_NOP=0, LUMP_DEL, LUMP_ADD, LUMP_ADD_SUBST }; |
|
41 |
-enum lump_subst{ SUBST_NOP=0, |
|
42 |
- SUBST_RCV_IP, SUBST_SND_IP, |
|
43 |
- SUBST_RCV_PORT, SUBST_SND_PORT, |
|
44 |
- SUBST_RCV_PROTO, SUBST_SND_PROTO |
|
41 |
+enum lump_op { LUMP_NOP=0, LUMP_DEL, LUMP_ADD, LUMP_ADD_SUBST, LUMP_ADD_OPT }; |
|
42 |
+enum lump_subst{ SUBST_NOP=0, /* do nothing */ |
|
43 |
+ SUBST_RCV_IP, SUBST_SND_IP, /* add ip address */ |
|
44 |
+ SUBST_RCV_PORT, SUBST_SND_PORT, /* add port no */ |
|
45 |
+ SUBST_RCV_PROTO, SUBST_SND_PROTO /* add protocol */ |
|
45 | 46 |
}; |
47 |
+ /* Where: |
|
48 |
+ SND = sending, e.g the src ip of the outgoing message |
|
49 |
+ RCV = received e.g the dst ip of the original incoming msg, |
|
50 |
+ or the ip of the ser socket on which the msg was received |
|
51 |
+ */ |
|
52 |
+ |
|
53 |
+enum lump_conditions { COND_FALSE, /* always false */ |
|
54 |
+ COND_TRUE, /* always true */ |
|
55 |
+ COND_IF_DIFF_REALMS,/* true if RCV realm != SND realm */ |
|
56 |
+ COND_IF_DIFF_AF, /* true if RCV af != SND af */ |
|
57 |
+ COND_IF_DIFF_PROTO, /* true if RCV proto != SND proto */ |
|
58 |
+ COND_IF_DIFF_PORT, /* true if RCV port != SND port */ |
|
59 |
+ COND_IF_DIFF_IP, /* true if RCV ip != SND ip */ |
|
60 |
+ COND_IF_RAND /* 50-50 random prob.of being true*/ |
|
61 |
+ }; |
|
62 |
+ /* Where: |
|
63 |
+ REALM= ip_addr:port:proto |
|
64 |
+ af = address family (ipv4 or ipv6) |
|
65 |
+ proto = protocol (tcp, udp, tls) |
|
66 |
+ */ |
|
67 |
+ |
|
46 | 68 |
enum lump_flag { LUMPFLAG_NONE=0, LUMPFLAG_DUPED=1, LUMPFLAG_SHMEM=2 }; |
47 | 69 |
|
48 | 70 |
struct lump{ |
... | ... |
@@ -52,6 +74,7 @@ struct lump{ |
52 | 74 |
union{ |
53 | 75 |
int offset; /* used for DEL, MODIFY */ |
54 | 76 |
enum lump_subst subst; /*what to subst: ip addr, port, proto*/ |
77 |
+ enum lump_conditions cond; /* condition for LUMP_ADD_OPT */ |
|
55 | 78 |
char * value; /* used for ADD */ |
56 | 79 |
}u; |
57 | 80 |
int len; /* length of this header field */ |
... | ... |
@@ -28,11 +28,6 @@ |
28 | 28 |
* |
29 | 29 |
* History: |
30 | 30 |
* -------- |
31 |
- * 2003-03-18 killed the build_warning snprintf (andrei) |
|
32 |
- * 2003-03-06 totags in outgoing replies bookmarked to enable |
|
33 |
- * ACK/200 tag matching |
|
34 |
- * 2003-03-01 VOICE_MAIL defs removed (jiri) |
|
35 |
- * 2003-02-28 scratchpad compatibility abandoned (jiri) |
|
36 | 31 |
* 2003-01-20 bug_fix: use of return value of snprintf aligned to C99 (jiri) |
37 | 32 |
* 2003-01-23 added rport patches, contributed by |
38 | 33 |
* Maxim Sobolev <sobomax@FreeBSD.org> and heavily modified by me |
... | ... |
@@ -42,7 +37,13 @@ |
42 | 37 |
* 2003-01-27 more rport fixes (make use of new via_param->start) (andrei) |
43 | 38 |
* 2003-01-27 next baby-step to removing ZT - PRESERVE_ZT (jiri) |
44 | 39 |
* 2003-01-29 scratchpad removed (jiri) |
40 |
+ * 2003-02-28 scratchpad compatibility abandoned (jiri) |
|
41 |
+ * 2003-03-01 VOICE_MAIL defs removed (jiri) |
|
42 |
+ * 2003-03-06 totags in outgoing replies bookmarked to enable |
|
43 |
+ * ACK/200 tag matching (andrei) |
|
44 |
+ * 2003-03-18 killed the build_warning snprintf (andrei) |
|
45 | 45 |
* 2003-03-31 added subst lump support (andrei) |
46 |
+ * 2003-04-01 added opt (conditional) lump support (andrei) |
|
46 | 47 |
* |
47 | 48 |
*/ |
48 | 49 |
|
... | ... |
@@ -356,6 +357,71 @@ char* clen_builder(struct sip_msg* msg, unsigned int *clen_len) |
356 | 357 |
|
357 | 358 |
|
358 | 359 |
|
360 |
+/* checks if a lump opt condition |
|
361 |
+ * returns 1 if cond is true, 0 if false */ |
|
362 |
+static inline int lump_check_opt( enum lump_conditions cond, |
|
363 |
+ struct sip_msg* msg, |
|
364 |
+ struct socket_info* snd_s |
|
365 |
+ ) |
|
366 |
+{ |
|
367 |
+ struct ip_addr* ip; |
|
368 |
+ unsigned short port; |
|
369 |
+ int proto; |
|
370 |
+ |
|
371 |
+#define get_ip_port_proto \ |
|
372 |
+ if (snd_s==0){ \ |
|
373 |
+ LOG(L_CRIT, "ERROR: lump_check_opt: null send socket\n"); \ |
|
374 |
+ return 1; /* we presume they are different :-) */ \ |
|
375 |
+ } \ |
|
376 |
+ if (msg->rcv.bind_address){ \ |
|
377 |
+ ip=&msg->rcv.bind_address->address; \ |
|
378 |
+ port=msg->rcv.bind_address->port_no; \ |
|
379 |
+ proto=msg->rcv.bind_address->proto; \ |
|
380 |
+ }else{ \ |
|
381 |
+ ip=&msg->rcv.dst_ip; \ |
|
382 |
+ port=msg->rcv.dst_port; \ |
|
383 |
+ proto=msg->rcv.proto; \ |
|
384 |
+ } \ |
|
385 |
+ |
|
386 |
+ switch(cond){ |
|
387 |
+ case COND_FALSE: |
|
388 |
+ return 0; |
|
389 |
+ case COND_TRUE: |
|
390 |
+ return 1; |
|
391 |
+ case COND_IF_DIFF_REALMS: |
|
392 |
+ get_ip_port_proto; |
|
393 |
+ /* faster tests first */ |
|
394 |
+ if ((port==snd_s->port_no)&&(proto==snd_s->proto)&& |
|
395 |
+ (ip_addr_cmp(ip, &snd_s->address))) |
|
396 |
+ return 0; |
|
397 |
+ else return 1; |
|
398 |
+ case COND_IF_DIFF_AF: |
|
399 |
+ get_ip_port_proto; |
|
400 |
+ if (ip->af!=snd_s->address.af) return 1; |
|
401 |
+ else return 0; |
|
402 |
+ case COND_IF_DIFF_PROTO: |
|
403 |
+ get_ip_port_proto; |
|
404 |
+ if (proto!=snd_s->proto) return 1; |
|
405 |
+ else return 0; |
|
406 |
+ case COND_IF_DIFF_PORT: |
|
407 |
+ get_ip_port_proto; |
|
408 |
+ if (port!=snd_s->port_no) return 1; |
|
409 |
+ else return 0; |
|
410 |
+ case COND_IF_DIFF_IP: |
|
411 |
+ get_ip_port_proto; |
|
412 |
+ if (ip_addr_cmp(ip, &snd_s->address)) return 0; |
|
413 |
+ else return 1; |
|
414 |
+ case COND_IF_RAND: |
|
415 |
+ return (rand()>=RAND_MAX/2); |
|
416 |
+ default: |
|
417 |
+ LOG(L_CRIT, "BUG: lump_check_opt: unknown lump condition %d\n", |
|
418 |
+ cond); |
|
419 |
+ } |
|
420 |
+ return 0; /* false */ |
|
421 |
+} |
|
422 |
+ |
|
423 |
+ |
|
424 |
+ |
|
359 | 425 |
/* computes the "unpacked" len of a lump list, |
360 | 426 |
code moved from build_req_from_req */ |
361 | 427 |
static inline int lumps_len(struct sip_msg* msg, struct socket_info* send_sock) |
... | ... |
@@ -430,6 +496,9 @@ static inline int lumps_len(struct sip_msg* msg, struct socket_info* send_sock) |
430 | 496 |
new_len=0; |
431 | 497 |
|
432 | 498 |
for(t=msg->add_rm;t;t=t->next){ |
499 |
+ /* skip if this is an OPT lump and the condition is not satisfied */ |
|
500 |
+ if ((t->op==LUMP_ADD_OPT) && !lump_check_opt(t->u.cond, msg, send_sock)) |
|
501 |
+ continue; |
|
433 | 502 |
for(r=t->before;r;r=r->before){ |
434 | 503 |
switch(r->op){ |
435 | 504 |
case LUMP_ADD: |
... | ... |
@@ -438,12 +507,19 @@ static inline int lumps_len(struct sip_msg* msg, struct socket_info* send_sock) |
438 | 507 |
case LUMP_ADD_SUBST: |
439 | 508 |
SUBST_LUMP_LEN(r); |
440 | 509 |
break; |
510 |
+ case LUMP_ADD_OPT: |
|
511 |
+ /* skip if this is an OPT lump and the condition is |
|
512 |
+ * not satisfied */ |
|
513 |
+ if (!lump_check_opt(r->u.cond, msg, send_sock)) |
|
514 |
+ goto skip_before; |
|
515 |
+ break; |
|
441 | 516 |
default: |
442 | 517 |
/* only ADD allowed for before/after */ |
443 | 518 |
LOG(L_CRIT, "BUG: lumps_len: invalid op " |
444 | 519 |
"for data lump (%x)\n", r->op); |
445 | 520 |
} |
446 | 521 |
} |
522 |
+skip_before: |
|
447 | 523 |
switch(t->op){ |
448 | 524 |
case LUMP_ADD: |
449 | 525 |
new_len+=t->len; |
... | ... |
@@ -451,6 +527,10 @@ static inline int lumps_len(struct sip_msg* msg, struct socket_info* send_sock) |
451 | 527 |
case LUMP_ADD_SUBST: |
452 | 528 |
SUBST_LUMP_LEN(t); |
453 | 529 |
break; |
530 |
+ case LUMP_ADD_OPT: |
|
531 |
+ /* we don't do anything here, it's only a condition for |
|
532 |
+ * before & after */ |
|
533 |
+ break; |
|
454 | 534 |
case LUMP_DEL: |
455 | 535 |
/* fix overlapping deleted zones */ |
456 | 536 |
if (t->u.offset < s_offset){ |
... | ... |
@@ -483,12 +563,19 @@ static inline int lumps_len(struct sip_msg* msg, struct socket_info* send_sock) |
483 | 563 |
case LUMP_ADD_SUBST: |
484 | 564 |
SUBST_LUMP_LEN(r); |
485 | 565 |
break; |
566 |
+ case LUMP_ADD_OPT: |
|
567 |
+ /* skip if this is an OPT lump and the condition is |
|
568 |
+ * not satisfied */ |
|
569 |
+ if (!lump_check_opt(r->u.cond, msg, send_sock)) |
|
570 |
+ goto skip_after; |
|
571 |
+ break; |
|
486 | 572 |
default: |
487 | 573 |
/* only ADD allowed for before/after */ |
488 | 574 |
LOG(L_CRIT, "BUG:lumps_len: invalid" |
489 | 575 |
" op for data lump (%x)\n", r->op); |
490 | 576 |
} |
491 | 577 |
} |
578 |
+skip_after: |
|
492 | 579 |
} |
493 | 580 |
return new_len; |
494 | 581 |
} |
... | ... |
@@ -634,6 +721,13 @@ static inline void process_lumps( struct sip_msg* msg, |
634 | 721 |
switch(t->op){ |
635 | 722 |
case LUMP_ADD: |
636 | 723 |
case LUMP_ADD_SUBST: |
724 |
+ case LUMP_ADD_OPT: |
|
725 |
+ /* skip if this is an OPT lump and the condition is |
|
726 |
+ * not satisfied */ |
|
727 |
+ if ((t->op==LUMP_ADD_OPT) && |
|
728 |
+ (!lump_check_opt(t->u.cond, msg, send_sock))) |
|
729 |
+ continue; |
|
730 |
+ break; |
|
637 | 731 |
/* just add it here! */ |
638 | 732 |
/* process before */ |
639 | 733 |
for(r=t->before;r;r=r->before){ |
... | ... |
@@ -646,18 +740,35 @@ static inline void process_lumps( struct sip_msg* msg, |
646 | 740 |
case LUMP_ADD_SUBST: |
647 | 741 |
SUBST_LUMP(r); |
648 | 742 |
break; |
743 |
+ case LUMP_ADD_OPT: |
|
744 |
+ /* skip if this is an OPT lump and the condition is |
|
745 |
+ * not satisfied */ |
|
746 |
+ if (!lump_check_opt(r->u.cond, msg, send_sock)) |
|
747 |
+ goto skip_before; |
|
748 |
+ break; |
|
649 | 749 |
default: |
650 | 750 |
/* only ADD allowed for before/after */ |
651 | 751 |
LOG(L_CRIT, "BUG:process_lumps: " |
652 | 752 |
"invalid op for data lump (%x)\n", r->op); |
653 | 753 |
} |
654 | 754 |
} |
755 |
+skip_before: |
|
655 | 756 |
/* copy "main" part */ |
656 |
- if(t->op==LUMP_ADD){ |
|
657 |
- memcpy(new_buf+offset, t->u.value, t->len); |
|
658 |
- offset+=t->len; |
|
659 |
- }else{ |
|
660 |
- SUBST_LUMP(t); |
|
757 |
+ switch(t->op){ |
|
758 |
+ case LUMP_ADD: |
|
759 |
+ memcpy(new_buf+offset, t->u.value, t->len); |
|
760 |
+ offset+=t->len; |
|
761 |
+ break; |
|
762 |
+ case LUMP_ADD_SUBST: |
|
763 |
+ SUBST_LUMP(t); |
|
764 |
+ break; |
|
765 |
+ case LUMP_ADD_OPT: |
|
766 |
+ /* do nothing, it's only a condition */ |
|
767 |
+ break; |
|
768 |
+ default: |
|
769 |
+ /* should not ever get here */ |
|
770 |
+ LOG(L_CRIT, "BUG: process_lumps: unhandled data lump " |
|
771 |
+ " op %d\n", t->op); |
|
661 | 772 |
} |
662 | 773 |
/* process after */ |
663 | 774 |
for(r=t->after;r;r=r->after){ |
... | ... |
@@ -670,12 +781,19 @@ static inline void process_lumps( struct sip_msg* msg, |
670 | 781 |
case LUMP_ADD_SUBST: |
671 | 782 |
SUBST_LUMP(r); |
672 | 783 |
break; |
784 |
+ case LUMP_ADD_OPT: |
|
785 |
+ /* skip if this is an OPT lump and the condition is |
|
786 |
+ * not satisfied */ |
|
787 |
+ if (!lump_check_opt(r->u.cond, msg, send_sock)) |
|
788 |
+ goto skip_after; |
|
789 |
+ break; |
|
673 | 790 |
default: |
674 | 791 |
/* only ADD allowed for before/after */ |
675 | 792 |
LOG(L_CRIT, "BUG:process_lumps: " |
676 | 793 |
"invalid op for data lump (%x)\n", r->op); |
677 | 794 |
} |
678 | 795 |
} |
796 |
+skip_after: |
|
679 | 797 |
break; |
680 | 798 |
case LUMP_NOP: |
681 | 799 |
case LUMP_DEL: |
... | ... |
@@ -704,12 +822,19 @@ static inline void process_lumps( struct sip_msg* msg, |
704 | 822 |
case LUMP_ADD_SUBST: |
705 | 823 |
SUBST_LUMP(r); |
706 | 824 |
break; |
825 |
+ case LUMP_ADD_OPT: |
|
826 |
+ /* skip if this is an OPT lump and the condition is |
|
827 |
+ * not satisfied */ |
|
828 |
+ if (!lump_check_opt(r->u.cond, msg, send_sock)) |
|
829 |
+ goto skip_nop_before; |
|
830 |
+ break; |
|
707 | 831 |
default: |
708 | 832 |
/* only ADD allowed for before/after */ |
709 | 833 |
LOG(L_CRIT, "BUG:process_lumps: " |
710 | 834 |
"invalid op for data lump (%x)\n",r->op); |
711 | 835 |
} |
712 | 836 |
} |
837 |
+skip_nop_before: |
|
713 | 838 |
/* process main (del only) */ |
714 | 839 |
if (t->op==LUMP_DEL){ |
715 | 840 |
/* skip len bytes from orig msg */ |
... | ... |
@@ -726,12 +851,19 @@ static inline void process_lumps( struct sip_msg* msg, |
726 | 851 |
case LUMP_ADD_SUBST: |
727 | 852 |
SUBST_LUMP(r); |
728 | 853 |
break; |
854 |
+ case LUMP_ADD_OPT: |
|
855 |
+ /* skip if this is an OPT lump and the condition is |
|
856 |
+ * not satisfied */ |
|
857 |
+ if (!lump_check_opt(r->u.cond, msg, send_sock)) |
|
858 |
+ goto skip_nop_after; |
|
859 |
+ break; |
|
729 | 860 |
default: |
730 | 861 |
/* only ADD allowed for before/after */ |
731 | 862 |
LOG(L_CRIT, "BUG:process_lumps: " |
732 | 863 |
"invalid op for data lump (%x)\n", r->op); |
733 | 864 |
} |
734 | 865 |
} |
866 |
+skip_nop_after: |
|
735 | 867 |
break; |
736 | 868 |
default: |
737 | 869 |
LOG(L_CRIT, "BUG: process_lumps: " |