Browse code

nathelper: optional parameter mode for handle_ruri_alias()

- if not 0, then consume the last alias parameter instead of the first
one

Daniel-Constantin Mierla authored on 01/06/2021 07:28:08
Showing 1 changed files
... ...
@@ -112,6 +112,7 @@ 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 113
 static int w_set_contact_alias_f(struct sip_msg *msg, char *str1, char *str2);
114 114
 static int handle_ruri_alias_f(struct sip_msg *, char *, char *);
115
+static int handle_ruri_alias_mode_f(sip_msg_t *msg, char *pmode, char *p2);
115 116
 static int pv_get_rr_count_f(struct sip_msg *, pv_param_t *, pv_value_t *);
116 117
 static int pv_get_rr_top_count_f(struct sip_msg *, pv_param_t *, pv_value_t *);
117 118
 static int fix_nated_sdp_f(struct sip_msg *, char *, char *);
... ...
@@ -218,6 +219,9 @@ static cmd_export_t cmds[] = {
218 219
 	{"handle_ruri_alias",  (cmd_function)handle_ruri_alias_f,    0,
219 220
 		0, 0,
220 221
 		REQUEST_ROUTE|BRANCH_ROUTE|LOCAL_ROUTE},
222
+	{"handle_ruri_alias",  (cmd_function)handle_ruri_alias_mode_f, 1,
223
+		fixup_igp_null, fixup_free_igp_null,
224
+		REQUEST_ROUTE|BRANCH_ROUTE|LOCAL_ROUTE},
221 225
 	{"fix_nated_sdp",      (cmd_function)fix_nated_sdp_f,        1,
222 226
 		fixup_fix_sdp,  0,
223 227
 		REQUEST_ROUTE|ONREPLY_ROUTE|FAILURE_ROUTE|BRANCH_ROUTE|LOCAL_ROUTE},
... ...
@@ -1117,14 +1121,14 @@ static int add_contact_alias_3_f(
1117 1121
 #define ALIAS_LEN (sizeof(ALIAS) - 1)
1118 1122
 
1119 1123
 /*
1120
- * Checks if r-uri has alias param and if so, removes it and sets $du
1121
- * based on its value.
1124
+ * Checks if r-uri has alias param and if so, removes the first (mode==0)
1125
+ * or the last one (mode!=0) and sets $du based on its value.
1122 1126
  */
1123
-static int handle_ruri_alias(struct sip_msg *msg)
1127
+static int ki_handle_ruri_alias_mode(struct sip_msg *msg, int mode)
1124 1128
 {
1125 1129
 	str uri, proto;
1126 1130
 	char buf[MAX_URI_SIZE], *val, *sep, *at, *next, *cur_uri, *rest, *port,
1127
-			*trans;
1131
+			*trans, *start;
1128 1132
 	unsigned int len, rest_len, val_len, alias_len, proto_type, cur_uri_len,
1129 1133
 			ip_port_len;
1130 1134
 
... ...
@@ -1138,11 +1142,20 @@ static int handle_ruri_alias(struct sip_msg *msg)
1138 1142
 		LM_DBG("no params\n");
1139 1143
 		return 2;
1140 1144
 	}
1141
-	while(rest_len >= ALIAS_LEN) {
1142
-		if(strncmp(rest, ALIAS, ALIAS_LEN) == 0)
1143
-			break;
1145
+	start = NULL;
1146
+	/* locate last alias parameter */
1147
+	while(rest_len > ALIAS_LEN + 4) {
1148
+		if(strncmp(rest, ALIAS, ALIAS_LEN) == 0) {
1149
+			start = rest;
1150
+			if(mode==0) {
1151
+				/* use first alias parameter */
1152
+				break;
1153
+			}
1154
+			rest = rest + ALIAS_LEN;
1155
+			rest_len = rest_len - ALIAS_LEN;
1156
+		}
1144 1157
 		sep = memchr(rest, 59 /* ; */, rest_len);
1145
-		if(sep == NULL) {
1158
+		if(sep == NULL && start == NULL) {
1146 1159
 			LM_DBG("no alias param\n");
1147 1160
 			return 2;
1148 1161
 		} else {
... ...
@@ -1151,10 +1164,11 @@ static int handle_ruri_alias(struct sip_msg *msg)
1151 1164
 		}
1152 1165
 	}
1153 1166
 
1154
-	if(rest_len < ALIAS_LEN) {
1167
+	if(start == NULL) {
1155 1168
 		LM_DBG("no alias param\n");
1156 1169
 		return 2;
1157 1170
 	}
1171
+	rest = start;
1158 1172
 
1159 1173
 	/* set dst uri based on alias param value */
1160 1174
 	val = rest + ALIAS_LEN;
... ...
@@ -1225,9 +1239,36 @@ static int handle_ruri_alias(struct sip_msg *msg)
1225 1239
 	return rewrite_uri(msg, &uri);
1226 1240
 }
1227 1241
 
1242
+/*
1243
+ * Checks if r-uri has alias param and if so, removes the first one and sets $du
1244
+ * based on its value.
1245
+ */
1246
+static int ki_handle_ruri_alias(struct sip_msg *msg)
1247
+{
1248
+	return ki_handle_ruri_alias_mode(msg, 0);
1249
+}
1250
+
1251
+/*
1252
+ * Checks if r-uri has alias param and if so, removes the first one and sets $du
1253
+ * based on its value.
1254
+ */
1228 1255
 static int handle_ruri_alias_f(struct sip_msg *msg, char *str1, char *str2)
1229 1256
 {
1230
-	return handle_ruri_alias(msg);
1257
+	return ki_handle_ruri_alias_mode(msg, 0);
1258
+}
1259
+
1260
+/*
1261
+ * Checks if r-uri has alias param and if so, removes the first or the last one
1262
+ * and sets $du based on its value.
1263
+ */
1264
+static int handle_ruri_alias_mode_f(struct sip_msg *msg, char *pmode, char *str2)
1265
+{
1266
+	int mode = 0;
1267
+	if(fixup_get_ivalue(msg, (gparam_t*)pmode, &mode)<0) {
1268
+		LM_ERR("failed to get the value for mode parameter\n");
1269
+		return -1;
1270
+	}
1271
+	return ki_handle_ruri_alias_mode(msg, mode);
1231 1272
 }
1232 1273
 
1233 1274
 /*
... ...
@@ -2745,10 +2786,15 @@ static sr_kemi_t sr_kemi_nathelper_exports[] = {
2745 2786
 			SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
2746 2787
 	},
2747 2788
 	{ str_init("nathelper"), str_init("handle_ruri_alias"),
2748
-		SR_KEMIP_INT, handle_ruri_alias,
2789
+		SR_KEMIP_INT, ki_handle_ruri_alias,
2749 2790
 		{ SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE,
2750 2791
 			SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
2751 2792
 	},
2793
+	{ str_init("nathelper"), str_init("handle_ruri_alias_mode"),
2794
+		SR_KEMIP_INT, ki_handle_ruri_alias_mode,
2795
+		{ SR_KEMIP_INT, SR_KEMIP_NONE, SR_KEMIP_NONE,
2796
+			SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
2797
+	},
2752 2798
 	{ str_init("nathelper"), str_init("is_rfc1918"),
2753 2799
 		SR_KEMIP_INT, is_rfc1918,
2754 2800
 		{ SR_KEMIP_STR, SR_KEMIP_NONE, SR_KEMIP_NONE,