Ver código fonte

Merge pull request #2390 from kamailio/nathelper-set_contact_alias-trim

nathelper: add optional set_contact_alias([trim]) parameter
Daniel-Constantin Mierla 5 anos atrás
pai
commit
a6652652b9

+ 85 - 0
src/core/dset.c

@@ -1029,6 +1029,91 @@ int uri_restore_rcv_alias(str *uri, str *nuri, str *suri)
 	return 0;
 }
 
+
+/**
+ * trim alias parameter from uri
+ * - nuri->s must point to a buffer of nuri->len size
+ */
+int uri_trim_rcv_alias(str *uri, str *nuri)
+{
+	char *p;
+	str skip;
+	str ip, port;
+	int proto;
+
+	if(uri == NULL || nuri == NULL) {
+		LM_ERR("invalid parameter value\n");
+		return -1;
+	}
+
+	/* sip:x;alias=1.1.1.1~0~0 */
+	if(uri->len < 23) {
+		/* no alias possible */
+		return 0;
+	}
+	p = uri->s + uri->len - 18;
+	skip.s = 0;
+	while(p > uri->s + 5) {
+		if(strncmp(p, ";alias=", 7) == 0) {
+			skip.s = p;
+			break;
+		}
+		p--;
+	}
+	if(skip.s == 0) {
+		/* alias parameter not found */
+		return 0;
+	}
+	p += 7;
+	ip.s = p;
+	p = (char *)memchr(ip.s, '~', (size_t)(uri->s + uri->len - ip.s));
+	if(p == NULL) {
+		/* proper alias parameter not found */
+		return 0;
+	}
+	ip.len = p - ip.s;
+	p++;
+	if(p >= uri->s + uri->len) {
+		/* proper alias parameter not found */
+		return 0;
+	}
+	port.s = p;
+	p = (char *)memchr(port.s, '~', (size_t)(uri->s + uri->len - port.s));
+	if(p == NULL) {
+		/* proper alias parameter not found */
+		return 0;
+	}
+	port.len = p - port.s;
+	p++;
+	if(p >= uri->s + uri->len) {
+		/* proper alias parameter not found */
+		return 0;
+	}
+	proto = (int)(*p - '0');
+	p++;
+
+	if(p != uri->s + uri->len && *p != ';') {
+		/* proper alias parameter not found */
+		return 0;
+	}
+	skip.len = (int)(p - skip.s);
+	if(nuri->len <= uri->len - skip.len) {
+		LM_ERR("uri buffer too small\n");
+		return -1;
+	}
+
+	p = nuri->s;
+	memcpy(p, uri->s, (size_t)(skip.s - uri->s));
+	p += skip.s - uri->s;
+	memcpy(p, skip.s + skip.len,
+			(size_t)(uri->s + uri->len - skip.s - skip.len));
+	p += uri->s + uri->len - skip.s - skip.len;
+	nuri->len = p - nuri->s;
+
+	LM_DBG("decoded <%.*s> => [%.*s]\n", uri->len, uri->s, nuri->len, nuri->s);
+	return 1;
+}
+
 /* address of record (aor) management */
 
 /* address of record considered case sensitive

+ 1 - 0
src/core/dset.h

@@ -284,6 +284,7 @@ int setbflagsval(unsigned int branch, flag_t val);
 
 int uri_add_rcv_alias(sip_msg_t *msg, str *uri, str *nuri);
 int uri_restore_rcv_alias(str *uri, str *nuri, str *suri);
+int uri_trim_rcv_alias(str *uri, str *nuri);
 
 int init_dst_set(void);
 

+ 11 - 1
src/modules/nathelper/doc/nathelper_admin.xml

@@ -842,7 +842,7 @@ if(is_rfc1918("$rd")) {
 
 	<section id="nathelper.set_contact_alias">
 		<title>
-		<function moreinfo="none">set_contact_alias()</function>
+		<function moreinfo="none">set_contact_alias([trim])</function>
 		</title>
 		<para>
 		Adds an <quote>;alias=ip~port~transport</quote> parameter to the
@@ -850,6 +850,16 @@ if(is_rfc1918("$rd")) {
 		The new contact URI is immediately visible to other modules in the
 		way the <function>fix_nated_contact()</function> does it.
 		</para>
+		<para>Meaning of parameters:</para>
+		<itemizedlist>
+			<listitem>
+				<para>
+					<emphasis>trim</emphasis> - by default, set_contact_alias() will not detect and trim an
+					already existing alias parameter. If this optional parameter is set to "1", set_contact_alias()
+					will trim the existing alias before adding a new one.
+				</para>
+			</listitem>
+		</itemizedlist>
 		<para>
 		This function can be used from
 		REQUEST_ROUTE, ONREPLY_ROUTE, BRANCH_ROUTE, and FAILURE_ROUTE.

+ 47 - 7
src/modules/nathelper/nathelper.c

@@ -110,6 +110,7 @@ static int fix_nated_contact_f(struct sip_msg *, char *, char *);
 static int add_contact_alias_0_f(struct sip_msg *, char *, char *);
 static int add_contact_alias_3_f(struct sip_msg *, char *, char *, char *);
 static int set_contact_alias_f(struct sip_msg *msg, char *str1, char *str2);
+static int w_set_contact_alias_f(struct sip_msg *msg, char *str1, char *str2);
 static int handle_ruri_alias_f(struct sip_msg *, char *, char *);
 static int pv_get_rr_count_f(struct sip_msg *, pv_param_t *, pv_value_t *);
 static int pv_get_rr_top_count_f(struct sip_msg *, pv_param_t *, pv_value_t *);
@@ -212,6 +213,8 @@ static cmd_export_t cmds[] = {
 	{"set_contact_alias",  (cmd_function)set_contact_alias_f,  0,
 		0, 0,
 		REQUEST_ROUTE|ONREPLY_ROUTE|BRANCH_ROUTE|LOCAL_ROUTE},
+	{"set_contact_alias",  (cmd_function)w_set_contact_alias_f, 1,
+		fixup_int_1, 0, REQUEST_ROUTE|ONREPLY_ROUTE|BRANCH_ROUTE|LOCAL_ROUTE},
 	{"handle_ruri_alias",  (cmd_function)handle_ruri_alias_f,    0,
 		0, 0,
 		REQUEST_ROUTE|BRANCH_ROUTE|LOCAL_ROUTE},
@@ -704,10 +707,12 @@ static int fix_nated_contact_f(struct sip_msg *msg, char *str1, char *str2)
  * Replaces ip:port pair in the Contact: field with the source address
  * of the packet.
  */
-static int set_contact_alias(struct sip_msg *msg)
+static int set_contact_alias(struct sip_msg *msg, int trim)
 {
 	char nbuf[MAX_URI_SIZE];
+	char cbuf[MAX_URI_SIZE];
 	str nuri;
+	str curi;
 	int br;
 
 	int offset, len;
@@ -718,16 +723,24 @@ static int set_contact_alias(struct sip_msg *msg)
 
 	nuri.s = nbuf;
 	nuri.len = MAX_URI_SIZE;
+	curi.s = cbuf;
+	curi.len = MAX_URI_SIZE;
 	if(get_contact_uri(msg, &uri, &c) == -1)
 		return -1;
 	if((c->uri.s < msg->buf) || (c->uri.s > (msg->buf + msg->len))) {
 		LM_ERR("you can't update contact twice, check your config!\n");
 		return -1;
 	}
-
-	if(uri_add_rcv_alias(msg, &c->uri, &nuri) < 0) {
-		LM_DBG("cannot add the alias parameter\n");
-		return -1;
+	if(trim > 0 && uri_trim_rcv_alias(&c->uri, &curi) > 0) {
+		if(uri_add_rcv_alias(msg, &curi, &nuri) < 0) {
+			LM_DBG("cannot add the alias parameter\n");
+			return -1;
+		}
+	} else {
+		if(uri_add_rcv_alias(msg, &c->uri, &nuri) < 0) {
+			LM_DBG("cannot add the alias parameter\n");
+			return -1;
+		}
 	}
 
 	br = 1;
@@ -767,9 +780,31 @@ static int set_contact_alias(struct sip_msg *msg)
 	return 1;
 }
 
+static int ki_set_contact_alias(struct sip_msg *msg)
+{
+	return set_contact_alias(msg, 0);
+}
+
+static int ki_set_contact_alias_trim(struct sip_msg *msg)
+{
+	return set_contact_alias(msg, 1);
+}
+
 static int set_contact_alias_f(struct sip_msg *msg, char *str1, char *str2)
 {
-	return set_contact_alias(msg);
+	return set_contact_alias(msg, 0);
+}
+
+static int w_set_contact_alias_f(struct sip_msg *msg, char *str1, char *str2)
+{
+	int i = 0;
+	if(str1) {
+		if(get_int_fparam(&i, msg, (fparam_t *)str1) < 0)
+			return -1;
+	}
+	if(i > 1)
+		i = 1;
+	return set_contact_alias(msg, i);
 }
 
 #define SALIAS ";alias="
@@ -2689,7 +2724,12 @@ static sr_kemi_t sr_kemi_nathelper_exports[] = {
 			SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
 	},
 	{ str_init("nathelper"), str_init("set_contact_alias"),
-		SR_KEMIP_INT, set_contact_alias,
+		SR_KEMIP_INT, ki_set_contact_alias,
+		{ SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE,
+			SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
+	},
+	{ str_init("nathelper"), str_init("set_contact_alias_trim"),
+		SR_KEMIP_INT, ki_set_contact_alias_trim,
 		{ SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE,
 			SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
 	},