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 159
 	unsigned short port_no;
155 160
 	unsigned short proto; /* from transport */
156 161
 	uri_type type; /* uri scheme */
157
-#ifdef USE_COMP
158
-	unsigned short comp;
159
-#endif
162
+	uri_flags flags;
160 163
 	/* parameters */
161 164
 	str transport;
162 165
 	str ttl;
... ...
@@ -173,6 +176,9 @@ struct sip_uri {
173 176
 	str method_val;
174 177
 	str lr_val; /* lr value placeholder for lr=on a.s.o*/
175 178
 	str r2_val;
179
+#ifdef USE_COMP
180
+	unsigned short comp;
181
+#endif
176 182
 };
177 183
 
178 184
 
... ...
@@ -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 141
 								user.len=p-user.s; \
140 142
 							}\
141 143
 							/* save the uri type/scheme */ \
142
-							backup=uri->type; \
144
+							backup_urit=uri->type; \
145
+							backup_urif=uri->flags; \
143 146
 							/* everything else is 0 */ \
144 147
 							memset(uri, 0, sizeof(struct sip_uri)); \
145
-							/* restore the scheme, copy user & pass */ \
146
-							uri->type=backup; \
148
+							/* restore the scheme & flags, copy user & pass */ \
149
+							uri->type=backup_urit; \
150
+							uri->flags=backup_urif; \
147 151
 							uri->user=user; \
148 152
 							if (pass)	uri->passwd=password;  \
149 153
 							s=p+1; \
... ...
@@ -435,6 +439,15 @@ int parse_uri(char* buf, int len, struct sip_uri* uri)
435 439
 						s=p+1;
436 440
 						break;
437 441
 						/* almost anything permitted in the user part */
442
+					case '.':
443
+					case '-':
444
+					case '(':
445
+					case ')':
446
+						/* tel uri visual separators, set flag meaning, that
447
+						 * user should be normalized before usage
448
+						 */
449
+						uri->flags|=URI_USER_NORMALIZE;
450
+						break;
438 451
 					case '[':
439 452
 					case ']': /* the user part cannot contain "[]" */
440 453
 						goto error_bad_char;
... ...
@@ -1083,29 +1096,28 @@ int parse_uri(char* buf, int len, struct sip_uri* uri)
1083 1096
 			goto error_bug;
1084 1097
 	}
1085 1098
 	switch(uri->type){
1099
+		case SIPS_URI_T:
1086 1100
 		case SIP_URI_T:
1087 1101
 			if ((uri->user_param_val.len == 5) &&
1088 1102
 				(strncmp(uri->user_param_val.s, "phone", 5) == 0)) {
1089 1103
 				uri->type = TEL_URI_T;
1104
+				uri->flags |= URI_SIP_USER_PHONE;
1090 1105
 				/* move params from user into uri->params */
1091 1106
 				p=q_memchr(uri->user.s, ';', uri->user.len);
1092 1107
 				if (p){
1108
+					/* NOTE: 
1109
+					 * specialized uri params (user, maddr, etc.) still hold
1110
+					 * the values from the sip-uri envelope
1111
+					 * while uri->params point to the params in the embedded tel uri
1112
+					 */
1093 1113
 					uri->params.s=p+1;
1094 1114
 					uri->params.len=uri->user.s+uri->user.len-uri->params.s;
1095 1115
 					uri->user.len=p-uri->user.s;
1116
+				} else {
1117
+					uri->params.len=0;
1096 1118
 				}
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
-				}
1119
+			} else {
1120
+				uri->flags&=~URI_USER_NORMALIZE;
1109 1121
 			}
1110 1122
 			break;
1111 1123
 		case TEL_URI_T:
... ...
@@ -1133,6 +1145,10 @@ int parse_uri(char* buf, int len, struct sip_uri* uri)
1133 1145
 			uri->params.len, ZSW(uri->params.s), uri->params.len,
1134 1146
 			uri->headers.len, ZSW(uri->headers.s), uri->headers.len
1135 1147
 		);
1148
+	DBG(" uri flags : ");
1149
+		if (uri->flags & URI_USER_NORMALIZE) DBG("user_need_norm ");
1150
+		if (uri->flags & URI_SIP_USER_PHONE) DBG("sip_user_phone ");
1151
+		DBG("   value=%d\n",uri->flags);
1136 1152
 	DBG(" uri params:\n   transport=<%.*s>, val=<%.*s>, proto=%d\n",
1137 1153
 			uri->transport.len, ZSW(uri->transport.s), uri->transport_val.len,
1138 1154
 			ZSW(uri->transport_val.s), uri->proto);
... ...
@@ -1390,3 +1406,47 @@ int parse_orig_ruri(struct sip_msg* msg)
1390 1406
 	if (ret<0) LOG(L_ERR, "ERROR: parse_orig_ruri failed\n");
1391 1407
 	return ret;
1392 1408
 }
1409
+
1410
+inline int normalize_tel_user(char* res, str* src) {
1411
+	int i, l;
1412
+	l=0;
1413
+	for (i=0; i<src->len; i++) {
1414
+		switch (src->s[i]) {
1415
+			case '-':
1416
+			case '.':
1417
+			case '(':
1418
+			case ')':
1419
+				break;
1420
+			default:
1421
+				res[l++]=src->s[i];
1422
+		}
1423
+	}  
1424
+	return l;
1425
+}
1426
+
1427
+
1428
+static str	s_sip  = STR_STATIC_INIT("sip");
1429
+static str	s_sips = STR_STATIC_INIT("sips");
1430
+static str	s_tel  = STR_STATIC_INIT("tel");
1431
+static str	s_tels = STR_STATIC_INIT("tels");
1432
+static str	s_null = STR_STATIC_INIT("");
1433
+
1434
+inline void uri_type_to_str(uri_type type, str *s) {
1435
+	switch (type) {
1436
+	case SIP_URI_T:
1437
+		*s = s_sip;
1438
+		break;
1439
+	case SIPS_URI_T:
1440
+		*s = s_sips;
1441
+		break;
1442
+	case TEL_URI_T:
1443
+		*s = s_tel;
1444
+		break;
1445
+	case TELS_URI_T:
1446
+		*s = s_tels;
1447
+		break;
1448
+	default:
1449
+		*s = s_null;
1450
+	}
1451
+}
1452
+
... ...
@@ -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 611
 	if (parse_uri(res->s, res->len, &uri)<0)
620 612
 		return -1;
621 613
 
614
+	if (uri.flags & URI_USER_NORMALIZE) {
615
+		if (!(res->s=get_static_buffer(uri.user.len)))
616
+			return -1;
617
+		if ((res->len=normalize_tel_user(res->s, (&uri.user)))==0)
618
+			return 1;
619
+		return 0;
620
+	}
622 621
 	RETURN0_res(uri.user);
623 622
 }
624 623