Browse code

registrar: added option to store advertised address in socket field (#2498)

* registrar: added new parameter sock_addr

- override socket address on which the register request was received
- default is NULL - store local socket address
- usefull when kamailio is behind NAT and it is necessary to store public instead private address

* registrar: replaced dynamically allocated var with static var

Made refactoring of proposed solution.

* registrar: socket field in location db will be initialized by advertise address from listen parameter

According to code review recommendations I changed my solution - removed new config file parameter and
use advertise address from listen parameter to initialized received socket which is written to
location db inside registration record.

* registrar: added additional check socket bind_address for null

* registrar: introduced config parameter to enable/disable socket advertised address feature

Konstantin authored on 14/10/2020 09:22:20 • GitHub committed on 14/10/2020 09:22:20
Showing 4 changed files
... ...
@@ -535,6 +535,31 @@ modparam("registrar", "sock_hdr_name", "Sock-Info")
535 535
 		</example>
536 536
 	</section>
537 537
 
538
+	<section id="registrar.p.use_advertised_address">
539
+		<title><varname>use_advertised_address</varname> (integer)</title>
540
+		<para>
541
+		This parameter can be used to override value written into socket field when contact is saved.
542
+		If set to 1, advertised address will be written instead local listen socket.
543
+		</para>
544
+		<para>
545
+		This could be useful when kamailio is installed behind NAT and it is necessary to store its public IP 
546
+		instead socket on which the register request was received.
547
+		</para>
548
+		<para>
549
+		<emphasis>
550
+			Default value is 0 (disabled).
551
+		</emphasis>
552
+		</para>
553
+		<example>
554
+		<title>Set <varname>use_advertised_address</varname> parameter</title>
555
+		<programlisting format="linespecific">
556
+...
557
+modparam("registrar", "use_advertised_address", 1)
558
+...
559
+		</programlisting>
560
+		</example>
561
+	</section>
562
+
538 563
 	<section id="registrar.p.method_filtering">
539 564
 		<title><varname>method_filtering</varname> (integer)</title>
540 565
 		<para>
... ...
@@ -132,6 +132,8 @@ int reg_use_domain = 0;
132 132
 int sock_flag = -1;
133 133
 str sock_hdr_name = {0,0};
134 134
 
135
+int sock_advertise_enabled = 0;
136
+
135 137
 /* where to go for event route ("usrloc:contact-expired") */
136 138
 int reg_expire_event_rt = -1; /* default disabled */
137 139
 str reg_event_callback = STR_NULL;
... ...
@@ -249,6 +251,7 @@ static param_export_t params[] = {
249 251
 	{"lookup_filter_mode", INT_PARAM, &reg_lookup_filter_mode			},
250 252
 	{"min_expires_mode",   PARAM_INT, &reg_min_expires_mode				},
251 253
 	{"use_expired_contacts",  INT_PARAM, &default_registrar_cfg.use_expired_contacts	 },
254
+	{"use_advertised_address", PARAM_INT, &sock_advertise_enabled		},
252 255
 	{0, 0, 0}
253 256
 };
254 257
 
... ...
@@ -99,6 +99,7 @@ extern int reg_flow_timer;
99 99
 
100 100
 extern str sock_hdr_name;
101 101
 extern int sock_flag;
102
+extern int sock_advertise_enabled;
102 103
 
103 104
 extern str reg_xavp_cfg;
104 105
 extern str reg_xavp_rcd;
... ...
@@ -229,6 +229,7 @@ static inline ucontact_info_t* pack_ci( struct sip_msg* _m, contact_t* _c,
229 229
 	static int received_found;
230 230
 	static unsigned int allowed, allow_parsed;
231 231
 	static struct sip_msg *m = 0;
232
+	static struct socket_info si = {0};
232 233
 	int_str val;
233 234
 
234 235
 	if (_m!=0) {
... ...
@@ -256,6 +257,10 @@ static inline ucontact_info_t* pack_ci( struct sip_msg* _m, contact_t* _c,
256 257
 			ci.sock = get_sock_val(_m);
257 258
 			if (ci.sock==0)
258 259
 				ci.sock = _m->rcv.bind_address;
260
+		} else if (sock_advertise_enabled && _m->rcv.bind_address && _m->rcv.bind_address->useinfo.sock_str.len > 0) {
261
+		    memset(&si, 0, sizeof(struct socket_info));
262
+		    si.sock_str = _m->rcv.bind_address->useinfo.sock_str;
263
+		    ci.sock = &si;
259 264
 		} else {
260 265
 			ci.sock = _m->rcv.bind_address;
261 266
 		}
... ...
@@ -412,6 +417,7 @@ static inline ucontact_info_t* pack_ci( struct sip_msg* _m, contact_t* _c,
412 417
 
413 418
 	return &ci;
414 419
 error:
420
+
415 421
 	return 0;
416 422
 }
417 423
 
... ...
@@ -559,7 +565,7 @@ static inline int insert_contacts(struct sip_msg* _m, udomain_t* _d, str* _a, in
559 565
 	} else { /* No contacts found */
560 566
 		build_contact(_m, NULL, &u->host);
561 567
 	}
562
-
568
+	
563 569
 #ifdef USE_TCP
564 570
 	if ( tcp_check && e_max>0 ) {
565 571
 		e_max -= act_time;
... ...
@@ -572,6 +578,7 @@ static inline int insert_contacts(struct sip_msg* _m, udomain_t* _d, str* _a, in
572 578
 error:
573 579
 	if (r)
574 580
 		ul.delete_urecord(_d, _a, r);
581
+
575 582
 	return -1;
576 583
 }
577 584
 
... ...
@@ -816,6 +823,7 @@ static inline int update_contacts(struct sip_msg* _m, urecord_t* _r, int _mode,
816 823
 
817 824
 	return rc;
818 825
 error:
826
+
819 827
 	return -1;
820 828
 }
821 829