Browse code

Avoid parsing the Request URI when it is not necessary.

When @ruri.user was executed, the first select call set
the value of the URI in str format regardless of whether
or not it had already been parsed. The second function call
took the str value, and parsed the URI to get its user part.

This patch introduces a global pointer variable that can be set
to the already parsed URI being processed. Any nested select
function can check this pointer and access the parsed URI if
possible.

Miklos Tirpak authored on 15/05/2009 07:42:29
Showing 3 changed files
... ...
@@ -60,6 +60,13 @@ static select_table_t *select_list = &select_core_table;
60 60
  */
61 61
 int select_level = 0;
62 62
 
63
+/* pointer to the SIP uri beeing processed.
64
+ * Nested function calls can pass information to each
65
+ * other using this pointer. Only for performace reasons.
66
+ * (Miklos)
67
+ */
68
+struct sip_uri	*select_uri_p = NULL;
69
+
63 70
 /** parse a select identifier (internal version)
64 71
  * Parse select string into select structure s
65 72
  * moves pointer p to the first unused char.
... ...
@@ -399,6 +406,9 @@ int run_select(str* res, select_t* s, struct sip_msg* msg)
399 399
 	}
400 400
 	DBG("Calling SELECT %p \n", s->f);
401 401
 
402
+	/* reset the uri pointer */
403
+	select_uri_p = NULL;
404
+
402 405
 	/* save and restore the original select_level
403 406
 	 * because of the nested selects */
404 407
 	orig_level = select_level;
... ...
@@ -149,6 +149,13 @@ typedef struct select_table {
149 149
  */
150 150
 extern int select_level;
151 151
 
152
+/* pointer to the SIP uri beeing processed.
153
+ * Nested function calls can pass information to each
154
+ * other using this pointer. Only for performace reasons.
155
+ * (Miklos)
156
+ */
157
+extern struct sip_uri	*select_uri_p;
158
+
152 159
 /*
153 160
  * Lookup corresponding select function based on
154 161
  * the select parameters
... ...
@@ -69,6 +69,9 @@
69 69
 
70 70
 int select_ruri(str* res, select_t* s, struct sip_msg* msg)
71 71
 {
72
+	if (msg->parsed_uri_ok)
73
+		select_uri_p = &msg->parsed_uri;
74
+
72 75
 	if (msg->first_line.type==SIP_REQUEST) {
73 76
 		if(msg->new_uri.s) {
74 77
 			RETURN0_res(msg->new_uri);
... ...
@@ -94,9 +97,15 @@ int select_next_hop(str* res, select_t* s, struct sip_msg* msg)
94 94
 			RETURN0_res(msg->dst_uri);
95 95
 		}
96 96
 		else if(msg->new_uri.s) {
97
+			if (msg->parsed_uri_ok)
98
+				select_uri_p = &msg->parsed_uri;
97 99
 			RETURN0_res(msg->new_uri);
98 100
 		}
99 101
 		else {
102
+			if (msg->parsed_uri_ok)
103
+				select_uri_p = &msg->parsed_uri;
104
+			else if (msg->parsed_orig_ruri_ok)
105
+				select_uri_p = &msg->parsed_orig_ruri;
100 106
 			RETURN0_res(msg->first_line.u.request.uri);
101 107
 		}
102 108
 	}
... ...
@@ -691,30 +700,36 @@ static struct sip_uri uri;
691 691
 
692 692
 int select_uri_type(str* res, select_t* s, struct sip_msg* msg)
693 693
 {
694
-	trim(res);
695
-	if (parse_uri(res->s, res->len, &uri)<0)
696
-		return -1;
694
+	if (select_uri_p == NULL) {
695
+		trim(res);
696
+		if (parse_uri(res->s, res->len, &uri)<0)
697
+			return -1;
698
+		select_uri_p = &uri;
699
+	}
697 700
 
698
-	if (uri.type==ERROR_URI_T)
701
+	if (select_uri_p->type==ERROR_URI_T)
699 702
 		return -1;
700 703
 
701
-	uri_type_to_str(uri.type, res);
704
+	uri_type_to_str(select_uri_p->type, res);
702 705
 	return 0;
703 706
 }
704 707
 
705 708
 int select_uri_user(str* res, select_t* s, struct sip_msg* msg)
706 709
 {
707
-	if (parse_uri(res->s, res->len, &uri)<0)
708
-		return -1;
710
+	if (select_uri_p == NULL) {
711
+		if (parse_uri(res->s, res->len, &uri)<0)
712
+			return -1;
713
+		select_uri_p = &uri;
714
+	}
709 715
 
710
-	if (uri.flags & URI_USER_NORMALIZE) {
711
-		if (!(res->s=get_static_buffer(uri.user.len)))
716
+	if (select_uri_p->flags & URI_USER_NORMALIZE) {
717
+		if (!(res->s=get_static_buffer(select_uri_p->user.len)))
712 718
 			return -1;
713
-		if ((res->len=normalize_tel_user(res->s, (&uri.user)))==0)
719
+		if ((res->len=normalize_tel_user(res->s, (&select_uri_p->user)))==0)
714 720
 			return 1;
715 721
 		return 0;
716 722
 	}
717
-	RETURN0_res(uri.user);
723
+	RETURN0_res(select_uri_p->user);
718 724
 }
719 725
 
720 726
 /* search for a parameter with "name"
... ...
@@ -757,23 +772,26 @@ int select_uri_rn_user(str* res, select_t* s, struct sip_msg* msg)
757 757
 	int	ret;
758 758
 	str	val;
759 759
 
760
-	if (parse_uri(res->s, res->len, &uri)<0)
761
-		return -1;
760
+	if (select_uri_p == NULL) {
761
+		if (parse_uri(res->s, res->len, &uri)<0)
762
+			return -1;
763
+		select_uri_p = &uri;
764
+	}
762 765
 
763 766
 	/* search for the "rn" parameter */
764
-	if ((ret = search_param(&uri.params, "rn", 2, &val)) != 0)
767
+	if ((ret = search_param(&select_uri_p->params, "rn", 2, &val)) != 0)
765 768
 		goto done;
766 769
 
767
-	if (uri.sip_params.s != uri.params.s) {
770
+	if (select_uri_p->sip_params.s != select_uri_p->params.s) {
768 771
 		/* check also the original sip: URI parameters */
769
-		if ((ret = search_param(&uri.sip_params, "rn", 2, &val)) != 0)
772
+		if ((ret = search_param(&select_uri_p->sip_params, "rn", 2, &val)) != 0)
770 773
 			goto done;
771 774
 	}
772 775
 
773
-	if ((uri.flags & URI_USER_NORMALIZE) == 0)
774
-		RETURN0_res(uri.user);
776
+	if ((select_uri_p->flags & URI_USER_NORMALIZE) == 0)
777
+		RETURN0_res(select_uri_p->user);
775 778
 	/* else normalize the user name */
776
-	val = uri.user;
779
+	val = select_uri_p->user;
777 780
 done:
778 781
 	if (ret < 0)
779 782
 		return -1; /* error */
... ...
@@ -787,26 +805,35 @@ done:
787 787
 
788 788
 int select_uri_pwd(str* res, select_t* s, struct sip_msg* msg)
789 789
 {
790
-	if (parse_uri(res->s, res->len, &uri)<0)
791
-		return -1;
790
+	if (select_uri_p == NULL) {
791
+		if (parse_uri(res->s, res->len, &uri)<0)
792
+			return -1;
793
+		select_uri_p = &uri;
794
+	}
792 795
 
793
-	RETURN0_res(uri.passwd);
796
+	RETURN0_res(select_uri_p->passwd);
794 797
 }
795 798
 
796 799
 int select_uri_host(str* res, select_t* s, struct sip_msg* msg)
797 800
 {
798
-	if (parse_uri(res->s, res->len, &uri)<0)
799
-		return -1;
801
+	if (select_uri_p == NULL) {
802
+		if (parse_uri(res->s, res->len, &uri)<0)
803
+			return -1;
804
+		select_uri_p = &uri;
805
+	}
800 806
 
801
-	RETURN0_res(uri.host);
807
+	RETURN0_res(select_uri_p->host);
802 808
 }
803 809
 
804 810
 int select_uri_port(str* res, select_t* s, struct sip_msg* msg)
805 811
 {
806
-	if (parse_uri(res->s, res->len, &uri)<0)
807
-		return -1;
812
+	if (select_uri_p == NULL) {
813
+		if (parse_uri(res->s, res->len, &uri)<0)
814
+			return -1;
815
+		select_uri_p = &uri;
816
+	}
808 817
 
809
-	RETURN0_res(uri.port);
818
+	RETURN0_res(select_uri_p->port);
810 819
 }
811 820
 
812 821
 int select_uri_hostport(str* res, select_t* s, struct sip_msg* msg)
... ...
@@ -814,31 +841,34 @@ int select_uri_hostport(str* res, select_t* s, struct sip_msg* msg)
814 814
 	char* p;
815 815
 	int size;
816 816
 	
817
-	if (parse_uri(res->s,res->len, &uri)<0)
818
-		return -1;
817
+	if (select_uri_p == NULL) {
818
+		if (parse_uri(res->s, res->len, &uri)<0)
819
+			return -1;
820
+		select_uri_p = &uri;
821
+	}
819 822
 
820
-	if (!uri.host.len)
823
+	if (!select_uri_p->host.len)
821 824
 		return -1;
822 825
 	
823
-	if (uri.port.len) {
824
-		res->s=uri.host.s;
825
-		res->len=uri.host.len+uri.port.len+1;
826
+	if (select_uri_p->port.len) {
827
+		res->s=select_uri_p->host.s;
828
+		res->len=select_uri_p->host.len+select_uri_p->port.len+1;
826 829
 		return 0;
827 830
 	}
828 831
 	
829
-	size=uri.host.len+5;
832
+	size=select_uri_p->host.len+5;
830 833
 	if (!(p = get_static_buffer(size)))
831 834
 		return -1;
832 835
 			
833
-	strncpy(p, uri.host.s, uri.host.len);
834
-	switch (uri.type) {
836
+	strncpy(p, select_uri_p->host.s, select_uri_p->host.len);
837
+	switch (select_uri_p->type) {
835 838
 		case SIPS_URI_T:
836 839
 		case TELS_URI_T:
837
-			strncpy(p+uri.host.len, ":5061", 5); 
840
+			strncpy(p+select_uri_p->host.len, ":5061", 5); 
838 841
 			break;
839 842
 		case SIP_URI_T:
840 843
 		case TEL_URI_T:
841
-			strncpy(p+uri.host.len, ":5060", 5);
844
+			strncpy(p+select_uri_p->host.len, ":5060", 5);
842 845
 			break;
843 846
 		case ERROR_URI_T:
844 847
 			return -1;
... ...
@@ -850,13 +880,16 @@ int select_uri_hostport(str* res, select_t* s, struct sip_msg* msg)
850 850
 
851 851
 int select_uri_proto(str* res, select_t* s, struct sip_msg* msg)
852 852
 {
853
-	if (parse_uri(res->s, res->len, &uri)<0)
854
-		return -1;
853
+	if (select_uri_p == NULL) {
854
+		if (parse_uri(res->s, res->len, &uri)<0)
855
+			return -1;
856
+		select_uri_p = &uri;
857
+	}
855 858
 
856
-	if (uri.proto != PROTO_NONE) {
857
-		proto_type_to_str(uri.proto, res);
859
+	if (select_uri_p->proto != PROTO_NONE) {
860
+		proto_type_to_str(select_uri_p->proto, res);
858 861
 	} else {
859
-		switch (uri.type) {
862
+		switch (select_uri_p->type) {
860 863
 			case SIPS_URI_T:
861 864
 			case TELS_URI_T:
862 865
 				proto_type_to_str(PROTO_TLS, res);
... ...
@@ -879,20 +912,23 @@ int select_uri_params(str* res, select_t* s, struct sip_msg* msg)
879 879
 		return select_any_params(res, s, msg);
880 880
 	}
881 881
 
882
-	if (parse_uri(res->s, res->len, &uri)<0)
883
-		return -1;
882
+	if (select_uri_p == NULL) {
883
+		if (parse_uri(res->s, res->len, &uri)<0)
884
+			return -1;
885
+		select_uri_p = &uri;
886
+	}
884 887
 	
885 888
 	if (s->param_offset[select_level+1]-s->param_offset[select_level]==1)
886
-		RETURN0_res(uri.params);
889
+		RETURN0_res(select_uri_p->params);
887 890
 
888
-	*res=uri.params;
891
+	*res=select_uri_p->params;
889 892
 	ret = select_any_params(res, s, msg);
890 893
 	if ((ret < 0)
891
-		&& (uri.sip_params.s != NULL)
892
-		&& (uri.sip_params.s != uri.params.s)
894
+		&& (select_uri_p->sip_params.s != NULL)
895
+		&& (select_uri_p->sip_params.s != select_uri_p->params.s)
893 896
 	) {
894 897
 		/* Search also in the original sip: uri parameters. */
895
-		*res = uri.sip_params;
898
+		*res = select_uri_p->sip_params;
896 899
 		ret = select_any_params(res, s, msg);
897 900
 	}
898 901
 	return ret;