[Serusers] Rewriting URI in the Contact field

Jan Janak J.Janak at sh.cvut.cz
Sun Jan 12 18:02:35 CET 2003


Hello,

I will review the patch and let you know.

  regards, Jan.

On 11-01 06:50, Maxim Sobolev wrote:
> Thank you for the explanation! Attached please find first version
> of `rport' support for SER (we need it in the core engine), the
> module will follow probably tomorrow. Please note that the code
> is quite raw (6:20 am here ;) and I did not perform any seriuos
> tests yet.
> 
> The code does the following:
> 
> 1. Adds support for `rport' Via field parameter into the message
> parser;
> 
> 2. Extends parser to allow valueless parameters as requred by
> the draft RFC. This will probably requre additional code
> review, as there may be places in the code where it is
> assumed that parameter value could not be a NULL pointer;
> 
> 3. Fills in blank rport parameter if present before forwarding
> a request or replying to it;
> 
> 4. Changes the code, so that if `rport' is present, then this
> port is used for connecting to that UA.
> 
> Any comments, corrections or suggestions are highly appreciated!
> 
> -Maxim
> 
> On Sat, Jan 11, 2003 at 12:04:34AM +0100, Jiri Kuthan wrote:
> > that's correct.
> > 
> > >1. Check that _m->somefield is NULL and call parse_headers() with the
> > >appropriate HDR_FOO flag.
> > 
> > yes. you can skip the first check, parse_headers will do it;
> > don't forget to handle errors if parse_headers returns -1
> > (most likely mem alloc failure)
> > 
> > >2. Check that _m->somefield is non-NULL and return if false.
> > 
> >   yes, that means, that the header field is not in message.
> > 
> >   note too that some header fields may occur multiple times; in which case
> >   msg->hdr_foo points to the first occurence; if you wish to
> >   process all of them, you need to traverse the list
> >   msg->headers
> > 
> > example from record-routing (XXX are my extra comments):
> > 
> > int find_first_route(struct sip_msg* _m)
> > {
> >     /* XXX don't look at _m->route ... parse_headers will do it for you */
> >     if (parse_headers(_m, HDR_ROUTE, 0) == -1) {
> >         /* XXX -1 is some bad error, most likely lack of memory  -- leave! */
> >         LOG(L_ERR, "find_first_route(): Error while parsing headers\n");
> >         return -1;
> >     } else {
> > 
> >         if (_m->route) {
> >             return 0;
> >         } else { /* XXX not found .... the header field is not there */
> >             DBG("find_first_route(): No Route headers found\n");
> >             return 1;
> >         }
> >     }
> > }
> > 
> > 
> > 
> > >3. Modify _m->somefield according to the type of that field.
> > >4. Using del_lump() mark original version of the header for deletion and
> > >using insert_new_lump() indicate where modified version should be placed
> > >before sending a message out.
> > 
> > 3 is the same as 4, isn't it. you modify a header field by creating
> > a delete lump refering the old value and an insert lump with the new
> > value. the new value must be created using pkg_malloc. the replace 
> > action in textops module is a good example. (The lump lists, sort 
> > of "diffs", is processed when later on the message is printed and forwarded.)
> > 
> > -Jiri 

> --- modules/sl/sl_funcs.c.orig	Mon Oct 21 23:30:15 2002
> +++ modules/sl/sl_funcs.c	Sat Jan 11 06:09:54 2003
> @@ -121,7 +121,7 @@
>  	to.sin_family = AF_INET; */
>  
>  	if (reply_to_via) {
> -		if (update_sock_struct_from_via(  &(to),  msg->via1 )==-1)
> +		if (update_sock_struct_from_via(  &(to),  msg->via1, msg)==-1)
>  		{
>  			LOG(L_ERR, "ERROR: sl_send_reply: "
>  				"cannot lookup reply dst: %s\n",
> --- modules/tm/t_lookup.c.orig	Mon Oct 21 22:21:50 2002
> +++ modules/tm/t_lookup.c	Sat Jan 11 06:09:54 2003
> @@ -717,7 +717,7 @@
>  	} else {
>  		via=msg->via1;
>  		/*init retrans buffer*/
> -		if (update_sock_struct_from_via( &(rb->to),via )==-1) {
> +		if (update_sock_struct_from_via( &(rb->to),via,msg )==-1) {
>  			LOG(L_ERR, "ERROR: init_rb: cannot lookup reply dst: %.*s\n",
>  				via->host.len, via->host.s );
>  			ser_error=E_BAD_VIA;
> --- parser/msg_parser.h.orig	Wed Oct 23 18:12:20 2002
> +++ parser/msg_parser.h	Sat Jan 11 06:15:11 2003
> @@ -118,6 +118,7 @@
>  	char* unparsed;   /* here we stopped parsing*/
>  
>  	struct ip_addr src_ip;
> +	unsigned short src_port_no;
>  	struct ip_addr dst_ip;
>  	
>  	char* orig;       /* original message copy */
> --- parser/parse_via.c.orig	Thu Sep 19 15:23:55 2002
> +++ parser/parse_via.c	Sat Jan 11 06:09:54 2003
> @@ -87,8 +87,10 @@
>  	MADDR1, MADDR2, MADDR3, MADDR4,
>  	RECEIVED1, RECEIVED2, RECEIVED3, RECEIVED4, RECEIVED5, RECEIVED6,
>  	RECEIVED7,
> +	RPORT1, RPORT2, RPORT3,
>  	     /* fin states (227-...)*/
>  	FIN_HIDDEN = 230, FIN_TTL, FIN_BRANCH, FIN_MADDR, FIN_RECEIVED,
> +	FIN_RPORT,
>  	     /*GEN_PARAM,
>  	       PARAM_ERROR*/ /* declared in msg_parser.h*/
>  };
> @@ -125,6 +127,7 @@
>  					case FIN_TTL:
>  					case FIN_MADDR:
>  					case FIN_RECEIVED:
> +					case FIN_RPORT:
>  						*tmp=0;
>  						param->type=state;
>  						param->name.len=tmp-param->name.s;
> @@ -160,6 +163,7 @@
>  					case FIN_TTL:
>  					case FIN_MADDR:
>  					case FIN_RECEIVED:
> +					case FIN_RPORT:
>  						*tmp=0;
>  						param->type=state;
>  						param->name.len=tmp-param->name.s;
> @@ -200,6 +204,7 @@
>  					case FIN_TTL:
>  					case FIN_MADDR:
>  					case FIN_RECEIVED:
> +					case FIN_RPORT:
>  						*tmp=0;
>  						param->type=state;
>  						param->name.len=tmp-param->name.s;
> @@ -231,6 +236,7 @@
>  					case FIN_TTL:
>  					case FIN_MADDR:
>  					case FIN_RECEIVED:
> +					case FIN_RPORT:
>  						*tmp=0;
>  						param->type=state;
>  						param->name.len=tmp-param->name.s;
> @@ -267,6 +273,7 @@
>  					case FIN_MADDR:
>  					case FIN_TTL:
>  					case FIN_RECEIVED:
> +					case FIN_RPORT:
>  						LOG(L_ERR, "ERROR: parse_via: invalid char <%c> in"
>  								" state %d\n", *tmp, state);
>  						goto error;
> @@ -296,6 +303,7 @@
>  					case FIN_MADDR:
>  					case FIN_TTL:
>  					case FIN_RECEIVED:
> +					case FIN_RPORT:
>  						LOG(L_ERR, "ERROR: parse_via_param: new via found" 
>  								"(',') when '=' expected (state %d=)\n",
>  								state);
> @@ -458,6 +466,9 @@
>  					case TTL1:
>  						state=TTL2;
>  						break;
> +					case RPORT3:
> +						state=FIN_RPORT;
> +						break;
>  					case GEN_PARAM:
>  						break;
>  					case F_CR:
> @@ -545,6 +556,9 @@
>  					case BRANCH1:
>  						state=BRANCH2;
>  						break;
> +					case RPORT2:
> +						state=RPORT3;
> +						break;
>  					case GEN_PARAM:
>  						break;
>  					case F_CR:
> @@ -619,7 +633,36 @@
>  						state=GEN_PARAM;
>  				}
>  				break;
> -
> +			case 'p':
> +			case 'P':
> +				switch(state){
> +					case RECEIVED1:
> +						state=RPORT1;
> +						break;
> +					case F_CR:
> +					case F_LF:
> +					case F_CRLF:
> +						state=END_OF_HEADER;
> +						goto end_via;
> +					default:
> +						state=GEN_PARAM;
> +				}
> +				break;
> +			case 'o':
> +			case 'O':
> +				switch(state){
> +					case RPORT1:
> +						state=RPORT2;
> +						break;
> +					case F_CR:
> +					case F_LF:
> +					case F_CRLF:
> +						state=END_OF_HEADER;
> +						goto end_via;
> +					default:
> +						state=GEN_PARAM;
> +				}
> +				break;
>  			default:
>  				switch(state){
>  					case F_PARAM:
> @@ -750,6 +793,11 @@
>  						param->value.len=tmp-param->value.s;
>  						state=F_PARAM;
>  						goto endofvalue;
> +					case F_VALUE:
> +						*tmp=0;
> +						param->value.len=0;
> +						state=F_PARAM;
> +						goto endofvalue;
>  					case P_STRING:
>  						break; /* what to do? */
>  					case F_LF:
> @@ -1681,6 +1729,8 @@
>  							vb->branch=param;
>  						else if (param->type==PARAM_RECEIVED)
>  							vb->received=param;
> +						else if (param->type==PARAM_RPORT)
> +							vb->rport=param;
>  						break;
>  					case P_PARAM:
>  						break;
> --- parser/parse_via.h.orig	Mon Oct 21 18:46:27 2002
> +++ parser/parse_via.h	Sat Jan 11 06:09:54 2003
> @@ -36,7 +36,7 @@
>   */
>  enum {
>  	PARAM_HIDDEN=230, PARAM_TTL, PARAM_BRANCH, 
> -	PARAM_MADDR, PARAM_RECEIVED, GEN_PARAM,
> +	PARAM_MADDR, PARAM_RECEIVED, PARAM_RPORT, GEN_PARAM,
>  	PARAM_ERROR
>  };
>  
> @@ -70,6 +70,7 @@
>  	struct via_param* branch;
>  	str tid; /* transaction id, part of branch */
>  	struct via_param* received;
> +	struct via_param* rport;
>  	
>  	struct via_body* next; /* pointer to next via body string if
>  				  compact via or null */
> --- config.h.orig	Mon Oct 21 22:21:50 2002
> +++ config.h	Sat Jan 11 06:09:54 2003
> @@ -82,6 +82,9 @@
>  #define RECEIVED   ";received="
>  #define RECEIVED_LEN 10
>  
> +#define RPORT ";rport="
> +#define RPORT_LEN 7
> +
>  #define SRV_PREFIX "_sip._udp."
>  #define SRV_PREFIX_LEN 10
>  
> @@ -112,6 +115,7 @@
>  /* forwarding  -- Via buffer dimensioning */
>  #define MAX_VIA_LINE_SIZE	240
>  #define MAX_RECEIVED_SIZE	57
> +#define MAX_RPORT_SIZE		13
>  
>  /* maximum number of branches per transaction */
>  #define MAX_BRANCHES    4
> --- forward.h.orig	Wed Oct 23 18:12:20 2002
> +++ forward.h	Sat Jan 11 06:09:54 2003
> @@ -40,7 +40,7 @@
>  int check_self(str* host, unsigned short port);
>  int forward_request( struct sip_msg* msg,  struct proxy_l* p);
>  int update_sock_struct_from_via( union sockaddr_union* to,
> -								struct via_body* via );
> +    struct via_body* via, struct sip_msg *msg );
>  int update_sock_struct_from_ip( union sockaddr_union* to,
>      struct sip_msg *msg );
>  int forward_reply( struct sip_msg* msg);
> --- ip_addr.h.orig	Mon Nov  4 19:05:32 2002
> +++ ip_addr.h	Sat Jan 11 06:09:54 2003
> @@ -201,6 +201,21 @@
>  	}
>  }
>  
> +static inline unsigned int su2port_no(union sockaddr_union* su)
> +{
> +	switch(su->s.sa_family){
> +	case AF_INET:
> +					return ntohs(su->sin.sin_port);
> +#ifdef USE_IPV6
> +	case AF_INET6:
> +					return ntohs(su->sin6.sin6_port);
> +#endif
> +	default:
> +					LOG(L_CRIT,"su2port_no: BUG: unknown address family %d\n",
> +							su->s.sa_family);
> +	}
> +	return 0;
> +}
>  
>  /* ip_addr2su -> the same as init_su*/
>  #define ip_addr2su init_su
> --- msg_translator.c.orig	Mon Oct 21 22:21:50 2002
> +++ msg_translator.c	Sat Jan 11 06:09:54 2003
> @@ -145,9 +145,10 @@
>  	else
>  		foo=&(msg->first_line.u.request.uri);
>  	print_len=snprintf(buf+fix_len, MAX_WARNING_LEN-fix_len,
> -		"pid=%d req_src_ip=%s in_uri=%.*s out_uri=%.*s via_cnt%c=%d\"",
> +		"pid=%d req_src_ip=%s req_src_port=%d in_uri=%.*s out_uri=%.*s via_cnt%c=%d\"",
>  		my_pid(),
>  		ip_addr2a(&msg->src_ip),
> +		msg->src_port_no,
>  		msg->first_line.u.request.uri.len, msg->first_line.u.request.uri.s,
>  		foo->len, foo->s, 
>  		msg->parsed_flag & HDR_EOH ? '=' : '>', /* should be = */
> @@ -208,7 +209,26 @@
>  	return buf;
>  }
>  
> +char *rport_builder(struct sip_msg *msg, unsigned int *rport_len)
> +{
> +	char *buf;
>  
> +	buf=pkg_malloc(sizeof(char)*MAX_RPORT_SIZE);
> +	if (buf==0){
> +		ser_error=E_OUT_OF_MEM;
> +		LOG(L_ERR, "ERROR: rport_builder: out of memory\n");
> +		return 0;
> +	}
> +	/*
> +	 * Don't need any sanity checks here, because
> +	 * msg->src_port_no is unsigned int, which means
> +	 * that it couldn't be more than 5 chars long in
> +	 * string representation.
> +	 */
> +	*rport_len = snprintf(buf, MAX_RPORT_SIZE, "%s%u", RPORT, msg->src_port_no);
> +
> +	return buf;
> +}
>  
>  /* computes the "unpacked" len of a lump list,
>     code moved from build_req_from_req */
> @@ -395,9 +415,10 @@
>  								unsigned int *returned_len,
>  								struct socket_info* send_sock)
>  {
> -	unsigned int len, new_len, received_len, uri_len, via_len;
> +	unsigned int len, new_len, received_len, rport_len, uri_len, via_len;
>  	char* line_buf;
>  	char* received_buf;
> +	char* rport_buf;
>  	char* new_buf;
>  	char* orig;
>  	char* buf;
> @@ -411,8 +432,10 @@
>  	buf=msg->buf;
>  	len=msg->len;
>  	received_len=0;
> +	rport_len=0;
>  	new_buf=0;
>  	received_buf=0;
> +	rport_buf=0;
>  
>  
>  	line_buf = via_builder( &via_len, send_sock, 
> @@ -430,6 +453,11 @@
>  		if ((received_buf=received_builder(msg,&received_len))==0)
>  			goto error01;  /* free also line_buf */
>  	}
> +	/* check if rport needs to be updated */
> +	if (msg->via1->rport && msg->via1->rport->value.s==0) {
> +		if ((rport_buf=rport_builder(msg,&rport_len))==0)
> +			goto error01;	/* free also line_buf */
> +	}
>  
>  	/* add via header to the list */
>  	/* try to add it before msg. 1st via */
> @@ -459,6 +487,14 @@
>  		if (insert_new_lump_after(anchor, received_buf, received_len, HDR_VIA)
>  				==0 ) goto error02; /* free also line_buf */
>  	}
> +	/* if rport needs to be updated do it */
> +	if (rport_len){
> +		offset = msg->via1->rport->value.s - buf - 1;
> +		anchor=del_lump(&msg->add_rm, offset, msg->via1->rport->size + 1, HDR_VIA);
> +		if (anchor==0) goto error02;	/* free also line_buf */
> +		if (insert_new_lump_after(anchor, rport_buf, rport_len, HDR_VIA)
> +				==0 ) goto error02;	/* free also line_buf */
> +	}
>  
>  	/* compute new msg len and fix overlapping zones*/
>  	new_len=len+lumps_len(msg->add_rm);
> @@ -507,6 +543,7 @@
>  	pkg_free(line_buf);
>  error02:
>  	if (received_buf) pkg_free(received_buf);
> +	if (rport_buf) pkg_free(rport_buf);
>  error00:
>  	*returned_len=0;
>  	return 0;
> @@ -587,14 +624,18 @@
>  	int               i;
>  	char              backup;
>  	char              *received_buf;
> +	char		  *rport_buf;
>  	unsigned int               received_len;
> +	unsigned int               rport_len;
>  	char              *warning;
>  	unsigned int      warning_len;
>  	int r;
>  	str to_tag;
>  
>  	received_buf=0;
> +	rport_buf=0;
>  	received_len=0;
> +	rport_len=0;
>  	buf=0;
>  	/* make -Wall happy */
>  	warning=0;
> @@ -621,6 +662,15 @@
>  			goto error00;
>  		}
>  	}
> +        /* check if rport needs to be updated */
> +        if (msg->via1->rport && msg->via1->rport->value.s==0) {
> +                if ((rport_buf=rport_builder(msg,&rport_len))==0) {
> +			LOG(L_ERR, "ERROR: build_res_buf_from_sip_req: "
> +				"alas, rport_builder failed\n");
> +                        goto error00;
> +		}
> +		rport_len -= msg->via1->rport->size;
> +        }
>  
>  	/*computes the lenght of the new response buffer*/
>  	len = 0;
> @@ -641,7 +691,7 @@
>  						len+=new_tag_len+5/*";tag="*/;
>  				}
>  			case HDR_VIA:
> -				if (hdr==msg->h_via1) len += received_len;
> +				if (hdr==msg->h_via1) len += received_len + rport_len;
>  			case HDR_FROM:
>  			case HDR_CALLID:
>  			case HDR_CSEQ:
> @@ -716,10 +766,23 @@
>  					break;
>  				}
>  			case HDR_VIA:
> -				append_str_trans( p, hdr->name.s ,
> +				if (hdr==msg->h_via1 && rport_buf) {
> +					append_str_trans( p, hdr->name.s ,
> +					    msg->via1->rport->name.s - hdr->name.s - 1, msg);
> +					append_str( p, rport_buf,
> +					    rport_len + msg->via1->rport->size, msg);
> +					append_str_trans( p, msg->via1->rport->name.s +
> +					    msg->via1->rport->size,
> +					    hdr->body.s + hdr->body.len -
> +					    msg->via1->rport->name.s -
> +					    msg->via1->rport->size, msg);
> +				} else {
> +					append_str_trans( p, hdr->name.s ,
>  					((hdr->body.s+hdr->body.len )-hdr->name.s ),msg);
> +				}
>  				if (hdr==msg->h_via1 && received_buf)
>  					append_str( p, received_buf, received_len, msg);
> +					
>  				append_str( p, CRLF,CRLF_LEN,msg);
>  				break;
>  			case HDR_FROM:
> @@ -763,10 +826,12 @@
>  	   needs to be deleted here
>  	*/
>  	if (received_buf) pkg_free(received_buf);
> +	if (rport_buf) pkg_free(rport_buf);
>  	return buf;
>  
>  error01:
>  	if (received_buf) pkg_free(received_buf);
> +	if (rport_buf) pkg_free(rport_buf);
>  error00:
>  	*returned_len=0;
>  	return 0;
> --- receive.c.orig	Thu Oct  3 23:06:10 2002
> +++ receive.c	Sat Jan 11 06:09:54 2003
> @@ -77,6 +77,7 @@
>  	   useful as most of the work is done with scrath-pad; -jiri  */
>  	buf[len]=0;
>  	su2ip_addr(&msg->src_ip, src_su);
> +	msg->src_port_no=su2port_no(src_su);
>  	msg->dst_ip=bind_address->address; /* won't work if listening on 0.0.0.0 */
>  	msg->id=msg_no;
>  	/* make a copy of the message */
> --- forward.c.orig	Thu Oct 24 17:21:08 2002
> +++ forward.c	Sat Jan 11 06:21:11 2003
> @@ -240,14 +240,21 @@
>  int update_sock_struct_from_ip( union sockaddr_union* to,
>  	struct sip_msg *msg )
>  {
> +	unsigned short port_no;
>  
> -	init_su(to, &msg->src_ip, 
> -		(msg->via1->port)?htons(msg->via1->port): htons(SIP_PORT) );
> +	if (msg->src_port_no)
> +		port_no = msg->src_port_no;
> +	else if (msg->via1->port)
> +		port_no = msg->via1->port;
> +	else
> +		port_no = SIP_PORT;
> +
> +	init_su(to, &msg->src_ip, htons(port_no));
>  	return 1;
>  }
>  
>  int update_sock_struct_from_via( union sockaddr_union* to,
> -								 struct via_body* via )
> +	struct via_body* via, struct sip_msg *msg )
>  {
>  	struct hostent* he;
>  	char *host_copy;
> @@ -266,6 +273,11 @@
>  		name=&(via->host);
>  		port=via->port;
>  	}
> +	if (via->rport && via->rport->value.s) {
> +		port=atoi(via->rport->value.s);
> +	} else if (via->rport && via->rport->value.s==0 && !via->received) {
> +		return update_sock_struct_from_ip( to, msg);
> +	}
>  	/* we do now a malloc/memcpy because gethostbyname loves \0-terminated 
>  	   strings; -jiri 
>  	   but only if host is not null terminated
> @@ -353,7 +365,7 @@
>  		goto error;
>  	}
>  
> -	if (update_sock_struct_from_via( to, msg->via2 )==-1) goto error;
> +	if (update_sock_struct_from_via( to, msg->via2, msg)==-1) goto error;
>  	send_sock=get_send_socket(to);
>  	if (send_sock==0){
>  		LOG(L_ERR, "forward_reply: ERROR: no sending socket found\n");

-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: not available
URL: <http://lists.sip-router.org/pipermail/sr-users/attachments/20030112/4ea90384/attachment.pgp>


More information about the sr-users mailing list