Browse code

Tel uri and sip;user=phone uri polishing. Checks username for visual separators, fix handle params for user=phone. Select @{...}.uri.user returns normalized username, module writer needs check the uri->flag.

Michal Matyska authored on 01/03/2007 12:30:27
Showing 5 changed files
... ...
@@ -143,6 +143,11 @@ struct sip_uri {
143 143
 
144 144
 enum _uri_type{ERROR_URI_T=0, SIP_URI_T, SIPS_URI_T, TEL_URI_T, TELS_URI_T};
145 145
 typedef enum _uri_type uri_type;
146
+enum _uri_flags{
147
+	URI_USER_NORMALIZE=1,
148
+	URI_SIP_USER_PHONE=2
149
+}; /* bit fields */
150
+typedef enum _uri_flags uri_flags;
146 151
 
147 152
 struct sip_uri {
148 153
 	str user;     /* Username */
... ...
@@ -154,9 +159,7 @@ struct sip_uri {
154 154
 	unsigned short port_no;
155 155
 	unsigned short proto; /* from transport */
156 156
 	uri_type type; /* uri scheme */
157
-#ifdef USE_COMP
158
-	unsigned short comp;
159
-#endif
157
+	uri_flags flags;
160 158
 	/* parameters */
161 159
 	str transport;
162 160
 	str ttl;
... ...
@@ -173,6 +176,9 @@ struct sip_uri {
173 173
 	str method_val;
174 174
 	str lr_val; /* lr value placeholder for lr=on a.s.o*/
175 175
 	str r2_val;
176
+#ifdef USE_COMP
177
+	unsigned short comp;
178
+#endif
176 179
 };
177 180
 
178 181
 
... ...
@@ -113,7 +113,9 @@ int parse_uri(char* buf, int len, struct sip_uri* uri)
113 113
 	int found_user;
114 114
 	int error_headers;
115 115
 	unsigned int scheme;
116
-	uri_type backup;
116
+	uri_type backup_urit;
117
+	uri_flags backup_urif;
118
+
117 119
 #ifdef USE_COMP
118 120
 	str comp_str; /* not returned for now */
119 121
 	str comp_val; /* not returned for now */
... ...
@@ -139,11 +141,13 @@ int parse_uri(char* buf, int len, struct sip_uri* uri)
139 139
 								user.len=p-user.s; \
140 140
 							}\
141 141
 							/* save the uri type/scheme */ \
142
-							backup=uri->type; \
142
+							backup_urit=uri->type; \
143
+							backup_urif=uri->flags; \
143 144
 							/* everything else is 0 */ \
144 145
 							memset(uri, 0, sizeof(struct sip_uri)); \
145
-							/* restore the scheme, copy user & pass */ \
146
-							uri->type=backup; \
146
+							/* restore the scheme & flags, copy user & pass */ \
147
+							uri->type=backup_urit; \
148
+							uri->flags=backup_urif; \
147 149
 							uri->user=user; \
148 150
 							if (pass)	uri->passwd=password;  \
149 151
 							s=p+1; \
... ...
@@ -435,6 +439,15 @@ int parse_uri(char* buf, int len, struct sip_uri* uri)
435 435
 						s=p+1;
436 436
 						break;
437 437
 						/* almost anything permitted in the user part */
438
+					case '.':
439
+					case '-':
440
+					case '(':
441
+					case ')':
442
+						/* tel uri visual separators, set flag meaning, that
443
+						 * user should be normalized before usage
444
+						 */
445
+						uri->flags|=URI_USER_NORMALIZE;
446
+						break;
438 447
 					case '[':
439 448
 					case ']': /* the user part cannot contain "[]" */
440 449
 						goto error_bad_char;
... ...
@@ -1083,29 +1096,28 @@ int parse_uri(char* buf, int len, struct sip_uri* uri)
1083 1083
 			goto error_bug;
1084 1084
 	}
1085 1085
 	switch(uri->type){
1086
+		case SIPS_URI_T:
1086 1087
 		case SIP_URI_T:
1087 1088
 			if ((uri->user_param_val.len == 5) &&
1088 1089
 				(strncmp(uri->user_param_val.s, "phone", 5) == 0)) {
1089 1090
 				uri->type = TEL_URI_T;
1091
+				uri->flags |= URI_SIP_USER_PHONE;
1090 1092
 				/* move params from user into uri->params */
1091 1093
 				p=q_memchr(uri->user.s, ';', uri->user.len);
1092 1094
 				if (p){
1095
+					/* NOTE: 
1096
+					 * specialized uri params (user, maddr, etc.) still hold
1097
+					 * the values from the sip-uri envelope
1098
+					 * while uri->params point to the params in the embedded tel uri
1099
+					 */
1093 1100
 					uri->params.s=p+1;
1094 1101
 					uri->params.len=uri->user.s+uri->user.len-uri->params.s;
1095 1102
 					uri->user.len=p-uri->user.s;
1103
+				} else {
1104
+					uri->params.len=0;
1096 1105
 				}
1097
-			}
1098
-			break;
1099
-		case SIPS_URI_T:
1100
-			if ((uri->user_param_val.len == 5) &&
1101
-				(strncmp(uri->user_param_val.s, "phone", 5) == 0)) {
1102
-				uri->type = TELS_URI_T;
1103
-				p=q_memchr(uri->user.s, ';', uri->user.len);
1104
-				if (p){
1105
-					uri->params.s=p+1;
1106
-					uri->params.len=uri->user.s+uri->user.len-uri->params.s;
1107
-					uri->user.len=p-uri->user.s;
1108
-				}
1106
+			} else {
1107
+				uri->flags&=~URI_USER_NORMALIZE;
1109 1108
 			}
1110 1109
 			break;
1111 1110
 		case TEL_URI_T:
... ...
@@ -1133,6 +1145,10 @@ int parse_uri(char* buf, int len, struct sip_uri* uri)
1133 1133
 			uri->params.len, ZSW(uri->params.s), uri->params.len,
1134 1134
 			uri->headers.len, ZSW(uri->headers.s), uri->headers.len
1135 1135
 		);
1136
+	DBG(" uri flags : ");
1137
+		if (uri->flags & URI_USER_NORMALIZE) DBG("user_need_norm ");
1138
+		if (uri->flags & URI_SIP_USER_PHONE) DBG("sip_user_phone ");
1139
+		DBG("   value=%d\n",uri->flags);
1136 1140
 	DBG(" uri params:\n   transport=<%.*s>, val=<%.*s>, proto=%d\n",
1137 1141
 			uri->transport.len, ZSW(uri->transport.s), uri->transport_val.len,
1138 1142
 			ZSW(uri->transport_val.s), uri->proto);
... ...
@@ -1390,3 +1406,47 @@ int parse_orig_ruri(struct sip_msg* msg)
1390 1390
 	if (ret<0) LOG(L_ERR, "ERROR: parse_orig_ruri failed\n");
1391 1391
 	return ret;
1392 1392
 }
1393
+
1394
+inline int normalize_tel_user(char* res, str* src) {
1395
+	int i, l;
1396
+	l=0;
1397
+	for (i=0; i<src->len; i++) {
1398
+		switch (src->s[i]) {
1399
+			case '-':
1400
+			case '.':
1401
+			case '(':
1402
+			case ')':
1403
+				break;
1404
+			default:
1405
+				res[l++]=src->s[i];
1406
+		}
1407
+	}  
1408
+	return l;
1409
+}
1410
+
1411
+
1412
+static str	s_sip  = STR_STATIC_INIT("sip");
1413
+static str	s_sips = STR_STATIC_INIT("sips");
1414
+static str	s_tel  = STR_STATIC_INIT("tel");
1415
+static str	s_tels = STR_STATIC_INIT("tels");
1416
+static str	s_null = STR_STATIC_INIT("");
1417
+
1418
+inline void uri_type_to_str(uri_type type, str *s) {
1419
+	switch (type) {
1420
+	case SIP_URI_T:
1421
+		*s = s_sip;
1422
+		break;
1423
+	case SIPS_URI_T:
1424
+		*s = s_sips;
1425
+		break;
1426
+	case TEL_URI_T:
1427
+		*s = s_tel;
1428
+		break;
1429
+	case TELS_URI_T:
1430
+		*s = s_tels;
1431
+		break;
1432
+	default:
1433
+		*s = s_null;
1434
+	}
1435
+}
1436
+
... ...
@@ -46,5 +46,7 @@
46 46
 int parse_uri(char *buf, int len, struct sip_uri* uri);
47 47
 int parse_sip_msg_uri(struct sip_msg* msg);
48 48
 int parse_orig_ruri(struct sip_msg* msg);
49
+int normalize_tel_user(char* res, str* src);
50
+void uri_type_to_str(uri_type type, str *s);
49 51
 
50 52
 #endif /* PARSE_URI_H */
... ...
@@ -54,6 +54,6 @@ int reset_static_buffer();
54 54
 int str_to_static_buffer(str* res, str* s);
55 55
 int int_to_static_buffer(str* res, int val);
56 56
 int uint_to_static_buffer(str* res, unsigned int val);
57
-int uint_ex_to_static_buffer(str* res, unsigned int val, int base, int pad);
57
+int uint_to_static_buffer_ex(str* res, unsigned int val, int base, int pad);
58 58
 
59 59
 #endif /* SELECT_BUFFER_H */
... ...
@@ -599,18 +599,10 @@ int select_uri_type(str* res, select_t* s, struct sip_msg* msg)
599 599
 	if (parse_uri(res->s, res->len, &uri)<0)
600 600
 		return -1;
601 601
 
602
-	switch (uri.type) {
603
-	case SIPS_URI_T:
604
-	case TELS_URI_T:
605
-		res->len=4;
606
-		break;
607
-	case SIP_URI_T:
608
-	case TEL_URI_T:
609
-		res->len=3;
610
-		break;
611
-	case ERROR_URI_T:
602
+	if (uri.type==ERROR_URI_T)
612 603
 		return -1;
613
-	}
604
+
605
+	uri_type_to_str(uri.type, res);
614 606
 	return 0;
615 607
 }
616 608
 
... ...
@@ -619,6 +611,13 @@ int select_uri_user(str* res, select_t* s, struct sip_msg* msg)
619 619
 	if (parse_uri(res->s, res->len, &uri)<0)
620 620
 		return -1;
621 621
 
622
+	if (uri.flags & URI_USER_NORMALIZE) {
623
+		if (!(res->s=get_static_buffer(uri.user.len)))
624
+			return -1;
625
+		if ((res->len=normalize_tel_user(res->s, (&uri.user)))==0)
626
+			return 1;
627
+		return 0;
628
+	}
622 629
 	RETURN0_res(uri.user);
623 630
 }
624 631