Browse code

- added body_lumps (jan patches + some changes) - anchor_lump & del_lump compare the offset with msg->eoh and add the lump to add_rm or body_lumps, so make sure to parse_headers(HDR_EOH) if you lumps might modify the body. - changed all the {anchor,del}_lump calls

Andrei Pelinescu-Onciul authored on 20/10/2003 17:10:13
Showing 11 changed files
... ...
@@ -43,7 +43,7 @@ export makefile_defs
43 43
 VERSION = 0
44 44
 PATCHLEVEL = 8
45 45
 SUBLEVEL =   12
46
-EXTRAVERSION = dev-19
46
+EXTRAVERSION = dev-20-lumps
47 47
 
48 48
 RELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)
49 49
 OS = $(shell uname -s | sed -e s/SunOS/solaris/ | tr "[A-Z]" "[a-z]")
... ...
@@ -2,6 +2,8 @@ $Id$
2 2
 
3 3
 ( - todo, x - done)
4 4
 
5
+- alias support fot tcp/tls port numbers
6
+- warning builder set_advertised address support
5 7
 - grep parse_uri & replace with parse_sip_msg_uri (e.g do_action!)
6 8
 x update AUTHORS, debian/copyright, ser.8, ser.cfg.5 from stable
7 9
 x update Makefile*  from stable
... ...
@@ -27,8 +27,11 @@
27 27
  * History:
28 28
  * --------
29 29
  *  2003-01-19  support for duplication lump lists added (jiri)
30
- *  2003-03-31  added subst lumps -- they expand in ip addr, port a.s.o (andrei)
30
+ *  2003-03-31  added subst lumps --they expand in ip addr, port a.s.o (andrei)
31 31
  *  2003-04-01  added conditional lump suport functions (andrei)
32
+ *  2003-10-20  anchor_lump & del_lump will automatically choose the lump list
33
+ *              based on  msg->eoh comparisons (andrei)
34
+ *  
32 35
  */
33 36
 
34 37
 
... ...
@@ -254,10 +257,15 @@ struct lump* insert_cond_lump_before(	struct lump* before,
254 254
 
255 255
 
256 256
 /* removes an already existing header/data lump */
257
-struct lump* del_lump(struct lump** list, int offset, int len, int type)
257
+/* WARNING: thist function adds the lump either to the msg->add_rm or
258
+ * msg->body_lumps list, depending on the offset being greater than msg->eoh,
259
+ * so msg->eoh must be parsed (parse with HDR_EOH) if you think your lump
260
+ *  might affect the body!! */
261
+struct lump* del_lump(struct sip_msg* msg, int offset, int len, int type)
258 262
 {
259 263
 	struct lump* tmp;
260 264
 	struct lump* prev, *t;
265
+	struct lump** list;
261 266
 
262 267
 	tmp=pkg_malloc(sizeof(struct lump));
263 268
 	if (tmp==0){
... ...
@@ -270,6 +278,11 @@ struct lump* del_lump(struct lump** list, int offset, int len, int type)
270 270
 	tmp->u.offset=offset;
271 271
 	tmp->len=len;
272 272
 	prev=0;
273
+	/* check to see whether this might be a body lump */
274
+	if ((msg->eoh) && (offset> (int)(msg->eoh-msg->buf)))
275
+		list=&msg->body_lumps;
276
+	else
277
+		list=&msg->add_rm;
273 278
 	for (t=*list;t; prev=t, t=t->next){
274 279
 		/* insert it sorted after offset */
275 280
 		if (((t->op==LUMP_DEL)||(t->op==LUMP_NOP))&&(t->u.offset>offset))
... ...
@@ -283,12 +296,18 @@ struct lump* del_lump(struct lump** list, int offset, int len, int type)
283 283
 
284 284
 
285 285
 
286
-/* add an anhor */
287
-struct lump* anchor_lump(struct lump** list, int offset, int len, int type)
286
+/* add an anchor
287
+ * WARNING: thist function adds the lump either to the msg->add_rm or
288
+ * msg->body_lumps list, depending on the offset being greater than msg->eoh,
289
+ * so msg->eoh must be parsed (parse with HDR_EOH) if you think your lump
290
+ *  might affect the body!! */
291
+struct lump* anchor_lump(struct sip_msg* msg, int offset, int len, int type)
288 292
 {
289 293
 	struct lump* tmp;
290 294
 	struct lump* prev, *t;
295
+	struct lump** list;
291 296
 
297
+	
292 298
 	tmp=pkg_malloc(sizeof(struct lump));
293 299
 	if (tmp==0){
294 300
 		ser_error=E_OUT_OF_MEM;
... ...
@@ -301,6 +320,12 @@ struct lump* anchor_lump(struct lump** list, int offset, int len, int type)
301 301
 	tmp->u.offset=offset;
302 302
 	tmp->len=len;
303 303
 	prev=0;
304
+	/* check to see whether this might be a body lump */
305
+	if ((msg->eoh) && (offset> (int)(msg->eoh-msg->buf)))
306
+		list=&msg->body_lumps;
307
+	else
308
+		list=&msg->add_rm;
309
+		
304 310
 	for (t=*list;t; prev=t, t=t->next){
305 311
 		/* insert it sorted after offset */
306 312
 		if (((t->op==LUMP_DEL)||(t->op==LUMP_NOP))&&(t->u.offset>offset))
... ...
@@ -40,82 +40,8 @@
40 40
 #ifndef data_lump_h
41 41
 #define data_lump_h
42 42
 
43
-
44
-enum lump_op { LUMP_NOP=0, LUMP_DEL, LUMP_ADD, LUMP_ADD_SUBST, LUMP_ADD_OPT };
45
-enum lump_subst{ SUBST_NOP=0,                     /* do nothing */
46
-				 SUBST_RCV_IP,    SUBST_SND_IP,   /* add ip address */
47
-				 SUBST_RCV_PORT,  SUBST_SND_PORT, /* add port no */
48
-				 SUBST_RCV_PROTO, SUBST_SND_PROTO,/* add protocol(udp,tcp,tls)*/
49
-				 SUBST_RCV_ALL,   SUBST_SND_ALL   /*  ip:port;transport=proto */
50
-				};
51
-				/* Where:
52
-				   SND = sending, e.g the src ip of the outgoing message
53
-				   RCV = received e.g the dst ip of the original incoming msg,
54
-				    or the ip of the ser socket on which the msg was received
55
-				   For SUBST_{RCV,SND}_ALL, :port is added only if port!=5060
56
-				    and transport=proto only if proto!=udp
57
-					*/
58
-
59
-enum lump_conditions {	COND_FALSE,         /* always false */
60
-						COND_TRUE,          /* always true */
61
-						COND_IF_DIFF_REALMS,/* true if RCV realm != SND realm */
62
-						COND_IF_DIFF_AF,    /* true if RCV af != SND af */
63
-						COND_IF_DIFF_PROTO, /* true if RCV proto != SND proto */
64
-						COND_IF_DIFF_PORT,  /* true if RCV port != SND port */
65
-						COND_IF_DIFF_IP,    /* true if RCV ip != SND ip */
66
-						COND_IF_RAND        /* 50-50 random prob.of being true*/
67
-						};
68
-						/* Where: 
69
-						   REALM= ip_addr:port:proto
70
-						   af   = address family (ipv4 or ipv6)
71
-						   proto = protocol (tcp, udp, tls)
72
-						*/
73
-
74
-enum lump_flag { LUMPFLAG_NONE=0, LUMPFLAG_DUPED=1, LUMPFLAG_SHMEM=2 };
75
-
76
-struct lump{
77
-	int type; /* VIA, OTHER, UNSPEC(=0), ... */
78
-	enum lump_op op;   /* DEL, ADD, NOP, UNSPEC(=0) */
79
-	
80
-	union{
81
-		int offset; /* used for DEL, MODIFY */
82
-		enum lump_subst subst; /*what to subst: ip addr, port, proto*/
83
-		enum lump_conditions cond; /* condition for LUMP_ADD_OPT */
84
-		char * value; /* used for ADD */
85
-	}u;
86
-	int len; /* length of this header field */
87
-	
88
-	
89
-	struct lump* before; /* list of headers to be inserted in front of the
90
-								current one */
91
-	struct lump* after; /* list of headers to be inserted immediately after
92
-							  the current one */
93
-	
94
-	struct lump* next;
95
-
96
-	enum lump_flag flags; /* additional hints for use from TM's shmem */
97
-};
98
-
99
-/*
100
- * hdrs must be kept sorted after their offset (DEL, NOP, UNSPEC)
101
- * and/or their position (ADD). E.g.:
102
- *  - to delete header Z insert it in to the list according to its offset 
103
- *   and with op=DELETE
104
- * - if you want to add a new header X after a  header Y, insert Y in the list
105
- *   with op NOP and after it X (op ADD).
106
- * - if you want X before Y, insert X in Y's before list.
107
- * - if you want X to be the first header just put it first in hdr_lst.
108
- *  -if you want to replace Y with X, insert Y with op=DELETE and then X with
109
- *  op=ADD.
110
- * before and after must contain only ADD ops!
111
- * 
112
- * Difference between "after" & "next" when ADDing:
113
- * "after" forces the new header immediately after the current one while
114
- * "next" means another header can be inserted between them.
115
- * 
116
- */
117
-
118
-
43
+#include "lump_struct.h"
44
+#include "parser/msg_parser.h"
119 45
 
120 46
 /* adds a header to the end */
121 47
 struct lump* append_new_lump(struct lump** list, char* new_hdr,
... ...
@@ -140,15 +66,11 @@ struct lump* insert_cond_lump_before(struct lump* after, enum lump_conditions c,
140 140
 									int type);
141 141
 
142 142
 /* removes an already existing header */
143
-struct lump* del_lump(struct lump** list, int offset, int len, int type);
143
+struct lump* del_lump(struct sip_msg* msg, int offset, int len, int type);
144 144
 /* set an anchor */
145
-struct lump* anchor_lump(struct lump** list, int offset, int len, int type);
145
+struct lump* anchor_lump(struct sip_msg* msg, int offset, int len, int type);
146 146
 
147 147
 
148
-/* frees the content of a lump struct */
149
-void free_lump(struct lump* l);
150
-/*frees an entire lump list, recursively */
151
-void free_lump_list(struct lump* lump_list);
152 148
 
153 149
 /* duplicates a lump list shallowly in pkg-mem */
154 150
 struct lump* dup_lump_list( struct lump *l );
155 151
new file mode 100644
... ...
@@ -0,0 +1,127 @@
0
+/*
1
+ * $Id$
2
+ *
3
+ * adding/removing headers or any other data chunk from a message
4
+ *
5
+ * Copyright (C) 2001-2003 Fhg Fokus
6
+ *
7
+ * This file is part of ser, a free SIP server.
8
+ *
9
+ * ser is free software; you can redistribute it and/or modify
10
+ * it under the terms of the GNU General Public License as published by
11
+ * the Free Software Foundation; either version 2 of the License, or
12
+ * (at your option) any later version
13
+ *
14
+ * For a license to use the ser software under conditions
15
+ * other than those described here, or to purchase support for this
16
+ * software, please contact iptel.org by e-mail at the following addresses:
17
+ *    info@iptel.org
18
+ *
19
+ * ser is distributed in the hope that it will be useful,
20
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
21
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22
+ * GNU General Public License for more details.
23
+ *
24
+ * You should have received a copy of the GNU General Public License 
25
+ * along with this program; if not, write to the Free Software 
26
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
27
+ */
28
+/* History:
29
+ * --------
30
+ *  2003-01-29  s/int/enum ... more convenient for gdb (jiri)
31
+ *  2003-03-31  added subst lumps -- they expand in ip addr, port a.s.o (andrei)
32
+ *  2003-04-01  added opt (condition) lumps (andrei)
33
+ *  2003-04-02  added more subst lumps: SUBST_{SND,RCV}_ALL  
34
+ *              => ip:port;transport=proto (andrei)
35
+ *  2003-10-20  splitted from data_lump.h (andrei)
36
+ *
37
+ */
38
+
39
+
40
+#ifndef lump_struct_h
41
+#define lump_struct_h
42
+
43
+
44
+
45
+enum lump_op { LUMP_NOP=0, LUMP_DEL, LUMP_ADD, LUMP_ADD_SUBST, LUMP_ADD_OPT };
46
+enum lump_subst{ SUBST_NOP=0,                     /* do nothing */
47
+				 SUBST_RCV_IP,    SUBST_SND_IP,   /* add ip address */
48
+				 SUBST_RCV_PORT,  SUBST_SND_PORT, /* add port no */
49
+				 SUBST_RCV_PROTO, SUBST_SND_PROTO,/* add protocol(udp,tcp,tls)*/
50
+				 SUBST_RCV_ALL,   SUBST_SND_ALL   /*  ip:port;transport=proto */
51
+				};
52
+				/* Where:
53
+				   SND = sending, e.g the src ip of the outgoing message
54
+				   RCV = received e.g the dst ip of the original incoming msg,
55
+				    or the ip of the ser socket on which the msg was received
56
+				   For SUBST_{RCV,SND}_ALL, :port is added only if port!=5060
57
+				    and transport=proto only if proto!=udp
58
+					*/
59
+
60
+enum lump_conditions {	COND_FALSE,         /* always false */
61
+						COND_TRUE,          /* always true */
62
+						COND_IF_DIFF_REALMS,/* true if RCV realm != SND realm */
63
+						COND_IF_DIFF_AF,    /* true if RCV af != SND af */
64
+						COND_IF_DIFF_PROTO, /* true if RCV proto != SND proto */
65
+						COND_IF_DIFF_PORT,  /* true if RCV port != SND port */
66
+						COND_IF_DIFF_IP,    /* true if RCV ip != SND ip */
67
+						COND_IF_RAND        /* 50-50 random prob.of being true*/
68
+						};
69
+						/* Where: 
70
+						   REALM= ip_addr:port:proto
71
+						   af   = address family (ipv4 or ipv6)
72
+						   proto = protocol (tcp, udp, tls)
73
+						*/
74
+
75
+enum lump_flag { LUMPFLAG_NONE=0, LUMPFLAG_DUPED=1, LUMPFLAG_SHMEM=2 };
76
+
77
+
78
+struct lump{
79
+	int type; /* VIA, OTHER, UNSPEC(=0), ... */
80
+	enum lump_op op;   /* DEL, ADD, NOP, UNSPEC(=0) */
81
+	
82
+	union{
83
+		int offset; /* used for DEL, MODIFY */
84
+		enum lump_subst subst; /*what to subst: ip addr, port, proto*/
85
+		enum lump_conditions cond; /* condition for LUMP_ADD_OPT */
86
+		char * value; /* used for ADD */
87
+	}u;
88
+	int len; /* length of this header field */
89
+	
90
+	
91
+	struct lump* before; /* list of headers to be inserted in front of the
92
+								current one */
93
+	struct lump* after; /* list of headers to be inserted immediately after
94
+							  the current one */
95
+	
96
+	struct lump* next;
97
+
98
+	enum lump_flag flags; /* additional hints for use from TM's shmem */
99
+};
100
+
101
+
102
+/*
103
+ * hdrs must be kept sorted after their offset (DEL, NOP, UNSPEC)
104
+ * and/or their position (ADD). E.g.:
105
+ *  - to delete header Z insert it in to the list according to its offset 
106
+ *   and with op=DELETE
107
+ * - if you want to add a new header X after a  header Y, insert Y in the list
108
+ *   with op NOP and after it X (op ADD).
109
+ * - if you want X before Y, insert X in Y's before list.
110
+ * - if you want X to be the first header just put it first in hdr_lst.
111
+ *  -if you want to replace Y with X, insert Y with op=DELETE and then X with
112
+ *  op=ADD.
113
+ * before and after must contain only ADD ops!
114
+ * 
115
+ * Difference between "after" & "next" when ADDing:
116
+ * "after" forces the new header immediately after the current one while
117
+ * "next" means another header can be inserted between them.
118
+ * 
119
+ */
120
+
121
+/* frees the content of a lump struct */
122
+void free_lump(struct lump* l);
123
+/*frees an entire lump list, recursively */
124
+void free_lump_list(struct lump* lump_list);
125
+
126
+#endif
... ...
@@ -253,7 +253,6 @@ struct sip_msg*  sip_msg_cloner( struct sip_msg *org_msg )
253 253
 	struct via_param  *prm;
254 254
 	struct to_param   *to_prm,*new_to_prm;
255 255
 	struct sip_msg    *new_msg;
256
-	struct lump       *lump_chain, *lump_tmp, **lump_anchor, **lump_anchor2;
257 256
 	struct lump_rpl   *rpl_lump, **rpl_lump_anchor;
258 257
 	char              *p,*foo;
259 258
 
... ...
@@ -340,25 +339,32 @@ struct sip_msg*  sip_msg_cloner( struct sip_msg *org_msg )
340 340
 	}/*for all headers*/
341 341
 
342 342
 	/* length of the data lump structures */
343
-	lump_chain = org_msg->add_rm;
344
-	while (lump_chain)
345
-	{
346
-		len += lump_len( lump_chain );
347
-		lump_tmp = lump_chain->before;
348
-		while ( lump_tmp )
349
-		{
350
-			len += lump_len( lump_tmp );
351
-			lump_tmp = lump_tmp->before;
352
-		}
353
-		lump_tmp = lump_chain->after;
354
-		while ( lump_tmp )
355
-		{
356
-			len += lump_len( lump_tmp );
357
-			lump_tmp = lump_tmp->after;
358
-		}
359
-		lump_chain = lump_chain->next;
360
-	}
361
-
343
+#define LUMP_LIST_LEN(len, list) \
344
+do { \
345
+        struct lump* tmp, *chain; \
346
+	chain = (list); \
347
+	while (chain) \
348
+	{ \
349
+		(len) += lump_len(chain); \
350
+		tmp = chain->before; \
351
+		while ( tmp ) \
352
+		{ \
353
+			(len) += lump_len( tmp ); \
354
+			tmp = tmp->before; \
355
+		} \
356
+		tmp = chain->after; \
357
+		while ( tmp ) \
358
+		{ \
359
+			(len) += lump_len( tmp ); \
360
+			tmp = tmp->after; \
361
+		} \
362
+		chain = chain->next; \
363
+	} \
364
+} while(0);
365
+
366
+	LUMP_LIST_LEN(len, org_msg->add_rm);
367
+	LUMP_LIST_LEN(len, org_msg->body_lumps);
368
+	
362 369
 	/*length of reply lump structures*/
363 370
 	for(rpl_lump=org_msg->reply_lump;rpl_lump;rpl_lump=rpl_lump->next)
364 371
 			len+=ROUND4(sizeof(struct lump_rpl))+ROUND4(rpl_lump->text.len);
... ...
@@ -376,6 +382,7 @@ struct sip_msg*  sip_msg_cloner( struct sip_msg *org_msg )
376 376
 	memcpy( new_msg , org_msg , sizeof(struct sip_msg) );
377 377
 	p += ROUND4(sizeof(struct sip_msg));
378 378
 	new_msg->add_rm = 0;
379
+	new_msg->body_lumps = 0;
379 380
 	/* new_uri */
380 381
 	if (org_msg->new_uri.s && org_msg->new_uri.len)
381 382
 	{
... ...
@@ -630,32 +637,40 @@ struct sip_msg*  sip_msg_cloner( struct sip_msg *org_msg )
630 630
 	}
631 631
 
632 632
 	/* clonning data lump */
633
-		lump_chain = org_msg->add_rm;
634
-		lump_anchor = &(new_msg->add_rm);
635
-	while (lump_chain)
636
-	{
637
-		lump_clone( (*lump_anchor) , lump_chain , p );
638
-		/*before list*/
639
-		lump_tmp = lump_chain->before;
640
-		lump_anchor2 = &((*lump_anchor)->before);
641
-		while ( lump_tmp )
642
-		{
643
-			lump_clone( (*lump_anchor2) , lump_tmp , p );
644
-			lump_anchor2 = &((*lump_anchor2)->before);
645
-			lump_tmp = lump_tmp->before;
646
-		}
647
-		/*after list*/
648
-		lump_tmp = lump_chain->after;
649
-		lump_anchor2 = &((*lump_anchor)->after);
650
-		while ( lump_tmp )
651
-		{
652
-			lump_clone( (*lump_anchor2) , lump_tmp , p );
653
-			lump_anchor2 = &((*lump_anchor2)->after);
654
-			lump_tmp = lump_tmp->after;
655
-		}
656
-		lump_anchor = &((*lump_anchor)->next);
657
-		lump_chain = lump_chain->next;
658
-	}
633
+#define CLONE_LUMP_LIST(anchor, list) \
634
+do { \
635
+        struct lump* lump_tmp, *l; \
636
+        struct lump** lump_anchor2, **a; \
637
+        a = (anchor); \
638
+        l = (list); \
639
+	while (l) \
640
+	{ \
641
+		lump_clone( (*a) , l , p ); \
642
+		/*before list*/ \
643
+		lump_tmp = l->before; \
644
+		lump_anchor2 = &((*a)->before); \
645
+		while ( lump_tmp ) \
646
+		{ \
647
+			lump_clone( (*lump_anchor2) , lump_tmp , p ); \
648
+			lump_anchor2 = &((*lump_anchor2)->before); \
649
+			lump_tmp = lump_tmp->before; \
650
+		} \
651
+		/*after list*/ \
652
+		lump_tmp = l->after; \
653
+		lump_anchor2 = &((*a)->after); \
654
+		while ( lump_tmp ) \
655
+		{ \
656
+			lump_clone( (*lump_anchor2) , lump_tmp , p ); \
657
+			lump_anchor2 = &((*lump_anchor2)->after); \
658
+			lump_tmp = lump_tmp->after; \
659
+		} \
660
+		a = &((*a)->next); \
661
+		l = l->next; \
662
+	} \
663
+} while(0)
664
+
665
+        CLONE_LUMP_LIST(&(new_msg->add_rm), org_msg->add_rm);
666
+        CLONE_LUMP_LIST(&(new_msg->body_lumps), org_msg->body_lumps);
659 667
 
660 668
 	/*cloning reply lump structures*/
661 669
 	rpl_lump_anchor = &(new_msg->reply_lump);
... ...
@@ -413,6 +413,7 @@ static int faked_env(struct sip_msg *fake,
413 413
 	/* set items, which will be duped to pkg_mem, to zero, so that
414 414
 	 * "restore" called on error does not free the original items */
415 415
 	fake->add_rm=0;
416
+	fake->body_lumps=0;
416 417
 	fake->new_uri.s=0; fake->new_uri.len=0; 
417 418
 
418 419
 	/* remember we are back in request processing, but process
... ...
@@ -459,12 +460,22 @@ static int faked_env(struct sip_msg *fake,
459 459
 			goto restore;
460 460
 		}
461 461
 	}
462
+
463
+	if (shmem_msg->body_lumps) {
464
+		fake->body_lumps=dup_lump_list(shmem_msg->body_lumps);
465
+		if (!fake->body_lumps) { /* non_empty->empty ... failure */
466
+			LOG(L_ERR, "ERROR: on_negative_reply: lump dup failed\n");
467
+			goto restore;
468
+		}
469
+	}
470
+	
462 471
 	/* success */
463 472
 	return 1;
464 473
 
465 474
 restore:
466 475
 	/* restore original environment and destroy faked message */
467 476
 	free_duped_lump_list(fake->add_rm);
477
+	free_duped_lump_list(fake->body_lumps);
468 478
 	if (fake->new_uri.s) pkg_free(fake->new_uri.s);
469 479
 	set_t(backup_t);
470 480
 	global_msg_id=backup_msgid;
... ...
@@ -36,6 +36,7 @@
36 36
 #include "../../parser/parser_f.h"
37 37
 #include "../../ut.h"
38 38
 #include "../../timer.h"
39
+#include "../../data_lump.h"
39 40
 
40 41
 #include "t_hooks.h"
41 42
 
... ...
@@ -53,8 +54,7 @@ int _test_insert_to_reply( struct sip_msg *msg, char *str )
53 53
     }
54 54
     memcpy( buf, str, len );
55 55
 
56
-    anchor = anchor_lump(&msg->add_rm,
57
-        msg->headers->name.s - msg->buf, 0 , 0);
56
+    anchor = anchor_lump(msg, msg->headers->name.s - msg->buf, 0 , 0);
58 57
     if (anchor == NULL) {
59 58
         LOG(L_ERR, "_test_insert_to_reply: anchor_lump failed\n");
60 59
         return 0;
... ...
@@ -53,7 +53,8 @@
53 53
  *             build_req_fomr_sip_req no longer adds 1 for ipv6 via parameter
54 54
  *              position calculations ([] are part of host.s now) (andrei)
55 55
  * 2003-10-02  via+lump dst address/port can be set to preset values (andrei)
56
- * 2003-10-08 receive_test function-alized (jiri)
56
+ * 2003-10-08  receive_test function-alized (jiri)
57
+ * 2003-10-20  added body_lump list (sip_msg), adjust_clen (andrei & jan)
57 58
  *
58 59
  */
59 60
 /* Via special params:
... ...
@@ -121,6 +122,7 @@
121 121
 #include "dprint.h"
122 122
 #include "config.h"
123 123
 #include "md5utils.h"
124
+#include "data_lump.h"
124 125
 #include "data_lump_rpl.h"
125 126
 #include "ip_addr.h"
126 127
 #include "resolve.h"
... ...
@@ -394,7 +396,7 @@ char* id_builder(struct sip_msg* msg, unsigned int *id_len)
394 394
 
395 395
 
396 396
 
397
-char* clen_builder(struct sip_msg* msg, unsigned int *clen_len)
397
+char* clen_builder(struct sip_msg* msg, unsigned int *clen_len, int diff)
398 398
 {
399 399
 	char* buf;
400 400
 	int len;
... ...
@@ -411,7 +413,7 @@ char* clen_builder(struct sip_msg* msg, unsigned int *clen_len)
411 411
 					" (missing crlf?)");
412 412
 		return 0;
413 413
 	}
414
-	value=msg->len-(int)(body-msg->buf);
414
+	value=msg->len-(int)(body-msg->buf)+diff;
415 415
 	value_s=int2str(value, &value_len);
416 416
 	DBG("clen_builder: content-length: %d (%s)\n", value, value_s);
417 417
 		
... ...
@@ -499,7 +501,7 @@ static inline int lump_check_opt(	enum lump_conditions cond,
499 499
 
500 500
 /* computes the "unpacked" len of a lump list,
501 501
    code moved from build_req_from_req */
502
-static inline int lumps_len(struct sip_msg* msg, struct socket_info* send_sock)
502
+static inline int lumps_len(struct sip_msg* msg, struct lump* lumps, struct socket_info* send_sock)
503 503
 {
504 504
 	int s_offset;
505 505
 	int new_len;
... ...
@@ -672,7 +674,7 @@ static inline int lumps_len(struct sip_msg* msg, struct socket_info* send_sock)
672 672
 		send_port_str=&(send_sock->port_no_str);
673 673
 	
674 674
 	
675
-	for(t=msg->add_rm;t;t=t->next){
675
+	for(t=lumps;t;t=t->next){
676 676
 		/* skip if this is an OPT lump and the condition is not satisfied */
677 677
 		if ((t->op==LUMP_ADD_OPT) && !lump_check_opt(t->u.cond, msg, send_sock))
678 678
 			continue;
... ...
@@ -763,7 +765,8 @@ skip_after:
763 763
 /* another helper functions, adds/Removes the lump,
764 764
 	code moved form build_req_from_req  */
765 765
 
766
-static inline void process_lumps(	struct sip_msg* msg,	
766
+static inline void process_lumps(	struct sip_msg* msg,
767
+					                                struct lump* lumps,
767 768
 									char* new_buf, 
768 769
 									unsigned int* new_buf_offs, 
769 770
 									unsigned int* orig_offs,
... ...
@@ -1027,7 +1030,7 @@ static inline void process_lumps(	struct sip_msg* msg,
1027 1027
 	offset=*new_buf_offs;
1028 1028
 	s_offset=*orig_offs;
1029 1029
 	
1030
-	for (t=msg->add_rm;t;t=t->next){
1030
+	for (t=lumps;t;t=t->next){
1031 1031
 		switch(t->op){
1032 1032
 			case LUMP_ADD:
1033 1033
 			case LUMP_ADD_SUBST:
... ...
@@ -1184,12 +1187,109 @@ skip_nop_after:
1184 1184
 }
1185 1185
 
1186 1186
 
1187
+/*
1188
+ * Adjust/insert Content-Length if necesarry
1189
+ */
1190
+static inline int adjust_clen(struct sip_msg* msg, int body_delta, int proto)
1191
+{
1192
+	struct lump* anchor;
1193
+	char* clen_buf;
1194
+	int clen_len;
1195
+
1196
+	/* Calculate message length difference caused by lumps modifying message
1197
+	 * body, from this point on the message body must not be modified. Zero
1198
+	 * value indicates that the body hasn't been modified
1199
+	*/
1200
+
1201
+	clen_buf = 0;
1202
+	anchor=0;
1203
+	
1204
+	/* check to see if we need to add clen */
1205
+#ifdef USE_TCP
1206
+	if (proto == PROTO_TCP
1207
+#ifdef USE_TLS
1208
+	    || proto == PROTO_TLS
1209
+#endif
1210
+	    ) {
1211
+		if (parse_headers(msg, HDR_CONTENTLENGTH, 0)==-1){
1212
+			LOG(L_ERR, "adjust_clen: error parsing content-length\n");
1213
+			goto error;
1214
+		}
1215
+		if (msg->content_length==0){
1216
+			/* not present, we need to add it */
1217
+			/* msg->unparsed should point just before the final crlf
1218
+			 * - whole message was parsed by the above parse_headers
1219
+			 *   which did not find content-length */
1220
+			anchor=anchor_lump(msg, msg->unparsed-msg->buf, 0,
1221
+												HDR_CONTENTLENGTH);
1222
+			if (anchor==0){
1223
+				LOG(L_ERR, "adjust_clen: cannot set clen anchor\n");
1224
+				goto error;
1225
+			}
1226
+		}
1227
+	}
1228
+#endif
1229
+	
1230
+	
1231
+	if ((anchor==0) && body_delta){
1232
+		if (parse_headers(msg, HDR_CONTENTLENGTH, 0) == -1) {
1233
+			LOG(L_ERR, "adjust_clen: Error parsing Content-Length\n");
1234
+			goto error;
1235
+		}
1236
+		
1237
+		/* The body has been changed, try to find
1238
+		 * existing Content-Length
1239
+		 */
1240
+		/* no need for Content-Length if it's and UDP packet and
1241
+		 * it hasn't Content-Lentgh already */
1242
+		if ((msg->content_length==0)){
1243
+		    /* content-length doesn't exist, append it */
1244
+			/* msg->unparsed should point just before the final crlf
1245
+			 * - whole message was parsed by the above parse_headers
1246
+			 *   which did not find content-length */
1247
+			if (proto!=PROTO_UDP){
1248
+				anchor=anchor_lump(msg, msg->unparsed-msg->buf, 0,
1249
+													HDR_CONTENTLENGTH);
1250
+				if (anchor==0){
1251
+					LOG(L_ERR, "adjust_clen: cannot set clen anchor\n");
1252
+					goto error;
1253
+				}
1254
+			}else{
1255
+				DBG("add_clen: UDP packet with no clen => not adding one \n");
1256
+			}
1257
+		}else{
1258
+			/* Content-Length has been found, remove it */
1259
+			anchor = del_lump(	msg, msg->content_length->name.s - msg->buf,
1260
+								msg->content_length->len, HDR_CONTENTLENGTH);
1261
+			if (anchor==0) {
1262
+				LOG(L_ERR, "adjust_clen: Can't remove original"
1263
+							" Content-Length\n");
1264
+				goto error;
1265
+			}
1266
+		}
1267
+	}
1268
+	
1269
+	if (anchor){
1270
+		clen_buf = clen_builder(msg, &clen_len, body_delta);
1271
+		if (!clen_buf) goto error;
1272
+		if (insert_new_lump_after(anchor, clen_buf, clen_len,
1273
+					HDR_CONTENTLENGTH) == 0)
1274
+			goto error;
1275
+	}
1276
+
1277
+	return 0;
1278
+error:
1279
+	if (clen_buf) pkg_free(clen_buf);
1280
+	return -1;
1281
+}
1282
+
1283
+
1187 1284
 
1188 1285
 char * build_req_buf_from_sip_req( struct sip_msg* msg,
1189 1286
 								unsigned int *returned_len,
1190 1287
 								struct socket_info* send_sock, int proto)
1191 1288
 {
1192
-	unsigned int len, new_len, received_len, rport_len, uri_len, via_len;
1289
+	unsigned int len, new_len, received_len, rport_len, uri_len, via_len, body_delta;
1193 1290
 	char* line_buf;
1194 1291
 	char* received_buf;
1195 1292
 	char* rport_buf;
... ...
@@ -1201,18 +1301,14 @@ char * build_req_buf_from_sip_req( struct sip_msg* msg,
1201 1201
 	str branch;
1202 1202
 	str extra_params;
1203 1203
 	struct hostport hp;
1204
-	
1204
+
1205 1205
 #ifdef USE_TCP
1206 1206
 	char* id_buf;
1207 1207
 	unsigned int id_len;
1208
-	char* clen_buf;
1209
-	unsigned int clen_len;
1210 1208
 	
1211 1209
 	
1212 1210
 	id_buf=0;
1213 1211
 	id_len=0;
1214
-	clen_buf=0;
1215
-	clen_len=0;
1216 1212
 #endif
1217 1213
 	via_insert_param=0;
1218 1214
 	extra_params.len=0;
... ...
@@ -1226,7 +1322,6 @@ char * build_req_buf_from_sip_req( struct sip_msg* msg,
1226 1226
 	received_buf=0;
1227 1227
 	rport_buf=0;
1228 1228
 	line_buf=0;
1229
-
1230 1229
 	
1231 1230
 #ifdef USE_TCP
1232 1231
 	/* add id if tcp */
... ...
@@ -1246,31 +1341,17 @@ char * build_req_buf_from_sip_req( struct sip_msg* msg,
1246 1246
 		extra_params.s=id_buf;
1247 1247
 		extra_params.len=id_len;
1248 1248
 	}
1249
-	/* if sending proto == tcp, check if Content-Length needs to be added*/
1250
-	if (proto==PROTO_TCP
1251
-#ifdef USE_TLS
1252
-			|| proto==PROTO_TLS
1253 1249
 #endif
1254
-			){
1255
-		DBG("build_req_from_req: checking for clen; proto=%d,"
1256
-			" rcv->proto=%d\n", proto, msg->rcv.proto);
1257
-		/* first of all parse content-length */
1258
-		if (parse_headers(msg, HDR_CONTENTLENGTH, 0)==-1){
1259
-			LOG(L_ERR, "build_req_buf_from_sip_req:"
1260
-							" error parsing content-length\n");
1261
-			goto skip_clen;
1262
-		}
1263
-		if (msg->content_length==0){
1264
-			/* we need to add it */
1265
-			if ((clen_buf=clen_builder(msg, &clen_len))==0){
1266
-				LOG(L_ERR, "build_req_buf_from_sip_req:" 
1267
-								" clen_builder failed\n");
1268
-				goto skip_clen;
1269
-			}
1270
-		}
1250
+	     /* Calculate message body difference and adjust
1251
+	      * Content-Length
1252
+	      */
1253
+	body_delta = lumps_len(msg, msg->body_lumps, send_sock);
1254
+	if (adjust_clen(msg, body_delta, proto) < 0) {
1255
+		LOG(L_ERR, "ERROR: build_req_buf_from_sip_req: Error while adjusting"
1256
+				" Content-Length\n");
1257
+		goto error00;
1271 1258
 	}
1272
-skip_clen:
1273
-#endif
1259
+
1274 1260
 	branch.s=msg->add_to_branch_s;
1275 1261
 	branch.len=msg->add_to_branch_len;
1276 1262
 	set_hostport(&hp, msg);
... ...
@@ -1306,7 +1387,7 @@ skip_clen:
1306 1306
 	/* add via header to the list */
1307 1307
 	/* try to add it before msg. 1st via */
1308 1308
 	/* add first via, as an anchor for second via*/
1309
-	anchor=anchor_lump(&(msg->add_rm), msg->via1->hdr.s-buf, 0, HDR_VIA);
1309
+	anchor=anchor_lump(msg, msg->via1->hdr.s-buf, 0, HDR_VIA);
1310 1310
 	if (anchor==0) goto error01;
1311 1311
 	if (insert_new_lump_before(anchor, line_buf, via_len, HDR_VIA)==0)
1312 1312
 		goto error01;
... ...
@@ -1332,11 +1413,11 @@ skip_clen:
1332 1332
 	 * overwrite the previous one if already present */
1333 1333
 	if (received_len){
1334 1334
 		if (msg->via1->received){ /* received already present => overwrite it*/
1335
-			via_insert_param=del_lump(&(msg->add_rm),
1335
+			via_insert_param=del_lump(msg,
1336 1336
 								msg->via1->received->start-buf-1, /*;*/
1337 1337
 								msg->via1->received->size+1, /*;*/ HDR_VIA);
1338 1338
 		}else if (via_insert_param==0){ /* receive not present, ok */
1339
-			via_insert_param=anchor_lump(&(msg->add_rm),
1339
+			via_insert_param=anchor_lump(msg,
1340 1340
 										msg->via1->hdr.s-buf+size,0, HDR_VIA);
1341 1341
 		}
1342 1342
 		if (via_insert_param==0) goto error02; /* free received_buf */
... ...
@@ -1346,12 +1427,12 @@ skip_clen:
1346 1346
 	/* if rport needs to be updated, delete it if present and add it's value */
1347 1347
 	if (rport_len){
1348 1348
 		if (msg->via1->rport){ /* rport already present */
1349
-			via_insert_param=del_lump(&(msg->add_rm),
1349
+			via_insert_param=del_lump(msg,
1350 1350
 								msg->via1->rport->start-buf-1, /*';'*/
1351 1351
 								msg->via1->rport->size+1 /* ; */, HDR_VIA);
1352 1352
 		}else if (via_insert_param==0){ /*force rport, no rport present */
1353 1353
 			/* no rport, add it */
1354
-			via_insert_param=anchor_lump(&(msg->add_rm),
1354
+			via_insert_param=anchor_lump(msg,
1355 1355
 										msg->via1->hdr.s-buf+size,0, HDR_VIA);
1356 1356
 		}
1357 1357
 		if (via_insert_param==0) goto error03; /* free rport_buf */
... ...
@@ -1360,22 +1441,9 @@ skip_clen:
1360 1360
 			goto error03; /* free rport_buf */
1361 1361
 			
1362 1362
 	}
1363
-#ifdef USE_TCP
1364
-	/* if clen needs to be added, add it */
1365
-	if (clen_len){
1366
-		/* msg->unparsed should point just before the final crlf,
1367
-		 * parse_headers is called from clen_builder */
1368
-		anchor=anchor_lump(&(msg->add_rm), msg->unparsed-buf, 0,
1369
-							 HDR_CONTENTLENGTH);
1370
-		if (anchor==0) goto error04; /* free clen_buf */
1371
-		if (insert_new_lump_after(anchor, clen_buf, clen_len,
1372
-					HDR_CONTENTLENGTH)==0)
1373
-			goto error04; /* free clen_buf*/
1374
-	}
1375
-#endif
1376 1363
 
1377 1364
 	/* compute new msg len and fix overlapping zones*/
1378
-	new_len=len+lumps_len(msg, send_sock);
1365
+	new_len=len+body_delta+lumps_len(msg, msg->add_rm, send_sock);
1379 1366
 #ifdef XL_DEBUG
1380 1367
 	LOG(L_ERR, "DEBUG: new_len(%d)=len(%d)+lumps_len\n", new_len, len);
1381 1368
 #endif
... ...
@@ -1405,7 +1473,8 @@ skip_clen:
1405 1405
 	}
1406 1406
 	new_buf[new_len]=0;
1407 1407
 	/* copy msg adding/removing lumps */
1408
-	process_lumps(msg, new_buf, &offset, &s_offset, send_sock);
1408
+	process_lumps(msg, msg->add_rm, new_buf, &offset, &s_offset, send_sock);
1409
+	process_lumps(msg, msg->body_lumps, new_buf, &offset, &s_offset,send_sock);
1409 1410
 	/* copy the rest of the message */
1410 1411
 	memcpy(new_buf+offset, buf+s_offset, len-s_offset);
1411 1412
 	new_buf[new_len]=0;
... ...
@@ -1431,10 +1500,6 @@ error02:
1431 1431
 	if (received_buf) pkg_free(received_buf);
1432 1432
 error03:
1433 1433
 	if (rport_buf) pkg_free(rport_buf);
1434
-#ifdef USE_TCP
1435
-error04:
1436
-	if (clen_buf) pkg_free(clen_buf);
1437
-#endif
1438 1434
 error00:
1439 1435
 #ifdef USE_TCP
1440 1436
 	if (id_buf) pkg_free(id_buf);
... ...
@@ -1448,19 +1513,12 @@ error00:
1448 1448
 char * build_res_buf_from_sip_res( struct sip_msg* msg,
1449 1449
 				unsigned int *returned_len)
1450 1450
 {
1451
-	unsigned int new_len, via_len;
1451
+	unsigned int new_len, via_len, body_delta;
1452 1452
 	char* new_buf;
1453 1453
 	unsigned offset, s_offset, via_offset;
1454 1454
 	char* buf;
1455 1455
 	unsigned int len;
1456
-#ifdef USE_TCP
1457
-	struct lump* anchor;
1458
-	char* clen_buf;
1459
-	unsigned int clen_len;
1460
-	
1461
-	clen_buf=0;
1462
-	clen_len=0;
1463
-#endif
1456
+
1464 1457
 	buf=msg->buf;
1465 1458
 	len=msg->len;
1466 1459
 	new_buf=0;
... ...
@@ -1473,57 +1531,26 @@ char * build_res_buf_from_sip_res( struct sip_msg* msg,
1473 1473
 		via_offset=msg->h_via1->name.s-buf;
1474 1474
 	}
1475 1475
 
1476
-#ifdef USE_TCP
1477
-
1478
-	/* if sending proto == tcp, check if Content-Length needs to be added*/
1479
-	if (msg->via2 && ((msg->via2->proto==PROTO_TCP)
1480
-#ifdef USE_TLS
1481
-				|| (msg->via2->proto==PROTO_TLS)
1482
-#endif
1483
-				)){
1484
-		DBG("build_res_from_sip_res: checking content-length for \n%.*s\n",
1485
-				(int)msg->len, msg->buf);
1486
-		/* first of all parse content-length */
1487
-		if (parse_headers(msg, HDR_CONTENTLENGTH, 0)==-1){
1488
-			LOG(L_ERR, "build_res_buf_from_sip_res:"
1489
-							" error parsing content-length\n");
1490
-			goto skip_clen;
1491
-		}
1492
-		if (msg->content_length==0){
1493
-			DBG("build_res_from_sip_res: no content_length hdr found\n");
1494
-			/* we need to add it */
1495
-			if ((clen_buf=clen_builder(msg, &clen_len))==0){
1496
-				LOG(L_ERR, "build_res_buf_from_sip_res:" 
1497
-								" clen_builder failed\n");
1498
-				goto skip_clen;
1499
-			}
1500
-		}
1476
+	     /* Calculate message body difference and adjust
1477
+	      * Content-Length
1478
+	      */
1479
+	body_delta = lumps_len(msg, msg->body_lumps, 0);
1480
+	if (adjust_clen(msg, body_delta, (msg->via2? msg->via2->proto:PROTO_UDP))
1481
+			< 0) {
1482
+		LOG(L_ERR, "ERROR: build_req_buf_from_sip_req: Error while adjusting"
1483
+				" Content-Length\n");
1484
+		goto error;
1501 1485
 	}
1502
-skip_clen:
1503
-#endif
1504
-	
1486
+
1505 1487
 	/* remove the first via*/
1506
-	if (del_lump( &(msg->add_rm), via_offset, via_len, HDR_VIA)==0){
1488
+	if (del_lump( msg, via_offset, via_len, HDR_VIA)==0){
1507 1489
 		LOG(L_ERR, "build_res_buf_from_sip_res: error trying to remove first"
1508 1490
 					"via\n");
1509 1491
 		goto error;
1510 1492
 	}
1511
-#ifdef USE_TCP
1512
-	/* if clen needs to be added, add it */
1513
-	if (clen_len){
1514
-		/* msg->unparsed should point just before the final crlf,
1515
-		 * parse_headers is called from clen_builder */
1516
-		anchor=anchor_lump(&(msg->add_rm), msg->unparsed-buf, 0, 
1517
-							HDR_CONTENTLENGTH);
1518
-		DBG("build_res_from_sip_res: adding content-length: %.*s\n",
1519
-				(int)clen_len, clen_buf);
1520
-		if (anchor==0) goto error_clen; /* free clen_buf*/
1521
-		if (insert_new_lump_after(anchor, clen_buf, clen_len,
1522
-					HDR_CONTENTLENGTH)==0)
1523
-			goto error_clen; /* free clen_buf*/
1524
-	}
1525
-#endif
1526
-	new_len=len+lumps_len(msg, 0); /*FIXME: we don't know the send sock */
1493
+
1494
+	new_len=len+body_delta+lumps_len(msg, msg->add_rm, 0); /*FIXME: we don't
1495
+														know the send sock */
1527 1496
 	
1528 1497
 	DBG(" old size: %d, new size: %d\n", len, new_len);
1529 1498
 	new_buf=(char*)pkg_malloc(new_len+1); /* +1 is for debugging 
... ...
@@ -1534,7 +1561,9 @@ skip_clen:
1534 1534
 	}
1535 1535
 	new_buf[new_len]=0; /* debug: print the message */
1536 1536
 	offset=s_offset=0;
1537
-	process_lumps(msg, new_buf, &offset, &s_offset, 0); /*FIXME: no send sock*/
1537
+	/*FIXME: no send sock*/
1538
+	process_lumps(msg, msg->add_rm, new_buf, &offset, &s_offset, 0);/*FIXME:*/
1539
+	process_lumps(msg, msg->body_lumps, new_buf, &offset, &s_offset, 0);
1538 1540
 	/* copy the rest of the message */
1539 1541
 	memcpy(new_buf+offset,
1540 1542
 		buf+s_offset, 
... ...
@@ -1545,10 +1574,6 @@ skip_clen:
1545 1545
 
1546 1546
 	*returned_len=new_len;
1547 1547
 	return new_buf;
1548
-#ifdef USE_TCP
1549
-error_clen:
1550
-	if (clen_buf) pkg_free(clen_buf);
1551
-#endif
1552 1548
 error:
1553 1549
 	*returned_len=0;
1554 1550
 	return 0;
... ...
@@ -588,6 +588,7 @@ void free_sip_msg(struct sip_msg* msg)
588 588
 	if (msg->new_uri.s) { pkg_free(msg->new_uri.s); msg->new_uri.len=0; }
589 589
 	if (msg->headers)     free_hdr_field_lst(msg->headers);
590 590
 	if (msg->add_rm)      free_lump_list(msg->add_rm);
591
+	if (msg->body_lumps)  free_lump_list(msg->body_lumps);
591 592
 	if (msg->reply_lump)   free_reply_lump(msg->reply_lump);
592 593
 	/* don't free anymore -- now a pointer to a static buffer */
593 594
 #	ifdef DYN_BUF
... ...
@@ -43,7 +43,7 @@
43 43
 
44 44
 #include "../comp_defs.h"
45 45
 #include "../str.h"
46
-#include "../data_lump.h"
46
+#include "../lump_struct.h"
47 47
 #include "../flags.h"
48 48
 #include "../ip_addr.h"
49 49
 #include "../md5utils.h"
... ...
@@ -212,6 +212,7 @@ struct sip_msg {
212 212
 	struct sip_uri parsed_orig_ruri;
213 213
 	
214 214
 	struct lump* add_rm;       /* used for all the forwarded requests/replies */
215
+	struct lump* body_lumps;     /* Lumps that update Content-Length */
215 216
 	struct lump_rpl *reply_lump; /* only for localy generated replies !!!*/
216 217
 
217 218
 	/* str add_to_branch;