- RURI is not parsed again if parsed_uri_ok=1
authorMiklos Tirpak <miklos@iptel.org>
Thu, 17 Apr 2008 16:22:18 +0000 (16:22 +0000)
committerMiklos Tirpak <miklos@iptel.org>
Thu, 17 Apr 2008 16:22:18 +0000 (16:22 +0000)
- new action type, SET_HOSTPORTTRANS_T, and the corresponding
script actions are introduced: sethostporttrans() and
rewritehostporttrans()

This action accepts an optional transport parameter, and clears the
previous transport param if there was any. It is safer to use this action
instead of SET_HOSTPORT_T in some cases, even if the transport param is
omitted, because the latter can leave the parameter in the RURI
causing troubles.

action.c
cfg.lex
cfg.y
route_struct.c
route_struct.h

index ab66353..9824340 100644 (file)
--- a/action.c
+++ b/action.c
@@ -462,6 +462,7 @@ int do_action(struct run_act_ctx* h, struct action* a, struct sip_msg* msg)
                        break;
                case SET_HOST_T:
                case SET_HOSTPORT_T:
+               case SET_HOSTPORTTRANS_T:
                case SET_USER_T:
                case SET_USERPASS_T:
                case SET_PORT_T:
@@ -503,18 +504,22 @@ int do_action(struct run_act_ctx* h, struct action* a, struct sip_msg* msg)
                                        ret=1;
                                        break;
                                }
-                               if (msg->new_uri.s) {
-                                       tmp=msg->new_uri.s;
-                                       len=msg->new_uri.len;
-                               }else{
-                                       tmp=msg->first_line.u.request.uri.s;
-                                       len=msg->first_line.u.request.uri.len;
-                               }
-                               if (parse_uri(tmp, len, &uri)<0){
-                                       LOG(L_ERR, "ERROR: do_action: bad uri <%s>, dropping"
-                                                               " packet\n", tmp);
-                                       ret=E_UNSPEC;
-                                       break;
+                               if (msg->parsed_uri_ok==0) {
+                                       if (msg->new_uri.s) {
+                                               tmp=msg->new_uri.s;
+                                               len=msg->new_uri.len;
+                                       }else{
+                                               tmp=msg->first_line.u.request.uri.s;
+                                               len=msg->first_line.u.request.uri.len;
+                                       }
+                                       if (parse_uri(tmp, len, &uri)<0){
+                                               LOG(L_ERR, "ERROR: do_action: bad uri <%s>, dropping"
+                                                                       " packet\n", tmp);
+                                               ret=E_UNSPEC;
+                                               break;
+                                       }
+                               } else {
+                                       uri=msg->parsed_uri;
                                }
 
                                new_uri=pkg_malloc(MAX_URI_SIZE);
@@ -593,7 +598,9 @@ int do_action(struct run_act_ctx* h, struct action* a, struct sip_msg* msg)
                                        if(crt+1>end) goto error_uri;
                                        *crt='@'; crt++;
                                }
-                               if ((a->type==SET_HOST_T) ||(a->type==SET_HOSTPORT_T)) {
+                               if ((a->type==SET_HOST_T)
+                                               || (a->type==SET_HOSTPORT_T)
+                                               || (a->type==SET_HOSTPORTTRANS_T)) {
                                        tmp=a->val[0].u.string;
                                        if (tmp) len = strlen(tmp);
                                        else len=0;
@@ -606,7 +613,9 @@ int do_action(struct run_act_ctx* h, struct action* a, struct sip_msg* msg)
                                        memcpy(crt,tmp,len);crt+=len;
                                }
                                /* port */
-                               if (a->type==SET_HOSTPORT_T) tmp=0;
+                               if ((a->type==SET_HOSTPORT_T)
+                                               || (a->type==SET_HOSTPORTTRANS_T))
+                                       tmp=0;
                                else if (a->type==SET_PORT_T) {
                                        tmp=a->val[0].u.string;
                                        if (tmp) len = strlen(tmp);
@@ -621,11 +630,31 @@ int do_action(struct run_act_ctx* h, struct action* a, struct sip_msg* msg)
                                        memcpy(crt,tmp,len);crt+=len;
                                }
                                /* params */
-                               tmp=uri.params.s;
-                               if (tmp){
-                                       len=uri.params.len; if(crt+len+1>end) goto error_uri;
-                                       *crt=';'; crt++;
-                                       memcpy(crt,tmp,len);crt+=len;
+                               if ((a->type==SET_HOSTPORTTRANS_T) && uri.transport.s) {
+                                       /* bypass the transport parameter */
+                                       if (uri.params.s < uri.transport.s) {
+                                               /* there are parameters before transport */
+                                               len = uri.transport.s - uri.params.s - 1;
+                                                       /* ignore the ';' at the end */
+                                               if (crt+len+1>end) goto error_uri;
+                                               *crt=';'; crt++;
+                                               memcpy(crt,uri.params.s,len);crt+=len;
+                                       }
+                                       len = (uri.params.s + uri.params.len) -
+                                               (uri.transport.s + uri.transport.len);
+                                       if (len > 0) {
+                                               /* there are parameters after transport */
+                                               if (crt+len>end) goto error_uri;
+                                               tmp = uri.transport.s + uri.transport.len;
+                                               memcpy(crt,tmp,len);crt+=len;
+                                       }
+                               } else {
+                                       tmp=uri.params.s;
+                                       if (tmp){
+                                               len=uri.params.len; if(crt+len+1>end) goto error_uri;
+                                               *crt=';'; crt++;
+                                               memcpy(crt,tmp,len);crt+=len;
+                                       }
                                }
                                /* headers */
                                tmp=uri.headers.s;
diff --git a/cfg.lex b/cfg.lex
index 31a7f76..176889b 100644 (file)
--- a/cfg.lex
+++ b/cfg.lex
@@ -152,6 +152,7 @@ ISAVPFLAGSET        isavpflagset
 AVPFLAGS_DECL  avpflags
 SET_HOST               "rewritehost"|"sethost"|"seth"
 SET_HOSTPORT   "rewritehostport"|"sethostport"|"sethp"
+SET_HOSTPORTTRANS      "rewritehostporttrans"|"sethostporttrans"|"sethpt"
 SET_USER               "rewriteuser"|"setuser"|"setu"
 SET_USERPASS   "rewriteuserpass"|"setuserpass"|"setup"
 SET_PORT               "rewriteport"|"setport"|"setp"
@@ -435,6 +436,7 @@ EAT_ABLE    [\ \t\b\r]
 <INITIAL>{EXEC}        { count(); yylval.strval=yytext; return EXEC; }
 <INITIAL>{SET_HOST}    { count(); yylval.strval=yytext; return SET_HOST; }
 <INITIAL>{SET_HOSTPORT}        { count(); yylval.strval=yytext; return SET_HOSTPORT; }
+<INITIAL>{SET_HOSTPORTTRANS}   { count(); yylval.strval=yytext; return SET_HOSTPORTTRANS; }
 <INITIAL>{SET_USER}    { count(); yylval.strval=yytext; return SET_USER; }
 <INITIAL>{SET_USERPASS}        { count(); yylval.strval=yytext; return SET_USERPASS; }
 <INITIAL>{SET_PORT}    { count(); yylval.strval=yytext; return SET_PORT; }
diff --git a/cfg.y b/cfg.y
index a9da803..2c43015 100644 (file)
--- a/cfg.y
+++ b/cfg.y
@@ -224,6 +224,7 @@ static struct socket_id* mk_listen_id(char*, int, int);
 %token EXEC
 %token SET_HOST
 %token SET_HOSTPORT
+%token SET_HOSTPORTTRANS
 %token PREFIX
 %token STRIP
 %token STRIP_TAIL
@@ -2058,6 +2059,9 @@ cmd:
        | SET_HOSTPORT LPAREN STRING RPAREN { $$=mk_action(SET_HOSTPORT_T, 1, STRING_ST, $3); }
        | SET_HOSTPORT error { $$=0; yyerror("missing '(' or ')' ?"); }
        | SET_HOSTPORT LPAREN error RPAREN { $$=0; yyerror("bad argument, string expected"); }
+       | SET_HOSTPORTTRANS LPAREN STRING RPAREN { $$=mk_action(SET_HOSTPORTTRANS_T, 1, STRING_ST, $3); }
+       | SET_HOSTPORTTRANS error { $$=0; yyerror("missing '(' or ')' ?"); }
+       | SET_HOSTPORTTRANS LPAREN error RPAREN { $$=0; yyerror("bad argument, string expected"); }
        | SET_PORT LPAREN STRING RPAREN { $$=mk_action(SET_PORT_T, 1, STRING_ST, $3); }
        | SET_PORT error { $$=0; yyerror("missing '(' or ')' ?"); }
        | SET_PORT LPAREN error RPAREN { $$=0; yyerror("bad argument, string expected"); }
index 8a6298b..f9fb0a6 100644 (file)
@@ -331,6 +331,9 @@ void print_action(struct action* t)
                case SET_HOSTPORT_T:
                        DBG("sethostport(");
                        break;
+               case SET_HOSTPORTTRANS_T:
+                       DBG("sethostporttrans(");
+                       break;
                case SET_USER_T:
                        DBG("setuser(");
                        break;
index f6d5e25..56bf442 100644 (file)
@@ -69,7 +69,8 @@ enum { METHOD_O=1, URI_O, FROM_URI_O, TO_URI_O, SRCIP_O, SRCPORT_O,
 
 enum { FORWARD_T=1, SEND_T, DROP_T, LOG_T, ERROR_T, ROUTE_T, EXEC_T,
                SET_HOST_T, SET_HOSTPORT_T, SET_USER_T, SET_USERPASS_T,
-               SET_PORT_T, SET_URI_T, IF_T, MODULE_T,
+               SET_PORT_T, SET_URI_T, SET_HOSTPORTTRANS_T,
+               IF_T, MODULE_T,
                SETFLAG_T, RESETFLAG_T, ISFLAGSET_T ,
                AVPFLAG_OPER_T,
                LEN_GT_T, PREFIX_T, STRIP_T,STRIP_TAIL_T,