2
0
Эх сурвалжийг харах

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 18 жил өмнө
parent
commit
9b1ad3737c

+ 9 - 3
parser/msg_parser.h

@@ -143,6 +143,11 @@ struct sip_uri {
 
 enum _uri_type{ERROR_URI_T=0, SIP_URI_T, SIPS_URI_T, TEL_URI_T, TELS_URI_T};
 typedef enum _uri_type uri_type;
+enum _uri_flags{
+	URI_USER_NORMALIZE=1,
+	URI_SIP_USER_PHONE=2
+}; /* bit fields */
+typedef enum _uri_flags uri_flags;
 
 struct sip_uri {
 	str user;     /* Username */
@@ -154,9 +159,7 @@ struct sip_uri {
 	unsigned short port_no;
 	unsigned short proto; /* from transport */
 	uri_type type; /* uri scheme */
-#ifdef USE_COMP
-	unsigned short comp;
-#endif
+	uri_flags flags;
 	/* parameters */
 	str transport;
 	str ttl;
@@ -173,6 +176,9 @@ struct sip_uri {
 	str method_val;
 	str lr_val; /* lr value placeholder for lr=on a.s.o*/
 	str r2_val;
+#ifdef USE_COMP
+	unsigned short comp;
+#endif
 };
 
 

+ 76 - 16
parser/parse_uri.c

@@ -113,7 +113,9 @@ int parse_uri(char* buf, int len, struct sip_uri* uri)
 	int found_user;
 	int error_headers;
 	unsigned int scheme;
-	uri_type backup;
+	uri_type backup_urit;
+	uri_flags backup_urif;
+
 #ifdef USE_COMP
 	str comp_str; /* not returned for now */
 	str comp_val; /* not returned for now */
@@ -139,11 +141,13 @@ int parse_uri(char* buf, int len, struct sip_uri* uri)
 								user.len=p-user.s; \
 							}\
 							/* save the uri type/scheme */ \
-							backup=uri->type; \
+							backup_urit=uri->type; \
+							backup_urif=uri->flags; \
 							/* everything else is 0 */ \
 							memset(uri, 0, sizeof(struct sip_uri)); \
-							/* restore the scheme, copy user & pass */ \
-							uri->type=backup; \
+							/* restore the scheme & flags, copy user & pass */ \
+							uri->type=backup_urit; \
+							uri->flags=backup_urif; \
 							uri->user=user; \
 							if (pass)	uri->passwd=password;  \
 							s=p+1; \
@@ -435,6 +439,15 @@ int parse_uri(char* buf, int len, struct sip_uri* uri)
 						s=p+1;
 						break;
 						/* almost anything permitted in the user part */
+					case '.':
+					case '-':
+					case '(':
+					case ')':
+						/* tel uri visual separators, set flag meaning, that
+						 * user should be normalized before usage
+						 */
+						uri->flags|=URI_USER_NORMALIZE;
+						break;
 					case '[':
 					case ']': /* the user part cannot contain "[]" */
 						goto error_bad_char;
@@ -1083,29 +1096,28 @@ int parse_uri(char* buf, int len, struct sip_uri* uri)
 			goto error_bug;
 	}
 	switch(uri->type){
+		case SIPS_URI_T:
 		case SIP_URI_T:
 			if ((uri->user_param_val.len == 5) &&
 				(strncmp(uri->user_param_val.s, "phone", 5) == 0)) {
 				uri->type = TEL_URI_T;
+				uri->flags |= URI_SIP_USER_PHONE;
 				/* move params from user into uri->params */
 				p=q_memchr(uri->user.s, ';', uri->user.len);
 				if (p){
+					/* NOTE: 
+					 * specialized uri params (user, maddr, etc.) still hold
+					 * the values from the sip-uri envelope
+					 * while uri->params point to the params in the embedded tel uri
+					 */
 					uri->params.s=p+1;
 					uri->params.len=uri->user.s+uri->user.len-uri->params.s;
 					uri->user.len=p-uri->user.s;
+				} else {
+					uri->params.len=0;
 				}
-			}
-			break;
-		case SIPS_URI_T:
-			if ((uri->user_param_val.len == 5) &&
-				(strncmp(uri->user_param_val.s, "phone", 5) == 0)) {
-				uri->type = TELS_URI_T;
-				p=q_memchr(uri->user.s, ';', uri->user.len);
-				if (p){
-					uri->params.s=p+1;
-					uri->params.len=uri->user.s+uri->user.len-uri->params.s;
-					uri->user.len=p-uri->user.s;
-				}
+			} else {
+				uri->flags&=~URI_USER_NORMALIZE;
 			}
 			break;
 		case TEL_URI_T:
@@ -1133,6 +1145,10 @@ int parse_uri(char* buf, int len, struct sip_uri* uri)
 			uri->params.len, ZSW(uri->params.s), uri->params.len,
 			uri->headers.len, ZSW(uri->headers.s), uri->headers.len
 		);
+	DBG(" uri flags : ");
+		if (uri->flags & URI_USER_NORMALIZE) DBG("user_need_norm ");
+		if (uri->flags & URI_SIP_USER_PHONE) DBG("sip_user_phone ");
+		DBG("   value=%d\n",uri->flags);
 	DBG(" uri params:\n   transport=<%.*s>, val=<%.*s>, proto=%d\n",
 			uri->transport.len, ZSW(uri->transport.s), uri->transport_val.len,
 			ZSW(uri->transport_val.s), uri->proto);
@@ -1390,3 +1406,47 @@ int parse_orig_ruri(struct sip_msg* msg)
 	if (ret<0) LOG(L_ERR, "ERROR: parse_orig_ruri failed\n");
 	return ret;
 }
+
+inline int normalize_tel_user(char* res, str* src) {
+	int i, l;
+	l=0;
+	for (i=0; i<src->len; i++) {
+		switch (src->s[i]) {
+			case '-':
+			case '.':
+			case '(':
+			case ')':
+				break;
+			default:
+				res[l++]=src->s[i];
+		}
+	}  
+	return l;
+}
+
+
+static str	s_sip  = STR_STATIC_INIT("sip");
+static str	s_sips = STR_STATIC_INIT("sips");
+static str	s_tel  = STR_STATIC_INIT("tel");
+static str	s_tels = STR_STATIC_INIT("tels");
+static str	s_null = STR_STATIC_INIT("");
+
+inline void uri_type_to_str(uri_type type, str *s) {
+	switch (type) {
+	case SIP_URI_T:
+		*s = s_sip;
+		break;
+	case SIPS_URI_T:
+		*s = s_sips;
+		break;
+	case TEL_URI_T:
+		*s = s_tel;
+		break;
+	case TELS_URI_T:
+		*s = s_tels;
+		break;
+	default:
+		*s = s_null;
+	}
+}
+

+ 2 - 0
parser/parse_uri.h

@@ -46,5 +46,7 @@
 int parse_uri(char *buf, int len, struct sip_uri* uri);
 int parse_sip_msg_uri(struct sip_msg* msg);
 int parse_orig_ruri(struct sip_msg* msg);
+int normalize_tel_user(char* res, str* src);
+void uri_type_to_str(uri_type type, str *s);
 
 #endif /* PARSE_URI_H */

+ 1 - 1
select_buf.h

@@ -54,6 +54,6 @@ int reset_static_buffer();
 int str_to_static_buffer(str* res, str* s);
 int int_to_static_buffer(str* res, int val);
 int uint_to_static_buffer(str* res, unsigned int val);
-int uint_ex_to_static_buffer(str* res, unsigned int val, int base, int pad);
+int uint_to_static_buffer_ex(str* res, unsigned int val, int base, int pad);
 
 #endif /* SELECT_BUFFER_H */

+ 10 - 11
select_core.c

@@ -599,18 +599,10 @@ int select_uri_type(str* res, select_t* s, struct sip_msg* msg)
 	if (parse_uri(res->s, res->len, &uri)<0)
 		return -1;
 
-	switch (uri.type) {
-	case SIPS_URI_T:
-	case TELS_URI_T:
-		res->len=4;
-		break;
-	case SIP_URI_T:
-	case TEL_URI_T:
-		res->len=3;
-		break;
-	case ERROR_URI_T:
+	if (uri.type==ERROR_URI_T)
 		return -1;
-	}
+
+	uri_type_to_str(uri.type, res);
 	return 0;
 }
 
@@ -619,6 +611,13 @@ int select_uri_user(str* res, select_t* s, struct sip_msg* msg)
 	if (parse_uri(res->s, res->len, &uri)<0)
 		return -1;
 
+	if (uri.flags & URI_USER_NORMALIZE) {
+		if (!(res->s=get_static_buffer(uri.user.len)))
+			return -1;
+		if ((res->len=normalize_tel_user(res->s, (&uri.user)))==0)
+			return 1;
+		return 0;
+	}
 	RETURN0_res(uri.user);
 }