Parcourir la source

- RURI is not parsed again if parsed_uri_ok=1

- 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.
Miklos Tirpak il y a 17 ans
Parent
commit
6973e34cd5
5 fichiers modifiés avec 59 ajouts et 20 suppressions
  1. 48 19
      action.c
  2. 2 0
      cfg.lex
  3. 4 0
      cfg.y
  4. 3 0
      route_struct.c
  5. 2 1
      route_struct.h

+ 48 - 19
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;

+ 2 - 0
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; }

+ 4 - 0
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"); }

+ 3 - 0
route_struct.c

@@ -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;

+ 2 - 1
route_struct.h

@@ -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,