Prechádzať zdrojové kódy

- 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 17 rokov pred
rodič
commit
6973e34cd5
5 zmenil súbory, kde vykonal 59 pridanie a 20 odobranie
  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,