[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