Browse code

keepalive: custom pinging interval per destination

- This functionality it's just available when using api.h bindings. For exported functions current value ka_ping_interval is used.
- Modified add_destination function to provide this new parameter.
- Now we have one timer per destination, instead of multiple, so we don't need to iterate over all destinations. Timers are cleaned when destinations are removed.

Nacho Garcia Segovia authored on 06/05/2020 21:10:40
Showing 8 changed files
... ...
@@ -38,7 +38,7 @@ typedef int ka_state;
38 38
 #define KA_STATE_DOWN 2
39 39
 
40 40
 typedef int (*ka_add_dest_f)(str *uri, str *owner, int flags,
41
-		ka_statechanged_f callback, void *user_attr);
41
+        int ping_interval, ka_statechanged_f callback, void *user_attr);
42 42
 typedef ka_state (*ka_dest_state_f)(str *uri);
43 43
 typedef int (*ka_del_destination_f)(str *uri, str *owner);
44 44
 typedef int (*ka_find_destination_f)(str *uri, str *owner,ka_dest_t **target,ka_dest_t **head);
... ...
@@ -46,6 +46,5 @@
46 46
     
47 47
     <xi:include href="keepalive_admin.xml"/>
48 48
     <xi:include href="keepalive_devel.xml"/>
49
-    
50
-    
49
+
51 50
 </book>
... ...
@@ -30,7 +30,7 @@
30 30
 
31 31
 	<section id="dev-add_destination">
32 32
 		<title>
33
-		<function moreinfo="none">add_destination(uri, owner, flags, [callback, [user_attr]])</function>
33
+		<function moreinfo="none">add_destination(uri, owner, flags, ping_interval, [callback, [user_attr]])</function>
34 34
 		</title>
35 35
 		<para>
36 36
 			This function registers a new destination to monitor. 
... ...
@@ -63,6 +63,11 @@
63 63
 				<emphasis>flags (integer)</emphasis> - destination flags (<emphasis>unused for now, use 0 value</emphasis>)
64 64
 			</para>
65 65
 		</listitem>
66
+		<listitem>
67
+			<para>
68
+				<emphasis>ping_interval (integer)</emphasis> - Pinging <emphasis>interval</emphasis> in seconds for this destination
69
+			</para>
70
+		</listitem>
66 71
 		<listitem>
67 72
 			<para>
68 73
 				<emphasis>callback (ka_statechanged_f, optional)</emphasis> - callback function, executed on destination's state change.
... ...
@@ -133,7 +138,7 @@ void my_callback(str uri, int state, void *user_attr) {
133 138
 str dest  = str_init("sip:192.168.10.21:5060");
134 139
 str owner = str_init("mymodule");
135 140
 
136
-if (ka_api.add_destination(dest, owner, 0, my_callback, NULL) != 0) {
141
+if (ka_api.add_destination(dest, owner, 0, 60, my_callback, NULL) != 0) {
137 142
     LM_ERR("can't add destination\n");
138 143
     goto error;
139 144
 }
... ...
@@ -38,6 +38,8 @@
38 38
 #define KA_PROBING_DST 8  /*!< checking destination */
39 39
 #define KA_STATES_ALL 15  /*!< all bits for the states of destination */
40 40
 
41
+extern int ka_ping_interval;
42
+
41 43
 #define ds_skip_dst(flags) ((flags) & (KA_INACTIVE_DST | KA_DISABLED_DST))
42 44
 
43 45
 #define KA_PROBE_NONE 0
... ...
@@ -64,6 +66,7 @@ typedef struct _ka_dest
64 66
 	struct ip_addr ip_address; /*!< IP-Address of the entry */
65 67
 	unsigned short int port;   /*!< Port of the URI */
66 68
 	unsigned short int proto;  /*!< Protocol of the URI */
69
+	struct timer_ln *timer;
67 70
 	struct _ka_dest *next;
68 71
 } ka_dest_t;
69 72
 
... ...
@@ -76,8 +79,10 @@ typedef struct _ka_destinations_list
76 79
 extern ka_destinations_list_t *ka_destinations_list;
77 80
 extern int ka_counter_del;
78 81
 
79
-int ka_add_dest(str *uri, str *owner, int flags, ka_statechanged_f callback,
80
-		void *user_attr);
82
+ticks_t ka_check_timer(ticks_t ticks, struct timer_ln* tl, void* param);
83
+
84
+int ka_add_dest(str *uri, str *owner, int flags, int ping_interval,
85
+        ka_statechanged_f callback, void *user_attr);
81 86
 int ka_destination_state(str *uri);
82 87
 int ka_str_copy(str *src, str *dest, char *prefix);
83 88
 int free_destination(ka_dest_t *dest) ;
... ...
@@ -62,8 +62,8 @@ int bind_keepalive(keepalive_api_t *api)
62 62
 /*
63 63
  * Add a new destination in keepalive pool
64 64
  */
65
-int ka_add_dest(str *uri, str *owner, int flags, ka_statechanged_f callback,
66
-		void *user_attr)
65
+int ka_add_dest(str *uri, str *owner, int flags, int ping_interval,
66
+    ka_statechanged_f callback, void *user_attr)
67 67
 {
68 68
 	struct sip_uri _uri;
69 69
 	ka_dest_t *dest=0,*hollow=0;
... ...
@@ -107,6 +107,20 @@ int ka_add_dest(str *uri, str *owner, int flags, ka_statechanged_f callback,
107 107
 	dest->statechanged_clb = callback;
108 108
 	dest->user_attr = user_attr;
109 109
 
110
+    dest->timer = timer_alloc();
111
+	if (dest->timer == NULL) {
112
+		LM_ERR("failed allocating timer\n");
113
+		goto err;
114
+  	}
115
+
116
+	timer_init(dest->timer, ka_check_timer, dest, 0);
117
+
118
+    int actual_ping_interval =  ping_interval == 0 ? ka_ping_interval : ping_interval;
119
+	if(timer_add(dest->timer, MS_TO_TICKS(actual_ping_interval * 1000)) < 0){
120
+		LM_ERR("failed to start timer\n");
121
+		goto err;
122
+	}
123
+
110 124
 	dest->next = ka_destinations_list->first;
111 125
 	ka_destinations_list->first = dest;
112 126
 
... ...
@@ -232,6 +246,12 @@ int ka_find_destination(str *uri, str *owner, ka_dest_t **target, ka_dest_t **he
232 246
 int free_destination(ka_dest_t *dest){
233 247
 
234 248
 	if(dest){
249
+        if(timer_del(dest->timer) < 0){
250
+          LM_ERR("failed to remove timer for destination <%.*s>\n", dest->uri.len, dest->uri.s);
251
+          return -1;
252
+        }
253
+
254
+        timer_free(dest->timer);
235 255
 		if(dest->uri.s)
236 256
 			shm_free(dest->uri.s);
237 257
 
... ...
@@ -48,47 +48,41 @@ static void ka_options_callback(struct cell *t, int type,
48 48
 
49 49
 extern str ka_ping_from;
50 50
 /*! \brief
51
- * Timer for checking probing destinations
51
+ * Callback run from timer,  for probing a destination
52 52
  *
53 53
  * This timer is regularly fired.
54 54
  */
55
-void ka_check_timer(unsigned int ticks, void *param)
55
+ticks_t ka_check_timer(ticks_t ticks, struct timer_ln* tl, void* param)
56 56
 {
57 57
 	ka_dest_t *ka_dest;
58 58
 	str ka_ping_method = str_init("OPTIONS");
59 59
 	str ka_outbound_proxy = {0, 0};
60 60
 	uac_req_t uac_r;
61 61
 
62
-	LM_DBG("ka check timer\n");
62
+	ka_dest = (ka_dest_t *)param;
63 63
 
64
-	ka_lock_destination_list();
64
+    LM_DBG("ka_check_timer dest:%.*s\n", ka_dest->uri.len, ka_dest->uri.s);
65 65
 
66
-	for(ka_dest = ka_destinations_list->first; ka_dest != NULL;
67
-			ka_dest = ka_dest->next) {
68
-		LM_DBG("ka_check_timer dest:%.*s\n", ka_dest->uri.len, ka_dest->uri.s);
66
+    if(ka_counter_del > 0 && ka_dest->counter > ka_counter_del) {
67
+        return (ticks_t)(0); /* stops the timer */
68
+    }
69 69
 
70
-		if(ka_counter_del > 0 && ka_dest->counter > ka_counter_del) {
71
-			continue;
72
-		}
70
+    /* Send ping using TM-Module.
71
+     * int request(str* m, str* ruri, str* to, str* from, str* h,
72
+     *		str* b, str *oburi,
73
+     *		transaction_cb cb, void* cbp); */
74
+    set_uac_req(&uac_r, &ka_ping_method, 0, 0, 0, TMCB_LOCAL_COMPLETED,
75
+            ka_options_callback, (void *)ka_dest);
73 76
 
74
-		/* Send ping using TM-Module.
75
-		 * int request(str* m, str* ruri, str* to, str* from, str* h,
76
-		 *		str* b, str *oburi,
77
-		 *		transaction_cb cb, void* cbp); */
78
-		set_uac_req(&uac_r, &ka_ping_method, 0, 0, 0, TMCB_LOCAL_COMPLETED,
79
-				ka_options_callback, (void *)ka_dest);
80
-
81
-		if(tmb.t_request(&uac_r, &ka_dest->uri, &ka_dest->uri, &ka_ping_from,
82
-				   &ka_outbound_proxy)
83
-				< 0) {
84
-			LM_ERR("unable to ping [%.*s]\n", ka_dest->uri.len, ka_dest->uri.s);
85
-		}
77
+    if(tmb.t_request(&uac_r, &ka_dest->uri, &ka_dest->uri, &ka_ping_from,
78
+               &ka_outbound_proxy)
79
+            < 0) {
80
+        LM_ERR("unable to ping [%.*s]\n", ka_dest->uri.len, ka_dest->uri.s);
81
+    }
86 82
 
87
-		ka_dest->last_checked = time(NULL);
88
-	}
89
-	ka_unlock_destination_list();
83
+    ka_dest->last_checked = time(NULL);
90 84
 
91
-	return;
85
+	return (ticks_t)(-1); /* periodical */
92 86
 }
93 87
 
94 88
 /*! \brief
... ...
@@ -51,7 +51,6 @@ static void mod_destroy(void);
51 51
 static int ka_mod_add_destination(modparam_t type, void *val);
52 52
 int ka_init_rpc(void);
53 53
 int ka_alloc_destinations_list();
54
-extern void ka_check_timer(unsigned int ticks, void *param);
55 54
 static int w_cmd_is_alive(struct sip_msg *msg, char *str1, char *str2);
56 55
 static int fixup_add_destination(void** param, int param_no);
57 56
 static int w_add_destination(sip_msg_t *msg, char *uri, char *owner);
... ...
@@ -125,11 +124,6 @@ static int mod_init(void)
125 124
 	if(ka_alloc_destinations_list() < 0)
126 125
 		return -1;
127 126
 
128
-	if(register_timer(ka_check_timer, NULL, ka_ping_interval) < 0) {
129
-		LM_ERR("failed registering timer\n");
130
-		return -1;
131
-	}
132
-
133 127
 	return 0;
134 128
 }
135 129
 
... ...
@@ -186,7 +180,7 @@ static int w_add_destination(sip_msg_t *msg, char *uri, char *owner)
186 180
 		return -1;
187 181
 	}
188 182
 
189
-	return ka_add_dest(&suri, &sowner, 0, 0, 0);
183
+	return ka_add_dest(&suri, &sowner, 0, ka_ping_interval, 0, 0);
190 184
 }
191 185
 
192 186
 /*!
... ...
@@ -197,7 +191,7 @@ static int ki_add_destination(sip_msg_t *msg, str *uri, str *owner)
197 191
 	if(ka_alloc_destinations_list() < 0)
198 192
 		return -1;
199 193
 
200
-	return ka_add_dest(uri, owner, 0, 0, 0);
194
+	return ka_add_dest(uri, owner, 0, ka_ping_interval, 0, 0);
201 195
 }
202 196
 
203 197
 /*!
... ...
@@ -247,7 +241,7 @@ static int ka_mod_add_destination(modparam_t type, void *val)
247 241
 	str owner = str_init("_params");
248 242
 	LM_DBG("adding destination %.*s\n", dest.len, dest.s);
249 243
 
250
-	return ka_add_dest(&dest, &owner, 0, 0, 0);
244
+	return ka_add_dest(&dest, &owner, 0, ka_ping_interval, 0, 0);
251 245
 }
252 246
 
253 247
 /*
... ...
@@ -122,7 +122,7 @@ static void keepalive_rpc_add(rpc_t *rpc, void *ctx)
122 122
 		return;
123 123
 	}
124 124
 
125
-	if(ka_add_dest(&sip_adress,&table_name,0,0,0) < 0 ){
125
+	if(ka_add_dest(&sip_adress,&table_name,0,ka_ping_interval,0,0) < 0 ){
126 126
 		LM_ERR("couldn't add data to list \n"  );
127 127
 		rpc->fault(ctx, 500, "couldn't add data to list");
128 128
 		return;