Browse code

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

nathelper: add optional set_contact_alias([trim]) parameter

Emmanuel Schmidbauer authored on 03/07/2020 14:32:25 • GitHub committed on 03/07/2020 14:32:25
Showing 4 changed files
... ...
@@ -1029,6 +1029,91 @@ int uri_restore_rcv_alias(str *uri, str *nuri, str *suri)
1029 1029
 	return 0;
1030 1030
 }
1031 1031
 
1032
+
1033
+/**
1034
+ * trim alias parameter from uri
1035
+ * - nuri->s must point to a buffer of nuri->len size
1036
+ */
1037
+int uri_trim_rcv_alias(str *uri, str *nuri)
1038
+{
1039
+	char *p;
1040
+	str skip;
1041
+	str ip, port;
1042
+	int proto;
1043
+
1044
+	if(uri == NULL || nuri == NULL) {
1045
+		LM_ERR("invalid parameter value\n");
1046
+		return -1;
1047
+	}
1048
+
1049
+	/* sip:x;alias=1.1.1.1~0~0 */
1050
+	if(uri->len < 23) {
1051
+		/* no alias possible */
1052
+		return 0;
1053
+	}
1054
+	p = uri->s + uri->len - 18;
1055
+	skip.s = 0;
1056
+	while(p > uri->s + 5) {
1057
+		if(strncmp(p, ";alias=", 7) == 0) {
1058
+			skip.s = p;
1059
+			break;
1060
+		}
1061
+		p--;
1062
+	}
1063
+	if(skip.s == 0) {
1064
+		/* alias parameter not found */
1065
+		return 0;
1066
+	}
1067
+	p += 7;
1068
+	ip.s = p;
1069
+	p = (char *)memchr(ip.s, '~', (size_t)(uri->s + uri->len - ip.s));
1070
+	if(p == NULL) {
1071
+		/* proper alias parameter not found */
1072
+		return 0;
1073
+	}
1074
+	ip.len = p - ip.s;
1075
+	p++;
1076
+	if(p >= uri->s + uri->len) {
1077
+		/* proper alias parameter not found */
1078
+		return 0;
1079
+	}
1080
+	port.s = p;
1081
+	p = (char *)memchr(port.s, '~', (size_t)(uri->s + uri->len - port.s));
1082
+	if(p == NULL) {
1083
+		/* proper alias parameter not found */
1084
+		return 0;
1085
+	}
1086
+	port.len = p - port.s;
1087
+	p++;
1088
+	if(p >= uri->s + uri->len) {
1089
+		/* proper alias parameter not found */
1090
+		return 0;
1091
+	}
1092
+	proto = (int)(*p - '0');
1093
+	p++;
1094
+
1095
+	if(p != uri->s + uri->len && *p != ';') {
1096
+		/* proper alias parameter not found */
1097
+		return 0;
1098
+	}
1099
+	skip.len = (int)(p - skip.s);
1100
+	if(nuri->len <= uri->len - skip.len) {
1101
+		LM_ERR("uri buffer too small\n");
1102
+		return -1;
1103
+	}
1104
+
1105
+	p = nuri->s;
1106
+	memcpy(p, uri->s, (size_t)(skip.s - uri->s));
1107
+	p += skip.s - uri->s;
1108
+	memcpy(p, skip.s + skip.len,
1109
+			(size_t)(uri->s + uri->len - skip.s - skip.len));
1110
+	p += uri->s + uri->len - skip.s - skip.len;
1111
+	nuri->len = p - nuri->s;
1112
+
1113
+	LM_DBG("decoded <%.*s> => [%.*s]\n", uri->len, uri->s, nuri->len, nuri->s);
1114
+	return 1;
1115
+}
1116
+
1032 1117
 /* address of record (aor) management */
1033 1118
 
1034 1119
 /* address of record considered case sensitive
... ...
@@ -284,6 +284,7 @@ int setbflagsval(unsigned int branch, flag_t val);
284 284
 
285 285
 int uri_add_rcv_alias(sip_msg_t *msg, str *uri, str *nuri);
286 286
 int uri_restore_rcv_alias(str *uri, str *nuri, str *suri);
287
+int uri_trim_rcv_alias(str *uri, str *nuri);
287 288
 
288 289
 int init_dst_set(void);
289 290
 
... ...
@@ -842,7 +842,7 @@ if(is_rfc1918("$rd")) {
842 842
 
843 843
 	<section id="nathelper.set_contact_alias">
844 844
 		<title>
845
-		<function moreinfo="none">set_contact_alias()</function>
845
+		<function moreinfo="none">set_contact_alias([trim])</function>
846 846
 		</title>
847 847
 		<para>
848 848
 		Adds an <quote>;alias=ip~port~transport</quote> parameter to the
... ...
@@ -850,6 +850,16 @@ if(is_rfc1918("$rd")) {
850 850
 		The new contact URI is immediately visible to other modules in the
851 851
 		way the <function>fix_nated_contact()</function> does it.
852 852
 		</para>
853
+		<para>Meaning of parameters:</para>
854
+		<itemizedlist>
855
+			<listitem>
856
+				<para>
857
+					<emphasis>trim</emphasis> - by default, set_contact_alias() will not detect and trim an
858
+					already existing alias parameter. If this optional parameter is set to "1", set_contact_alias()
859
+					will trim the existing alias before adding a new one.
860
+				</para>
861
+			</listitem>
862
+		</itemizedlist>
853 863
 		<para>
854 864
 		This function can be used from
855 865
 		REQUEST_ROUTE, ONREPLY_ROUTE, BRANCH_ROUTE, and FAILURE_ROUTE.
... ...
@@ -110,6 +110,7 @@ static int fix_nated_contact_f(struct sip_msg *, char *, char *);
110 110
 static int add_contact_alias_0_f(struct sip_msg *, char *, char *);
111 111
 static int add_contact_alias_3_f(struct sip_msg *, char *, char *, char *);
112 112
 static int set_contact_alias_f(struct sip_msg *msg, char *str1, char *str2);
113
+static int w_set_contact_alias_f(struct sip_msg *msg, char *str1, char *str2);
113 114
 static int handle_ruri_alias_f(struct sip_msg *, char *, char *);
114 115
 static int pv_get_rr_count_f(struct sip_msg *, pv_param_t *, pv_value_t *);
115 116
 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[] = {
212 213
 	{"set_contact_alias",  (cmd_function)set_contact_alias_f,  0,
213 214
 		0, 0,
214 215
 		REQUEST_ROUTE|ONREPLY_ROUTE|BRANCH_ROUTE|LOCAL_ROUTE},
216
+	{"set_contact_alias",  (cmd_function)w_set_contact_alias_f, 1,
217
+		fixup_int_1, 0, REQUEST_ROUTE|ONREPLY_ROUTE|BRANCH_ROUTE|LOCAL_ROUTE},
215 218
 	{"handle_ruri_alias",  (cmd_function)handle_ruri_alias_f,    0,
216 219
 		0, 0,
217 220
 		REQUEST_ROUTE|BRANCH_ROUTE|LOCAL_ROUTE},
... ...
@@ -704,10 +707,12 @@ static int fix_nated_contact_f(struct sip_msg *msg, char *str1, char *str2)
704 707
  * Replaces ip:port pair in the Contact: field with the source address
705 708
  * of the packet.
706 709
  */
707
-static int set_contact_alias(struct sip_msg *msg)
710
+static int set_contact_alias(struct sip_msg *msg, int trim)
708 711
 {
709 712
 	char nbuf[MAX_URI_SIZE];
713
+	char sbuf[MAX_URI_SIZE];
710 714
 	str nuri;
715
+	str suri;
711 716
 	int br;
712 717
 
713 718
 	int offset, len;
... ...
@@ -718,16 +723,24 @@ static int set_contact_alias(struct sip_msg *msg)
718 723
 
719 724
 	nuri.s = nbuf;
720 725
 	nuri.len = MAX_URI_SIZE;
726
+	suri.s = sbuf;
727
+	suri.len = MAX_URI_SIZE;
721 728
 	if(get_contact_uri(msg, &uri, &c) == -1)
722 729
 		return -1;
723 730
 	if((c->uri.s < msg->buf) || (c->uri.s > (msg->buf + msg->len))) {
724 731
 		LM_ERR("you can't update contact twice, check your config!\n");
725 732
 		return -1;
726 733
 	}
727
-
728
-	if(uri_add_rcv_alias(msg, &c->uri, &nuri) < 0) {
729
-		LM_DBG("cannot add the alias parameter\n");
730
-		return -1;
734
+	if(trim > 0 && uri_trim_rcv_alias(&c->uri, &suri) > 0) {
735
+		if(uri_add_rcv_alias(msg, &suri, &nuri) < 0) {
736
+			LM_DBG("cannot add the alias parameter\n");
737
+			return -1;
738
+		}
739
+	} else {
740
+		if(uri_add_rcv_alias(msg, &c->uri, &nuri) < 0) {
741
+			LM_DBG("cannot add the alias parameter\n");
742
+			return -1;
743
+		}
731 744
 	}
732 745
 
733 746
 	br = 1;
... ...
@@ -769,7 +782,19 @@ static int set_contact_alias(struct sip_msg *msg)
769 782
 
770 783
 static int set_contact_alias_f(struct sip_msg *msg, char *str1, char *str2)
771 784
 {
772
-	return set_contact_alias(msg);
785
+	return set_contact_alias(msg, 0);
786
+}
787
+
788
+static int w_set_contact_alias_f(struct sip_msg *msg, char *str1, char *str2)
789
+{
790
+	int i = 0;
791
+	if(str1) {
792
+		if(get_int_fparam(&i, msg, (fparam_t *)str1) < 0)
793
+			return -1;
794
+	}
795
+	if(i > 1)
796
+		i = 1;
797
+	return set_contact_alias(msg, i);
773 798
 }
774 799
 
775 800
 #define SALIAS ";alias="