Ver código fonte

parser changed to make body to point to body (w/o LWS), have a len
encompassing the complete hf (name.s..CRLF) and not to put zero-
terminators after header field names and cseq

Jiri Kuthan 22 anos atrás
pai
commit
1540fad105

+ 5 - 1
modules/tm/defs.h

@@ -24,12 +24,16 @@
  * You should have received a copy of the GNU General Public License 
  * along with this program; if not, write to the Free Software 
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * History:
+ * ---------
+ * 2003-01-27 t_uac deprecated (jiri)
  */
 
 
 #ifndef _TM_DEFS_H
 #define _TM_DEFS_H
 
-#undef DEPRECATE_OLD_STUFF
+#define DEPRECATE_OLD_STUFF
 
 #endif

+ 7 - 1
modules/tm/t_lookup.c

@@ -51,7 +51,8 @@
  *
  * History:
  * ----------
- * 2003-01-23 options for disabling r-uri matching introduced
+ * 2003-01-27 next baby-step to removing ZT - PRESERVE_ZT (jiri)
+ * 2003-01-23 options for disabling r-uri matching introduced (jiri)
  */
 
 
@@ -59,6 +60,7 @@
 
 
 #include <assert.h>
+#include "../../comp_defs.h"
 #include "../../dprint.h"
 #include "../../config.h"
 #include "../../parser/parser_f.h"
@@ -94,7 +96,11 @@
 	 (t_msg->via1->bsize-(t_msg->_via->name.s-(t_msg->_via->hdr.s+t_msg->_via->hdr.len)))\
 	)==0 )
 
+#ifdef PRESERVE_ZT
 #define HF_LEN(_hf) ((_hf)->body.s+(_hf)->body.len-(_hf)->name.s)
+#else
+#define HF_LEN(_hf) ((_hf)->len)
+#endif
 
 /* should be request-uri matching used as a part of pre-3261 
  * transaction matching, as the standard wants us to do so

+ 26 - 0
modules/tm/t_msgbuilder.c

@@ -25,11 +25,17 @@
  * You should have received a copy of the GNU General Public License 
  * along with this program; if not, write to the Free Software 
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ *
+ * History:
+ * ----------
+ * 2003-01-27 next baby-step to removing ZT - PRESERVE_ZT (jiri)
  */
 
 #include "defs.h"
 
 
+#include "../../comp_defs.h"
 #include "../../hash_func.h"
 #include "../../globals.h"
 #include "t_funcs.h"
@@ -95,18 +101,28 @@ char *build_local(struct cell *Trans,unsigned int branch,
 	}
 	*len+= via_len;
 	/*headers*/
+#ifdef PRESERVE_ZT
 	*len+=Trans->from.len+CRLF_LEN
 		+Trans->callid.len+CRLF_LEN
 		+to->len+CRLF_LEN
 		/* CSeq: 101 CANCEL */
 		+Trans->cseq_n.len+1+method_len+CRLF_LEN; 
+#else
+	*len+=Trans->from.len+Trans->callid.len+to->len+
+		+Trans->cseq_n.len+1+method_len+CRLF_LEN; 
+#endif
+
 
 	/* copy'n'paste Route headers */
 	if (!Trans->local) {
 		for ( hdr=Trans->uas.request->headers ; hdr ; hdr=hdr->next )
 			 if (hdr->type==HDR_ROUTE)
+#ifdef PRESERVE_ZT
 				*len+=((hdr->body.s+hdr->body.len ) - hdr->name.s ) + 
 					CRLF_LEN ;
+#else
+				*len+=hdr->len;
+#endif
 	}
 
 	/* User Agent */
@@ -133,12 +149,18 @@ char *build_local(struct cell *Trans,unsigned int branch,
 	append_mem_block(p,via,via_len);
 
 	/*other headers*/
+#ifdef PRESERVE_ZT
 	append_str( p, Trans->from );
 	append_mem_block( p, CRLF, CRLF_LEN );
 	append_str( p, Trans->callid );
 	append_mem_block( p, CRLF, CRLF_LEN );
 	append_str( p, *to );
 	append_mem_block( p, CRLF, CRLF_LEN );
+#else
+	append_str( p, Trans->from );
+	append_str( p, Trans->callid );
+	append_str( p, *to );
+#endif
 	append_str( p, Trans->cseq_n );
 	append_mem_block( p, " ", 1 );
 	append_mem_block( p, method, method_len );
@@ -147,9 +169,13 @@ char *build_local(struct cell *Trans,unsigned int branch,
 	if (!Trans->local)  {
 		for ( hdr=Trans->uas.request->headers ; hdr ; hdr=hdr->next )
 			if(hdr->type==HDR_ROUTE) {
+#ifdef PRESERVE_ZT
 				append_mem_block(p, hdr->name.s,
 					hdr->body.s+hdr->body.len-hdr->name.s );
 				append_mem_block(p, CRLF, CRLF_LEN );
+#else
+				append_mem_block(p, hdr->name.s, hdr->len );
+#endif
 			}
 	}
 

+ 7 - 0
modules/tm/t_reply.c

@@ -27,11 +27,13 @@
  *
  * History:
  * --------
+ * 2003-01-27 next baby-step to removing ZT - PRESERVE_ZT (jiri)
  * 2003-01-19 faked lump list created in on_reply handlers
  */
 
 #include "defs.h"
 
+#include "../../comp_defs.h"
 
 #include "../../hash_func.h"
 #include "t_funcs.h"
@@ -106,8 +108,13 @@ static char *build_ack(struct sip_msg* rpl,struct cell *trans,int branch,
             "cannot generate a HBH ACK if key HFs in reply missing\n");
         return NULL;
     }
+#ifdef PRESERVE_ZT
 	to.len=rpl->to->body.s+rpl->to->body.len-rpl->to->name.s;
 	to.s=rpl->orig+(rpl->to->name.s-rpl->buf);
+#else
+	to.s=rpl->to->name.s;
+	to.len=rpl->to->len;
+#endif
     return build_local( trans, branch, ret_len,
         ACK, ACK_LEN, &to );
 }

+ 1 - 1
modules/tm/tm.c

@@ -265,7 +265,7 @@ struct module_exports exports= {
 #ifndef DEPRECATE_OLD_STUFF
 	1+
 #endif
-	11,      /* Number of module paramers */
+	10,      /* Number of module paramers */
 
 	mod_init, /* module initialization function */
 	(response_function) t_on_reply,

+ 215 - 21
modules/tm/uac.c

@@ -44,6 +44,7 @@
  *
  * History:
  * --------
+ * 2003-01-27 fifo:t_uac_dlg completed (jiri)
  * 2003-01-23 t_uac_dlg now uses get_out_socket (jiri)
  */
 
@@ -80,6 +81,12 @@
 #include "t_msgbuilder.h"
 #include "uac.h"
 
+/* header fields which are explicitely processed and are not copied
+ * from FIFO line-by-line
+ */
+#define skip_hf(_hf) (((_hf)->type==HDR_FROM) || ((_hf)->type==HDR_TO) \
+	|| ((_hf)->type==HDR_CALLID) || ((_hf)->type==HDR_CSEQ))
+
 /* Call-ID has the following form: <callid_nr>-<pid>@<ip>
  * callid_nr is initialized as a random number and continually
  * increases; -<pid>@<ip> is kept in callid_suffix
@@ -97,6 +104,11 @@
 /* length of FROM tags */
 #define FROM_TAG_LEN (MD5_LEN +1 /* - */ + CRC16_LEN)
 
+struct str_list {
+	str s;
+	struct str_list *next;
+};
+
 static unsigned long callid_nr;
 static char *callid_suffix;
 static int callid_suffix_len;
@@ -330,6 +342,34 @@ done:
 }
 #endif
 
+static struct socket_info *uri2sock( str *uri, union sockaddr_union *to_su )
+{
+	struct proxy_l *proxy;
+	struct socket_info* send_sock;
+
+	proxy = uri2proxy(uri);
+	if (proxy == 0) {
+		ser_error = E_BAD_ADDRESS;
+		LOG(L_ERR, "ERROR: uri2sock: Can't create a dst proxy\n");
+		return 0;
+	}
+
+	hostent2su(to_su, &proxy->host, proxy->addr_idx, 
+			(proxy->port) ? htons(proxy->port) : htons(SIP_PORT));
+	send_sock=get_out_socket(to_su, PROTO_UDP);
+	if (send_sock == 0) {
+		LOG(L_ERR, "ERROR: uri2sock: no corresponding socket for af %d\n", 
+						to_su->s.sa_family );
+		ser_error = E_NO_SOCKET;
+	}
+
+
+	free_proxy(proxy);
+	free(proxy);
+	return send_sock;
+}
+	
+
 
 /*
  * Send a request within a dialog
@@ -404,11 +444,10 @@ int t_uac_dlg(str* msg,                     /* Type of the message - MESSAGE, OP
 	unsigned int req_len;
 	char *buf;
 	struct cell *new_cell;
-	struct proxy_l *proxy;
-	union sockaddr_union to_su;
 	struct socket_info* send_sock;
 	struct retr_buf *request;
 	str callid_s, ftag, tmp;
+	union sockaddr_union to_su;
 
 	/* make -Wall shut up */
 	ret=0;
@@ -423,22 +462,13 @@ int t_uac_dlg(str* msg,                     /* Type of the message - MESSAGE, OP
 		goto done;
 	}
 
-	proxy = uri2proxy((dst) ? (dst) : ruri);
-	if (proxy == 0) {
-		ser_error = ret = E_BAD_ADDRESS;
-		LOG(L_ERR, "ERROR: t_uac_dlg: Can't create a dst proxy\n");
-		goto done;
+	send_sock=uri2sock( dst? dst: ruri, &to_su );
+	if (send_sock==0) {
+		LOG(L_ERR, "ERROR: t_uac_dlg: no socket found\n");
+		goto error00;
 	}
 
 	branch=0;
-	hostent2su(&to_su, &proxy->host, proxy->addr_idx, (proxy->port) ? htons(proxy->port) : htons(SIP_PORT));
-	send_sock=get_out_socket(&to_su, PROTO_UDP);
-	if (send_sock == 0) {
-		LOG(L_ERR, "ERROR: t_uac_dlg: no corresponding listening socket for af %d\n", to_su.s.sa_family );
-		ret = E_NO_SOCKET;
-		goto error00;
-	}
-	
 	     /* No Call-ID given, calculate it */
 	if (cid == 0) {
 		callid_nr++;
@@ -513,8 +543,10 @@ int t_uac_dlg(str* msg,                     /* Type of the message - MESSAGE, OP
 	request->buffer_len = req_len;
 	new_cell->nr_of_outgoings++;
 
+/*
 	proxy->tx++;
 	proxy->tx_bytes += req_len;
+*/
 
 	if (SEND_BUFFER(request) == -1) {
 		if (dst) {
@@ -523,8 +555,10 @@ int t_uac_dlg(str* msg,                     /* Type of the message - MESSAGE, OP
 			tmp = *ruri;
 		}
 		LOG(L_ERR, "ERROR: t_uac: UAC sending to \'%.*s\' failed\n", tmp.len, tmp.s);
+/*
 		proxy->errors++;
 		proxy->ok = 0;
+*/
 	}
 	
 	start_retr(request);
@@ -539,8 +573,10 @@ error01:
 	free_cell(new_cell);
 
 error00:
+/*
 	free_proxy(proxy);
 	free(proxy);
+*/
 
 done: 
 	/* if we did not install cbp, release it now */
@@ -574,14 +610,16 @@ static void fifo_callback( struct cell *t, struct sip_msg *msg,
 	DBG("DEBUG: fifo_callback sucesssfuly completed\n");
 }	
 
+#ifndef DEPRECATE_OLD_STUFF
+
 /* to be obsoleted in favor of fifo_uac_from */
 int fifo_uac( FILE *stream, char *response_file ) 
 {
-	char method[MAX_METHOD];
+	str sm, sh, sb, sd; /* method, header, body, dst(outbound) */
+	char method[MAX_METHOD]; /* read buffers for these ... */
 	char header[MAX_HEADER];
 	char body[MAX_BODY];
 	char dst[MAX_DST];
-	str sm, sh, sb, sd;
 	char *shmem_file;
 	int fn_len;
 	int ret;
@@ -652,7 +690,6 @@ int fifo_uac( FILE *stream, char *response_file )
 	return 1;
 }
 
-#ifndef DEPRECATE_OLD_STUFF
 
 /* syntax:
 
@@ -762,6 +799,123 @@ int fifo_uac_from( FILE *stream, char *response_file )
 
 #endif
 
+static struct str_list *new_str(char *s, int len, struct str_list **last, int *total)
+{
+	struct str_list *new;
+	new=pkg_malloc(sizeof(struct str_list));
+	if (!new) {
+		LOG(L_ERR, "ERROR: get_hfblock: not enough mem\n");
+		return 0;
+	}
+	new->s.s=s;
+	new->s.len=len;
+	new->next=0;
+
+	(*last)->next=new;
+	*last=new;
+	*total+=len;
+
+	return new;
+}
+
+
+static char *get_hfblock(str *uri, struct hdr_field *hf, int *l) 
+{
+	struct str_list sl, *last, *new, *i, *foo;
+	int hf_avail, frag_len, total_len;
+	char *begin, *needle, *dst, *ret, *d;
+	str *sock_name, *portname;
+	union sockaddr_union to_su;
+	struct socket_info* send_sock;
+
+	ret=0; /* pesimist: assume failure */
+	total_len=0;
+	last=&sl;
+	last->next=0;
+	portname=sock_name=0;
+
+	for (; hf; hf=hf->next) {
+		if (skip_hf(hf)) continue;
+
+		begin=needle=hf->name.s; 
+		hf_avail=hf->len;
+
+		/* substitution loop */
+		while(hf_avail) {
+			d=memchr(needle, SUBST_CHAR, hf_avail);
+			if (!d || d+1>=needle+hf_avail) { /* nothing to substitute */
+				new=new_str(begin, hf_avail, &last, &total_len); 
+				if (!new) goto error;
+				break;
+			} else {
+				frag_len=d-begin;
+				d++; /* d not at the second substitution char */
+				switch(*d) {
+					case SUBST_CHAR:	/* double SUBST_CHAR: IP */
+						/* string before substitute */
+						new=new_str(begin, frag_len, &last, &total_len); 
+						if (!new) goto error;
+						/* substitute */
+						if (!sock_name) {
+							send_sock=uri2sock( uri, &to_su );
+							if (!send_sock) {
+								LOG(L_ERR, "ERROR: get_hf_block: send_sock failed\n");
+								goto error;
+							}
+							sock_name=&send_sock->address_str;
+							portname=&send_sock->port_no_str;
+						}
+						new=new_str(sock_name->s, sock_name->len,
+								&last, &total_len );
+						if (!new) goto error;
+						new=new_str(portname->s, portname->len,
+								&last, &total_len );
+						if (!new) goto error;
+						/* keep going ... */
+						begin=needle=d+1;hf_avail-=frag_len+2;
+						continue;
+					default:
+						/* no valid substitution char -- keep going */
+						hf_avail-=frag_len+1;
+						needle=d;
+				}
+			} /* possible substitute */
+		} /* substitution loop */
+		/* proceed to next header */
+		/* new=new_str(CRLF, CRLF_LEN, &last, &total_len );
+		if (!new) goto error; */
+		DBG("DEBUG: get_hf_block: one more hf processed\n");
+	} /* header loop */
+
+
+	/* construct a single header block now */
+	ret=pkg_malloc(total_len);
+	if (!ret) {
+		LOG(L_ERR, "ERROR: get_hf_block no pkg mem for hf block\n");
+		goto error;
+	}
+	i=sl.next;
+	dst=ret;
+	while(i) {
+		foo=i;
+		i=i->next;
+		memcpy(dst, foo->s.s, foo->s.len);
+		dst+=foo->s.len;
+		pkg_free(foo);
+	}
+	*l=total_len;
+	return ret;
+
+error:
+	i=sl.next;
+	while(i) {
+		foo=i;
+		i=i->next;
+		pkg_free(foo);
+	}
+	*l=0;
+	return 0;
+}
 
 static void fifo_uac_error(char *reply_fifo, int code, char *msg)
 {
@@ -784,6 +938,37 @@ static void fifo_uac_error(char *reply_fifo, int code, char *msg)
 	[body] 
 	.EOL
 
+
+	there is also the possibility to have server placed its
+    hostname:portnumber in header fields -- just put double
+	exclamation mark in any of the optional header fields
+	(i.e., any but From/To/CallID,CSeq), they will be 
+	substituted hn:pn
+
+Example:
+
+sc fifo t_uac_dlg MESSAGE sip:[email protected] \
+	. \ # no outbound proxy
+	'From:[email protected];tagd=123'  \ # no to-tag -> ephemeral
+	'To:[email protected]' \
+	'Foo: sip:user@!! '  \ # expansion here
+	'CSEQ: 11 MESSAGE   ' \
+	. \ # EoH
+	.	# empty body
+---
+U 192.168.2.16:5060 -> 192.168.2.1:5060
+MESSAGE sip:[email protected] SIP/2.0..
+Via: SIP/2.0/UDP 192.168.2.16;branch=z9hG4bK760c.922ea6a1.0..
+To: [email protected]..
+From: [email protected];tagd=123;tag=5405e669bc2980663aed2624dc31396f-fa77..
+CSeq: 11 MESSAGE..
+Call-ID: [email protected]..
+Content-Length: 0..
+User-Agent: Sip EXpress router (0.8.11pre4-tcp1-locking (i386/linux))..
+Foo: sip:[email protected]:5060..
+..
+
+
 */
 
 int fifo_uac_dlg( FILE *stream, char *response_file ) 
@@ -794,6 +979,7 @@ int fifo_uac_dlg( FILE *stream, char *response_file )
 	char header_buf[MAX_HEADER]; 
 	char body_buf[MAX_BODY]; 
 	str method, ruri, outbound, header, body;
+	str hfb; /* header field block */
 	struct sip_uri parsed_ruri, parsed_outbound;
 	str dummy_empty;
 	int fromtag;
@@ -925,7 +1111,12 @@ int fifo_uac_dlg( FILE *stream, char *response_file )
 		}
 	}
 
-
+	hfb.s=get_hfblock(outbound.len ? &outbound : &ruri, 
+					faked_msg.headers, &hfb.len);
+	if (!hfb.s) {
+		fifo_uac_error(response_file, 500, "no mem for hf block");
+		goto error;
+	}
 
 
 	DBG("DEBUG: fifo_uac: EoL -- proceeding to transaction creation\n");
@@ -935,7 +1126,7 @@ int fifo_uac_dlg( FILE *stream, char *response_file )
 		shmem_file=shm_malloc(fn_len);
 		if (shmem_file==0) {
 			fifo_uac_error(response_file, 500, "no shmem");
-			goto error;
+			goto error01;
 		}
 		memcpy(shmem_file, response_file, fn_len );
 	} else {
@@ -959,7 +1150,7 @@ int fifo_uac_dlg( FILE *stream, char *response_file )
 		faked_msg.callid ?
 			&faked_msg.callid->body:
 			0,
-		0, 						/* headers -- TBD */
+		&hfb, 						/* headers -- TBD */
 		&body,
 		fifo_callback, shmem_file );
 
@@ -980,6 +1171,9 @@ int fifo_uac_dlg( FILE *stream, char *response_file )
 		}
 	}
 
+error01:
+	pkg_free(hfb.s);
+
 error:
 	/* free_sip_msg(&faked_msg); */
 	if (faked_msg.headers) free_hdr_field_lst(faked_msg.headers);

+ 2 - 0
modules/tm/uac.h

@@ -37,6 +37,8 @@
 #include "config.h"
 #include "t_dlg.h"
 
+/* substitution character for FIFO UAC */
+#define SUBST_CHAR '!'
 #ifdef _DEPRECATED
 /* number of random digits in beginning of a string --
    please multiples of 2 */

+ 78 - 30
msg_translator.c

@@ -35,6 +35,7 @@
  * 2003-01-24 added i param to via of outgoing requests (used by tcp),
  *             modified via_builder params (andrei)
  * 2003-01-27 more rport fixes (make use of new via_param->start)  (andrei)
+ * 2003-01-27 next baby-step to removing ZT - PRESERVE_ZT (jiri)
  *
  */
 
@@ -47,6 +48,7 @@
 #include <stdio.h>
 #include <stdlib.h>
 
+#include "comp_defs.h"
 #include "msg_translator.h"
 #include "globals.h"
 #include "error.h"
@@ -61,17 +63,14 @@
 #include "pt.h"
 
 
-#define append_str(_dest,_src,_len,_msg) \
+#define append_str(_dest,_src,_len) \
 	do{\
 		memcpy( (_dest) , (_src) , (_len) );\
 		(_dest) += (_len) ;\
 	}while(0);
 
 #define append_str_trans(_dest,_src,_len,_msg) \
-	do{\
-		memcpy( (_dest) , (_msg)->orig+((_src)-(_msg)->buf) , (_len) );\
-		(_dest) += (_len) ;\
-	}while(0);
+	append_str( (_dest), (_msg)->orig+((_src)-(_msg)->buf) , (_len) );
 
 extern char version[];
 extern int version_len;
@@ -647,6 +646,7 @@ char * build_res_buf_from_sip_res( struct sip_msg* msg,
 	len=msg->len;
 	new_buf=0;
 	/* we must remove the first via */
+#ifdef PRESERVE_ZT
 	via_len=msg->via1->bsize;
 	via_offset=msg->via1->hdr.s-buf;
 	DBG("via len: %d, initial via offset: %d\n", via_len, via_offset);
@@ -659,6 +659,15 @@ char * build_res_buf_from_sip_res( struct sip_msg* msg,
 		/* add hdr size ("Via:")*/
 		via_len+=msg->via1->hdr.len+1;
 	}
+#else
+	if (msg->via1->next) {
+		via_len=msg->via1->bsize;
+		via_offset=msg->h_via1->body.s-buf;
+	} else {
+		via_len=msg->h_via1->len;
+		via_offset=msg->h_via1->name.s-buf;
+	}
+#endif
 	/* remove the first via*/
 	if (del_lump( &(msg->repl_add_rm), via_offset, via_len, HDR_VIA)==0){
 		LOG(L_ERR, "build_res_buf_from_sip_res: error trying to remove first"
@@ -713,6 +722,9 @@ char * build_res_buf_from_sip_req( unsigned int code, char *text,
 	char              *warning;
 	unsigned int      warning_len;
 	int r;
+#ifndef PRESERVE_ZT
+	char *after_body;
+#endif
 	str to_tag;
 
 	received_buf=0;
@@ -772,6 +784,12 @@ char * build_res_buf_from_sip_req( unsigned int code, char *text,
 				else
 					len+=new_tag_len+TOTAG_TOKEN_LEN/*";tag="*/;
 			}
+#ifndef PRESERVE_ZT
+			else {
+				len+=hdr->len;
+				continue;
+			}
+#endif
 		} else if (hdr->type==HDR_VIA) {
 				if (hdr==msg->h_via1) len += received_len+rport_len;
 		} else if (hdr->type==HDR_RECORDROUTE) {
@@ -782,7 +800,11 @@ char * build_res_buf_from_sip_req( unsigned int code, char *text,
 					|| hdr->type==HDR_CSEQ)) {
 			continue;
 		}
+#ifdef PRESERVE_ZT
 		len += ((hdr->body.s+hdr->body.len )-hdr->name.s )+CRLF_LEN;
+#else
+		len += hdr->len;
+#endif
 	}
 	len-=delete_len;
 	/*lumps length*/
@@ -829,26 +851,6 @@ char * build_res_buf_from_sip_req( unsigned int code, char *text,
 	for ( hdr=msg->headers ; hdr ; hdr=hdr->next )
 		switch (hdr->type)
 		{
-			case HDR_TO:
-				if (new_tag){
-					if (to_tag.s ) {
-						append_str_trans( p, hdr->name.s ,
-							to_tag.s-hdr->name.s,msg);
-						append_str( p, new_tag,new_tag_len,msg);
-						append_str_trans( p,to_tag.s+to_tag.len,
-							((hdr->body.s+hdr->body.len )-
-							(to_tag.s+to_tag.len)),msg);
-						append_str( p, CRLF,CRLF_LEN,msg);
-					}else{
-						append_str_trans( p, hdr->name.s ,
-							((hdr->body.s+hdr->body.len )-hdr->name.s ),
-							msg);
-						append_str( p, TOTAG_TOKEN,TOTAG_TOKEN_LEN,msg);
-						append_str( p, new_tag,new_tag_len,msg);
-						append_str( p, CRLF,CRLF_LEN,msg);
-					}
-					break;
-				}
 			case HDR_VIA:
 				if (hdr==msg->h_via1){
 					if (rport_buf){
@@ -856,7 +858,7 @@ char * build_res_buf_from_sip_req( unsigned int code, char *text,
 						append_str_trans( p, hdr->name.s ,
 							msg->via1->rport->start-hdr->name.s-1,msg);
 						/* copy new rport */
-						append_str(p, rport_buf, rport_len, msg);
+						append_str(p, rport_buf, rport_len);
 						/* copy the rest of the via */
 						append_str_trans(p, msg->via1->rport->start+
 											msg->via1->rport->size, 
@@ -866,26 +868,72 @@ char * build_res_buf_from_sip_req( unsigned int code, char *text,
 					}else{
 						/* normal whole via copy */
 						append_str_trans( p, hdr->name.s ,
-							((hdr->body.s+hdr->body.len )-hdr->name.s ),msg);
+							((hdr->body.s+hdr->body.len )-hdr->name.s ), msg);
 					}
 					if (received_buf)
-						append_str( p, received_buf, received_len, msg);
+						append_str( p, received_buf, received_len);
 				}else{
 					/* normal whole via copy */
 					append_str_trans( p, hdr->name.s ,
 						((hdr->body.s+hdr->body.len )-hdr->name.s ),msg);
 				}
-				append_str( p, CRLF,CRLF_LEN,msg);
+				append_str( p, CRLF,CRLF_LEN);
 				break;
 			case HDR_RECORDROUTE:
 				/* RR only for 1xx and 2xx replies */
 				if (code<180 || code>=300) break;
+			case HDR_TO:
+				if (new_tag){
+					if (to_tag.s ) { /* replacement */
+#ifdef PRESERVE_ZT
+						/* before to-tag */
+						append_str_trans( p, hdr->name.s ,
+							to_tag.s-hdr->name.s,msg);
+						/* to tag replacement */
+						append_str( p, new_tag,new_tag_len);
+						/* the rest after to-tag */
+						append_str_trans( p,to_tag.s+to_tag.len,
+							((hdr->body.s+hdr->body.len )-
+							(to_tag.s+to_tag.len)),msg);
+						append_str( p, CRLF,CRLF_LEN);
+#else
+						/* before to-tag */
+						append_str( p, hdr->name.s, to_tag.s-hdr->name.s);
+						/* to tag replacement */
+						append_str( p, new_tag,new_tag_len);
+						/* the rest after to-tag */
+						append_str( p, to_tag.s+to_tag.len,
+							hdr->name.s+hdr->len-(to_tag.s+to_tag.len));
+#endif
+					}else{ /* adding a new to-tag */
+#ifdef PRESERVE_ZT
+						append_str_trans( p, hdr->name.s ,
+							((hdr->body.s+hdr->body.len )-hdr->name.s ),
+							msg);
+						append_str( p, TOTAG_TOKEN,TOTAG_TOKEN_LEN);
+						append_str( p, new_tag,new_tag_len);
+						append_str( p, CRLF,CRLF_LEN);
+#else
+						after_body=hdr->body.s+hdr->body.len;
+						append_str( p, hdr->name.s, after_body-hdr->name.s);
+						append_str(p, TOTAG_TOKEN, TOTAG_TOKEN_LEN);
+						append_str( p, new_tag,new_tag_len);
+						append_str( p, after_body, 
+										hdr->name.s+hdr->len-after_body);
+#endif
+					}
+					break;
+				} /* no new to-tag -- proceed to 1:1 copying  */
 			case HDR_FROM:
 			case HDR_CALLID:
 			case HDR_CSEQ:
+#ifdef PRESERVE_ZT
 					append_str_trans( p, hdr->name.s ,
 						((hdr->body.s+hdr->body.len )-hdr->name.s ),msg);
-					append_str( p, CRLF,CRLF_LEN,msg);
+					append_str( p, CRLF,CRLF_LEN);
+#else
+					append_str(p, hdr->name.s, hdr->len);
+#endif
 		} /* for switch */
 	/*lumps*/
 	for(lump=msg->reply_lump;lump;lump=lump->next)

+ 6 - 1
parser/case_call.h

@@ -25,19 +25,24 @@
  * You should have received a copy of the GNU General Public License 
  * along with this program; if not, write to the Free Software 
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * History:
+ * ----------
+ * 2003-01-27 next baby-step to removing ZT - PRESERVE_ZT (jiri)
  */
 
 
 #ifndef CASE_CALL_H
 #define CASE_CALL_H
 
+#include "../comp_defs.h"
 
 #define ID_CASE                      \
      switch(LOWER_DWORD(val)) {      \
      case __id1_:                    \
 	     hdr->type = HDR_CALLID; \
 	     hdr->name.len = 7;      \
-	     *(p + 3) = '\0';        \
+	     SET_ZT(*(p + 3));        \
 	     return (p + 4);         \
 	                             \
      case __id2_:                    \

+ 7 - 3
parser/case_cont.h

@@ -25,19 +25,24 @@
  * You should have received a copy of the GNU General Public License 
  * along with this program; if not, write to the Free Software 
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * History:
+ * ----------
+ * 2003-01-27 next baby-step to removing ZT - PRESERVE_ZT (jiri)
  */
 
 
 #ifndef CASE_CONT_H
 #define CASE_CONT_H
 
+#include "../comp_defs.h"
 
 #define TH_CASE                                        \
         switch(LOWER_DWORD(val)) {                     \
         case _th12_:                                   \
                 hdr->type = HDR_CONTENTLENGTH;         \
                 hdr->name.len = 14;                    \
-                *(p + 3) = '\0';                       \
+                SET_ZT(*(p + 3));                       \
                 return (p + 4);                        \
         }                                              \
                                                        \
@@ -71,7 +76,7 @@
         case _act1_:                     \
 	        hdr->type = HDR_CONTACT; \
 	        hdr->name.len = 7;       \
-	        *(p + 3) = '\0';         \
+	        SET_ZT(*(p + 3));      \
 	        return (p + 4);          \
 	                                 \
         case _act2_:                     \
@@ -86,7 +91,6 @@
                 goto other;              \
         }                         
 
-
 #define cont_CASE      \
      p += 4;           \
      val = READ(p);    \

+ 6 - 1
parser/case_expi.h

@@ -25,19 +25,24 @@
  * You should have received a copy of the GNU General Public License 
  * along with this program; if not, write to the Free Software 
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * History:
+ * ---------
+ * 2003-01-27 next baby-step to removing ZT - PRESERVE_ZT (jiri)
  */
 
 
 #ifndef CASE_EXPI_H
 #define CASE_EXPI_H
 
+#include "../comp_defs.h"
 
 #define EXPI_RES_CASE                    \
         switch(LOWER_DWORD(val)) {       \
         case _res1_:                     \
 		hdr->type = HDR_EXPIRES; \
 		hdr->name.len = 7;       \
-                *(p + 3) = '\0';         \
+		SET_ZT(*(p + 3));          \
 		return (p + 4);          \
                                          \
         case _res2_:                     \

+ 9 - 1
parser/case_prox.h

@@ -25,19 +25,24 @@
  * You should have received a copy of the GNU General Public License 
  * along with this program; if not, write to the Free Software 
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * History:
+ * --------
+ * 2003-01-27 next baby-step to removing ZT - PRESERVE_ZT (jiri)
  */
 
 
 #ifndef CASE_PROX_H
 #define CASE_PROX_H
 
+#include "../comp_defs.h"
 
 #define ION_CASE                           \
         switch(LOWER_DWORD(val)) {         \
         case _ion1_:                       \
 	        hdr->type = HDR_PROXYAUTH; \
 	        hdr->name.len = 19;        \
-                *(p + 3) = '\0';           \
+            SET_ZT(*(p + 3));          \
 	        return (p + 4);            \
                                            \
         case _ion2_:                       \
@@ -46,6 +51,9 @@
 	        goto dc_end;               \
         }
 
+#define IZAT_CASE                  \
+        switch(LOWER_DWORD(val)) { \
+
 
 #define IZAT_CASE                  \
         switch(LOWER_DWORD(val)) { \

+ 7 - 1
parser/case_requ.h

@@ -25,19 +25,25 @@
  * You should have received a copy of the GNU General Public License 
  * along with this program; if not, write to the Free Software 
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * History:
+ * -------------
+ * 2003-01-27 next baby-step to removing ZT - PRESERVE_ZT (jiri)
  */
 
 
 #ifndef CASE_REQU_H
 #define CASE_REQU_H
 
+#include "../comp_defs.h"
+
 
 #define IRE_CASE                         \
         switch(LOWER_DWORD(val)) {       \
         case _ire1_:                     \
                 hdr->type = HDR_REQUIRE; \
                 hdr->name.len = 7;       \
-                *(p + 3) = '\0';         \
+                SET_ZT(*(p + 3));        \
                 return (p + 4);          \
                                          \
         case _ire2_:                     \

+ 6 - 1
parser/case_to.h

@@ -25,17 +25,22 @@
  * You should have received a copy of the GNU General Public License 
  * along with this program; if not, write to the Free Software 
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * History:
+ * ---------
+ * 2003-01-27 next baby-step to removing ZT - PRESERVE_ZT (jiri)
  */
 
 
 #ifndef CASE_TO_H
 #define CASE_TO_H
 
+#include "../comp_defs.h"
 
 #define to12_CASE           \
         hdr->type = HDR_TO; \
         hdr->name.len = 2;  \
-        *(p + 2) = '\0';    \
+        SET_ZT(*(p + 2));    \
         return (p + 4);
 
 

+ 5 - 1
parser/case_unsu.h

@@ -25,19 +25,23 @@
  * You should have received a copy of the GNU General Public License 
  * along with this program; if not, write to the Free Software 
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * History:
+ * 2003-01-27 next baby-step to removing ZT - PRESERVE_ZT (jiri)
  */
 
 
 #ifndef CASE_UNSU_H
 #define CASE_UNSU_H
 
+#include "../comp_defs.h"
 
 #define TED_CASE                             \
         switch(LOWER_DWORD(val)) {           \
         case _ted1_:                         \
                 hdr->type = HDR_UNSUPPORTED; \
                 hdr->name.len = 11;          \
-                *(p + 3) = '\0';             \
+                SET_ZT(*(p + 3));            \
 	        return (p + 4);              \
                                              \
         case _ted2_:                         \

+ 2 - 2
parser/case_via.h

@@ -31,14 +31,14 @@
 #ifndef CASE_VIA_H
 #define CASE_VIA_H
 
+#include "../comp_defs.h"
 
 #define via1_CASE            \
         hdr->type = HDR_VIA; \
         hdr->name.len = 3;   \
-        *(p + 3) = '\0';     \
+        SET_ZT(*(p + 3));     \
         return (p + 4)        
 
-
 #define via2_CASE            \
         hdr->type = HDR_VIA; \
         p += 4;              \

+ 8 - 0
parser/hf.h

@@ -23,6 +23,10 @@
  * You should have received a copy of the GNU General Public License 
  * along with this program; if not, write to the Free Software 
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * History:
+ * ---------
+ * 2003-01-27 next baby-step to removing ZT - PRESERVE_ZT (jiri)
  */
 
 
@@ -30,6 +34,7 @@
 #define HF_H
 
 #include "../str.h"
+#include "../comp_defs.h"
 
 
 /* Header types and flags */
@@ -68,6 +73,9 @@ struct hdr_field {
 	int type;                /* Header field type */
 	str name;                /* Header field name */
 	str body;                /* Header field body */
+#ifndef PRESERVE_ZT
+	int len;				 /* length from body until EoHF (incl. CRLF) */
+#endif
 	void* parsed;            /* Parsed data structures */
 	struct hdr_field* next;  /* Next header field in the list */
 };

+ 38 - 4
parser/msg_parser.c

@@ -26,12 +26,17 @@
  * You should have received a copy of the GNU General Public License 
  * along with this program; if not, write to the Free Software 
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * History:
+ * ---------
+ * 2003-01-27 next baby-step to removing ZT - PRESERVE_ZT (jiri)
  */
 
 
 #include <string.h>
 #include <stdlib.h>
 
+#include "../comp_defs.h"
 #include "msg_parser.h"
 #include "parser_f.h"
 #include "../ut.h"
@@ -79,6 +84,22 @@ char* get_hdr_field(char* buf, char* end, struct hdr_field* hdr)
 		LOG(L_ERR, "ERROR: get_hdr_field: bad header\n");
 		goto error;
 	}
+
+#ifndef PRESERVE_ZT
+	/* eliminate leading whitespace */
+	tmp=eat_lws_end(tmp, end);
+	if (tmp>=end) {
+		LOG(L_ERR, "ERROR: get_hdr_field: HF empty\n");
+		goto error;
+	}
+#else
+	;
+#endif
+
+	/* if header-field well-known, parse it, find its end otherwise ;
+	 * after leaving the hdr->type switch, tmp should be set to the
+	 * next header field
+	 */
 	switch(hdr->type){
 		case HDR_VIA:
 			/* keep number of vias parsed -- we want to report it in
@@ -118,8 +139,10 @@ char* get_hdr_field(char* buf, char* end, struct hdr_field* hdr)
 			}
 			hdr->parsed=cseq_b;
 			hdr->body.len=tmp-hdr->body.s;
-			DBG("get_hdr_field: cseq <%s>: <%s> <%s>\n",
-					hdr->name.s, cseq_b->number.s, cseq_b->method.s);
+			DBG("get_hdr_field: cseq <%.*s>: <%.*s> <%.*s>\n",
+					hdr->name.len, hdr->name.s, 
+					cseq_b->number.len, cseq_b->number.s, 
+					cseq_b->method.len, cseq_b->method.s);
 			break;
 		case HDR_TO:
 			to_b=pkg_malloc(sizeof(struct to_body));
@@ -137,8 +160,9 @@ char* get_hdr_field(char* buf, char* end, struct hdr_field* hdr)
 			}
 			hdr->parsed=to_b;
 			hdr->body.len=tmp-hdr->body.s;
-			DBG("DEBUG: get_hdr_field: <%s> [%d]; uri=[%.*s] \n",
-				hdr->name.s, hdr->body.len, to_b->uri.len,to_b->uri.s);
+			DBG("DEBUG: get_hdr_field: <%.*s> [%d]; uri=[%.*s] \n",
+				hdr->name.len, hdr->name.s, 
+				hdr->body.len, to_b->uri.len,to_b->uri.s);
 			DBG("DEBUG: to body [%.*s]\n",to_b->body.len,to_b->body.s);
 			break;
 		case HDR_CONTENTLENGTH:
@@ -188,7 +212,11 @@ char* get_hdr_field(char* buf, char* end, struct hdr_field* hdr)
 				}
 				tmp=match;
 			}while( match<end &&( (*match==' ')||(*match=='\t') ) );
+#ifdef PRESERVE_ZT
 			*(match-1)=0; /*null terminate*/
+#else
+			tmp=match;
+#endif
 			hdr->body.len=match-hdr->body.s;
 			break;
 		default:
@@ -198,10 +226,16 @@ char* get_hdr_field(char* buf, char* end, struct hdr_field* hdr)
 	}
 	/* jku: if \r covered by current length, shrink it */
 	trim_r( hdr->body );
+#ifndef PRESERVE_ZT
+	hdr->len=tmp-hdr->name.s;
+#endif
 	return tmp;
 error:
 	DBG("get_hdr_field: error exit\n");
 	hdr->type=HDR_ERROR;
+#ifndef PRESERVE_ZT
+	hdr->len=tmp-hdr->name.s;
+#endif
 	return tmp;
 }
 

+ 42 - 5
parser/parse_cseq.c

@@ -23,9 +23,14 @@
  * You should have received a copy of the GNU General Public License 
  * along with this program; if not, write to the Free Software 
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * 
+ * History:
+ * --------
+ * 2003-01-22 zero-termination in CSeq eliminated (jiri)
  */
 
 
+#include "../comp_defs.h"
 #include "parse_cseq.h"
 #include "parser_f.h"  /* eat_space_end and so on */
 #include "../dprint.h"
@@ -40,21 +45,32 @@
 char* parse_cseq(char *buf, char* end, struct cseq_body* cb)
 {
 	char *t, *m, *m_end;
+#ifdef PRESERVE_ZT
 	char c;
+#endif
 	
 	cb->error=PARSE_ERROR;
+#ifdef PRESERVE_ZT /* already called in calling function */
 	t=eat_space_end(buf, end);
 	if (t>=end) goto error;
+#else
+	t=buf;
+#endif
 	
 	cb->number.s=t;
 	t=eat_token_end(t, end);
 	if (t>=end) goto error;
+	cb->number.len=t-cb->number.s;
+
 	m=eat_space_end(t, end);
 	m_end=eat_token_end(m, end);
-	*t=0; /*null terminate it*/
-	cb->number.len=t-cb->number.s;
+	SET_ZT(*t);
 
-	if (m_end>=end) goto error;
+	if (m_end>=end) {
+			LOG(L_ERR, "ERROR: parse_cseq: "
+						"method terminated unexpectedly\n");
+			goto error;
+	}
 	if (m_end==m){
 		/* null method*/
 		LOG(L_ERR,  "ERROR:parse_cseq: no method found\n");
@@ -62,9 +78,11 @@ char* parse_cseq(char *buf, char* end, struct cseq_body* cb)
 	}
 	cb->method.s=m;
 	t=m_end;
+	cb->method.len=t-cb->method.s;
+
+#ifdef PRESERVE_ZT
 	c=*t;
 	*t=0; /*null terminate it*/
-	cb->method.len=t-cb->method.s;
 	t++;
 	/*check if the header ends here*/
 	if (c=='\n') goto check_continue;
@@ -80,9 +98,28 @@ char* parse_cseq(char *buf, char* end, struct cseq_body* cb)
 check_continue:
 		;
 	}while( (t<end) && ((*t==' ')||(*t=='\t')) );
-
 	cb->error=PARSE_OK;
 	return t;
+#else
+	/* there may be trailing LWS 
+	 * (it was not my idea to put it in SIP; -jiri )
+	 */
+	t=eat_lws_end(t, end);
+	/*check if the header ends here*/
+	if (t>=end) {
+		LOG(L_ERR, "ERROR: parse_cseq: strange EoHF\n");
+		goto error;
+	}
+	if (*t=='\r' && t+1<end && *(t+1)=='\n') {
+			cb->error=PARSE_OK;
+			return t+2;
+	}
+	if (*t=='\n') {
+			cb->error=PARSE_OK;
+			return t+1;
+	}
+	LOG(L_ERR, "ERROR: CSeq EoL expected\n");
+#endif
 error:
 	LOG(L_ERR, "ERROR: parse_cseq: bad cseq\n");
 	return t;

+ 9 - 4
parser/parse_hname2.c

@@ -25,9 +25,14 @@
  * You should have received a copy of the GNU General Public License 
  * along with this program; if not, write to the Free Software 
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * History:
+ * --------
+ * 2003-01-27 next baby-step to removing ZT - PRESERVE_ZT (jiri)
  */
 
 
+#include "../comp_defs.h"
 #include "parse_hname2.h"
 #include "keys.h"
 #include "../ut.h"  /* q_memchr */
@@ -109,7 +114,7 @@ static inline char* skip_ws(char* p, unsigned int size)
         case ':':                  \
 	        hdr->type = id;    \
 	        hdr->name.len = 1; \
-	        *(p + 1) = '\0';   \
+	        SET_ZT(*(p + 1));   \
 	        return (p + 2);    \
         }                            
 
@@ -145,7 +150,7 @@ char* parse_hname2(char* begin, char* end, struct hdr_field* hdr)
 			case ':':                   
 				hdr->type = HDR_TO; 
 				hdr->name.len = 1;  
-				*(p + 1) = '\0'; 
+				SET_ZT(*(p+1));
 				return (p + 2);     
 			}                           
 			break;
@@ -169,7 +174,7 @@ char* parse_hname2(char* begin, char* end, struct hdr_field* hdr)
 	        goto other;
 	} else {
 		hdr->name.len = p - hdr->name.s;
-		*p = '\0';
+		SET_ZT(*p);
 		return (p + 1);
 	}
 
@@ -183,7 +188,7 @@ char* parse_hname2(char* begin, char* end, struct hdr_field* hdr)
 		return 0;
 	} else {
 		hdr->type = HDR_OTHER;
-		*p = '\0';
+		SET_ZT(*p);
 		hdr->name.len = p - hdr->name.s;
 		return (p + 1);
 	}

+ 4 - 0
parser/parser_f.c

@@ -26,6 +26,10 @@
  * You should have received a copy of the GNU General Public License 
  * along with this program; if not, write to the Free Software 
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * History:
+ * ---------
+ * 2003-01-27 next baby-step to removing ZT - PRESERVE_ZT (jiri)
  */
 
 

+ 17 - 1
parser/parser_f.h

@@ -29,16 +29,32 @@
 #ifndef parser_f_h
 #define parser_f_h
 
+#include "../comp_defs.h"
+
 char* eat_line(char* buffer, unsigned int len);
 
 /* turn the most frequently called functions into inline functions */
 
-
 inline static char* eat_space_end(char* p, char* pend)
 {
 	for(;(p<pend)&&(*p==' ' || *p=='\t') ;p++);
 	return p;
 }
+#ifndef PRESERVE_ZT
+#define SP(_c) ((_c)=='\t' || (_c)==' ')
+inline static char* eat_lws_end(char* p, char* pend)
+{
+	while(p<pend) {
+		if (SP(*p)) p++;
+		/* btw--I really dislike line folding; -jiri */
+		else if (*p=='\n' && p+1<pend && SP(*(p+1))) p+=2;
+		else if (*p=='\r' && p+2<pend && *(p+1)=='\n' 
+					&& SP(*(p+2))) p+=3;
+		else break; /* no whitespace encountered */
+	}
+	return p;
+}
+#endif