Browse code

topos: add functionality to set a variable host part for the Contact header

- add functionality to set a variable host part for the Contact header
- could be refactored to use a xavp instead of avp, together with the other
parameters in this area ([a,b]_contact_avp)

Henning Westerholt authored on 31/03/2021 13:28:30
Showing 3 changed files
... ...
@@ -292,7 +292,8 @@ modparam("topos", "event_mode", 2)
292 292
 		<title><varname>contact_host</varname> (str)</title>
293 293
 		<para>
294 294
 			You may need to control the host part of the Contact header added
295
-			by topos.
295
+			by topos. If the contact_host_avp parameter is set, this value is
296
+			ignored.
296 297
 
297 298
 			For example when using TLS with TOPOS the remote UAS must be able to open
298 299
 			a new TLS socket to the contact header.
... ...
@@ -433,6 +434,33 @@ modparam("topos", "b_contact_avp", "$avp(tps-bct)")
433 434
 ...
434 435
 modparam("topos", "rr_update", 1)
435 436
 ...
437
+</programlisting>
438
+		</example>
439
+	</section>
440
+	<section id="topos.p.contact_host_avp">
441
+		<title><varname>contact_host_avp</varname> (str)</title>
442
+		<para>
443
+			You may need to control the host part of the Contact header added
444
+			by topos. This parameter allows to take the value from an AVP
445
+			during run-time. If this parameter is set, the contact_host
446
+			parameter is ignored.
447
+
448
+			For example when using TLS with TOPOS the remote UAS must be able to open
449
+			a new TLS socket to the contact header.
450
+			In this case, the contact header must contain a domain name with a trusted CA
451
+			signed certitificate.
452
+		</para>
453
+		<para>
454
+		<emphasis>
455
+			Default value is empty, not set.
456
+		</emphasis>
457
+		</para>
458
+		<example>
459
+		<title>Set <varname>contact_host_avp</varname> parameter</title>
460
+		<programlisting format="linespecific">
461
+...
462
+modparam("topos", "contact_host_avp", "$avp(contact_host)")
463
+...
436 464
 </programlisting>
437 465
 		</example>
438 466
 	</section>
... ...
@@ -96,6 +96,8 @@ static int _tps_eventrt_sending = -1;
96 96
 static str _tps_eventrt_sending_name = str_init("topos:msg-sending");
97 97
 str _tps_contact_host = str_init("");
98 98
 int _tps_contact_mode = 0;
99
+str _tps_contact_host_avp = str_init("");
100
+pv_spec_t _tps_contact_host_avp_spec;
99 101
 str _tps_cparam_name = str_init("tps");
100 102
 str _tps_acontact_avp;
101 103
 str _tps_bcontact_avp;
... ...
@@ -142,7 +144,8 @@ static param_export_t params[]={
142 144
 	{"cparam_name",		PARAM_STR, &_tps_cparam_name},
143 145
 	{"a_contact_avp",	PARAM_STR, &_tps_acontact_avp},
144 146
 	{"b_contact_avp",	PARAM_STR, &_tps_bcontact_avp},
145
-	{"rr_update",       PARAM_INT, &_tps_rr_update},
147
+	{"contact_host_avp",    PARAM_STR, &_tps_contact_host_avp},
148
+	{"rr_update",		PARAM_INT, &_tps_rr_update},
146 149
 	{0,0,0}
147 150
 };
148 151
 
... ...
@@ -235,6 +238,15 @@ static int mod_init(void)
235 238
 		}
236 239
 	}
237 240
 
241
+	if(_tps_contact_host_avp.len > 0 && _tps_contact_host_avp.s != NULL) {
242
+		if(pv_parse_spec(&_tps_contact_host_avp, &_tps_contact_host_avp_spec) == 0
243
+				|| _tps_contact_host_avp_spec.type != PVT_AVP) {
244
+			LM_ERR("malformed or non AVP %.*s AVP definition\n",
245
+			_tps_contact_host_avp.len, _tps_contact_host_avp.s);
246
+			return -1;
247
+		}
248
+	}
249
+
238 250
 	sr_event_register_cb(SREV_NET_DATA_IN,  tps_msg_received);
239 251
 	sr_event_register_cb(SREV_NET_DATA_OUT, tps_msg_sent);
240 252
 
... ...
@@ -61,6 +61,8 @@ extern str _tps_acontact_avp;
61 61
 extern str _tps_bcontact_avp;
62 62
 extern pv_spec_t _tps_acontact_spec;
63 63
 extern pv_spec_t _tps_bcontact_spec;
64
+extern str _tps_contact_host_avp;
65
+extern pv_spec_t _tps_contact_host_avp_spec;
64 66
 
65 67
 #define TPS_STORAGE_LOCK_SIZE	1<<9
66 68
 static gen_lock_set_t *_tps_storage_lock_set = NULL;
... ...
@@ -343,12 +345,23 @@ int tps_storage_fill_contact(sip_msg_t *msg, tps_data_t *td, str *uuid, int dir,
343 345
 			td->cp++;
344 346
 		}
345 347
 
346
-		if (_tps_contact_host.len) { // using configured hostname in the contact header
347
-			memcpy(td->cp, _tps_contact_host.s, _tps_contact_host.len);
348
-			td->cp += _tps_contact_host.len;
348
+		// contact_host AVP takes preference
349
+		if (_tps_contact_host_avp.len) {
350
+			if ((pv_get_spec_value(msg, &_tps_contact_host_avp_spec, &pv_val) != 0) &&
351
+					(pv_val.flags & PV_VAL_STR) && (pv_val.rs.len <= 0)) {
352
+				LM_ERR("could not evaluate contact_host AVP\n");
353
+				return -1;
354
+			}
355
+			memcpy(td->cp, pv_val.rs.s, pv_val.rs.len);
356
+			td->cp += pv_val.rs.len;
349 357
 		} else {
350
-			memcpy(td->cp, puri.host.s, puri.host.len);
351
-			td->cp += puri.host.len;
358
+			if (_tps_contact_host.len) { // using configured hostname in the contact header
359
+				memcpy(td->cp, _tps_contact_host.s, _tps_contact_host.len);
360
+				td->cp += _tps_contact_host.len;
361
+			} else {
362
+				memcpy(td->cp, puri.host.s, puri.host.len);
363
+				td->cp += puri.host.len;
364
+			}
352 365
 		}
353 366
 		if(puri.port.len>0) {
354 367
 			*td->cp = ':';