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 257
 
255 258
 
256 259
 /* removes an already existing header/data lump */
257
-struct lump* del_lump(struct lump** list, int offset, int len, int type)
260
+/* WARNING: thist function adds the lump either to the msg->add_rm or
261
+ * msg->body_lumps list, depending on the offset being greater than msg->eoh,
262
+ * so msg->eoh must be parsed (parse with HDR_EOH) if you think your lump
263
+ *  might affect the body!! */
264
+struct lump* del_lump(struct sip_msg* msg, int offset, int len, int type)
258 265
 {
259 266
 	struct lump* tmp;
260 267
 	struct lump* prev, *t;
268
+	struct lump** list;
261 269
 
262 270
 	tmp=pkg_malloc(sizeof(struct lump));
263 271
 	if (tmp==0){
... ...
@@ -270,6 +278,11 @@ struct lump* del_lump(struct lump** list, int offset, int len, int type)
270 278
 	tmp->u.offset=offset;
271 279
 	tmp->len=len;
272 280
 	prev=0;
281
+	/* check to see whether this might be a body lump */
282
+	if ((msg->eoh) && (offset> (int)(msg->eoh-msg->buf)))
283
+		list=&msg->body_lumps;
284
+	else
285
+		list=&msg->add_rm;
273 286
 	for (t=*list;t; prev=t, t=t->next){
274 287
 		/* insert it sorted after offset */
275 288
 		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 296
 
284 297
 
285 298
 
286
-/* add an anhor */
287
-struct lump* anchor_lump(struct lump** list, int offset, int len, int type)
299
+/* add an anchor
300
+ * WARNING: thist function adds the lump either to the msg->add_rm or
301
+ * msg->body_lumps list, depending on the offset being greater than msg->eoh,
302
+ * so msg->eoh must be parsed (parse with HDR_EOH) if you think your lump
303
+ *  might affect the body!! */
304
+struct lump* anchor_lump(struct sip_msg* msg, int offset, int len, int type)
288 305
 {
289 306
 	struct lump* tmp;
290 307
 	struct lump* prev, *t;
308
+	struct lump** list;
291 309
 
310
+	
292 311
 	tmp=pkg_malloc(sizeof(struct lump));
293 312
 	if (tmp==0){
294 313
 		ser_error=E_OUT_OF_MEM;
... ...
@@ -301,6 +320,12 @@ struct lump* anchor_lump(struct lump** list, int offset, int len, int type)
301 320
 	tmp->u.offset=offset;
302 321
 	tmp->len=len;
303 322
 	prev=0;
323
+	/* check to see whether this might be a body lump */
324
+	if ((msg->eoh) && (offset> (int)(msg->eoh-msg->buf)))
325
+		list=&msg->body_lumps;
326
+	else
327
+		list=&msg->add_rm;
328
+		
304 329
 	for (t=*list;t; prev=t, t=t->next){
305 330
 		/* insert it sorted after offset */
306 331
 		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 66
 									int type);
141 67
 
142 68
 /* removes an already existing header */
143
-struct lump* del_lump(struct lump** list, int offset, int len, int type);
69
+struct lump* del_lump(struct sip_msg* msg, int offset, int len, int type);
144 70
 /* set an anchor */
145
-struct lump* anchor_lump(struct lump** list, int offset, int len, int type);
71
+struct lump* anchor_lump(struct sip_msg* msg, int offset, int len, int type);
146 72
 
147 73
 
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 74
 
153 75
 /* duplicates a lump list shallowly in pkg-mem */
154 76
 struct lump* dup_lump_list( struct lump *l );
155 77
new file mode 100644
... ...
@@ -0,0 +1,127 @@
1
+/*
2
+ * $Id$
3
+ *
4
+ * adding/removing headers or any other data chunk from a message
5
+ *
6
+ * Copyright (C) 2001-2003 Fhg Fokus
7
+ *
8
+ * This file is part of ser, a free SIP server.
9
+ *
10
+ * ser is free software; you can redistribute it and/or modify
11
+ * it under the terms of the GNU General Public License as published by
12
+ * the Free Software Foundation; either version 2 of the License, or
13
+ * (at your option) any later version
14
+ *
15
+ * For a license to use the ser software under conditions
16
+ * other than those described here, or to purchase support for this
17
+ * software, please contact iptel.org by e-mail at the following addresses:
18
+ *    info@iptel.org
19
+ *
20
+ * ser is distributed in the hope that it will be useful,
21
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
22
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
23
+ * GNU General Public License for more details.
24
+ *
25
+ * You should have received a copy of the GNU General Public License 
26
+ * along with this program; if not, write to the Free Software 
27
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
28
+ */
29
+/* History:
30
+ * --------
31
+ *  2003-01-29  s/int/enum ... more convenient for gdb (jiri)
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)
34
+ *  2003-04-02  added more subst lumps: SUBST_{SND,RCV}_ALL  
35
+ *              => ip:port;transport=proto (andrei)
36
+ *  2003-10-20  splitted from data_lump.h (andrei)
37
+ *
38
+ */
39
+
40
+
41
+#ifndef lump_struct_h
42
+#define lump_struct_h
43
+
44
+
45
+
46
+enum lump_op { LUMP_NOP=0, LUMP_DEL, LUMP_ADD, LUMP_ADD_SUBST, LUMP_ADD_OPT };
47
+enum lump_subst{ SUBST_NOP=0,                     /* do nothing */
48
+				 SUBST_RCV_IP,    SUBST_SND_IP,   /* add ip address */
49
+				 SUBST_RCV_PORT,  SUBST_SND_PORT, /* add port no */
50
+				 SUBST_RCV_PROTO, SUBST_SND_PROTO,/* add protocol(udp,tcp,tls)*/
51
+				 SUBST_RCV_ALL,   SUBST_SND_ALL   /*  ip:port;transport=proto */
52
+				};
53
+				/* Where:
54
+				   SND = sending, e.g the src ip of the outgoing message
55
+				   RCV = received e.g the dst ip of the original incoming msg,
56
+				    or the ip of the ser socket on which the msg was received
57
+				   For SUBST_{RCV,SND}_ALL, :port is added only if port!=5060
58
+				    and transport=proto only if proto!=udp
59
+					*/
60
+
61
+enum lump_conditions {	COND_FALSE,         /* always false */
62
+						COND_TRUE,          /* always true */
63
+						COND_IF_DIFF_REALMS,/* true if RCV realm != SND realm */
64
+						COND_IF_DIFF_AF,    /* true if RCV af != SND af */
65
+						COND_IF_DIFF_PROTO, /* true if RCV proto != SND proto */
66
+						COND_IF_DIFF_PORT,  /* true if RCV port != SND port */
67
+						COND_IF_DIFF_IP,    /* true if RCV ip != SND ip */
68
+						COND_IF_RAND        /* 50-50 random prob.of being true*/
69
+						};
70
+						/* Where: 
71
+						   REALM= ip_addr:port:proto
72
+						   af   = address family (ipv4 or ipv6)
73
+						   proto = protocol (tcp, udp, tls)
74
+						*/
75
+
76
+enum lump_flag { LUMPFLAG_NONE=0, LUMPFLAG_DUPED=1, LUMPFLAG_SHMEM=2 };
77
+
78
+
79
+struct lump{
80
+	int type; /* VIA, OTHER, UNSPEC(=0), ... */
81
+	enum lump_op op;   /* DEL, ADD, NOP, UNSPEC(=0) */
82
+	
83
+	union{
84
+		int offset; /* used for DEL, MODIFY */
85
+		enum lump_subst subst; /*what to subst: ip addr, port, proto*/
86
+		enum lump_conditions cond; /* condition for LUMP_ADD_OPT */
87
+		char * value; /* used for ADD */
88
+	}u;
89
+	int len; /* length of this header field */
90
+	
91
+	
92
+	struct lump* before; /* list of headers to be inserted in front of the
93
+								current one */
94
+	struct lump* after; /* list of headers to be inserted immediately after
95
+							  the current one */
96
+	
97
+	struct lump* next;
98
+
99
+	enum lump_flag flags; /* additional hints for use from TM's shmem */
100
+};
101
+
102
+
103
+/*
104
+ * hdrs must be kept sorted after their offset (DEL, NOP, UNSPEC)
105
+ * and/or their position (ADD). E.g.:
106
+ *  - to delete header Z insert it in to the list according to its offset 
107
+ *   and with op=DELETE
108
+ * - if you want to add a new header X after a  header Y, insert Y in the list
109
+ *   with op NOP and after it X (op ADD).
110
+ * - if you want X before Y, insert X in Y's before list.
111
+ * - if you want X to be the first header just put it first in hdr_lst.
112
+ *  -if you want to replace Y with X, insert Y with op=DELETE and then X with
113
+ *  op=ADD.
114
+ * before and after must contain only ADD ops!
115
+ * 
116
+ * Difference between "after" & "next" when ADDing:
117
+ * "after" forces the new header immediately after the current one while
118
+ * "next" means another header can be inserted between them.
119
+ * 
120
+ */
121
+
122
+/* frees the content of a lump struct */
123
+void free_lump(struct lump* l);
124
+/*frees an entire lump list, recursively */
125
+void free_lump_list(struct lump* lump_list);
126
+
127
+#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 339
 	}/*for all headers*/
341 340
 
342 341
 	/* 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
-
342
+#define LUMP_LIST_LEN(len, list) \
343
+do { \
344
+        struct lump* tmp, *chain; \
345
+	chain = (list); \
346
+	while (chain) \
347
+	{ \
348
+		(len) += lump_len(chain); \
349
+		tmp = chain->before; \
350
+		while ( tmp ) \
351
+		{ \
352
+			(len) += lump_len( tmp ); \
353
+			tmp = tmp->before; \
354
+		} \
355
+		tmp = chain->after; \
356
+		while ( tmp ) \
357
+		{ \
358
+			(len) += lump_len( tmp ); \
359
+			tmp = tmp->after; \
360
+		} \
361
+		chain = chain->next; \
362
+	} \
363
+} while(0);
364
+
365
+	LUMP_LIST_LEN(len, org_msg->add_rm);
366
+	LUMP_LIST_LEN(len, org_msg->body_lumps);
367
+	
362 368
 	/*length of reply lump structures*/
363 369
 	for(rpl_lump=org_msg->reply_lump;rpl_lump;rpl_lump=rpl_lump->next)
364 370
 			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 382
 	memcpy( new_msg , org_msg , sizeof(struct sip_msg) );
377 383
 	p += ROUND4(sizeof(struct sip_msg));
378 384
 	new_msg->add_rm = 0;
385
+	new_msg->body_lumps = 0;
379 386
 	/* new_uri */
380 387
 	if (org_msg->new_uri.s && org_msg->new_uri.len)
381 388
 	{
... ...
@@ -630,32 +637,40 @@ struct sip_msg*  sip_msg_cloner( struct sip_msg *org_msg )
630 637
 	}
631 638
 
632 639
 	/* 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
-	}
640
+#define CLONE_LUMP_LIST(anchor, list) \
641
+do { \
642
+        struct lump* lump_tmp, *l; \
643
+        struct lump** lump_anchor2, **a; \
644
+        a = (anchor); \
645
+        l = (list); \
646
+	while (l) \
647
+	{ \
648
+		lump_clone( (*a) , l , p ); \
649
+		/*before list*/ \
650
+		lump_tmp = l->before; \
651
+		lump_anchor2 = &((*a)->before); \
652
+		while ( lump_tmp ) \
653
+		{ \
654
+			lump_clone( (*lump_anchor2) , lump_tmp , p ); \
655
+			lump_anchor2 = &((*lump_anchor2)->before); \
656
+			lump_tmp = lump_tmp->before; \
657
+		} \
658
+		/*after list*/ \
659
+		lump_tmp = l->after; \
660
+		lump_anchor2 = &((*a)->after); \
661
+		while ( lump_tmp ) \
662
+		{ \
663
+			lump_clone( (*lump_anchor2) , lump_tmp , p ); \
664
+			lump_anchor2 = &((*lump_anchor2)->after); \
665
+			lump_tmp = lump_tmp->after; \
666
+		} \
667
+		a = &((*a)->next); \
668
+		l = l->next; \
669
+	} \
670
+} while(0)
671
+
672
+        CLONE_LUMP_LIST(&(new_msg->add_rm), org_msg->add_rm);
673
+        CLONE_LUMP_LIST(&(new_msg->body_lumps), org_msg->body_lumps);
659 674
 
660 675
 	/*cloning reply lump structures*/
661 676
 	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 460
 			goto restore;
460 461
 		}
461 462
 	}
463
+
464
+	if (shmem_msg->body_lumps) {
465
+		fake->body_lumps=dup_lump_list(shmem_msg->body_lumps);
466
+		if (!fake->body_lumps) { /* non_empty->empty ... failure */
467
+			LOG(L_ERR, "ERROR: on_negative_reply: lump dup failed\n");
468
+			goto restore;
469
+		}
470
+	}
471
+	
462 472
 	/* success */
463 473
 	return 1;
464 474
 
465 475
 restore:
466 476
 	/* restore original environment and destroy faked message */
467 477
 	free_duped_lump_list(fake->add_rm);
478
+	free_duped_lump_list(fake->body_lumps);
468 479
 	if (fake->new_uri.s) pkg_free(fake->new_uri.s);
469 480
 	set_t(backup_t);
470 481
 	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 54
     }
54 55
     memcpy( buf, str, len );
55 56
 
56
-    anchor = anchor_lump(&msg->add_rm,
57
-        msg->headers->name.s - msg->buf, 0 , 0);
57
+    anchor = anchor_lump(msg, msg->headers->name.s - msg->buf, 0 , 0);
58 58
     if (anchor == NULL) {
59 59
         LOG(L_ERR, "_test_insert_to_reply: anchor_lump failed\n");
60 60
         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 122
 #include "dprint.h"
122 123
 #include "config.h"
123 124
 #include "md5utils.h"
125
+#include "data_lump.h"
124 126
 #include "data_lump_rpl.h"
125 127
 #include "ip_addr.h"
126 128
 #include "resolve.h"
... ...
@@ -394,7 +396,7 @@ char* id_builder(struct sip_msg* msg, unsigned int *id_len)
394 396
 
395 397
 
396 398
 
397
-char* clen_builder(struct sip_msg* msg, unsigned int *clen_len)
399
+char* clen_builder(struct sip_msg* msg, unsigned int *clen_len, int diff)
398 400
 {
399 401
 	char* buf;
400 402
 	int len;
... ...
@@ -411,7 +413,7 @@ char* clen_builder(struct sip_msg* msg, unsigned int *clen_len)
411 413
 					" (missing crlf?)");
412 414
 		return 0;
413 415
 	}
414
-	value=msg->len-(int)(body-msg->buf);
416
+	value=msg->len-(int)(body-msg->buf)+diff;
415 417
 	value_s=int2str(value, &value_len);
416 418
 	DBG("clen_builder: content-length: %d (%s)\n", value, value_s);
417 419
 		
... ...
@@ -499,7 +501,7 @@ static inline int lump_check_opt(	enum lump_conditions cond,
499 501
 
500 502
 /* computes the "unpacked" len of a lump list,
501 503
    code moved from build_req_from_req */
502
-static inline int lumps_len(struct sip_msg* msg, struct socket_info* send_sock)
504
+static inline int lumps_len(struct sip_msg* msg, struct lump* lumps, struct socket_info* send_sock)
503 505
 {
504 506
 	int s_offset;
505 507
 	int new_len;
... ...
@@ -672,7 +674,7 @@ static inline int lumps_len(struct sip_msg* msg, struct socket_info* send_sock)
672 674
 		send_port_str=&(send_sock->port_no_str);
673 675
 	
674 676
 	
675
-	for(t=msg->add_rm;t;t=t->next){
677
+	for(t=lumps;t;t=t->next){
676 678
 		/* skip if this is an OPT lump and the condition is not satisfied */
677 679
 		if ((t->op==LUMP_ADD_OPT) && !lump_check_opt(t->u.cond, msg, send_sock))
678 680
 			continue;
... ...
@@ -763,7 +765,8 @@ skip_after:
763 765
 /* another helper functions, adds/Removes the lump,
764 766
 	code moved form build_req_from_req  */
765 767
 
766
-static inline void process_lumps(	struct sip_msg* msg,	
768
+static inline void process_lumps(	struct sip_msg* msg,
769
+					                                struct lump* lumps,
767 770
 									char* new_buf, 
768 771
 									unsigned int* new_buf_offs, 
769 772
 									unsigned int* orig_offs,
... ...
@@ -1027,7 +1030,7 @@ static inline void process_lumps(	struct sip_msg* msg,
1027 1030
 	offset=*new_buf_offs;
1028 1031
 	s_offset=*orig_offs;
1029 1032
 	
1030
-	for (t=msg->add_rm;t;t=t->next){
1033
+	for (t=lumps;t;t=t->next){
1031 1034
 		switch(t->op){
1032 1035
 			case LUMP_ADD:
1033 1036
 			case LUMP_ADD_SUBST:
... ...
@@ -1184,12 +1187,109 @@ skip_nop_after:
1184 1187
 }
1185 1188
 
1186 1189
 
1190
+/*
1191
+ * Adjust/insert Content-Length if necesarry
1192
+ */
1193
+static inline int adjust_clen(struct sip_msg* msg, int body_delta, int proto)
1194
+{
1195
+	struct lump* anchor;
1196
+	char* clen_buf;
1197
+	int clen_len;
1198
+
1199
+	/* Calculate message length difference caused by lumps modifying message
1200
+	 * body, from this point on the message body must not be modified. Zero
1201
+	 * value indicates that the body hasn't been modified
1202
+	*/
1203
+
1204
+	clen_buf = 0;
1205
+	anchor=0;
1206
+	
1207
+	/* check to see if we need to add clen */
1208
+#ifdef USE_TCP
1209
+	if (proto == PROTO_TCP
1210
+#ifdef USE_TLS
1211
+	    || proto == PROTO_TLS
1212
+#endif
1213
+	    ) {
1214
+		if (parse_headers(msg, HDR_CONTENTLENGTH, 0)==-1){
1215
+			LOG(L_ERR, "adjust_clen: error parsing content-length\n");
1216
+			goto error;
1217
+		}
1218
+		if (msg->content_length==0){
1219
+			/* not present, we need to add it */
1220
+			/* msg->unparsed should point just before the final crlf
1221
+			 * - whole message was parsed by the above parse_headers
1222
+			 *   which did not find content-length */
1223
+			anchor=anchor_lump(msg, msg->unparsed-msg->buf, 0,
1224
+												HDR_CONTENTLENGTH);
1225
+			if (anchor==0){
1226
+				LOG(L_ERR, "adjust_clen: cannot set clen anchor\n");
1227
+				goto error;
1228
+			}
1229
+		}
1230
+	}
1231
+#endif
1232
+	
1233
+	
1234
+	if ((anchor==0) && body_delta){
1235
+		if (parse_headers(msg, HDR_CONTENTLENGTH, 0) == -1) {
1236
+			LOG(L_ERR, "adjust_clen: Error parsing Content-Length\n");
1237
+			goto error;
1238
+		}
1239
+		
1240
+		/* The body has been changed, try to find
1241
+		 * existing Content-Length
1242
+		 */
1243
+		/* no need for Content-Length if it's and UDP packet and
1244
+		 * it hasn't Content-Lentgh already */
1245
+		if ((msg->content_length==0)){
1246
+		    /* content-length doesn't exist, append it */
1247
+			/* msg->unparsed should point just before the final crlf
1248
+			 * - whole message was parsed by the above parse_headers
1249
+			 *   which did not find content-length */
1250
+			if (proto!=PROTO_UDP){
1251
+				anchor=anchor_lump(msg, msg->unparsed-msg->buf, 0,
1252
+													HDR_CONTENTLENGTH);
1253
+				if (anchor==0){
1254
+					LOG(L_ERR, "adjust_clen: cannot set clen anchor\n");
1255
+					goto error;
1256
+				}
1257
+			}else{
1258
+				DBG("add_clen: UDP packet with no clen => not adding one \n");
1259
+			}
1260
+		}else{
1261
+			/* Content-Length has been found, remove it */
1262
+			anchor = del_lump(	msg, msg->content_length->name.s - msg->buf,
1263
+								msg->content_length->len, HDR_CONTENTLENGTH);
1264
+			if (anchor==0) {
1265
+				LOG(L_ERR, "adjust_clen: Can't remove original"
1266
+							" Content-Length\n");
1267
+				goto error;
1268
+			}
1269
+		}
1270
+	}
1271
+	
1272
+	if (anchor){
1273
+		clen_buf = clen_builder(msg, &clen_len, body_delta);
1274
+		if (!clen_buf) goto error;
1275
+		if (insert_new_lump_after(anchor, clen_buf, clen_len,
1276
+					HDR_CONTENTLENGTH) == 0)
1277
+			goto error;
1278
+	}
1279
+
1280
+	return 0;
1281
+error:
1282
+	if (clen_buf) pkg_free(clen_buf);
1283
+	return -1;
1284
+}
1285
+
1286
+
1187 1287
 
1188 1288
 char * build_req_buf_from_sip_req( struct sip_msg* msg,
1189 1289
 								unsigned int *returned_len,
1190 1290
 								struct socket_info* send_sock, int proto)
1191 1291
 {
1192
-	unsigned int len, new_len, received_len, rport_len, uri_len, via_len;
1292
+	unsigned int len, new_len, received_len, rport_len, uri_len, via_len, body_delta;
1193 1293
 	char* line_buf;
1194 1294
 	char* received_buf;
1195 1295
 	char* rport_buf;
... ...
@@ -1201,18 +1301,14 @@ char * build_req_buf_from_sip_req( struct sip_msg* msg,
1201 1301
 	str branch;
1202 1302
 	str extra_params;
1203 1303
 	struct hostport hp;
1204
-	
1304
+
1205 1305
 #ifdef USE_TCP
1206 1306
 	char* id_buf;
1207 1307
 	unsigned int id_len;
1208
-	char* clen_buf;
1209
-	unsigned int clen_len;
1210 1308
 	
1211 1309
 	
1212 1310
 	id_buf=0;
1213 1311
 	id_len=0;
1214
-	clen_buf=0;
1215
-	clen_len=0;
1216 1312
 #endif
1217 1313
 	via_insert_param=0;
1218 1314
 	extra_params.len=0;
... ...
@@ -1226,7 +1322,6 @@ char * build_req_buf_from_sip_req( struct sip_msg* msg,
1226 1322
 	received_buf=0;
1227 1323
 	rport_buf=0;
1228 1324
 	line_buf=0;
1229
-
1230 1325
 	
1231 1326
 #ifdef USE_TCP
1232 1327
 	/* add id if tcp */
... ...
@@ -1246,31 +1341,17 @@ char * build_req_buf_from_sip_req( struct sip_msg* msg,
1246 1341
 		extra_params.s=id_buf;
1247 1342
 		extra_params.len=id_len;
1248 1343
 	}
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 1344
 #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
-		}
1345
+	     /* Calculate message body difference and adjust
1346
+	      * Content-Length
1347
+	      */
1348
+	body_delta = lumps_len(msg, msg->body_lumps, send_sock);
1349
+	if (adjust_clen(msg, body_delta, proto) < 0) {
1350
+		LOG(L_ERR, "ERROR: build_req_buf_from_sip_req: Error while adjusting"
1351
+				" Content-Length\n");
1352
+		goto error00;
1271 1353
 	}
1272
-skip_clen:
1273
-#endif
1354
+
1274 1355
 	branch.s=msg->add_to_branch_s;
1275 1356
 	branch.len=msg->add_to_branch_len;
1276 1357
 	set_hostport(&hp, msg);
... ...
@@ -1306,7 +1387,7 @@ skip_clen:
1306 1387
 	/* add via header to the list */
1307 1388
 	/* try to add it before msg. 1st via */
1308 1389
 	/* add first via, as an anchor for second via*/
1309
-	anchor=anchor_lump(&(msg->add_rm), msg->via1->hdr.s-buf, 0, HDR_VIA);
1390
+	anchor=anchor_lump(msg, msg->via1->hdr.s-buf, 0, HDR_VIA);
1310 1391
 	if (anchor==0) goto error01;
1311 1392
 	if (insert_new_lump_before(anchor, line_buf, via_len, HDR_VIA)==0)
1312 1393
 		goto error01;
... ...
@@ -1332,11 +1413,11 @@ skip_clen:
1332 1413
 	 * overwrite the previous one if already present */
1333 1414
 	if (received_len){
1334 1415
 		if (msg->via1->received){ /* received already present => overwrite it*/
1335
-			via_insert_param=del_lump(&(msg->add_rm),
1416
+			via_insert_param=del_lump(msg,
1336 1417
 								msg->via1->received->start-buf-1, /*;*/
1337 1418
 								msg->via1->received->size+1, /*;*/ HDR_VIA);
1338 1419
 		}else if (via_insert_param==0){ /* receive not present, ok */
1339
-			via_insert_param=anchor_lump(&(msg->add_rm),
1420
+			via_insert_param=anchor_lump(msg,
1340 1421
 										msg->via1->hdr.s-buf+size,0, HDR_VIA);
1341 1422
 		}
1342 1423
 		if (via_insert_param==0) goto error02; /* free received_buf */
... ...
@@ -1346,12 +1427,12 @@ skip_clen:
1346 1427
 	/* if rport needs to be updated, delete it if present and add it's value */
1347 1428
 	if (rport_len){
1348 1429
 		if (msg->via1->rport){ /* rport already present */
1349
-			via_insert_param=del_lump(&(msg->add_rm),
1430
+			via_insert_param=del_lump(msg,
1350 1431
 								msg->via1->rport->start-buf-1, /*';'*/
1351 1432
 								msg->via1->rport->size+1 /* ; */, HDR_VIA);
1352 1433
 		}else if (via_insert_param==0){ /*force rport, no rport present */
1353 1434
 			/* no rport, add it */
1354
-			via_insert_param=anchor_lump(&(msg->add_rm),
1435
+			via_insert_param=anchor_lump(msg,
1355 1436
 										msg->via1->hdr.s-buf+size,0, HDR_VIA);
1356 1437
 		}
1357 1438
 		if (via_insert_param==0) goto error03; /* free rport_buf */
... ...
@@ -1360,22 +1441,9 @@ skip_clen:
1360 1441
 			goto error03; /* free rport_buf */
1361 1442
 			
1362 1443
 	}
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 1444
 
1377 1445
 	/* compute new msg len and fix overlapping zones*/
1378
-	new_len=len+lumps_len(msg, send_sock);
1446
+	new_len=len+body_delta+lumps_len(msg, msg->add_rm, send_sock);
1379 1447
 #ifdef XL_DEBUG
1380 1448
 	LOG(L_ERR, "DEBUG: new_len(%d)=len(%d)+lumps_len\n", new_len, len);
1381 1449
 #endif
... ...
@@ -1405,7 +1473,8 @@ skip_clen:
1405 1473
 	}
1406 1474
 	new_buf[new_len]=0;
1407 1475
 	/* copy msg adding/removing lumps */
1408
-	process_lumps(msg, new_buf, &offset, &s_offset, send_sock);
1476
+	process_lumps(msg, msg->add_rm, new_buf, &offset, &s_offset, send_sock);
1477
+	process_lumps(msg, msg->body_lumps, new_buf, &offset, &s_offset,send_sock);
1409 1478
 	/* copy the rest of the message */
1410 1479
 	memcpy(new_buf+offset, buf+s_offset, len-s_offset);
1411 1480
 	new_buf[new_len]=0;
... ...
@@ -1431,10 +1500,6 @@ error02:
1431 1500
 	if (received_buf) pkg_free(received_buf);
1432 1501
 error03:
1433 1502
 	if (rport_buf) pkg_free(rport_buf);
1434
-#ifdef USE_TCP
1435
-error04:
1436
-	if (clen_buf) pkg_free(clen_buf);
1437
-#endif
1438 1503
 error00:
1439 1504
 #ifdef USE_TCP
1440 1505
 	if (id_buf) pkg_free(id_buf);
... ...
@@ -1448,19 +1513,12 @@ error00:
1448 1513
 char * build_res_buf_from_sip_res( struct sip_msg* msg,
1449 1514
 				unsigned int *returned_len)
1450 1515
 {
1451
-	unsigned int new_len, via_len;
1516
+	unsigned int new_len, via_len, body_delta;
1452 1517
 	char* new_buf;
1453 1518
 	unsigned offset, s_offset, via_offset;
1454 1519
 	char* buf;
1455 1520
 	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
1521
+
1464 1522
 	buf=msg->buf;
1465 1523
 	len=msg->len;
1466 1524
 	new_buf=0;
... ...
@@ -1473,57 +1531,26 @@ char * build_res_buf_from_sip_res( struct sip_msg* msg,
1473 1531
 		via_offset=msg->h_via1->name.s-buf;
1474 1532
 	}
1475 1533
 
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
-		}
1534
+	     /* Calculate message body difference and adjust
1535
+	      * Content-Length
1536
+	      */
1537
+	body_delta = lumps_len(msg, msg->body_lumps, 0);
1538
+	if (adjust_clen(msg, body_delta, (msg->via2? msg->via2->proto:PROTO_UDP))
1539
+			< 0) {
1540
+		LOG(L_ERR, "ERROR: build_req_buf_from_sip_req: Error while adjusting"
1541
+				" Content-Length\n");
1542
+		goto error;
1501 1543
 	}
1502
-skip_clen:
1503
-#endif
1504
-	
1544
+
1505 1545
 	/* remove the first via*/
1506
-	if (del_lump( &(msg->add_rm), via_offset, via_len, HDR_VIA)==0){
1546
+	if (del_lump( msg, via_offset, via_len, HDR_VIA)==0){
1507 1547
 		LOG(L_ERR, "build_res_buf_from_sip_res: error trying to remove first"
1508 1548
 					"via\n");
1509 1549
 		goto error;
1510 1550
 	}
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 */
1551
+
1552
+	new_len=len+body_delta+lumps_len(msg, msg->add_rm, 0); /*FIXME: we don't
1553
+														know the send sock */
1527 1554
 	
1528 1555
 	DBG(" old size: %d, new size: %d\n", len, new_len);
1529 1556
 	new_buf=(char*)pkg_malloc(new_len+1); /* +1 is for debugging 
... ...
@@ -1534,7 +1561,9 @@ skip_clen:
1534 1561
 	}
1535 1562
 	new_buf[new_len]=0; /* debug: print the message */
1536 1563
 	offset=s_offset=0;
1537
-	process_lumps(msg, new_buf, &offset, &s_offset, 0); /*FIXME: no send sock*/
1564
+	/*FIXME: no send sock*/
1565
+	process_lumps(msg, msg->add_rm, new_buf, &offset, &s_offset, 0);/*FIXME:*/
1566
+	process_lumps(msg, msg->body_lumps, new_buf, &offset, &s_offset, 0);
1538 1567
 	/* copy the rest of the message */
1539 1568
 	memcpy(new_buf+offset,
1540 1569
 		buf+s_offset, 
... ...
@@ -1545,10 +1574,6 @@ skip_clen:
1545 1574
 
1546 1575
 	*returned_len=new_len;
1547 1576
 	return new_buf;
1548
-#ifdef USE_TCP
1549
-error_clen:
1550
-	if (clen_buf) pkg_free(clen_buf);
1551
-#endif
1552 1577
 error:
1553 1578
 	*returned_len=0;
1554 1579
 	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;