Browse code

usrloc: new param to close TCP connections

the new `close_expired_tcp`, if set, forces Kamailio to close the TCP
connections of expired contacts

Camille Oudot authored on 25/02/2015 11:13:16
Showing 4 changed files
... ...
@@ -896,6 +896,27 @@ modparam("usrloc", "handle_lost_tcp", 1)
896 896
 		</example>
897 897
 	</section>
898 898
 
899
+	<section id="usrloc.p.close_expired_tcp">
900
+		<title><varname>close_expired_tcp</varname> (int)</title>
901
+		<para>
902
+            If set to 1, Kamailio will close the TCP connection when a contact
903
+            has expired, if the corresponding transport is TCP/TLS/WS/WSS.
904
+        </para>
905
+		<para>
906
+		<emphasis>
907
+			Default value is <quote>0</quote>.
908
+		</emphasis>
909
+		</para>
910
+		<example>
911
+		<title>Set <varname>close_expired_tcp</varname> parameter</title>
912
+		<programlisting format="linespecific">
913
+...
914
+modparam("usrloc", "close_expired_tcp", 1)
915
+...
916
+</programlisting>
917
+		</example>
918
+	</section>
919
+
899 920
 	<section id="usrloc.p.expires_type">
900 921
 		<title><varname>expires_type</varname> (int)</title>
901 922
 		<para>
... ...
@@ -152,6 +152,7 @@ int db_mode         = 0;				/*!< Database sync scheme: 0-no db, 1-write through,
152 152
 int use_domain      = 0;				/*!< Whether usrloc should use domain part of aor */
153 153
 int desc_time_order = 0;				/*!< By default do not enable timestamp ordering */
154 154
 int handle_lost_tcp = 0;				/*!< By default do not remove contacts before expiration time */
155
+int close_expired_tcp = 0;				/*!< By default do not close TCP connections for expired contacts */
155 156
 
156 157
 int ul_fetch_rows = 2000;				/*!< number of rows to fetch from result */
157 158
 int ul_hash_size = 10;
... ...
@@ -207,6 +208,7 @@ static param_export_t params[] = {
207 207
 	{"hash_size",           INT_PARAM, &ul_hash_size    },
208 208
 	{"nat_bflag",           INT_PARAM, &nat_bflag       },
209 209
 	{"handle_lost_tcp",     INT_PARAM, &handle_lost_tcp },
210
+	{"tcp_close_expired",   INT_PARAM, &close_expired_tcp },
210 211
 	{"preload",             PARAM_STRING|USE_FUNC_PARAM, (void*)ul_preload_param},
211 212
 	{"db_update_as_insert", INT_PARAM, &ul_db_update_as_insert},
212 213
 	{"timer_procs",         INT_PARAM, &ul_timer_procs},
... ...
@@ -81,6 +81,8 @@ extern int ul_db_update_as_insert;
81 81
 extern int ul_db_check_update;
82 82
 extern int ul_keepalive_timeout;
83 83
 extern int handle_lost_tcp;
84
+extern int close_expired_tcp;
85
+
84 86
 
85 87
 /*! nat branch flag */
86 88
 extern unsigned int nat_bflag;
... ...
@@ -34,6 +34,7 @@
34 34
 #include "../../ut.h"
35 35
 #include "../../hashes.h"
36 36
 #include "../../tcp_conn.h"
37
+#include "../../pass_fd.h"
37 38
 #include "ul_mod.h"
38 39
 #include "usrloc.h"
39 40
 #include "utime.h"
... ...
@@ -237,6 +238,31 @@ static inline int is_tcp_alive(ucontact_t *c)
237 237
 }
238 238
 
239 239
 /*!
240
+ * \brief Close a TCP connection
241
+ *
242
+ * Requests the TCP main process to close the specified TCP connection
243
+ * \param conid the internal connection ID
244
+ */
245
+static inline int close_connection(int conid) {
246
+	struct tcp_connection *con;
247
+	long msg[2];
248
+	int n;
249
+	if ((con = tcpconn_get(conid, 0, 0, 0, 0))) {
250
+		msg[0] = (long)con;
251
+		msg[1] = CONN_EOF;
252
+
253
+		n = send_all(unix_tcp_sock, msg, sizeof(msg));
254
+		tcpconn_put(con);
255
+		if (unlikely(n <= 0)){
256
+			LM_ERR("failed to send close request: %s (%d)\n", strerror(errno), errno);
257
+			return 0;
258
+		}
259
+		return 1;
260
+	}
261
+	return 0;
262
+}
263
+
264
+/*!
240 265
  * \brief Expires timer for NO_DB db_mode
241 266
  *
242 267
  * Expires timer for NO_DB db_mode, process all contacts from
... ...
@@ -247,6 +273,7 @@ static inline void nodb_timer(urecord_t* _r)
247 247
 {
248 248
 	ucontact_t* ptr, *t;
249 249
 
250
+
250 251
 	ptr = _r->contacts;
251 252
 
252 253
 	while(ptr) {
... ...
@@ -264,6 +291,10 @@ static inline void nodb_timer(urecord_t* _r)
264 264
 				ptr->aor->len, ZSW(ptr->aor->s),
265 265
 				ptr->c.len, ZSW(ptr->c.s));
266 266
 
267
+			if (close_expired_tcp && is_valid_tcpconn(ptr)) {
268
+				close_connection(ptr->tcpconn_id);
269
+			}
270
+
267 271
 			t = ptr;
268 272
 			ptr = ptr->next;
269 273
 
... ...
@@ -301,6 +332,10 @@ static inline void wt_timer(urecord_t* _r)
301 301
 				ptr->aor->len, ZSW(ptr->aor->s),
302 302
 				ptr->c.len, ZSW(ptr->c.s));
303 303
 
304
+			if (close_expired_tcp && is_valid_tcpconn(ptr)) {
305
+				close_connection(ptr->tcpconn_id);
306
+			}
307
+
304 308
 			t = ptr;
305 309
 			ptr = ptr->next;
306 310
 
... ...
@@ -350,6 +385,10 @@ static inline void wb_timer(urecord_t* _r)
350 350
 				ptr->c.len, ZSW(ptr->c.s));
351 351
 			update_stat( _r->slot->d->expires, 1);
352 352
 
353
+			if (close_expired_tcp && is_valid_tcpconn(ptr)) {
354
+				close_connection(ptr->tcpconn_id);
355
+			}
356
+
353 357
 			t = ptr;
354 358
 			ptr = ptr->next;
355 359