Browse code

- added opt (conditional) lumps, see data_lump.h: COND_FALSE, COND_TRUE, COND_IF_DIFF_REALMS, COND_IF_DIFF_AF, COND_IF_DIFF_PROTO, COND_IF_DIFF_PORT, COND_IF_DIFF_IP, COND_IF_RAND (the last one is very usefull :-))

Andrei Pelinescu-Onciul authored on 01/04/2003 15:43:41
Showing 3 changed files
... ...
@@ -18,7 +18,7 @@
18 18
 VERSION = 0
19 19
 PATCHLEVEL = 8
20 20
 SUBLEVEL =   11
21
-EXTRAVERSION = pre9-repl_add_rm
21
+EXTRAVERSION = pre9-opt_l
22 22
 
23 23
 RELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)
24 24
 OS = $(shell uname -s | sed -e s/SunOS/solaris/ | tr "[A-Z]" "[a-z]")
... ...
@@ -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 37
 #define data_lump_h
38 38
 
39 39
 
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
40
+enum lump_op { LUMP_NOP=0, LUMP_DEL, LUMP_ADD, LUMP_ADD_SUBST, LUMP_ADD_OPT };
41
+enum lump_subst{ SUBST_NOP=0,                     /* do nothing */
42
+				 SUBST_RCV_IP,    SUBST_SND_IP,   /* add ip address */
43
+				 SUBST_RCV_PORT,  SUBST_SND_PORT, /* add port no */
44
+				 SUBST_RCV_PROTO, SUBST_SND_PROTO /* add protocol */
45 45
 				};
46
+				/* Where:
47
+				   SND = sending, e.g the src ip of the outgoing message
48
+				   RCV = received e.g the dst ip of the original incoming msg,
49
+				    or the ip of the ser socket on which the msg was received
50
+					*/
51
+
52
+enum lump_conditions {	COND_FALSE,         /* always false */
53
+						COND_TRUE,          /* always true */
54
+						COND_IF_DIFF_REALMS,/* true if RCV realm != SND realm */
55
+						COND_IF_DIFF_AF,    /* true if RCV af != SND af */
56
+						COND_IF_DIFF_PROTO, /* true if RCV proto != SND proto */
57
+						COND_IF_DIFF_PORT,  /* true if RCV port != SND port */
58
+						COND_IF_DIFF_IP,    /* true if RCV ip != SND ip */
59
+						COND_IF_RAND        /* 50-50 random prob.of being true*/
60
+						};
61
+						/* Where: 
62
+						   REALM= ip_addr:port:proto
63
+						   af   = address family (ipv4 or ipv6)
64
+						   proto = protocol (tcp, udp, tls)
65
+						*/
66
+
46 67
 enum lump_flag { LUMPFLAG_NONE=0, LUMPFLAG_DUPED=1, LUMPFLAG_SHMEM=2 };
47 68
 
48 69
 struct lump{
... ...
@@ -52,6 +74,7 @@ struct lump{
52 52
 	union{
53 53
 		int offset; /* used for DEL, MODIFY */
54 54
 		enum lump_subst subst; /*what to subst: ip addr, port, proto*/
55
+		enum lump_conditions cond; /* condition for LUMP_ADD_OPT */
55 56
 		char * value; /* used for ADD */
56 57
 	}u;
57 58
 	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 42
  * 2003-01-27  more rport fixes (make use of new via_param->start)  (andrei)
43 43
  * 2003-01-27  next baby-step to removing ZT - PRESERVE_ZT (jiri)
44 44
  * 2003-01-29  scratchpad removed (jiri)
45
+ * 2003-02-28  scratchpad compatibility abandoned (jiri)
46
+ * 2003-03-01  VOICE_MAIL defs removed (jiri)
47
+ * 2003-03-06  totags in outgoing replies bookmarked to enable
48
+ *             ACK/200 tag matching (andrei)
49
+ * 2003-03-18  killed the build_warning snprintf (andrei)
45 50
  * 2003-03-31  added subst lump support (andrei)
51
+ * 2003-04-01  added opt (conditional) lump support (andrei)
46 52
  *
47 53
  */
48 54
 
... ...
@@ -356,6 +357,71 @@ char* clen_builder(struct sip_msg* msg, unsigned int *clen_len)
356 356
 
357 357
 
358 358
 
359
+/* checks if a lump opt condition 
360
+ * returns 1 if cond is true, 0 if false */
361
+static inline int lump_check_opt(	enum lump_conditions cond,
362
+									struct sip_msg* msg,
363
+									struct socket_info* snd_s
364
+									)
365
+{
366
+	struct ip_addr* ip;
367
+	unsigned short port;
368
+	int proto;
369
+
370
+#define get_ip_port_proto \
371
+			if (snd_s==0){ \
372
+				LOG(L_CRIT, "ERROR: lump_check_opt: null send socket\n"); \
373
+				return 1; /* we presume they are different :-) */ \
374
+			} \
375
+			if (msg->rcv.bind_address){ \
376
+				ip=&msg->rcv.bind_address->address; \
377
+				port=msg->rcv.bind_address->port_no; \
378
+				proto=msg->rcv.bind_address->proto; \
379
+			}else{ \
380
+				ip=&msg->rcv.dst_ip; \
381
+				port=msg->rcv.dst_port; \
382
+				proto=msg->rcv.proto; \
383
+			} \
384
+			
385
+	switch(cond){
386
+		case COND_FALSE:
387
+			return 0;
388
+		case COND_TRUE:
389
+			return 1;
390
+		case COND_IF_DIFF_REALMS:
391
+			get_ip_port_proto;
392
+			/* faster tests first */
393
+			if ((port==snd_s->port_no)&&(proto==snd_s->proto)&&
394
+				(ip_addr_cmp(ip, &snd_s->address)))
395
+				return 0;
396
+			else return 1;
397
+		case COND_IF_DIFF_AF:
398
+			get_ip_port_proto;
399
+			if (ip->af!=snd_s->address.af) return 1;
400
+			else return 0;
401
+		case COND_IF_DIFF_PROTO:
402
+			get_ip_port_proto;
403
+			if (proto!=snd_s->proto) return 1;
404
+			else return 0;
405
+		case COND_IF_DIFF_PORT:
406
+			get_ip_port_proto;
407
+			if (port!=snd_s->port_no) return 1;
408
+			else return 0;
409
+		case COND_IF_DIFF_IP:
410
+			get_ip_port_proto;
411
+			if (ip_addr_cmp(ip, &snd_s->address)) return 0;
412
+			else return 1;
413
+		case COND_IF_RAND:
414
+			return (rand()>=RAND_MAX/2);
415
+		default:
416
+			LOG(L_CRIT, "BUG: lump_check_opt: unknown lump condition %d\n",
417
+					cond);
418
+	}
419
+	return 0; /* false */
420
+}
421
+
422
+
423
+
359 424
 /* computes the "unpacked" len of a lump list,
360 425
    code moved from build_req_from_req */
361 426
 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 430
 	new_len=0;
431 431
 	
432 432
 	for(t=msg->add_rm;t;t=t->next){
433
+		/* skip if this is an OPT lump and the condition is not satisfied */
434
+		if ((t->op==LUMP_ADD_OPT) && !lump_check_opt(t->u.cond, msg, send_sock))
435
+			continue;
433 436
 		for(r=t->before;r;r=r->before){
434 437
 			switch(r->op){
435 438
 				case LUMP_ADD:
... ...
@@ -438,12 +507,19 @@ static inline int lumps_len(struct sip_msg* msg, struct socket_info* send_sock)
438 438
 				case LUMP_ADD_SUBST:
439 439
 					SUBST_LUMP_LEN(r);
440 440
 					break;
441
+				case LUMP_ADD_OPT:
442
+					/* skip if this is an OPT lump and the condition is 
443
+					 * not satisfied */
444
+					if (!lump_check_opt(r->u.cond, msg, send_sock))
445
+						goto skip_before;
446
+					break;
441 447
 				default:
442 448
 					/* only ADD allowed for before/after */
443 449
 						LOG(L_CRIT, "BUG: lumps_len: invalid op "
444 450
 							"for data lump (%x)\n", r->op);
445 451
 			}
446 452
 		}
453
+skip_before:
447 454
 		switch(t->op){
448 455
 			case LUMP_ADD:
449 456
 				new_len+=t->len;
... ...
@@ -451,6 +527,10 @@ static inline int lumps_len(struct sip_msg* msg, struct socket_info* send_sock)
451 451
 			case LUMP_ADD_SUBST:
452 452
 				SUBST_LUMP_LEN(t);
453 453
 				break;
454
+			case LUMP_ADD_OPT:
455
+				/* we don't do anything here, it's only a condition for
456
+				 * before & after */
457
+				break;
454 458
 			case LUMP_DEL:
455 459
 				/* fix overlapping deleted zones */
456 460
 				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 483
 				case LUMP_ADD_SUBST:
484 484
 					SUBST_LUMP_LEN(r);
485 485
 					break;
486
+				case LUMP_ADD_OPT:
487
+					/* skip if this is an OPT lump and the condition is 
488
+					 * not satisfied */
489
+					if (!lump_check_opt(r->u.cond, msg, send_sock))
490
+						goto skip_after;
491
+					break;
486 492
 				default:
487 493
 					/* only ADD allowed for before/after */
488 494
 					LOG(L_CRIT, "BUG:lumps_len: invalid"
489 495
 								" op for data lump (%x)\n", r->op);
490 496
 			}
491 497
 		}
498
+skip_after:
492 499
 	}
493 500
 	return new_len;
494 501
 }
... ...
@@ -634,6 +721,13 @@ static inline void process_lumps(	struct sip_msg* msg,
634 634
 		switch(t->op){
635 635
 			case LUMP_ADD:
636 636
 			case LUMP_ADD_SUBST:
637
+			case LUMP_ADD_OPT:
638
+				/* skip if this is an OPT lump and the condition is 
639
+				 * not satisfied */
640
+				if ((t->op==LUMP_ADD_OPT) &&
641
+						(!lump_check_opt(t->u.cond, msg, send_sock))) 
642
+					continue;
643
+				break;
637 644
 				/* just add it here! */
638 645
 				/* process before  */
639 646
 				for(r=t->before;r;r=r->before){
... ...
@@ -646,18 +740,35 @@ static inline void process_lumps(	struct sip_msg* msg,
646 646
 						case LUMP_ADD_SUBST:
647 647
 							SUBST_LUMP(r);
648 648
 							break;
649
+						case LUMP_ADD_OPT:
650
+							/* skip if this is an OPT lump and the condition is 
651
+					 		* not satisfied */
652
+							if (!lump_check_opt(r->u.cond, msg, send_sock))
653
+								goto skip_before;
654
+							break;
649 655
 						default:
650 656
 							/* only ADD allowed for before/after */
651 657
 							LOG(L_CRIT, "BUG:process_lumps: "
652 658
 									"invalid op for data lump (%x)\n", r->op);
653 659
 					}
654 660
 				}
661
+skip_before:
655 662
 				/* 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);
663
+				switch(t->op){
664
+					case LUMP_ADD:
665
+						memcpy(new_buf+offset, t->u.value, t->len);
666
+						offset+=t->len;
667
+						break;
668
+					case LUMP_ADD_SUBST:
669
+						SUBST_LUMP(t);
670
+						break;
671
+					case LUMP_ADD_OPT:
672
+						/* do nothing, it's only a condition */
673
+						break;
674
+					default: 
675
+						/* should not ever get here */
676
+						LOG(L_CRIT, "BUG: process_lumps: unhandled data lump "
677
+								" op %d\n", t->op);
661 678
 				}
662 679
 				/* process after */
663 680
 				for(r=t->after;r;r=r->after){
... ...
@@ -670,12 +781,19 @@ static inline void process_lumps(	struct sip_msg* msg,
670 670
 						case LUMP_ADD_SUBST:
671 671
 							SUBST_LUMP(r);
672 672
 							break;
673
+						case LUMP_ADD_OPT:
674
+							/* skip if this is an OPT lump and the condition is 
675
+					 		* not satisfied */
676
+							if (!lump_check_opt(r->u.cond, msg, send_sock))
677
+								goto skip_after;
678
+							break;
673 679
 						default:
674 680
 							/* only ADD allowed for before/after */
675 681
 							LOG(L_CRIT, "BUG:process_lumps: "
676 682
 									"invalid op for data lump (%x)\n", r->op);
677 683
 					}
678 684
 				}
685
+skip_after:
679 686
 				break;
680 687
 			case LUMP_NOP:
681 688
 			case LUMP_DEL:
... ...
@@ -704,12 +822,19 @@ static inline void process_lumps(	struct sip_msg* msg,
704 704
 						case LUMP_ADD_SUBST:
705 705
 							SUBST_LUMP(r);
706 706
 							break;
707
+						case LUMP_ADD_OPT:
708
+							/* skip if this is an OPT lump and the condition is 
709
+					 		* not satisfied */
710
+							if (!lump_check_opt(r->u.cond, msg, send_sock))
711
+								goto skip_nop_before;
712
+							break;
707 713
 						default:
708 714
 							/* only ADD allowed for before/after */
709 715
 							LOG(L_CRIT, "BUG:process_lumps: "
710 716
 									"invalid op for data lump (%x)\n",r->op);
711 717
 					}
712 718
 				}
719
+skip_nop_before:
713 720
 				/* process main (del only) */
714 721
 				if (t->op==LUMP_DEL){
715 722
 					/* skip len bytes from orig msg */
... ...
@@ -726,12 +851,19 @@ static inline void process_lumps(	struct sip_msg* msg,
726 726
 						case LUMP_ADD_SUBST:
727 727
 							SUBST_LUMP(r);
728 728
 							break;
729
+						case LUMP_ADD_OPT:
730
+							/* skip if this is an OPT lump and the condition is 
731
+					 		* not satisfied */
732
+							if (!lump_check_opt(r->u.cond, msg, send_sock)) 
733
+								goto skip_nop_after;
734
+							break;
729 735
 						default:
730 736
 							/* only ADD allowed for before/after */
731 737
 							LOG(L_CRIT, "BUG:process_lumps: "
732 738
 									"invalid op for data lump (%x)\n", r->op);
733 739
 					}
734 740
 				}
741
+skip_nop_after:
735 742
 				break;
736 743
 			default:
737 744
 					LOG(L_CRIT, "BUG: process_lumps: "