|
@@ -394,7 +394,7 @@ char* id_builder(struct sip_msg* msg, unsigned int *id_len)
|
|
|
|
|
|
|
|
|
|
|
|
-char* clen_builder(struct sip_msg* msg, unsigned int *clen_len, int body_delta)
|
|
|
+char* clen_builder(struct sip_msg* msg, unsigned int *clen_len)
|
|
|
{
|
|
|
char* buf;
|
|
|
int len;
|
|
@@ -408,10 +408,10 @@ char* clen_builder(struct sip_msg* msg, unsigned int *clen_len, int body_delta)
|
|
|
if (body==0){
|
|
|
ser_error=E_BAD_REQ;
|
|
|
LOG(L_ERR, "ERROR: clen_builder: no message body found"
|
|
|
- " (missing crlf?)");
|
|
|
+ " (missing crlf?)");
|
|
|
return 0;
|
|
|
}
|
|
|
- value=msg->len-(int)(body-msg->buf) + body_delta;
|
|
|
+ value=msg->len-(int)(body-msg->buf);
|
|
|
value_s=int2str(value, &value_len);
|
|
|
DBG("clen_builder: content-length: %d (%s)\n", value, value_s);
|
|
|
|
|
@@ -499,7 +499,7 @@ static inline int lump_check_opt( enum lump_conditions cond,
|
|
|
|
|
|
/* computes the "unpacked" len of a lump list,
|
|
|
code moved from build_req_from_req */
|
|
|
-static inline int lumps_len(struct sip_msg* msg, struct lump* lumps, struct socket_info* send_sock)
|
|
|
+static inline int lumps_len(struct sip_msg* msg, struct socket_info* send_sock)
|
|
|
{
|
|
|
int s_offset;
|
|
|
int new_len;
|
|
@@ -672,7 +672,7 @@ static inline int lumps_len(struct sip_msg* msg, struct lump* lumps, struct sock
|
|
|
send_port_str=&(send_sock->port_no_str);
|
|
|
|
|
|
|
|
|
- for(t=lumps;t;t=t->next){
|
|
|
+ for(t=msg->add_rm;t;t=t->next){
|
|
|
/* skip if this is an OPT lump and the condition is not satisfied */
|
|
|
if ((t->op==LUMP_ADD_OPT) && !lump_check_opt(t->u.cond, msg, send_sock))
|
|
|
continue;
|
|
@@ -764,11 +764,10 @@ skip_after:
|
|
|
code moved form build_req_from_req */
|
|
|
|
|
|
static inline void process_lumps( struct sip_msg* msg,
|
|
|
- struct lump* lumps,
|
|
|
- char* new_buf,
|
|
|
- unsigned int* new_buf_offs,
|
|
|
- unsigned int* orig_offs,
|
|
|
- struct socket_info* send_sock)
|
|
|
+ char* new_buf,
|
|
|
+ unsigned int* new_buf_offs,
|
|
|
+ unsigned int* orig_offs,
|
|
|
+ struct socket_info* send_sock)
|
|
|
{
|
|
|
struct lump *t;
|
|
|
struct lump *r;
|
|
@@ -1028,7 +1027,7 @@ static inline void process_lumps( struct sip_msg* msg,
|
|
|
offset=*new_buf_offs;
|
|
|
s_offset=*orig_offs;
|
|
|
|
|
|
- for (t=lumps;t;t=t->next){
|
|
|
+ for (t=msg->add_rm;t;t=t->next){
|
|
|
switch(t->op){
|
|
|
case LUMP_ADD:
|
|
|
case LUMP_ADD_SUBST:
|
|
@@ -1185,101 +1184,12 @@ skip_nop_after:
|
|
|
}
|
|
|
|
|
|
|
|
|
-/*
|
|
|
- * Adjust/insert Content-Length if necesarry
|
|
|
- */
|
|
|
-static inline int adjust_clen(struct sip_msg* msg, int body_delta, int proto)
|
|
|
-{
|
|
|
- struct lump* anchor;
|
|
|
- char* clen_buf;
|
|
|
- int clen_len;
|
|
|
-
|
|
|
- /* Calculate message length difference caused by
|
|
|
- * lumps modifying message body, from this point on
|
|
|
- * the message body must not be modified. Zero value
|
|
|
- * indicates that the body hasn't been modified
|
|
|
- */
|
|
|
- clen_buf = 0;
|
|
|
-
|
|
|
- if (body_delta) {
|
|
|
- /* The body has been changed, try to find
|
|
|
- * existing Content-Length
|
|
|
- */
|
|
|
- if (parse_headers(msg, HDR_CONTENTLENGTH, 0) == -1) {
|
|
|
- LOG(L_ERR, "adjust_clen: Error parsing content-length\n");
|
|
|
- goto error;
|
|
|
- }
|
|
|
-
|
|
|
- anchor = 0;
|
|
|
- if (msg->content_length) {
|
|
|
- /* Content-Length has been found,
|
|
|
- * remove it
|
|
|
- */
|
|
|
- anchor = del_lump(&msg->add_rm, msg->content_length->name.s - msg->buf,
|
|
|
- msg->content_length->len, HDR_CONTENTLENGTH);
|
|
|
- if (!anchor) {
|
|
|
- LOG(L_ERR, "build_req_from_sip_req: Can't remove original Content-Length\n");
|
|
|
- goto error;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- if (proto == PROTO_UDP) {
|
|
|
- /* Protocol is UDP and Content-Length has
|
|
|
- * been removed, insert new value
|
|
|
- */
|
|
|
- if (anchor) {
|
|
|
- clen_buf = clen_builder(msg, &clen_len, body_delta);
|
|
|
- if (!clen_buf) goto error;
|
|
|
- if (insert_new_lump_after(anchor, clen_buf, clen_len, HDR_CONTENTLENGTH) == 0) goto error;
|
|
|
- }
|
|
|
- } else {
|
|
|
- /* Protocol is not UDP, insert new Content-Length,
|
|
|
- * no matter if Content-Length has been removed or not
|
|
|
- */
|
|
|
- if (!anchor) {
|
|
|
- /* Create anchor */
|
|
|
- /* msg->unparsed should point just before the final crlf,
|
|
|
- * parse_headers is called from clen_builder */
|
|
|
- anchor = anchor_lump(&(msg->add_rm), msg->unparsed - msg->buf, 0, HDR_CONTENTLENGTH);
|
|
|
- if (!anchor) goto error;
|
|
|
- }
|
|
|
-
|
|
|
- clen_buf = clen_builder(msg, &clen_len, body_delta);
|
|
|
- if (!clen_buf) goto error;
|
|
|
- if (insert_new_lump_after(anchor, clen_buf, clen_len, HDR_CONTENTLENGTH) == 0) goto error;
|
|
|
- }
|
|
|
- } else {
|
|
|
-#ifdef USE_TCP
|
|
|
- if (proto == PROTO_TCP
|
|
|
-#ifdef USE_TLS
|
|
|
- || proto == PROTO_TLS
|
|
|
-#endif
|
|
|
- ) {
|
|
|
- anchor = anchor_lump(&(msg->add_rm), msg->unparsed - msg->buf, 0, HDR_CONTENTLENGTH);
|
|
|
- if (!anchor) goto error;
|
|
|
-
|
|
|
- clen_buf = clen_builder(msg, &clen_len, body_delta);
|
|
|
- if (!clen_buf) goto error;
|
|
|
- if (insert_new_lump_after(anchor, clen_buf, clen_len, HDR_CONTENTLENGTH) == 0) goto error;
|
|
|
- }
|
|
|
-#endif
|
|
|
- }
|
|
|
-
|
|
|
- return 0;
|
|
|
-
|
|
|
- error:
|
|
|
- if (clen_buf) pkg_free(clen_buf);
|
|
|
- return -1;
|
|
|
-}
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
|
|
|
char * build_req_buf_from_sip_req( struct sip_msg* msg,
|
|
|
unsigned int *returned_len,
|
|
|
struct socket_info* send_sock, int proto)
|
|
|
-{
|
|
|
- unsigned int len, new_len, received_len, rport_len, uri_len, via_len, body_delta;
|
|
|
+{
|
|
|
+ unsigned int len, new_len, received_len, rport_len, uri_len, via_len;
|
|
|
char* line_buf;
|
|
|
char* received_buf;
|
|
|
char* rport_buf;
|
|
@@ -1291,16 +1201,18 @@ char * build_req_buf_from_sip_req( struct sip_msg* msg,
|
|
|
str branch;
|
|
|
str extra_params;
|
|
|
struct hostport hp;
|
|
|
- char* clen_buf;
|
|
|
- unsigned int clen_len;
|
|
|
|
|
|
#ifdef USE_TCP
|
|
|
char* id_buf;
|
|
|
unsigned int id_len;
|
|
|
+ char* clen_buf;
|
|
|
+ unsigned int clen_len;
|
|
|
|
|
|
|
|
|
id_buf=0;
|
|
|
id_len=0;
|
|
|
+ clen_buf=0;
|
|
|
+ clen_len=0;
|
|
|
#endif
|
|
|
via_insert_param=0;
|
|
|
extra_params.len=0;
|
|
@@ -1314,8 +1226,6 @@ char * build_req_buf_from_sip_req( struct sip_msg* msg,
|
|
|
received_buf=0;
|
|
|
rport_buf=0;
|
|
|
line_buf=0;
|
|
|
- clen_buf=0;
|
|
|
- clen_len=0;
|
|
|
|
|
|
|
|
|
#ifdef USE_TCP
|
|
@@ -1336,16 +1246,31 @@ char * build_req_buf_from_sip_req( struct sip_msg* msg,
|
|
|
extra_params.s=id_buf;
|
|
|
extra_params.len=id_len;
|
|
|
}
|
|
|
+ /* if sending proto == tcp, check if Content-Length needs to be added*/
|
|
|
+ if (proto==PROTO_TCP
|
|
|
+#ifdef USE_TLS
|
|
|
+ || proto==PROTO_TLS
|
|
|
#endif
|
|
|
- /* Calculate messsage body difference and adjust
|
|
|
- * Content-Length
|
|
|
- */
|
|
|
- body_delta = lumps_len(msg, msg->body_lumps, send_sock);
|
|
|
- if (adjust_clen(msg, body_delta, proto) < 0) {
|
|
|
- LOG(L_ERR, "ERROR: build_req_buf_from sip_req: Error while adjusting Contact-Length\n");
|
|
|
- goto error00;
|
|
|
+ ){
|
|
|
+ DBG("build_req_from_req: checking for clen; proto=%d,"
|
|
|
+ " rcv->proto=%d\n", proto, msg->rcv.proto);
|
|
|
+ /* first of all parse content-length */
|
|
|
+ if (parse_headers(msg, HDR_CONTENTLENGTH, 0)==-1){
|
|
|
+ LOG(L_ERR, "build_req_buf_from_sip_req:"
|
|
|
+ " error parsing content-length\n");
|
|
|
+ goto skip_clen;
|
|
|
+ }
|
|
|
+ if (msg->content_length==0){
|
|
|
+ /* we need to add it */
|
|
|
+ if ((clen_buf=clen_builder(msg, &clen_len))==0){
|
|
|
+ LOG(L_ERR, "build_req_buf_from_sip_req:"
|
|
|
+ " clen_builder failed\n");
|
|
|
+ goto skip_clen;
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
-
|
|
|
+skip_clen:
|
|
|
+#endif
|
|
|
branch.s=msg->add_to_branch_s;
|
|
|
branch.len=msg->add_to_branch_len;
|
|
|
set_hostport(&hp, msg);
|
|
@@ -1435,9 +1360,22 @@ char * build_req_buf_from_sip_req( struct sip_msg* msg,
|
|
|
goto error03; /* free rport_buf */
|
|
|
|
|
|
}
|
|
|
+#ifdef USE_TCP
|
|
|
+ /* if clen needs to be added, add it */
|
|
|
+ if (clen_len){
|
|
|
+ /* msg->unparsed should point just before the final crlf,
|
|
|
+ * parse_headers is called from clen_builder */
|
|
|
+ anchor=anchor_lump(&(msg->add_rm), msg->unparsed-buf, 0,
|
|
|
+ HDR_CONTENTLENGTH);
|
|
|
+ if (anchor==0) goto error04; /* free clen_buf */
|
|
|
+ if (insert_new_lump_after(anchor, clen_buf, clen_len,
|
|
|
+ HDR_CONTENTLENGTH)==0)
|
|
|
+ goto error04; /* free clen_buf*/
|
|
|
+ }
|
|
|
+#endif
|
|
|
|
|
|
/* compute new msg len and fix overlapping zones*/
|
|
|
- new_len=len+body_delta+lumps_len(msg, msg->add_rm, send_sock);
|
|
|
+ new_len=len+lumps_len(msg, send_sock);
|
|
|
#ifdef XL_DEBUG
|
|
|
LOG(L_ERR, "DEBUG: new_len(%d)=len(%d)+lumps_len\n", new_len, len);
|
|
|
#endif
|
|
@@ -1467,8 +1405,7 @@ char * build_req_buf_from_sip_req( struct sip_msg* msg,
|
|
|
}
|
|
|
new_buf[new_len]=0;
|
|
|
/* copy msg adding/removing lumps */
|
|
|
- process_lumps(msg, msg->add_rm, new_buf, &offset, &s_offset, send_sock);
|
|
|
- process_lumps(msg, msg->body_lumps, new_buf, &offset, &s_offset, send_sock);
|
|
|
+ process_lumps(msg, new_buf, &offset, &s_offset, send_sock);
|
|
|
/* copy the rest of the message */
|
|
|
memcpy(new_buf+offset, buf+s_offset, len-s_offset);
|
|
|
new_buf[new_len]=0;
|
|
@@ -1494,6 +1431,10 @@ error02:
|
|
|
if (received_buf) pkg_free(received_buf);
|
|
|
error03:
|
|
|
if (rport_buf) pkg_free(rport_buf);
|
|
|
+#ifdef USE_TCP
|
|
|
+error04:
|
|
|
+ if (clen_buf) pkg_free(clen_buf);
|
|
|
+#endif
|
|
|
error00:
|
|
|
#ifdef USE_TCP
|
|
|
if (id_buf) pkg_free(id_buf);
|
|
@@ -1507,16 +1448,22 @@ error00:
|
|
|
char * build_res_buf_from_sip_res( struct sip_msg* msg,
|
|
|
unsigned int *returned_len)
|
|
|
{
|
|
|
- unsigned int new_len, via_len, body_delta;
|
|
|
+ unsigned int new_len, via_len;
|
|
|
char* new_buf;
|
|
|
unsigned offset, s_offset, via_offset;
|
|
|
char* buf;
|
|
|
unsigned int len;
|
|
|
-
|
|
|
+#ifdef USE_TCP
|
|
|
+ struct lump* anchor;
|
|
|
+ char* clen_buf;
|
|
|
+ unsigned int clen_len;
|
|
|
+
|
|
|
+ clen_buf=0;
|
|
|
+ clen_len=0;
|
|
|
+#endif
|
|
|
buf=msg->buf;
|
|
|
len=msg->len;
|
|
|
new_buf=0;
|
|
|
-
|
|
|
/* we must remove the first via */
|
|
|
if (msg->via1->next) {
|
|
|
via_len=msg->via1->bsize;
|
|
@@ -1526,23 +1473,57 @@ char * build_res_buf_from_sip_res( struct sip_msg* msg,
|
|
|
via_offset=msg->h_via1->name.s-buf;
|
|
|
}
|
|
|
|
|
|
- /* Calculate messsage body difference and adjust
|
|
|
- * Content-Length
|
|
|
- */
|
|
|
- body_delta = lumps_len(msg, msg->body_lumps, 0);
|
|
|
- if (adjust_clen(msg, body_delta, (msg->via2 ? msg->via2->proto : PROTO_UDP)) < 0) {
|
|
|
- LOG(L_ERR, "ERROR: build_req_buf_from sip_req: Error while adjusting Contact-Length\n");
|
|
|
- goto error;
|
|
|
- }
|
|
|
+#ifdef USE_TCP
|
|
|
|
|
|
+ /* if sending proto == tcp, check if Content-Length needs to be added*/
|
|
|
+ if (msg->via2 && ((msg->via2->proto==PROTO_TCP)
|
|
|
+#ifdef USE_TLS
|
|
|
+ || (msg->via2->proto==PROTO_TLS)
|
|
|
+#endif
|
|
|
+ )){
|
|
|
+ DBG("build_res_from_sip_res: checking content-length for \n%.*s\n",
|
|
|
+ (int)msg->len, msg->buf);
|
|
|
+ /* first of all parse content-length */
|
|
|
+ if (parse_headers(msg, HDR_CONTENTLENGTH, 0)==-1){
|
|
|
+ LOG(L_ERR, "build_res_buf_from_sip_res:"
|
|
|
+ " error parsing content-length\n");
|
|
|
+ goto skip_clen;
|
|
|
+ }
|
|
|
+ if (msg->content_length==0){
|
|
|
+ DBG("build_res_from_sip_res: no content_length hdr found\n");
|
|
|
+ /* we need to add it */
|
|
|
+ if ((clen_buf=clen_builder(msg, &clen_len))==0){
|
|
|
+ LOG(L_ERR, "build_res_buf_from_sip_res:"
|
|
|
+ " clen_builder failed\n");
|
|
|
+ goto skip_clen;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+skip_clen:
|
|
|
+#endif
|
|
|
+
|
|
|
/* remove the first via*/
|
|
|
if (del_lump( &(msg->add_rm), via_offset, via_len, HDR_VIA)==0){
|
|
|
LOG(L_ERR, "build_res_buf_from_sip_res: error trying to remove first"
|
|
|
"via\n");
|
|
|
goto error;
|
|
|
}
|
|
|
-
|
|
|
- new_len=len+body_delta+lumps_len(msg, msg->add_rm, 0); /*FIXME: we don't know the send sock */
|
|
|
+#ifdef USE_TCP
|
|
|
+ /* if clen needs to be added, add it */
|
|
|
+ if (clen_len){
|
|
|
+ /* msg->unparsed should point just before the final crlf,
|
|
|
+ * parse_headers is called from clen_builder */
|
|
|
+ anchor=anchor_lump(&(msg->add_rm), msg->unparsed-buf, 0,
|
|
|
+ HDR_CONTENTLENGTH);
|
|
|
+ DBG("build_res_from_sip_res: adding content-length: %.*s\n",
|
|
|
+ (int)clen_len, clen_buf);
|
|
|
+ if (anchor==0) goto error_clen; /* free clen_buf*/
|
|
|
+ if (insert_new_lump_after(anchor, clen_buf, clen_len,
|
|
|
+ HDR_CONTENTLENGTH)==0)
|
|
|
+ goto error_clen; /* free clen_buf*/
|
|
|
+ }
|
|
|
+#endif
|
|
|
+ new_len=len+lumps_len(msg, 0); /*FIXME: we don't know the send sock */
|
|
|
|
|
|
DBG(" old size: %d, new size: %d\n", len, new_len);
|
|
|
new_buf=(char*)pkg_malloc(new_len+1); /* +1 is for debugging
|
|
@@ -1553,8 +1534,7 @@ char * build_res_buf_from_sip_res( struct sip_msg* msg,
|
|
|
}
|
|
|
new_buf[new_len]=0; /* debug: print the message */
|
|
|
offset=s_offset=0;
|
|
|
- process_lumps(msg, msg->add_rm, new_buf, &offset, &s_offset, 0); /*FIXME: no send sock*/
|
|
|
- process_lumps(msg, msg->body_lumps, new_buf, &offset, &s_offset, 0); /*FIXME: no send sock*/
|
|
|
+ process_lumps(msg, new_buf, &offset, &s_offset, 0); /*FIXME: no send sock*/
|
|
|
/* copy the rest of the message */
|
|
|
memcpy(new_buf+offset,
|
|
|
buf+s_offset,
|
|
@@ -1565,6 +1545,10 @@ char * build_res_buf_from_sip_res( struct sip_msg* msg,
|
|
|
|
|
|
*returned_len=new_len;
|
|
|
return new_buf;
|
|
|
+#ifdef USE_TCP
|
|
|
+error_clen:
|
|
|
+ if (clen_buf) pkg_free(clen_buf);
|
|
|
+#endif
|
|
|
error:
|
|
|
*returned_len=0;
|
|
|
return 0;
|