Browse code

- 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 authored on 17/04/2008 16:22:18
Showing 5 changed files
... ...
@@ -462,6 +462,7 @@ int do_action(struct run_act_ctx* h, struct action* a, struct sip_msg* msg)
462 462
 			break;
463 463
 		case SET_HOST_T:
464 464
 		case SET_HOSTPORT_T:
465
+		case SET_HOSTPORTTRANS_T:
465 466
 		case SET_USER_T:
466 467
 		case SET_USERPASS_T:
467 468
 		case SET_PORT_T:
... ...
@@ -503,18 +504,22 @@ int do_action(struct run_act_ctx* h, struct action* a, struct sip_msg* msg)
503 503
 					ret=1;
504 504
 					break;
505 505
 				}
506
-				if (msg->new_uri.s) {
507
-					tmp=msg->new_uri.s;
508
-					len=msg->new_uri.len;
509
-				}else{
510
-					tmp=msg->first_line.u.request.uri.s;
511
-					len=msg->first_line.u.request.uri.len;
512
-				}
513
-				if (parse_uri(tmp, len, &uri)<0){
514
-					LOG(L_ERR, "ERROR: do_action: bad uri <%s>, dropping"
515
-								" packet\n", tmp);
516
-					ret=E_UNSPEC;
517
-					break;
506
+				if (msg->parsed_uri_ok==0) {
507
+					if (msg->new_uri.s) {
508
+						tmp=msg->new_uri.s;
509
+						len=msg->new_uri.len;
510
+					}else{
511
+						tmp=msg->first_line.u.request.uri.s;
512
+						len=msg->first_line.u.request.uri.len;
513
+					}
514
+					if (parse_uri(tmp, len, &uri)<0){
515
+						LOG(L_ERR, "ERROR: do_action: bad uri <%s>, dropping"
516
+									" packet\n", tmp);
517
+						ret=E_UNSPEC;
518
+						break;
519
+					}
520
+				} else {
521
+					uri=msg->parsed_uri;
518 522
 				}
519 523
 
520 524
 				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)
593 593
 					if(crt+1>end) goto error_uri;
594 594
 					*crt='@'; crt++;
595 595
 				}
596
-				if ((a->type==SET_HOST_T) ||(a->type==SET_HOSTPORT_T)) {
596
+				if ((a->type==SET_HOST_T)
597
+						|| (a->type==SET_HOSTPORT_T)
598
+						|| (a->type==SET_HOSTPORTTRANS_T)) {
597 599
 					tmp=a->val[0].u.string;
598 600
 					if (tmp) len = strlen(tmp);
599 601
 					else len=0;
... ...
@@ -606,7 +613,9 @@ int do_action(struct run_act_ctx* h, struct action* a, struct sip_msg* msg)
606 606
 					memcpy(crt,tmp,len);crt+=len;
607 607
 				}
608 608
 				/* port */
609
-				if (a->type==SET_HOSTPORT_T) tmp=0;
609
+				if ((a->type==SET_HOSTPORT_T)
610
+						|| (a->type==SET_HOSTPORTTRANS_T))
611
+					tmp=0;
610 612
 				else if (a->type==SET_PORT_T) {
611 613
 					tmp=a->val[0].u.string;
612 614
 					if (tmp) len = strlen(tmp);
... ...
@@ -621,11 +630,31 @@ int do_action(struct run_act_ctx* h, struct action* a, struct sip_msg* msg)
621 621
 					memcpy(crt,tmp,len);crt+=len;
622 622
 				}
623 623
 				/* params */
624
-				tmp=uri.params.s;
625
-				if (tmp){
626
-					len=uri.params.len; if(crt+len+1>end) goto error_uri;
627
-					*crt=';'; crt++;
628
-					memcpy(crt,tmp,len);crt+=len;
624
+				if ((a->type==SET_HOSTPORTTRANS_T) && uri.transport.s) {
625
+					/* bypass the transport parameter */
626
+					if (uri.params.s < uri.transport.s) {
627
+						/* there are parameters before transport */
628
+						len = uri.transport.s - uri.params.s - 1;
629
+							/* ignore the ';' at the end */
630
+						if (crt+len+1>end) goto error_uri;
631
+						*crt=';'; crt++;
632
+						memcpy(crt,uri.params.s,len);crt+=len;
633
+					}
634
+					len = (uri.params.s + uri.params.len) -
635
+						(uri.transport.s + uri.transport.len);
636
+					if (len > 0) {
637
+						/* there are parameters after transport */
638
+						if (crt+len>end) goto error_uri;
639
+						tmp = uri.transport.s + uri.transport.len;
640
+						memcpy(crt,tmp,len);crt+=len;
641
+					}
642
+				} else {
643
+					tmp=uri.params.s;
644
+					if (tmp){
645
+						len=uri.params.len; if(crt+len+1>end) goto error_uri;
646
+						*crt=';'; crt++;
647
+						memcpy(crt,tmp,len);crt+=len;
648
+					}
629 649
 				}
630 650
 				/* headers */
631 651
 				tmp=uri.headers.s;
... ...
@@ -152,6 +152,7 @@ ISAVPFLAGSET	isavpflagset
152 152
 AVPFLAGS_DECL	avpflags
153 153
 SET_HOST		"rewritehost"|"sethost"|"seth"
154 154
 SET_HOSTPORT	"rewritehostport"|"sethostport"|"sethp"
155
+SET_HOSTPORTTRANS	"rewritehostporttrans"|"sethostporttrans"|"sethpt"
155 156
 SET_USER		"rewriteuser"|"setuser"|"setu"
156 157
 SET_USERPASS	"rewriteuserpass"|"setuserpass"|"setup"
157 158
 SET_PORT		"rewriteport"|"setport"|"setp"
... ...
@@ -435,6 +436,7 @@ EAT_ABLE	[\ \t\b\r]
435 435
 <INITIAL>{EXEC}	{ count(); yylval.strval=yytext; return EXEC; }
436 436
 <INITIAL>{SET_HOST}	{ count(); yylval.strval=yytext; return SET_HOST; }
437 437
 <INITIAL>{SET_HOSTPORT}	{ count(); yylval.strval=yytext; return SET_HOSTPORT; }
438
+<INITIAL>{SET_HOSTPORTTRANS}	{ count(); yylval.strval=yytext; return SET_HOSTPORTTRANS; }
438 439
 <INITIAL>{SET_USER}	{ count(); yylval.strval=yytext; return SET_USER; }
439 440
 <INITIAL>{SET_USERPASS}	{ count(); yylval.strval=yytext; return SET_USERPASS; }
440 441
 <INITIAL>{SET_PORT}	{ count(); yylval.strval=yytext; return SET_PORT; }
... ...
@@ -224,6 +224,7 @@ static struct socket_id* mk_listen_id(char*, int, int);
224 224
 %token EXEC
225 225
 %token SET_HOST
226 226
 %token SET_HOSTPORT
227
+%token SET_HOSTPORTTRANS
227 228
 %token PREFIX
228 229
 %token STRIP
229 230
 %token STRIP_TAIL
... ...
@@ -2058,6 +2059,9 @@ cmd:
2058 2058
 	| SET_HOSTPORT LPAREN STRING RPAREN { $$=mk_action(SET_HOSTPORT_T, 1, STRING_ST, $3); }
2059 2059
 	| SET_HOSTPORT error { $$=0; yyerror("missing '(' or ')' ?"); }
2060 2060
 	| SET_HOSTPORT LPAREN error RPAREN { $$=0; yyerror("bad argument, string expected"); }
2061
+	| SET_HOSTPORTTRANS LPAREN STRING RPAREN { $$=mk_action(SET_HOSTPORTTRANS_T, 1, STRING_ST, $3); }
2062
+	| SET_HOSTPORTTRANS error { $$=0; yyerror("missing '(' or ')' ?"); }
2063
+	| SET_HOSTPORTTRANS LPAREN error RPAREN { $$=0; yyerror("bad argument, string expected"); }
2061 2064
 	| SET_PORT LPAREN STRING RPAREN { $$=mk_action(SET_PORT_T, 1, STRING_ST, $3); }
2062 2065
 	| SET_PORT error { $$=0; yyerror("missing '(' or ')' ?"); }
2063 2066
 	| SET_PORT LPAREN error RPAREN { $$=0; yyerror("bad argument, string expected"); }
... ...
@@ -331,6 +331,9 @@ void print_action(struct action* t)
331 331
 		case SET_HOSTPORT_T:
332 332
 			DBG("sethostport(");
333 333
 			break;
334
+		case SET_HOSTPORTTRANS_T:
335
+			DBG("sethostporttrans(");
336
+			break;
334 337
 		case SET_USER_T:
335 338
 			DBG("setuser(");
336 339
 			break;
... ...
@@ -69,7 +69,8 @@ enum { METHOD_O=1, URI_O, FROM_URI_O, TO_URI_O, SRCIP_O, SRCPORT_O,
69 69
 
70 70
 enum { FORWARD_T=1, SEND_T, DROP_T, LOG_T, ERROR_T, ROUTE_T, EXEC_T,
71 71
 		SET_HOST_T, SET_HOSTPORT_T, SET_USER_T, SET_USERPASS_T,
72
-		SET_PORT_T, SET_URI_T, IF_T, MODULE_T,
72
+		SET_PORT_T, SET_URI_T, SET_HOSTPORTTRANS_T,
73
+		IF_T, MODULE_T,
73 74
 		SETFLAG_T, RESETFLAG_T, ISFLAGSET_T ,
74 75
 		AVPFLAG_OPER_T,
75 76
 		LEN_GT_T, PREFIX_T, STRIP_T,STRIP_TAIL_T,