Ver código fonte

Merge pull request #23 from kamailio/cchance/registrar

registrar: check for local path on lookup
Charles Chance 10 anos atrás
pai
commit
887167f8e3

+ 26 - 0
modules/registrar/doc/registrar_admin.xml

@@ -630,6 +630,32 @@ modparam("registrar", "path_use_received", 1)
 		</example>
 	</section>
 
+	<section id="registrar.p.path_check_local">
+		<title><varname>path_check_local</varname> (integer)</title>
+		<para>
+		If set to 1, when performing a lookup the Path (if present) is evaluated
+		and if the first hop is local (according to <quote>myself</quote> test), we
+		skip it	to avoid unnecessary looping.
+		</para>
+		<para>
+		This is useful if multiple servers are sharing a common location database,
+		each saving contacts with their local address as the Path.
+		</para>
+		<para>
+		<emphasis>
+		Default value is 0 (disabled).
+		</emphasis>
+		</para>
+		<example>
+		<title>Set <varname>path_check_local</varname> parameter</title>
+		<programlisting format="linespecific">
+...
+modparam("registrar", "path_check_local", 1)
+...
+		</programlisting>
+		</example>
+	</section>
+
 	<section id="registrar.p.reg_callid_avp">
 		<title><varname>reg_callid_avp</varname> (string)</title>
 		<para>

+ 67 - 7
modules/registrar/lookup.c

@@ -41,6 +41,7 @@
 #include "../../action.h"
 #include "../../mod_fix.h"
 #include "../../parser/parse_rr.h"
+#include "../../forward.h"
 #include "../usrloc/usrloc.h"
 #include "common.h"
 #include "regtime.h"
@@ -121,6 +122,8 @@ int lookup_helper(struct sip_msg* _m, udomain_t* _d, str* _uri, int _mode)
 	sr_xavp_t *list=NULL;
 	str xname = {"ruid", 4};
 	sr_xval_t xval;
+	sip_uri_t path_uri;
+	str path_str;
 
 	ret = -1;
 
@@ -256,16 +259,47 @@ int lookup_helper(struct sip_msg* _m, udomain_t* _d, str* _uri, int _mode)
 				xavp_add_value(&reg_xavp_rcd, &xval, NULL);
 			}
 		}
+
 		/* If a Path is present, use first path-uri in favour of
 		 * received-uri because in that case the last hop towards the uac
 		 * has to handle NAT. - agranig */
 		if (ptr->path.s && ptr->path.len) {
-			if (get_path_dst_uri(&ptr->path, &path_dst) < 0) {
+			/* make a copy, so any change we need to make here does not mess up the structure in usrloc */
+			path_str = ptr->path;
+			if (get_path_dst_uri(&path_str, &path_dst) < 0) {
 				LM_ERR("failed to get dst_uri for Path\n");
 				ret = -3;
 				goto done;
 			}
-			if (set_path_vector(_m, &ptr->path) < 0) {
+			if (path_check_local > 0) {
+				if (parse_uri(path_dst.s, path_dst.len, &path_uri) < 0){
+					LM_ERR("failed to parse the Path URI\n");
+					ret = -3;
+					goto done;
+				}
+				if (check_self(&(path_uri.host), 0, 0)) {
+					/* first hop in path vector is local - check for additional hops and if present, point to next one */
+					if (path_str.len > (path_dst.len + 3)) {
+						path_str.s = path_str.s + path_dst.len + 3;
+						path_str.len = path_str.len - path_dst.len - 3;
+						if (get_path_dst_uri(&path_str, &path_dst) < 0) {
+							LM_ERR("failed to get second dst_uri for Path\n");
+							ret = -3;
+							goto done;
+						}
+					} else {
+						/* no more hops */
+						path_dst.s = NULL;
+						path_dst.len = 0;
+					}
+				}
+			}
+		} else {
+			path_dst.s = NULL;
+			path_dst.len = 0;
+		}
+		if (path_dst.s && path_dst.len) {
+			if (set_path_vector(_m, &path_str) < 0) {
 				LM_ERR("failed to set path vector\n");
 				ret = -3;
 				goto done;
@@ -333,10 +367,36 @@ int lookup_helper(struct sip_msg* _m, udomain_t* _d, str* _uri, int _mode)
 	for( ; ptr ; ptr = ptr->next ) {
 		if (VALID_CONTACT(ptr, act_time) && allowed_method(_m, ptr)) {
 			path_dst.len = 0;
-			if(ptr->path.s && ptr->path.len 
-			&& get_path_dst_uri(&ptr->path, &path_dst) < 0) {
-				LM_ERR("failed to get dst_uri for Path\n");
-				continue;
+			if(ptr->path.s && ptr->path.len) {
+				path_str = ptr->path;
+				if (get_path_dst_uri(&path_str, &path_dst) < 0) {
+					LM_ERR("failed to get dst_uri for Path\n");
+					continue;
+				}
+				if (path_check_local > 0) {
+					if (parse_uri(path_dst.s, path_dst.len, &path_uri) < 0) {
+						LM_ERR("failed to parse the Path URI\n");
+						continue;
+					}
+					if (check_self(&(path_uri.host), 0, 0)) {
+						/* first hop in path vector is local - check for additional hops and if present, point to next one */
+						if (path_str.len > (path_dst.len + 3)) {
+							path_str.s = path_str.s + path_dst.len + 3;
+							path_str.len = path_str.len - path_dst.len - 3;
+							if (get_path_dst_uri(&path_str, &path_dst) < 0) {
+								LM_ERR("failed to get second dst_uri for Path\n");
+								continue;
+							}
+						} else {
+							/* no more hops */
+							path_dst.s = NULL;
+							path_dst.len = 0;
+						}
+					}
+				}
+			} else {
+				path_dst.s = NULL;
+				path_dst.len = 0;
 			}
 
 			/* The same as for the first contact applies for branches 
@@ -345,7 +405,7 @@ int lookup_helper(struct sip_msg* _m, udomain_t* _d, str* _uri, int _mode)
 			       ptr->instance.len, ptr->instance.s);
 			if (append_branch(_m, &ptr->c,
 					  path_dst.len?&path_dst:&ptr->received,
-					  &ptr->path, ptr->q, ptr->cflags,
+					  path_dst.len?&path_str:0, ptr->q, ptr->cflags,
 					  ptr->sock,
 					  ptr->instance.len?&(ptr->instance):0,
 				          ptr->instance.len?ptr->reg_id:0,

+ 2 - 0
modules/registrar/reg_mod.c

@@ -116,6 +116,7 @@ int path_mode = PATH_MODE_STRICT;		/*!< if the Path HF should be inserted in the
 
 int path_use_params = 0;			/*!< if the received- and nat-parameters of last Path uri should be used
  						 * to determine if UAC is nat'ed */
+int path_check_local = 0;
 
 /* sruid to get internal uid */
 sruid_t _reg_sruid;
@@ -233,6 +234,7 @@ static param_export_t params[] = {
 	{"use_path",           INT_PARAM, &path_enabled        					},
 	{"path_mode",          INT_PARAM, &path_mode           					},
 	{"path_use_received",  INT_PARAM, &path_use_params     					},
+        {"path_check_local",   INT_PARAM, &path_check_local                                     },
 	{"xavp_cfg",           PARAM_STR, &reg_xavp_cfg     					},
 	{"xavp_rcd",           PARAM_STR, &reg_xavp_rcd     					},
 	{"gruu_enabled",       INT_PARAM, &reg_gruu_enabled    					},

+ 1 - 0
modules/registrar/reg_mod.h

@@ -94,6 +94,7 @@ extern int method_filtering;
 extern int path_enabled;
 extern int path_mode;
 extern int path_use_params;
+extern int path_check_local;
 extern int reg_gruu_enabled;
 extern int reg_outbound_mode;
 extern int reg_regid_mode;