Browse code

- add_rm lump list split into add_rm (for headers) and body_lump (for body), this allows fast calculation of the message body delta to generate Content-Length value properly - Updated developer's guide - updates modules that modify message body to use body_lumps - updated tm to process both lists - updated msg_translator to process body lumps first to find out body length, generate lumps necesarry to update Content-Lenght and calculate length of add_rm lumps then

Jan Janak authored on 14/10/2003 00:13:34
Showing 6 changed files
... ...
@@ -1454,6 +1454,8 @@ struct sip_msg {
1454 1454
 		
1455 1455
     struct lump* add_rm;         /* used for all the forwarded 
1456 1456
                                   * requests */
1457
+    struct lump* body_lumps;     /* Lumps that modify message body
1458
+                                  * (update Content-Length */
1457 1459
     struct lump* repl_add_rm;    /* used for all the forwarded replies */
1458 1460
     struct lump_rpl *reply_lump; /* only for locally generated replies !!!*/
1459 1461
 
... ...
@@ -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,24 +339,30 @@ 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
-	}
342
+#define LUMP_LIST_LEN(len, list) \
343
+do { \
344
+        struct lump* lump_tmp; \
345
+	while ((list)) \
346
+	{ \
347
+		(len) += lump_len((list)); \
348
+		lump_tmp = (list)->before; \
349
+		while ( lump_tmp ) \
350
+		{ \
351
+			(len) += lump_len( lump_tmp ); \
352
+			lump_tmp = lump_tmp->before; \
353
+		} \
354
+		lump_tmp = (list)->after; \
355
+		while ( lump_tmp ) \
356
+		{ \
357
+			(len) += lump_len( lump_tmp ); \
358
+			lump_tmp = lump_tmp->after; \
359
+		} \
360
+		(list) = (list)->next; \
361
+	} \
362
+} while(0);
363
+
364
+	LUMP_LIST_LEN(len, org_msg->add_rm);
365
+	LUMP_LIST_LEN(len, org_msg->body_lumps);
361 366
 
362 367
 	/*length of reply lump structures*/
363 368
 	for(rpl_lump=org_msg->reply_lump;rpl_lump;rpl_lump=rpl_lump->next)
... ...
@@ -376,6 +381,7 @@ struct sip_msg*  sip_msg_cloner( struct sip_msg *org_msg )
376 381
 	memcpy( new_msg , org_msg , sizeof(struct sip_msg) );
377 382
 	p += ROUND4(sizeof(struct sip_msg));
378 383
 	new_msg->add_rm = 0;
384
+	new_msg->body_lumps = 0;
379 385
 	/* new_uri */
380 386
 	if (org_msg->new_uri.s && org_msg->new_uri.len)
381 387
 	{
... ...
@@ -629,33 +635,42 @@ struct sip_msg*  sip_msg_cloner( struct sip_msg *org_msg )
629 635
 		new_msg->last_header = last_hdr;
630 636
 	}
631 637
 
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
-	}
638
+
639
+	     /* clonning data lump */
640
+#define CLONE_LUMP_LIST(anchor, list) \
641
+{ \
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
+}
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);
... ...
@@ -673,11 +688,6 @@ struct sip_msg*  sip_msg_cloner( struct sip_msg *org_msg )
673 688
 	}
674 689
 
675 690
 	clone_authorized_hooks(new_msg, org_msg);
676
-
691
+	
677 692
 	return new_msg;
678 693
 }
679
-
680
-
681
-
682
-
683
-
... ...
@@ -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,21 @@ 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: body lump dup failed\n");
468
+			goto restore;
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;
... ...
@@ -394,7 +394,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 body_delta)
398 398
 {
399 399
 	char* buf;
400 400
 	int len;
... ...
@@ -408,10 +408,10 @@ char* clen_builder(struct sip_msg* msg, unsigned int *clen_len)
408 408
 	if (body==0){
409 409
 		ser_error=E_BAD_REQ;
410 410
 		LOG(L_ERR, "ERROR: clen_builder: no message body found"
411
-					" (missing crlf?)");
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) + body_delta;
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 +499,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 +672,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;
... ...
@@ -764,10 +764,11 @@ skip_after:
764 764
 	code moved form build_req_from_req  */
765 765
 
766 766
 static inline void process_lumps(	struct sip_msg* msg,	
767
-									char* new_buf, 
768
-									unsigned int* new_buf_offs, 
769
-									unsigned int* orig_offs,
770
-									struct socket_info* send_sock)
767
+					struct lump* lumps,
768
+					char* new_buf, 
769
+					unsigned int* new_buf_offs, 
770
+					unsigned int* orig_offs,
771
+					struct socket_info* send_sock)
771 772
 {
772 773
 	struct lump *t;
773 774
 	struct lump *r;
... ...
@@ -1027,7 +1028,7 @@ static inline void process_lumps(	struct sip_msg* msg,
1027 1028
 	offset=*new_buf_offs;
1028 1029
 	s_offset=*orig_offs;
1029 1030
 	
1030
-	for (t=msg->add_rm;t;t=t->next){
1031
+	for (t=lumps;t;t=t->next){
1031 1032
 		switch(t->op){
1032 1033
 			case LUMP_ADD:
1033 1034
 			case LUMP_ADD_SUBST:
... ...
@@ -1184,12 +1185,101 @@ skip_nop_after:
1184 1185
 }
1185 1186
 
1186 1187
 
1188
+/*
1189
+ * Adjust/insert Content-Length if necesarry
1190
+ */
1191
+static inline int adjust_clen(struct sip_msg* msg, int body_delta, int proto)
1192
+{
1193
+	struct lump* anchor;
1194
+	char* clen_buf;
1195
+	int clen_len;
1196
+	
1197
+	     /* Calculate message length difference caused by 
1198
+	      * lumps modifying message body, from this point on
1199
+	      * the message body must not be modified. Zero value
1200
+	      * indicates that the body hasn't been modified
1201
+	      */
1202
+	clen_buf = 0;
1203
+
1204
+	if (body_delta) {
1205
+		     /* The body has been changed, try to find
1206
+		      * existing Content-Length
1207
+		      */
1208
+		if (parse_headers(msg, HDR_CONTENTLENGTH, 0) == -1) {
1209
+			LOG(L_ERR, "adjust_clen: Error parsing content-length\n");
1210
+			goto error;
1211
+		}
1212
+
1213
+		anchor = 0;
1214
+		if (msg->content_length) {
1215
+			     /* Content-Length has been found,
1216
+			      * remove it
1217
+			      */
1218
+			anchor = del_lump(&msg->add_rm, msg->content_length->name.s - msg->buf, 
1219
+					  msg->content_length->len, HDR_CONTENTLENGTH);
1220
+			if (!anchor) {
1221
+				LOG(L_ERR, "build_req_from_sip_req: Can't remove original Content-Length\n");
1222
+				goto error;
1223
+			}
1224
+		}
1225
+
1226
+		if (proto == PROTO_UDP) {
1227
+			     /* Protocol is UDP and Content-Length has
1228
+			      * been removed, insert new value
1229
+			      */
1230
+			if (anchor) {
1231
+				clen_buf = clen_builder(msg, &clen_len, body_delta);
1232
+				if (!clen_buf) goto error;
1233
+				if (insert_new_lump_after(anchor, clen_buf, clen_len, HDR_CONTENTLENGTH) == 0) goto error;
1234
+			}
1235
+		} else {
1236
+			     /* Protocol is not UDP, insert new Content-Length,
1237
+			      * no matter if Content-Length has been removed or not
1238
+			      */
1239
+			if (!anchor) {
1240
+				     /* Create anchor */
1241
+				     /* msg->unparsed should point just before the final crlf,
1242
+				      * parse_headers is called from clen_builder */
1243
+				anchor = anchor_lump(&(msg->add_rm), msg->unparsed - msg->buf, 0, HDR_CONTENTLENGTH);
1244
+				if (!anchor) goto error;
1245
+			}
1246
+
1247
+			clen_buf = clen_builder(msg, &clen_len, body_delta);
1248
+			if (!clen_buf) goto error;
1249
+			if (insert_new_lump_after(anchor, clen_buf, clen_len, HDR_CONTENTLENGTH) == 0) goto error;
1250
+		}
1251
+	} else {
1252
+#ifdef USE_TCP
1253
+		if (proto == PROTO_TCP
1254
+#ifdef USE_TLS
1255
+		    || proto == PROTO_TLS
1256
+#endif
1257
+		    ) {
1258
+			anchor = anchor_lump(&(msg->add_rm), msg->unparsed - msg->buf, 0, HDR_CONTENTLENGTH);
1259
+			if (!anchor) goto error;
1260
+			
1261
+			clen_buf = clen_builder(msg, &clen_len, body_delta);
1262
+			if (!clen_buf) goto error;
1263
+			if (insert_new_lump_after(anchor, clen_buf, clen_len, HDR_CONTENTLENGTH) == 0) goto error;
1264
+		}
1265
+#endif
1266
+	}
1267
+
1268
+	return 0;
1269
+
1270
+ error:
1271
+	if (clen_buf) pkg_free(clen_buf);
1272
+	return -1;
1273
+}
1274
+
1275
+
1276
+
1187 1277
 
1188 1278
 char * build_req_buf_from_sip_req( struct sip_msg* msg,
1189 1279
 								unsigned int *returned_len,
1190 1280
 								struct socket_info* send_sock, int proto)
1191
-{
1192
-	unsigned int len, new_len, received_len, rport_len, uri_len, via_len;
1281
+{	
1282
+	unsigned int len, new_len, received_len, rport_len, uri_len, via_len, body_delta;
1193 1283
 	char* line_buf;
1194 1284
 	char* received_buf;
1195 1285
 	char* rport_buf;
... ...
@@ -1201,18 +1291,16 @@ char * build_req_buf_from_sip_req( struct sip_msg* msg,
1201 1291
 	str branch;
1202 1292
 	str extra_params;
1203 1293
 	struct hostport hp;
1294
+	char* clen_buf;
1295
+	unsigned int clen_len;
1204 1296
 	
1205 1297
 #ifdef USE_TCP
1206 1298
 	char* id_buf;
1207 1299
 	unsigned int id_len;
1208
-	char* clen_buf;
1209
-	unsigned int clen_len;
1210 1300
 	
1211 1301
 	
1212 1302
 	id_buf=0;
1213 1303
 	id_len=0;
1214
-	clen_buf=0;
1215
-	clen_len=0;
1216 1304
 #endif
1217 1305
 	via_insert_param=0;
1218 1306
 	extra_params.len=0;
... ...
@@ -1226,6 +1314,8 @@ char * build_req_buf_from_sip_req( struct sip_msg* msg,
1226 1314
 	received_buf=0;
1227 1315
 	rport_buf=0;
1228 1316
 	line_buf=0;
1317
+	clen_buf=0;
1318
+	clen_len=0;
1229 1319
 
1230 1320
 	
1231 1321
 #ifdef USE_TCP
... ...
@@ -1246,31 +1336,16 @@ char * build_req_buf_from_sip_req( struct sip_msg* msg,
1246 1336
 		extra_params.s=id_buf;
1247 1337
 		extra_params.len=id_len;
1248 1338
 	}
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 1339
 #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
-		}
1340
+	     /* Calculate messsage body difference and adjust
1341
+	      * Content-Length
1342
+	      */
1343
+	body_delta = lumps_len(msg, msg->body_lumps, send_sock);
1344
+        if (adjust_clen(msg, body_delta, proto) < 0) {
1345
+		LOG(L_ERR, "ERROR: build_req_buf_from sip_req: Error while adjusting Contact-Length\n");
1346
+		goto error00;
1271 1347
 	}
1272
-skip_clen:
1273
-#endif
1348
+
1274 1349
 	branch.s=msg->add_to_branch_s;
1275 1350
 	branch.len=msg->add_to_branch_len;
1276 1351
 	set_hostport(&hp, msg);
... ...
@@ -1360,22 +1435,9 @@ skip_clen:
1360 1435
 			goto error03; /* free rport_buf */
1361 1436
 			
1362 1437
 	}
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 1438
 
1377 1439
 	/* compute new msg len and fix overlapping zones*/
1378
-	new_len=len+lumps_len(msg, send_sock);
1440
+	new_len=len+body_delta+lumps_len(msg, msg->add_rm, send_sock);
1379 1441
 #ifdef XL_DEBUG
1380 1442
 	LOG(L_ERR, "DEBUG: new_len(%d)=len(%d)+lumps_len\n", new_len, len);
1381 1443
 #endif
... ...
@@ -1405,7 +1467,8 @@ skip_clen:
1405 1467
 	}
1406 1468
 	new_buf[new_len]=0;
1407 1469
 	/* copy msg adding/removing lumps */
1408
-	process_lumps(msg, new_buf, &offset, &s_offset, send_sock);
1470
+	process_lumps(msg, msg->add_rm, new_buf, &offset, &s_offset, send_sock);
1471
+	process_lumps(msg, msg->body_lumps, new_buf, &offset, &s_offset, send_sock);
1409 1472
 	/* copy the rest of the message */
1410 1473
 	memcpy(new_buf+offset, buf+s_offset, len-s_offset);
1411 1474
 	new_buf[new_len]=0;
... ...
@@ -1431,10 +1494,6 @@ error02:
1431 1494
 	if (received_buf) pkg_free(received_buf);
1432 1495
 error03:
1433 1496
 	if (rport_buf) pkg_free(rport_buf);
1434
-#ifdef USE_TCP
1435
-error04:
1436
-	if (clen_buf) pkg_free(clen_buf);
1437
-#endif
1438 1497
 error00:
1439 1498
 #ifdef USE_TCP
1440 1499
 	if (id_buf) pkg_free(id_buf);
... ...
@@ -1448,22 +1507,16 @@ error00:
1448 1507
 char * build_res_buf_from_sip_res( struct sip_msg* msg,
1449 1508
 				unsigned int *returned_len)
1450 1509
 {
1451
-	unsigned int new_len, via_len;
1510
+	unsigned int new_len, via_len, body_delta;
1452 1511
 	char* new_buf;
1453 1512
 	unsigned offset, s_offset, via_offset;
1454 1513
 	char* buf;
1455 1514
 	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
1515
+
1464 1516
 	buf=msg->buf;
1465 1517
 	len=msg->len;
1466 1518
 	new_buf=0;
1519
+
1467 1520
 	/* we must remove the first via */
1468 1521
 	if (msg->via1->next) {
1469 1522
 		via_len=msg->via1->bsize;
... ...
@@ -1473,57 +1526,23 @@ char * build_res_buf_from_sip_res( struct sip_msg* msg,
1473 1526
 		via_offset=msg->h_via1->name.s-buf;
1474 1527
 	}
1475 1528
 
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
-		}
1529
+	     /* Calculate messsage body difference and adjust
1530
+	      * Content-Length
1531
+	      */
1532
+	body_delta = lumps_len(msg, msg->body_lumps, 0);
1533
+        if (adjust_clen(msg, body_delta, (msg->via2 ? msg->via2->proto : PROTO_UDP)) < 0) {
1534
+		LOG(L_ERR, "ERROR: build_req_buf_from sip_req: Error while adjusting Contact-Length\n");
1535
+		goto error;
1501 1536
 	}
1502
-skip_clen:
1503
-#endif
1504
-	
1537
+
1505 1538
 	/* remove the first via*/
1506 1539
 	if (del_lump( &(msg->add_rm), via_offset, via_len, HDR_VIA)==0){
1507 1540
 		LOG(L_ERR, "build_res_buf_from_sip_res: error trying to remove first"
1508 1541
 					"via\n");
1509 1542
 		goto error;
1510 1543
 	}
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 */
1544
+
1545
+	new_len=len+body_delta+lumps_len(msg, msg->add_rm, 0); /*FIXME: we don't know the send sock */
1527 1546
 	
1528 1547
 	DBG(" old size: %d, new size: %d\n", len, new_len);
1529 1548
 	new_buf=(char*)pkg_malloc(new_len+1); /* +1 is for debugging 
... ...
@@ -1534,7 +1553,8 @@ skip_clen:
1534 1553
 	}
1535 1554
 	new_buf[new_len]=0; /* debug: print the message */
1536 1555
 	offset=s_offset=0;
1537
-	process_lumps(msg, new_buf, &offset, &s_offset, 0); /*FIXME: no send sock*/
1556
+	process_lumps(msg, msg->add_rm, new_buf, &offset, &s_offset, 0); /*FIXME: no send sock*/
1557
+	process_lumps(msg, msg->body_lumps, new_buf, &offset, &s_offset, 0); /*FIXME: no send sock*/
1538 1558
 	/* copy the rest of the message */
1539 1559
 	memcpy(new_buf+offset,
1540 1560
 		buf+s_offset, 
... ...
@@ -1545,10 +1565,6 @@ skip_clen:
1545 1565
 
1546 1566
 	*returned_len=new_len;
1547 1567
 	return new_buf;
1548
-#ifdef USE_TCP
1549
-error_clen:
1550
-	if (clen_buf) pkg_free(clen_buf);
1551
-#endif
1552 1568
 error:
1553 1569
 	*returned_len=0;
1554 1570
 	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
... ...
@@ -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 modify message body (they update Contact-Length) */
215 216
 	struct lump_rpl *reply_lump; /* only for localy generated replies !!!*/
216 217
 
217 218
 	/* str add_to_branch;