Browse Source

- 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 22 năm trước cách đây
mục cha
commit
d1e2a411e8
3 tập tin đã thay đổi với 171 bổ sung16 xóa
  1. 1 1
      Makefile.defs
  2. 28 5
      data_lump.h
  3. 142 10
      msg_translator.c

+ 1 - 1
Makefile.defs

@@ -18,7 +18,7 @@
 VERSION = 0
 PATCHLEVEL = 8
 SUBLEVEL =   11
-EXTRAVERSION = pre9-repl_add_rm
+EXTRAVERSION = pre9-opt_l
 
 RELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)
 OS = $(shell uname -s | sed -e s/SunOS/solaris/ | tr "[A-Z]" "[a-z]")

+ 28 - 5
data_lump.h

@@ -30,6 +30,7 @@
  * --------
  *  2003-01-29  s/int/enum ... more convenient for gdb (jiri)
  *  2003-03-31  added subst lumps -- they expand in ip addr, port a.s.o (andrei)
+ *  2003-04-01  added opt (condition) lumps (andrei)
  */
 
 
@@ -37,12 +38,33 @@
 #define data_lump_h
 
 
-enum lump_op { LUMP_NOP=0, LUMP_DEL, LUMP_ADD, LUMP_ADD_SUBST };
-enum lump_subst{ SUBST_NOP=0,
-				 SUBST_RCV_IP,    SUBST_SND_IP,
-				 SUBST_RCV_PORT,  SUBST_SND_PORT,
-				 SUBST_RCV_PROTO, SUBST_SND_PROTO
+enum lump_op { LUMP_NOP=0, LUMP_DEL, LUMP_ADD, LUMP_ADD_SUBST, LUMP_ADD_OPT };
+enum lump_subst{ SUBST_NOP=0,                     /* do nothing */
+				 SUBST_RCV_IP,    SUBST_SND_IP,   /* add ip address */
+				 SUBST_RCV_PORT,  SUBST_SND_PORT, /* add port no */
+				 SUBST_RCV_PROTO, SUBST_SND_PROTO /* add protocol */
 				};
+				/* Where:
+				   SND = sending, e.g the src ip of the outgoing message
+				   RCV = received e.g the dst ip of the original incoming msg,
+				    or the ip of the ser socket on which the msg was received
+					*/
+
+enum lump_conditions {	COND_FALSE,         /* always false */
+						COND_TRUE,          /* always true */
+						COND_IF_DIFF_REALMS,/* true if RCV realm != SND realm */
+						COND_IF_DIFF_AF,    /* true if RCV af != SND af */
+						COND_IF_DIFF_PROTO, /* true if RCV proto != SND proto */
+						COND_IF_DIFF_PORT,  /* true if RCV port != SND port */
+						COND_IF_DIFF_IP,    /* true if RCV ip != SND ip */
+						COND_IF_RAND        /* 50-50 random prob.of being true*/
+						};
+						/* Where: 
+						   REALM= ip_addr:port:proto
+						   af   = address family (ipv4 or ipv6)
+						   proto = protocol (tcp, udp, tls)
+						*/
+
 enum lump_flag { LUMPFLAG_NONE=0, LUMPFLAG_DUPED=1, LUMPFLAG_SHMEM=2 };
 
 struct lump{
@@ -52,6 +74,7 @@ struct lump{
 	union{
 		int offset; /* used for DEL, MODIFY */
 		enum lump_subst subst; /*what to subst: ip addr, port, proto*/
+		enum lump_conditions cond; /* condition for LUMP_ADD_OPT */
 		char * value; /* used for ADD */
 	}u;
 	int len; /* length of this header field */

+ 142 - 10
msg_translator.c

@@ -28,11 +28,6 @@
  *
  * History:
  * --------
- * 2003-03-18  killed the build_warning snprintf (andrei)
- * 2003-03-06  totags in outgoing replies bookmarked to enable
- *             ACK/200 tag matching
- * 2003-03-01  VOICE_MAIL defs removed (jiri)
- * 2003-02-28  scratchpad compatibility abandoned (jiri)
  * 2003-01-20  bug_fix: use of return value of snprintf aligned to C99 (jiri)
  * 2003-01-23  added rport patches, contributed by 
  *              Maxim Sobolev <[email protected]> and heavily modified by me
@@ -42,7 +37,13 @@
  * 2003-01-27  more rport fixes (make use of new via_param->start)  (andrei)
  * 2003-01-27  next baby-step to removing ZT - PRESERVE_ZT (jiri)
  * 2003-01-29  scratchpad removed (jiri)
+ * 2003-02-28  scratchpad compatibility abandoned (jiri)
+ * 2003-03-01  VOICE_MAIL defs removed (jiri)
+ * 2003-03-06  totags in outgoing replies bookmarked to enable
+ *             ACK/200 tag matching (andrei)
+ * 2003-03-18  killed the build_warning snprintf (andrei)
  * 2003-03-31  added subst lump support (andrei)
+ * 2003-04-01  added opt (conditional) lump support (andrei)
  *
  */
 
@@ -356,6 +357,71 @@ char* clen_builder(struct sip_msg* msg, unsigned int *clen_len)
 
 
 
+/* checks if a lump opt condition 
+ * returns 1 if cond is true, 0 if false */
+static inline int lump_check_opt(	enum lump_conditions cond,
+									struct sip_msg* msg,
+									struct socket_info* snd_s
+									)
+{
+	struct ip_addr* ip;
+	unsigned short port;
+	int proto;
+
+#define get_ip_port_proto \
+			if (snd_s==0){ \
+				LOG(L_CRIT, "ERROR: lump_check_opt: null send socket\n"); \
+				return 1; /* we presume they are different :-) */ \
+			} \
+			if (msg->rcv.bind_address){ \
+				ip=&msg->rcv.bind_address->address; \
+				port=msg->rcv.bind_address->port_no; \
+				proto=msg->rcv.bind_address->proto; \
+			}else{ \
+				ip=&msg->rcv.dst_ip; \
+				port=msg->rcv.dst_port; \
+				proto=msg->rcv.proto; \
+			} \
+			
+	switch(cond){
+		case COND_FALSE:
+			return 0;
+		case COND_TRUE:
+			return 1;
+		case COND_IF_DIFF_REALMS:
+			get_ip_port_proto;
+			/* faster tests first */
+			if ((port==snd_s->port_no)&&(proto==snd_s->proto)&&
+				(ip_addr_cmp(ip, &snd_s->address)))
+				return 0;
+			else return 1;
+		case COND_IF_DIFF_AF:
+			get_ip_port_proto;
+			if (ip->af!=snd_s->address.af) return 1;
+			else return 0;
+		case COND_IF_DIFF_PROTO:
+			get_ip_port_proto;
+			if (proto!=snd_s->proto) return 1;
+			else return 0;
+		case COND_IF_DIFF_PORT:
+			get_ip_port_proto;
+			if (port!=snd_s->port_no) return 1;
+			else return 0;
+		case COND_IF_DIFF_IP:
+			get_ip_port_proto;
+			if (ip_addr_cmp(ip, &snd_s->address)) return 0;
+			else return 1;
+		case COND_IF_RAND:
+			return (rand()>=RAND_MAX/2);
+		default:
+			LOG(L_CRIT, "BUG: lump_check_opt: unknown lump condition %d\n",
+					cond);
+	}
+	return 0; /* false */
+}
+
+
+
 /* computes the "unpacked" len of a lump list,
    code moved from build_req_from_req */
 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)
 	new_len=0;
 	
 	for(t=msg->add_rm;t;t=t->next){
+		/* skip if this is an OPT lump and the condition is not satisfied */
+		if ((t->op==LUMP_ADD_OPT) && !lump_check_opt(t->u.cond, msg, send_sock))
+			continue;
 		for(r=t->before;r;r=r->before){
 			switch(r->op){
 				case LUMP_ADD:
@@ -438,12 +507,19 @@ static inline int lumps_len(struct sip_msg* msg, struct socket_info* send_sock)
 				case LUMP_ADD_SUBST:
 					SUBST_LUMP_LEN(r);
 					break;
+				case LUMP_ADD_OPT:
+					/* skip if this is an OPT lump and the condition is 
+					 * not satisfied */
+					if (!lump_check_opt(r->u.cond, msg, send_sock))
+						goto skip_before;
+					break;
 				default:
 					/* only ADD allowed for before/after */
 						LOG(L_CRIT, "BUG: lumps_len: invalid op "
 							"for data lump (%x)\n", r->op);
 			}
 		}
+skip_before:
 		switch(t->op){
 			case LUMP_ADD:
 				new_len+=t->len;
@@ -451,6 +527,10 @@ static inline int lumps_len(struct sip_msg* msg, struct socket_info* send_sock)
 			case LUMP_ADD_SUBST:
 				SUBST_LUMP_LEN(t);
 				break;
+			case LUMP_ADD_OPT:
+				/* we don't do anything here, it's only a condition for
+				 * before & after */
+				break;
 			case LUMP_DEL:
 				/* fix overlapping deleted zones */
 				if (t->u.offset < s_offset){
@@ -483,12 +563,19 @@ static inline int lumps_len(struct sip_msg* msg, struct socket_info* send_sock)
 				case LUMP_ADD_SUBST:
 					SUBST_LUMP_LEN(r);
 					break;
+				case LUMP_ADD_OPT:
+					/* skip if this is an OPT lump and the condition is 
+					 * not satisfied */
+					if (!lump_check_opt(r->u.cond, msg, send_sock))
+						goto skip_after;
+					break;
 				default:
 					/* only ADD allowed for before/after */
 					LOG(L_CRIT, "BUG:lumps_len: invalid"
 								" op for data lump (%x)\n", r->op);
 			}
 		}
+skip_after:
 	}
 	return new_len;
 }
@@ -634,6 +721,13 @@ static inline void process_lumps(	struct sip_msg* msg,
 		switch(t->op){
 			case LUMP_ADD:
 			case LUMP_ADD_SUBST:
+			case LUMP_ADD_OPT:
+				/* skip if this is an OPT lump and the condition is 
+				 * not satisfied */
+				if ((t->op==LUMP_ADD_OPT) &&
+						(!lump_check_opt(t->u.cond, msg, send_sock))) 
+					continue;
+				break;
 				/* just add it here! */
 				/* process before  */
 				for(r=t->before;r;r=r->before){
@@ -646,18 +740,35 @@ static inline void process_lumps(	struct sip_msg* msg,
 						case LUMP_ADD_SUBST:
 							SUBST_LUMP(r);
 							break;
+						case LUMP_ADD_OPT:
+							/* skip if this is an OPT lump and the condition is 
+					 		* not satisfied */
+							if (!lump_check_opt(r->u.cond, msg, send_sock))
+								goto skip_before;
+							break;
 						default:
 							/* only ADD allowed for before/after */
 							LOG(L_CRIT, "BUG:process_lumps: "
 									"invalid op for data lump (%x)\n", r->op);
 					}
 				}
+skip_before:
 				/* copy "main" part */
-				if(t->op==LUMP_ADD){
-					memcpy(new_buf+offset, t->u.value, t->len);
-					offset+=t->len;
-				}else{
-					SUBST_LUMP(t);
+				switch(t->op){
+					case LUMP_ADD:
+						memcpy(new_buf+offset, t->u.value, t->len);
+						offset+=t->len;
+						break;
+					case LUMP_ADD_SUBST:
+						SUBST_LUMP(t);
+						break;
+					case LUMP_ADD_OPT:
+						/* do nothing, it's only a condition */
+						break;
+					default: 
+						/* should not ever get here */
+						LOG(L_CRIT, "BUG: process_lumps: unhandled data lump "
+								" op %d\n", t->op);
 				}
 				/* process after */
 				for(r=t->after;r;r=r->after){
@@ -670,12 +781,19 @@ static inline void process_lumps(	struct sip_msg* msg,
 						case LUMP_ADD_SUBST:
 							SUBST_LUMP(r);
 							break;
+						case LUMP_ADD_OPT:
+							/* skip if this is an OPT lump and the condition is 
+					 		* not satisfied */
+							if (!lump_check_opt(r->u.cond, msg, send_sock))
+								goto skip_after;
+							break;
 						default:
 							/* only ADD allowed for before/after */
 							LOG(L_CRIT, "BUG:process_lumps: "
 									"invalid op for data lump (%x)\n", r->op);
 					}
 				}
+skip_after:
 				break;
 			case LUMP_NOP:
 			case LUMP_DEL:
@@ -704,12 +822,19 @@ static inline void process_lumps(	struct sip_msg* msg,
 						case LUMP_ADD_SUBST:
 							SUBST_LUMP(r);
 							break;
+						case LUMP_ADD_OPT:
+							/* skip if this is an OPT lump and the condition is 
+					 		* not satisfied */
+							if (!lump_check_opt(r->u.cond, msg, send_sock))
+								goto skip_nop_before;
+							break;
 						default:
 							/* only ADD allowed for before/after */
 							LOG(L_CRIT, "BUG:process_lumps: "
 									"invalid op for data lump (%x)\n",r->op);
 					}
 				}
+skip_nop_before:
 				/* process main (del only) */
 				if (t->op==LUMP_DEL){
 					/* skip len bytes from orig msg */
@@ -726,12 +851,19 @@ static inline void process_lumps(	struct sip_msg* msg,
 						case LUMP_ADD_SUBST:
 							SUBST_LUMP(r);
 							break;
+						case LUMP_ADD_OPT:
+							/* skip if this is an OPT lump and the condition is 
+					 		* not satisfied */
+							if (!lump_check_opt(r->u.cond, msg, send_sock)) 
+								goto skip_nop_after;
+							break;
 						default:
 							/* only ADD allowed for before/after */
 							LOG(L_CRIT, "BUG:process_lumps: "
 									"invalid op for data lump (%x)\n", r->op);
 					}
 				}
+skip_nop_after:
 				break;
 			default:
 					LOG(L_CRIT, "BUG: process_lumps: "