[asterisk-commits] oej: branch oej/uriparsing r40384 - in /team/oej/uriparsing: ./ channels/

asterisk-commits at lists.digium.com asterisk-commits at lists.digium.com
Fri Aug 18 07:53:06 MST 2006


Author: oej
Date: Fri Aug 18 09:53:06 2006
New Revision: 40384

URL: http://svn.digium.com/view/asterisk?rev=40384&view=rev
Log:
Reset automerge

Modified:
    team/oej/uriparsing/   (props changed)
    team/oej/uriparsing/channels/chan_sip.c

Propchange: team/oej/uriparsing/
------------------------------------------------------------------------------
    automerge = http://edvina.net/training/

Modified: team/oej/uriparsing/channels/chan_sip.c
URL: http://svn.digium.com/view/asterisk/team/oej/uriparsing/channels/chan_sip.c?rev=40384&r1=40383&r2=40384&view=diff
==============================================================================
--- team/oej/uriparsing/channels/chan_sip.c (original)
+++ team/oej/uriparsing/channels/chan_sip.c Fri Aug 18 09:53:06 2006
@@ -604,6 +604,17 @@
 	struct ast_channel *chan2;	/*!< Second channel involved */
 	struct sip_request req;		/*!< Request that caused the transfer (REFER) */
 	int seqno;			/*!< Sequence number */
+};
+
+/*! \brief structure for URI parsing */
+struct sipuri {
+	char uri[AST_MAX_EXTENSION];		/*!< Full URI */
+	char username[AST_MAX_EXTENSION];	/*!< Username part only */
+	char domain[AST_MAX_EXTENSION];		/*!< Domain name */
+	char displayname[AST_MAX_EXTENSION];	/*!< Display name (caller id name)  */
+	char cleancallerid[AST_MAX_EXTENSION];	/*!< cleaned up username (caller ID) */
+	int portno;				/*!< Port no */
+	char method[10];			/*!< sip, sips etc */
 };
 
 struct sip_pkt;
@@ -1405,12 +1416,12 @@
 static const char *get_header(const struct sip_request *req, const char *name);
 static int lws2sws(char *msgbuf, int len);
 static void extract_uri(struct sip_pvt *p, struct sip_request *req);
+static char *get_calleridname(const char *input, char *output, size_t outputsize);
 static int get_refer_info(struct sip_pvt *transferer, struct sip_request *outgoing_req);
 static int get_also_info(struct sip_pvt *p, struct sip_request *oreq);
 static int parse_ok_contact(struct sip_pvt *pvt, struct sip_request *req);
 static int set_address_from_contact(struct sip_pvt *pvt);
 static void check_via(struct sip_pvt *p, struct sip_request *req);
-static char *get_calleridname(const char *input, char *output, size_t outputsize);
 static int get_rpid_num(const char *input, char *output, int maxlen);
 static int get_rdnis(struct sip_pvt *p, struct sip_request *oreq);
 static int get_destination(struct sip_pvt *p, struct sip_request *oreq);
@@ -1525,6 +1536,75 @@
 	get_codec: sip_get_codec,
 };
 
+
+/*! \brief Parse uri into different parts 
+	\param headerdata From or To header like
+		- Carl Sparks <carl.sparks at mydomain.com:5034>
+		- Kevin Smith <484848333 at mydomain.com>
+	\param uri Output splitted data 
+	\return 1 if not a SIP uri, otherwise 0
+*/
+static int parseuri(const char *headerdata, struct sipuri *uri)
+{
+	char *tmp, *tmp2;
+	char buf[AST_MAX_EXTENSION];
+	int res = 0;
+
+	if (pedanticsipchecking)
+		ast_uri_decode(headerdata);
+
+	/* Get display name */
+	ast_copy_string(buf, headerdata, sizeof(buf));
+	get_calleridname(buf, uri->displayname, sizeof(uri->displayname));
+
+	/* Get the uri in < and > */
+	tmp = get_in_brackets(headerdata);
+	
+	/* Find method */
+	if (!strncmp(tmp, "sip:", 4)) {
+		tmp += 4;
+	} else {
+		res = 1;	/* Not a SIP URI */
+	}
+
+	/* Remove URI options for now */
+	if ((tmp2 = strchr(tmp2, ';')))
+		*tmp2 = '\0';
+	
+	/* Get the username */
+	tmp2 = strchr(tmp, '@');
+	if (!tmp2) {
+		uri->username[0] = '\0';
+		tmp2 = tmp;
+	} else {
+		*tmp2 = '\0';	/* Cut off domain */
+		tmp2++;
+	}
+	ast_copy_string(uri->username, tmp, sizeof(uri->username));
+
+	/* Get the domain */
+	tmp = strchr(tmp2, ':');
+	if (tmp) {
+		*tmp = '\0';	/* Cut off port */
+		tmp++;
+	}
+	ast_copy_string(uri->domain, tmp2, sizeof(uri->domain));
+
+	/* Get the port */
+	uri->portno = atoi (tmp);
+
+	/* Fix a caller id from the username part if needed*/
+	if (!ast_strlen_zero(uri->username)) {
+		tmp = ast_strdupa(uri->username);
+		if (ast_is_shrinkable_phonenumber(tmp))
+			ast_shrink_phone_number(tmp);
+		ast_copy_string(uri->cleancallerid, tmp, sizeof(uri->cleancallerid));
+	} else
+		uri->cleancallerid[0] = '\0';
+
+	return res;
+}
+
 /*! \brief Interface structure with callbacks used to connect to UDPTL module*/
 static struct ast_udptl_protocol sip_udptl = {
 	type: "SIP",
@@ -1537,7 +1617,6 @@
 {
 	int i = (sizeof(referstatusstrings) / sizeof(referstatusstrings[0]));
 	int x;
-
 	for (x = 0; x < i; x++) {
 		if (referstatusstrings[x].status ==  rstatus)
 			return (char *) referstatusstrings[x].text;
@@ -7846,47 +7925,24 @@
 	struct sip_peer *peer;
 	char tmp[256];
 	char iabuf[INET_ADDRSTRLEN];
-	char *name, *c;
 	char *t;
-	char *domain;
-
-	/* Terminate URI */
-	t = uri;
-	while(*t && (*t > 32) && (*t != ';'))
-		t++;
-	*t = '\0';
+	struct sipuri topeer;
+
+	/* Parse parts from To: header into structure */
+	parseuri(get_header(req, "To"), &topeer);
 	
-	ast_copy_string(tmp, get_header(req, "To"), sizeof(tmp));
-	if (pedanticsipchecking)
-		ast_uri_decode(tmp);
-
-	c = get_in_brackets(tmp);
-	c = strsep(&c, ";");	/* Ditch ;user=phone */
-
-	if (!strncmp(c, "sip:", 4)) {
-		name = c + 4;
-	} else {
-		name = c;
-		ast_log(LOG_NOTICE, "Invalid to address: '%s' from %s (missing sip:) trying to use anyway...\n", c, ast_inet_ntoa(iabuf, sizeof(iabuf), sin->sin_addr));
-	}
-
-	/* Strip off the domain name */
-	if ((c = strchr(name, '@'))) {
-		*c++ = '\0';
-		domain = c;
-		if ((c = strchr(domain, ':')))	/* Remove :port */
-			*c = '\0';
-		if (!AST_LIST_EMPTY(&domain_list)) {
-			if (!check_sip_domain(domain, NULL, 0)) {
-				transmit_response(p, "404 Not found (unknown domain)", &p->initreq);
-				return AUTH_UNKNOWN_DOMAIN;
-			}
-		}
-	}
-
-	ast_string_field_set(p, exten, name);
+	if (!AST_LIST_EMPTY(&domain_list)) {
+		if (!check_sip_domain(topeer.domain, NULL, 0)) {
+			transmit_response(p, "404 Not found (unknown domain)", &p->initreq);
+			return AUTH_UNKNOWN_DOMAIN;
+		}
+	}
+
+	ast_string_field_set(p, exten, topeer.username);
 	build_contact(p);
-	peer = find_peer(name, NULL, 1);
+
+	/* Find the peer */
+	peer = find_peer(topeer.username, NULL, 1);
 	if (!(peer && ast_apply_ha(peer->ha, sin))) {
 		if (peer)
 			ASTOBJ_UNREF(peer, sip_destroy_peer);
@@ -7928,7 +7984,7 @@
 	}
 	if (!peer && autocreatepeer) {
 		/* Create peer if we have autocreate mode enabled */
-		peer = temp_peer(name);
+		peer = temp_peer(topeer.username);
 		if (peer) {
 			ASTOBJ_CONTAINER_LINK(&peerl, peer);
 			sip_cancel_destroy(p);
@@ -8040,9 +8096,10 @@
 static int get_destination(struct sip_pvt *p, struct sip_request *oreq)
 {
 	char tmp[256] = "", *uri, *a;
-	char tmpf[256] = "", *from;
+	char tmpf[256] = "";
 	struct sip_request *req;
 	char *colon;
+	struct sipuri fromuri, requesturi;
 	
 	req = oreq;
 	if (!req)
@@ -8058,53 +8115,20 @@
 	uri = get_in_brackets(tmp);
 
 	if (strncmp(uri, "sip:", 4)) {
-		ast_log(LOG_WARNING, "Huh?  Not a SIP header (%s)?\n", uri);
+		ast_log(LOG_WARNING, "Huh?  Not a SIP uri (%s)?\n", uri);
 		return -1;
 	}
-	uri += 4;
-
-	/* Now find the From: caller ID and name */
-	ast_copy_string(tmpf, get_header(req, "From"), sizeof(tmpf));
-	if (!ast_strlen_zero(tmpf)) {
-		if (pedanticsipchecking)
-			ast_uri_decode(tmpf);
-		from = get_in_brackets(tmpf);
-	} else {
-		from = NULL;
-	}
-	
-	if (!ast_strlen_zero(from)) {
-		if (strncmp(from, "sip:", 4)) {
-			ast_log(LOG_WARNING, "Huh?  Not a SIP header (%s)?\n", from);
-			return -1;
-		}
-		from += 4;
-		if ((a = strchr(from, '@')))
-			*a++ = '\0';
-		else
-			a = from;	/* just a domain */
-		from = strsep(&from, ";");	/* Remove userinfo options */
-		a = strsep(&a, ";");		/* Remove URI options */
-		ast_string_field_set(p, fromdomain, a);
-	}
-
-	/* Skip any options and find the domain */
-
-	/* Get the target domain */
-	if ((a = strchr(uri, '@'))) {
-		*a++ = '\0';
-	} else {	/* No username part */
-		a = uri;
-		uri = "s";	/* Set extension to "s" */
-	}
-	colon = strchr(a, ':'); /* Remove :port */
-	if (colon)
-		*colon = '\0';
-
-	uri = strsep(&uri, ";");	/* Remove userinfo options */
-	a = strsep(&a, ";");		/* Remove URI options */
-
-	ast_string_field_set(p, domain, a);
+
+	if(parseuri(uri, &requesturi)) {
+		ast_log(LOG_WARNING, "Huh?  Not a SIP uri in request? (%s)\n", uri);
+		return -1;
+	}
+	if (parseuri(get_header(req, "From"), &fromuri)) {
+		ast_log(LOG_WARNING, "Huh?  Not a SIP uri in From?\n");
+		return -1;
+	}
+
+	ast_string_field_set(p, domain, requesturi.domain);
 
 	if (!AST_LIST_EMPTY(&domain_list)) {
 		char domain_context[AST_MAX_EXTENSION];
@@ -8121,23 +8145,27 @@
 			ast_string_field_set(p, context, domain_context);
 	}
 
+	if (!ast_strlen_zero(fromuri.domain)) {
+		ast_string_field_set(p, fromdomain, fromuri.domain);
+	}
+
 	if (sip_debug_test_pvt(p))
 		ast_verbose("Looking for %s in %s (domain %s)\n", uri, p->context, p->domain);
 
 	/* Check the dialplan for the username part of the request URI,
 	   the domain will be stored in the SIPDOMAIN variable
 		Return 0 if we have a matching extension */
-	if (ast_exists_extension(NULL, p->context, uri, 1, from) ||
-		!strcmp(uri, ast_pickup_ext())) {
+	if (ast_exists_extension(NULL, p->context, requesturi.username, 1, fromuri.username) ||
+		!strcmp(requesturi.username, ast_pickup_ext())) {
 		if (!oreq)
-			ast_string_field_set(p, exten, uri);
+			ast_string_field_set(p, exten, requesturi.username);
 		return 0;
 	}
 
 	/* Return 1 for pickup extension or overlap dialling support (if we support it) */
 	if((ast_test_flag(&global_flags[1], SIP_PAGE2_ALLOWOVERLAP) && 
- 	    ast_canmatch_extension(NULL, p->context, uri, 1, from)) ||
-	    !strncmp(uri, ast_pickup_ext(), strlen(uri))) {
+ 	    ast_canmatch_extension(NULL, p->context, requesturi.username, 1, fromuri.username)) ||
+	    !strcmp(requesturi.username, ast_pickup_ext(), strlen(requesturi.username))) {
 		return 1;
 	}
 	
@@ -8544,38 +8572,35 @@
 {
 	struct sip_user *user = NULL;
 	struct sip_peer *peer;
-	char from[256], *c;
-	char *of;
+	char *of, *c;
+	const char *rpid;
 	char rpid_num[50];
-	const char *rpid;
 	char iabuf[INET_ADDRSTRLEN];
 	enum check_auth_result res = AUTH_SUCCESSFUL;
 	char *t;
-	char calleridname[50];
 	int debug=sip_debug_test_addr(sin);
 	struct ast_variable *tmpvar = NULL, *v = NULL;
 	int usenatroute;
+	struct sipuri from;
 
 	/* Terminate URI */
 	t = uri;
 	while (*t && *t > 32 && *t != ';')
 		t++;
 	*t = '\0';
-	ast_copy_string(from, get_header(req, "From"), sizeof(from));	/* XXX bug in original code, overwrote string */
-	if (pedanticsipchecking)
-		ast_uri_decode(from);
-	/* XXX here tries to map the username for invite things */
-	memset(calleridname, 0, sizeof(calleridname));
-	get_calleridname(from, calleridname, sizeof(calleridname));
-	if (calleridname[0])
-		ast_string_field_set(p, cid_name, calleridname);
+
+	parseuri(get_header(req, "From"), &from);
+	
+	if (from.cleancallerid[0])
+		ast_string_field_set(p, cid_num, from.cleancallerid);
+	if (from.displayname[0])
+		ast_string_field_set(p, cid_name, from.displayname);
 
 	rpid = get_header(req, "Remote-Party-ID");
 	memset(rpid_num, 0, sizeof(rpid_num));
 	if (!ast_strlen_zero(rpid)) 
 		p->callingpres = get_rpid_num(rpid, rpid_num, sizeof(rpid_num));
 
-	of = get_in_brackets(from);
 	if (ast_strlen_zero(p->exten)) {
 		t = uri;
 		if (!strncmp(t, "sip:", 4))
@@ -8587,33 +8612,18 @@
 		if (ast_strlen_zero(p->our_contact))
 			build_contact(p);
 	}
-	/* save the URI part of the From header */
-	ast_string_field_set(p, from, of);
-	if (strncmp(of, "sip:", 4)) {
-		ast_log(LOG_NOTICE, "From address missing 'sip:', using it anyway\n");
-	} else
-		of += 4;
-	/* Get just the username part */
-	if ((c = strchr(of, '@'))) {
-		char *tmp;
-		*c = '\0';
-		if ((c = strchr(of, ':')))
-			*c = '\0';
-		tmp = ast_strdupa(of);
-		if (ast_is_shrinkable_phonenumber(tmp))
-			ast_shrink_phone_number(tmp);
-		ast_string_field_set(p, cid_num, tmp);
-	}
-	if (ast_strlen_zero(of))
+
+	if (ast_strlen_zero(from.username))	/* No username, nothing to auth */
 		return AUTH_SUCCESSFUL;
 
 	if (!authpeer)	/* If we are looking for a peer, don't check the user objects (or realtime) */
-		user = find_user(of, 1);
+		user = find_user(from.username, 1);
 
 	/* Find user based on user name in the from header */
 	if (user && ast_apply_ha(user->ha, sin)) {
 		ast_copy_flags(&p->flags[0], &user->flags[0], SIP_FLAGS_TO_COPY);
 		ast_copy_flags(&p->flags[1], &user->flags[1], SIP_PAGE2_FLAGS_TO_COPY);
+
 		/* copy channel vars */
 		for (v = user->chanvars ; v ; v = v->next) {
 			if ((tmpvar = ast_variable_new(v->name, v->value))) {
@@ -8622,17 +8632,10 @@
 			}
 		}
 		p->prefs = user->prefs;
+
 		/* replace callerid if rpid found, and not restricted */
-		if (!ast_strlen_zero(rpid_num) && ast_test_flag(&p->flags[0], SIP_TRUSTRPID)) {
-			char *tmp;
-			if (*calleridname)
-				ast_string_field_set(p, cid_name, calleridname);
-			tmp = ast_strdupa(rpid_num);
-			if (ast_is_shrinkable_phonenumber(tmp))
-				ast_shrink_phone_number(tmp);
-			ast_string_field_set(p, cid_num, tmp);
-		}
-		
+		if (!ast_strlen_zero(rpid_num) && ast_test_flag(&p->flags[0], SIP_TRUSTRPID))
+			ast_string_field_set(p, cid_num, rpid_num);
 		usenatroute = ast_test_flag(&p->flags[0], SIP_NAT_ROUTE);
 
 		if (p->rtp) {
@@ -8720,7 +8723,7 @@
 		/* If we didn't find a user match, check for peers */
 		if (sipmethod == SIP_SUBSCRIBE)
 			/* For subscribes, match on peer name only */
-			peer = find_peer(of, NULL, 1);
+			peer = find_peer(from.username, NULL, 1);
 		else
 			/* Look for peer based on the IP address we received data from */
 			/* If peer is registered from this IP address or have this as a default
@@ -8743,8 +8746,6 @@
 			/* replace callerid if rpid found, and not restricted */
 			if (!ast_strlen_zero(rpid_num) && ast_test_flag(&p->flags[0], SIP_TRUSTRPID)) {
 				char *tmp = ast_strdupa(rpid_num);
-				if (*calleridname)
-					ast_string_field_set(p, cid_name, calleridname);
 				if (ast_is_shrinkable_phonenumber(tmp))
 					ast_shrink_phone_number(tmp);
 				ast_string_field_set(p, cid_num, tmp);
@@ -14690,6 +14691,74 @@
 	ast_update_use_count();
 	restart_monitor();
 	return tmpc;
+}
+
+/*! \brief Parse uri into different parts 
+	\param headerdata From or To header like
+		- Carl Sparks <carl.sparks at mydomain.com:5034>
+		- Kevin Smith <484848333 at mydomain.com>
+	\param uri Output splitted data 
+	\return 1 if not a SIP uri, otherwise 0
+*/
+static int parseuri(char *headerdata, struct sipuri *uri)
+{
+	char *tmp, *tmp2;
+	char buf[AST_MAXEXTENSION];
+	int res = 0;
+
+	if (pedanticsipchecking)
+		ast_uri_decode(headerdata);
+
+	/* Get display name */
+	ast_copy_string(buf, headerdata, sizeof(buf));
+	get_calleridname(buf, uri->displayname, sizeof(uri->displayname));
+
+	/* Get the uri in < and > */
+	tmp = get_in_brackets(headerdata);
+	
+	/* Find method */
+	if (!strncmp(tmp, "sip:", 4)) {
+		tmp += 4;
+	} else {
+		res = 1;	/* Not a SIP URI */
+	}
+
+	/* Remove URI options for now */
+	if (tmp2 = strchr(tmp2, ';'))
+		*tmp2 = '\0';
+	
+	/* Get the username */
+	tmp2 = strchr(tmp, '@');
+	if (!tmp2)
+		uri->username[0] = '\0';
+		tmp2 = tmp;
+	else {
+		*tmp2 = '\0';	/* Cut off domain */
+		tmp2++;
+	}
+	ast_copy_string(uri->username, tmp, sizeof(uri->username));
+
+	/* Get the domain */
+	tmp = strchr(tmp2, ':');
+	if (tmp) {
+		*tmp = '\0';	/* Cut off port */
+		tmp++;
+	}
+	ast_copy_string(uri->domain, tmp2, sizeof(uri->domain));
+
+	/* Get the port */
+	uri->portno = atoi (tmp);
+
+	/* Fix a caller id from the username part if needed*/
+	if (!ast_strlen_zero(uri->username)) {
+		tmp = ast_strdupa(uri->username);
+		if (ast_is_shrinkable_phonenumber(tmp))
+			ast_shrink_phone_number(tmp);
+		ast_copy_string(uri->cleancallerid, tmp, sizeof(uri->cleancallerid));
+	} else
+		uri->cleancallerid[0] = '\0';
+
+	return res;
 }
 
 /*!
@@ -16255,6 +16324,7 @@
 			memset(lhost, 0, sizeof(lhost));
 			memset(lport, 0, sizeof(lport));
 			localtmp++;
+
 			/* This is okey because lhost and lport are as big as tmp */
 			sscanf(localtmp, "%[^<>:; ]:%[^<>:; ]", lhost, lport);
 			if (ast_strlen_zero(lhost)) {



More information about the asterisk-commits mailing list