Browse code

core: check & fix Content-Length when sending on tcp

- automatically check & fix wrong Content-Length before forwarding
on tcp or tls

Andrei Pelinescu-Onciul authored on 09/03/2009 13:47:48
Showing 1 changed files
... ...
@@ -1358,6 +1358,10 @@ static inline int adjust_clen(struct sip_msg* msg, int body_delta, int proto)
1358 1358
 	struct lump* anchor;
1359 1359
 	char* clen_buf;
1360 1360
 	int clen_len, body_only;
1361
+#ifdef USE_TCP
1362
+	char* body;
1363
+	int comp_clen;
1364
+#endif /* USE_TCP */
1361 1365
 
1362 1366
 	/* Calculate message length difference caused by lumps modifying message
1363 1367
 	 * body, from this point on the message body must not be modified. Zero
... ...
@@ -1379,7 +1383,7 @@ static inline int adjust_clen(struct sip_msg* msg, int body_delta, int proto)
1379 1379
 			LOG(L_ERR, "adjust_clen: error parsing content-length\n");
1380 1380
 			goto error;
1381 1381
 		}
1382
-		if (msg->content_length==0){
1382
+		if (unlikely(msg->content_length==0)){
1383 1383
 			/* not present, we need to add it */
1384 1384
 			/* msg->unparsed should point just before the final crlf
1385 1385
 			 * - whole message was parsed by the above parse_headers
... ...
@@ -1391,12 +1395,37 @@ static inline int adjust_clen(struct sip_msg* msg, int body_delta, int proto)
1391 1391
 				goto error;
1392 1392
 			}
1393 1393
 			body_only=0;
1394
+		}else{
1395
+			/* compute current content length and compare it with the
1396
+			   one in the message */
1397
+			body=get_body(msg);
1398
+			if (unlikely(body==0)){
1399
+				ser_error=E_BAD_REQ;
1400
+				LOG(L_ERR, "adjust_clen: no message body found"
1401
+						" (missing crlf?)");
1402
+				goto error;
1403
+			}
1404
+			comp_clen=msg->len-(int)(body-msg->buf)+body_delta;
1405
+			if (comp_clen!=(int)(long)msg->content_length->parsed){
1406
+				/* note: we don't distinguish here between received with
1407
+				   wrong content-length and content-length changed, we just
1408
+				   fix it automatically in both cases (the reason being
1409
+				   that an error message telling we have received a msg-
1410
+				   with wrong content-length is of very little use) */
1411
+				anchor = del_lump(msg, msg->content_length->body.s-msg->buf,
1412
+									msg->content_length->body.len,
1413
+									HDR_CONTENTLENGTH_T);
1414
+				if (anchor==0) {
1415
+					LOG(L_ERR, "adjust_clen: Can't remove original"
1416
+								" Content-Length\n");
1417
+					goto error;
1418
+				}
1419
+				body_only=1;
1420
+			}
1394 1421
 		}
1395
-	}
1396
-#endif
1397
-
1398
-
1399
-	if ((anchor==0) && body_delta){
1422
+	}else
1423
+#endif /* USE_TCP */
1424
+	if (body_delta){
1400 1425
 		if (parse_headers(msg, HDR_CONTENTLENGTH_F, 0) == -1) {
1401 1426
 			LOG(L_ERR, "adjust_clen: Error parsing Content-Length\n");
1402 1427
 			goto error;
... ...
@@ -1420,13 +1449,14 @@ static inline int adjust_clen(struct sip_msg* msg, int body_delta, int proto)
1420 1420
 					goto error;
1421 1421
 				}
1422 1422
 				body_only=0;
1423
-			}else{
1424
-				DBG("adjust_clen: UDP packet with no clen => not adding one \n");
1425
-			}
1423
+			} /* else
1424
+				DBG("adjust_clen: UDP packet with no clen => "
1425
+						"not adding one \n"); */
1426 1426
 		}else{
1427 1427
 			/* Content-Length has been found, remove it */
1428 1428
 			anchor = del_lump(	msg, msg->content_length->body.s - msg->buf,
1429
-								msg->content_length->body.len, HDR_CONTENTLENGTH_T);
1429
+								msg->content_length->body.len,
1430
+								HDR_CONTENTLENGTH_T);
1430 1431
 			if (anchor==0) {
1431 1432
 				LOG(L_ERR, "adjust_clen: Can't remove original"
1432 1433
 							" Content-Length\n");
... ...
@@ -1442,7 +1472,7 @@ static inline int adjust_clen(struct sip_msg* msg, int body_delta, int proto)
1442 1442
 					HDR_CONTENTLENGTH_T) == 0)
1443 1443
 			goto error;
1444 1444
 	}
1445
-
1445
+	
1446 1446
 	return 0;
1447 1447
 error:
1448 1448
 	if (clen_buf) pkg_free(clen_buf);