Browse code

- basic tel uri support (it's parsed, SIP_URI_T, SIPS_URI_T and TEL_URI_T added)

Andrei Pelinescu-Onciul authored on 25/02/2005 14:19:57
Showing 6 changed files
... ...
@@ -53,7 +53,7 @@ MAIN_NAME=ser
53 53
 VERSION = 0
54 54
 PATCHLEVEL = 10
55 55
 SUBLEVEL =   99
56
-EXTRAVERSION = -dev1
56
+EXTRAVERSION = -dev2
57 57
 
58 58
 RELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)
59 59
 OS = $(shell uname -s | sed -e s/SunOS/solaris/ | tr "[A-Z]" "[a-z]")
... ...
@@ -174,10 +174,11 @@ int do_action(struct action* a, struct sip_msg* msg)
174 174
 							goto error_fwd_uri;
175 175
 					}
176 176
 #ifdef USE_TLS
177
-					if (u->secure){
177
+					if (u->type==SIPS_URI_T){
178 178
 						if (u->proto==PROTO_UDP){
179 179
 							LOG(L_ERR, "ERROR: do_action: forward: secure uri"
180
-									" incompatible with transport %d\n", u->proto);
180
+									" incompatible with transport %d\n",
181
+									u->proto);
181 182
 							ret=E_BAD_PROTO;
182 183
 							goto error_fwd_uri;
183 184
 						}
... ...
@@ -108,7 +108,7 @@ inline static struct proxy_l *uri2proxy( str *uri, int proto )
108 108
 		return 0;
109 109
 	}
110 110
 	
111
-	if (parsed_uri.secure){
111
+	if (parsed_uri.type==SIPS_URI_T){
112 112
 		if ((parsed_uri.proto!=PROTO_TCP) && (parsed_uri.proto!=PROTO_NONE)){
113 113
 			LOG(L_ERR, "ERROR: uri2proxy: bad transport  for sips uri: %d\n",
114 114
 					parsed_uri.proto);
... ...
@@ -37,6 +37,7 @@
37 37
  *  2003-04-12  added msg_flags to sip_msg (andrei)
38 38
  *  2003-11-02  added diversion header field to sip_msg (jh)
39 39
  *  2004-11-08  added force_send_socket (andrei)
40
+ *  2005-02-25  uri types added (sip, sips & tel)  (andrei)
40 41
  */
41 42
 
42 43
 
... ...
@@ -121,6 +122,9 @@ struct sip_uri {
121 121
 };
122 122
 #endif
123 123
 
124
+enum _uri_type{ERROR_URI_T=0, SIP_URI_T, SIPS_URI_T, TEL_URI_T};
125
+typedef enum _uri_type uri_type;
126
+
124 127
 struct sip_uri {
125 128
 	str user;     /* Username */
126 129
 	str passwd;   /* Password */
... ...
@@ -130,7 +134,7 @@ struct sip_uri {
130 130
 	str headers;  
131 131
 	unsigned short port_no;
132 132
 	unsigned short proto; /* from transport */
133
-	int secure; /* 1 if is a sips, 0 otherwise */
133
+	uri_type type; /* uri scheme */
134 134
 	/* parameters */
135 135
 	str transport;
136 136
 	str ttl;
... ...
@@ -33,6 +33,7 @@
33 33
  * 2003-04-11  ser_error is now set in parse_uri (andrei)
34 34
  * 2003-04-26  ZSW (jiri)
35 35
  * 2003-07-03  sips:, r2, lr=on support added (andrei)
36
+ * 2005-02-25  preliminary tel uri support (andrei)
36 37
  */
37 38
 
38 39
 
... ...
@@ -96,6 +97,11 @@ int parse_uri(char* buf, int len, struct sip_uri* uri)
96 96
 	char* pass;
97 97
 	int found_user;
98 98
 	int error_headers;
99
+	unsigned int scheme;
100
+	
101
+#define SIP_SCH		0x3a706973
102
+#define SIPS_SCH	0x73706973
103
+#define TEL_SCH		0x3a6c6574
99 104
 	
100 105
 #define case_port( ch, var) \
101 106
 	case ch: \
... ...
@@ -315,15 +321,18 @@ int parse_uri(char* buf, int len, struct sip_uri* uri)
315 315
 	port_no=0;
316 316
 	state=URI_INIT;
317 317
 	memset(uri, 0, sizeof(struct sip_uri)); /* zero it all, just to be sure*/
318
-	/*look for sip:*/
318
+	/*look for sip:, sips: or tel:*/
319 319
 	if (len<5) goto error_too_short;
320
-	if (! ( ((buf[0]|0x20)=='s')&&((buf[1]|0x20)=='i')&&((buf[2]|0x20)=='p')))
321
-		goto error_bad_uri;
322
-	if (buf[3]!=':'){
323
-		/* parse also sips: */
324
-		if  (((buf[3]|0x20)=='s')&&(buf[4]==':')) {p++; uri->secure=1;}
320
+	scheme=buf[0]+(buf[1]<<8)+(buf[2]<<16)+(buf[3]<<24);
321
+	scheme|=0x20202020;
322
+	if (scheme==SIP_SCH){
323
+		uri->type=SIP_URI_T;
324
+	}else if(scheme==SIPS_SCH){
325
+		if(buf[4]==':'){ p++; uri->type=SIPS_URI_T;}
325 326
 		else goto error_bad_uri;
326
-	}
327
+	}else if (scheme==TEL_SCH){
328
+		uri->type=TEL_URI_T;
329
+	}else goto error_bad_uri;
327 330
 	
328 331
 	s=p;
329 332
 	for(;p<end; p++){
... ...
@@ -942,11 +951,18 @@ int parse_uri(char* buf, int len, struct sip_uri* uri)
942 942
 		default:
943 943
 			goto error_bug;
944 944
 	}
945
-	
946
-#if EXTRA_DEBUG
945
+	if (uri->type==TEL_URI_T){
946
+		/* fix tel uris, move the number in uri and empty the host */
947
+		uri->user=uri->host;
948
+		uri->host.s="";
949
+		uri->host.len=0;
950
+	}
951
+#ifdef EXTRA_DEBUG
947 952
 	/* do stuff */
948
-	DBG("parsed uri:\n user=<%.*s>(%d)\n passwd=<%.*s>(%d)\n host=<%.*s>(%d)\n"
949
-			" port=<%.*s>(%d): %d\n params=<%.*s>(%d)\n headers=<%.*s>(%d)\n",
953
+	DBG("parsed uri:\n type=%d user=<%.*s>(%d)\n passwd=<%.*s>(%d)\n"
954
+			" host=<%.*s>(%d)\n port=<%.*s>(%d): %d\n params=<%.*s>(%d)\n"
955
+			" headers=<%.*s>(%d)\n",
956
+			uri->type,
950 957
 			uri->user.len, ZSW(uri->user.s), uri->user.len,
951 958
 			uri->passwd.len, ZSW(uri->passwd.s), uri->passwd.len,
952 959
 			uri->host.len, ZSW(uri->host.s), uri->host.len,
... ...
@@ -3,11 +3,23 @@
3 3
 #include <string.h>
4 4
 #include "../str.h"
5 5
 
6
+/* ser compat defs */
7
+
6 8
 #define DBG printf
7 9
 #define LOG(lev, fmt, args...) printf(fmt, ## args)
8 10
 
11
+#define EXTRA_DEBUG
12
+#define ZSW(s)	((s)?(s):"")
13
+#define E_BAD_URI -100
14
+
15
+int ser_error=0;
16
+
17
+
9 18
 enum {PROTO_NONE, PROTO_UDP, PROTO_TCP, PROTO_TLS, PROTO_SCTP };
10 19
 
20
+enum _uri_type{ERROR_URI_T=0, SIP_URI_T, SIPS_URI_T, TEL_URI_T};
21
+typedef enum _uri_type uri_type;
22
+
11 23
 struct sip_uri {
12 24
 	str user;     /* Username */
13 25
 	str passwd;   /* Password */
... ...
@@ -17,6 +29,7 @@ struct sip_uri {
17 17
 	str headers;  
18 18
 	unsigned short port_no;
19 19
 	unsigned short proto; /* from transport */
20
+	uri_type type; /* uri scheme */
20 21
 	/* parameters */
21 22
 	str transport;
22 23
 	str ttl;
... ...
@@ -24,16 +37,20 @@ struct sip_uri {
24 24
 	str maddr;
25 25
 	str method;
26 26
 	str lr;
27
+	str r2; /* ser specific rr parameter */
27 28
 	/* values */
28 29
 	str transport_val;
29 30
 	str ttl_val;
30 31
 	str user_param_val;
31 32
 	str maddr_val;
32 33
 	str method_val;
34
+	str lr_val; /* lr value placeholder for lr=on a.s.o*/
35
+	str r2_val;
33 36
 };
34 37
 
35 38
 
36 39
 
40
+
37 41
 int parse_uri(char* buf, int len, struct sip_uri* uri)
38 42
 {
39 43
 	enum states  {	URI_INIT, URI_USER, URI_PASSWORD, URI_PASSWORD_ALPHA,
... ...
@@ -53,7 +70,10 @@ int parse_uri(char* buf, int len, struct sip_uri* uri)
53 53
 					/* maddr */
54 54
 					      PMA_A, PMA_D, PMA_D2, PMA_R, PMA_eq,
55 55
 					/* lr */
56
-					PLR_L, PLR_R_FIN,
56
+					PLR_L, PLR_R_FIN, PLR_eq,
57
+					/* r2 */
58
+					PR2_R, PR2_2_FIN, PR2_eq,
59
+					
57 60
 					/* transport values */
58 61
 					/* udp */
59 62
 					VU_U, VU_D, VU_P_FIN,
... ...
@@ -78,6 +98,11 @@ int parse_uri(char* buf, int len, struct sip_uri* uri)
78 78
 	char* pass;
79 79
 	int found_user;
80 80
 	int error_headers;
81
+	unsigned int scheme;
82
+	
83
+#define SIP_SCH		0x3a706973
84
+#define SIPS_SCH	0x73706973
85
+#define TEL_SCH		0x3a6c6574
81 86
 	
82 87
 #define case_port( ch, var) \
83 88
 	case ch: \
... ...
@@ -297,14 +322,22 @@ int parse_uri(char* buf, int len, struct sip_uri* uri)
297 297
 	port_no=0;
298 298
 	state=URI_INIT;
299 299
 	memset(uri, 0, sizeof(struct sip_uri)); /* zero it all, just to be sure*/
300
-	/*look for sip:*/
301
-	if (len<4) goto error_too_short;
302
-	if (! ( ((buf[0]|0x20)=='s')&&((buf[1]|0x20)=='i')&&((buf[2]|0x20)=='p')&&
303
-		     (buf[3]==':') ) ) goto error_bad_uri;
300
+	/*look for sip:, sips: or tel:*/
301
+	if (len<5) goto error_too_short;
302
+	scheme=buf[0]+(buf[1]<<8)+(buf[2]<<16)+(buf[3]<<24);
303
+	scheme|=0x20202020;
304
+	if (scheme==SIP_SCH){
305
+		uri->type=SIP_URI_T;
306
+	}else if(scheme==SIPS_SCH){
307
+		if(buf[4]==':'){ p++; uri->type=SIPS_URI_T;}
308
+		else goto error_bad_uri;
309
+	}else if (scheme==TEL_SCH){
310
+		uri->type=TEL_URI_T;
311
+	}else goto error_bad_uri;
304 312
 	
305 313
 	s=p;
306 314
 	for(;p<end; p++){
307
-		switch(state){
315
+		switch((unsigned char)state){
308 316
 			case URI_INIT:
309 317
 				switch(*p){
310 318
 					case '[':
... ...
@@ -535,13 +568,17 @@ int parse_uri(char* buf, int len, struct sip_uri* uri)
535 535
 						b=p;
536 536
 						state=PLR_L;
537 537
 						break;
538
+					case 'r':
539
+					case 'R':
540
+						b=p;
541
+						state=PR2_R;
538 542
 					default:
539 543
 						state=URI_PARAM_P;
540 544
 				}
541 545
 				break;
542 546
 			case URI_PARAM_P: /* ignore current param */
543 547
 				/* supported params:
544
-				 *  maddr, transport, ttl, lr, user, method  */
548
+				 *  maddr, transport, ttl, lr, user, method, r2  */
545 549
 				switch(*p){
546 550
 					param_common_cases;
547 551
 				};
... ...
@@ -677,6 +714,9 @@ int parse_uri(char* buf, int len, struct sip_uri* uri)
677 677
 					case '@':
678 678
 						still_at_user; 
679 679
 						break;
680
+					case '=':
681
+						state=PLR_eq;
682
+						break;
680 683
 					semicolon_case; 
681 684
 						uri->lr.s=b;
682 685
 						uri->lr.len=(p-b);
... ...
@@ -691,7 +731,52 @@ int parse_uri(char* buf, int len, struct sip_uri* uri)
691 691
 						state=URI_PARAM_P;
692 692
 				}
693 693
 				break;
694
-						
694
+				/* handle lr=something case */
695
+			case PLR_eq:
696
+				param=&uri->lr;
697
+				param_val=&uri->lr_val;
698
+				switch(*p){
699
+					param_common_cases;
700
+					default:
701
+						v=p;
702
+						state=URI_VAL_P;
703
+				}
704
+				break;
705
+			/* r2 */
706
+			param_switch1(PR2_R,  '2', PR2_2_FIN);
707
+			case PR2_2_FIN:
708
+				switch(*p){
709
+					case '@':
710
+						still_at_user; 
711
+						break;
712
+					case '=':
713
+						state=PR2_eq;
714
+						break;
715
+					semicolon_case; 
716
+						uri->r2.s=b;
717
+						uri->r2.len=(p-b);
718
+						break;
719
+					question_case; 
720
+						uri->r2.s=b;
721
+						uri->r2.len=(p-b);
722
+						break;
723
+					colon_case;
724
+						break;
725
+					default:
726
+						state=URI_PARAM_P;
727
+				}
728
+				break;
729
+				/* handle lr=something case */
730
+			case PR2_eq:
731
+				param=&uri->r2;
732
+				param_val=&uri->r2_val;
733
+				switch(*p){
734
+					param_common_cases;
735
+					default:
736
+						v=p;
737
+						state=URI_VAL_P;
738
+				}
739
+				break;
695 740
 				
696 741
 				
697 742
 			case URI_HEADERS:
... ...
@@ -800,16 +885,25 @@ int parse_uri(char* buf, int len, struct sip_uri* uri)
800 800
 		case PM_D:
801 801
 		case PM_eq:
802 802
 		case PLR_L: /* lr */
803
+		case PR2_R:  /* r2 */
803 804
 			uri->params.s=s;
804 805
 			uri->params.len=p-s;
805 806
 			break;
806 807
 		/* fin param states */
807 808
 		case PLR_R_FIN:
809
+		case PLR_eq:
808 810
 			uri->params.s=s;
809 811
 			uri->params.len=p-s;
810 812
 			uri->lr.s=b;
811 813
 			uri->lr.len=p-b;
812 814
 			break;
815
+		case PR2_2_FIN:
816
+		case PR2_eq:
817
+			uri->params.s=s;
818
+			uri->params.len=p-s;
819
+			uri->r2.s=b;
820
+			uri->r2.len=p-b;
821
+			break;
813 822
 		case URI_VAL_P:
814 823
 		/* intermediate value states */
815 824
 		case VU_U:
... ...
@@ -858,74 +952,88 @@ int parse_uri(char* buf, int len, struct sip_uri* uri)
858 858
 		default:
859 859
 			goto error_bug;
860 860
 	}
861
-	
861
+	if (uri->type==TEL_URI_T){
862
+		/* fix tel uris, move the number in uri and empty the host */
863
+		uri->user=uri->host;
864
+		uri->host.s="";
865
+		uri->host.len=0;
866
+	}
867
+#ifdef EXTRA_DEBUG
862 868
 	/* do stuff */
863
-	DBG("parsed uri:\n user=<%.*s>(%d)\n passwd=<%.*s>(%d)\n host=<%.*s>(%d)\n"
864
-			" port=<%.*s>(%d): %d\n params=<%.*s>(%d)\n headers=<%.*s>(%d)\n",
865
-			uri->user.len, uri->user.s, uri->user.len,
866
-			uri->passwd.len, uri->passwd.s, uri->passwd.len,
867
-			uri->host.len, uri->host.s, uri->host.len,
868
-			uri->port.len, uri->port.s, uri->port.len, uri->port_no,
869
-			uri->params.len, uri->params.s, uri->params.len,
870
-			uri->headers.len, uri->headers.s, uri->headers.len
869
+	DBG("parsed uri:\n type=%d user=<%.*s>(%d)\n passwd=<%.*s>(%d)\n"
870
+			" host=<%.*s>(%d)\n port=<%.*s>(%d): %d\n params=<%.*s>(%d)\n"
871
+			" headers=<%.*s>(%d)\n",
872
+			uri->type,
873
+			uri->user.len, ZSW(uri->user.s), uri->user.len,
874
+			uri->passwd.len, ZSW(uri->passwd.s), uri->passwd.len,
875
+			uri->host.len, ZSW(uri->host.s), uri->host.len,
876
+			uri->port.len, ZSW(uri->port.s), uri->port.len, uri->port_no,
877
+			uri->params.len, ZSW(uri->params.s), uri->params.len,
878
+			uri->headers.len, ZSW(uri->headers.s), uri->headers.len
871 879
 		);
872 880
 	DBG(" uri params:\n   transport=<%.*s>, val=<%.*s>, proto=%d\n",
873
-			uri->transport.len, uri->transport.s, uri->transport_val.len,
874
-			uri->transport_val.s, uri->proto);
881
+			uri->transport.len, ZSW(uri->transport.s), uri->transport_val.len,
882
+			ZSW(uri->transport_val.s), uri->proto);
875 883
 	DBG("   user-param=<%.*s>, val=<%.*s>\n",
876
-			uri->user_param.len, uri->user_param.s, uri->user_param_val.len,
877
-			uri->user_param_val.s);
884
+			uri->user_param.len, ZSW(uri->user_param.s), 
885
+			uri->user_param_val.len, ZSW(uri->user_param_val.s));
878 886
 	DBG("   method=<%.*s>, val=<%.*s>\n",
879
-			uri->method.len, uri->method.s, uri->method_val.len,
880
-			uri->method_val.s);
887
+			uri->method.len, ZSW(uri->method.s), 
888
+			uri->method_val.len, ZSW(uri->method_val.s));
881 889
 	DBG("   ttl=<%.*s>, val=<%.*s>\n",
882
-			uri->ttl.len, uri->ttl.s, uri->ttl_val.len,
883
-			uri->ttl_val.s);
890
+			uri->ttl.len, ZSW(uri->ttl.s), 
891
+			uri->ttl_val.len, ZSW(uri->ttl_val.s));
884 892
 	DBG("   maddr=<%.*s>, val=<%.*s>\n",
885
-			uri->maddr.len, uri->maddr.s, uri->maddr_val.len,
886
-			uri->maddr_val.s);
887
-	DBG("   lr=<%.*s>\n", uri->lr.len, uri->lr.s); 
893
+			uri->maddr.len, ZSW(uri->maddr.s), 
894
+			uri->maddr_val.len, ZSW(uri->maddr_val.s));
895
+	DBG("   lr=<%.*s>\n", uri->lr.len, ZSW(uri->lr.s)); 
896
+#endif
888 897
 	return 0;
889 898
 	
890 899
 error_too_short:
891 900
 	LOG(L_ERR, "ERROR: parse_uri: uri too short: <%.*s> (%d)\n",
892
-			len, buf, len);
893
-	return -1;
901
+			len, ZSW(buf), len);
902
+	ser_error=E_BAD_URI;
903
+	return E_BAD_URI;
894 904
 error_bad_char:
895 905
 	LOG(L_ERR, "ERROR: parse_uri: bad char '%c' in state %d"
896 906
 			" parsed: <%.*s> (%d) / <%.*s> (%d)\n",
897
-			*p, state, (p-buf), buf, (p-buf), len, buf, len);
898
-	return -1;
907
+			*p, state, (int)(p-buf), ZSW(buf), (int)(p-buf), len, ZSW(buf), len);
908
+	return E_BAD_URI;
899 909
 error_bad_host:
900 910
 	LOG(L_ERR, "ERROR: parse_uri: bad host in uri (error at char %c in"
901 911
 			" state %d) parsed: <%.*s>(%d) /<%.*s> (%d)\n",
902
-			*p, state, (p-buf), buf, (p-buf), len, buf, len);
903
-	return -1;
912
+			*p, state, (int)(p-buf), ZSW(buf), (int)(p-buf), len, ZSW(buf), len);
913
+	ser_error=E_BAD_URI;
914
+	return E_BAD_URI;
904 915
 error_bad_port:
905 916
 	LOG(L_ERR, "ERROR: parse_uri: bad port in uri (error at char %c in"
906 917
 			" state %d) parsed: <%.*s>(%d) /<%.*s> (%d)\n",
907
-			*p, state, (p-buf), buf, (p-buf), len, buf, len);
908
-	return -1;
918
+			*p, state, (int)(p-buf), ZSW(buf), (int)(p-buf), len, ZSW(buf), len);
919
+	ser_error=E_BAD_URI;
920
+	return E_BAD_URI;
909 921
 error_bad_uri:
910 922
 	LOG(L_ERR, "ERROR: parse_uri: bad uri,  state %d"
911 923
 			" parsed: <%.*s> (%d) / <%.*s> (%d)\n",
912
-			 state, (p-buf), buf, (p-buf), len, buf, len);
913
-	return -1;
924
+			 state, (int)(p-buf), ZSW(buf), (int)(p-buf), len, ZSW(buf), len);
925
+	ser_error=E_BAD_URI;
926
+	return E_BAD_URI;
914 927
 error_headers:
915 928
 	LOG(L_ERR, "ERROR: parse_uri: bad uri headers: <%.*s>(%d)"
916 929
 			" / <%.*s>(%d)\n",
917
-			uri->headers.len, uri->headers.s, uri->headers.len,
918
-			len, buf, len);
919
-	return -1;
930
+			uri->headers.len, ZSW(uri->headers.s), uri->headers.len,
931
+			len, ZSW(buf), len);
932
+	ser_error=E_BAD_URI;
933
+	return E_BAD_URI;
920 934
 error_bug:
921 935
 	LOG(L_CRIT, "BUG: parse_uri: bad  state %d"
922 936
 			" parsed: <%.*s> (%d) / <%.*s> (%d)\n",
923
-			 state, (p-buf), buf, (p-buf), len, buf, len);
924
-	return -1;
937
+			 state, (int)(p-buf), ZSW(buf), (int)(p-buf), len, ZSW(buf), len);
938
+	ser_error=E_BAD_URI;
939
+	return E_BAD_URI;
925 940
 }
926 941
 
927 942
 
928
-
929 943
 int main (int argc, char** argv)
930 944
 {
931 945