keepalive: custom pinging interval per destination
authorNacho Garcia Segovia <nacho.gs@zaleos.net>
Wed, 6 May 2020 21:10:40 +0000 (23:10 +0200)
committerNacho Garcia Segovia <nacho.gs@zaleos.net>
Wed, 6 May 2020 21:10:40 +0000 (23:10 +0200)
- 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.

src/modules/keepalive/api.h
src/modules/keepalive/doc/keepalive.xml
src/modules/keepalive/doc/keepalive_devel.xml
src/modules/keepalive/keepalive.h
src/modules/keepalive/keepalive_api.c
src/modules/keepalive/keepalive_core.c
src/modules/keepalive/keepalive_mod.c
src/modules/keepalive/keepalive_rpc.c

index b2d9a2f..eca8bf2 100644 (file)
@@ -38,7 +38,7 @@ typedef int ka_state;
 #define KA_STATE_DOWN 2
 
 typedef int (*ka_add_dest_f)(str *uri, str *owner, int flags,
-               ka_statechanged_f callback, void *user_attr);
+        int ping_interval, ka_statechanged_f callback, void *user_attr);
 typedef ka_state (*ka_dest_state_f)(str *uri);
 typedef int (*ka_del_destination_f)(str *uri, str *owner);
 typedef int (*ka_find_destination_f)(str *uri, str *owner,ka_dest_t **target,ka_dest_t **head);
index 824393c..a03b2bf 100644 (file)
@@ -46,6 +46,5 @@
     
     <xi:include href="keepalive_admin.xml"/>
     <xi:include href="keepalive_devel.xml"/>
-    
-    
+
 </book>
index c5021e4..b8ea133 100644 (file)
@@ -30,7 +30,7 @@
 
        <section id="dev-add_destination">
                <title>
-               <function moreinfo="none">add_destination(uri, owner, flags, [callback, [user_attr]])</function>
+               <function moreinfo="none">add_destination(uri, owner, flags, ping_interval, [callback, [user_attr]])</function>
                </title>
                <para>
                        This function registers a new destination to monitor. 
                                <emphasis>flags (integer)</emphasis> - destination flags (<emphasis>unused for now, use 0 value</emphasis>)
                        </para>
                </listitem>
+               <listitem>
+                       <para>
+                               <emphasis>ping_interval (integer)</emphasis> - Pinging <emphasis>interval</emphasis> in seconds for this destination
+                       </para>
+               </listitem>
                <listitem>
                        <para>
                                <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) {
 str dest  = str_init("sip:192.168.10.21:5060");
 str owner = str_init("mymodule");
 
-if (ka_api.add_destination(dest, owner, 0, my_callback, NULL) != 0) {
+if (ka_api.add_destination(dest, owner, 0, 60, my_callback, NULL) != 0) {
     LM_ERR("can't add destination\n");
     goto error;
 }
index 2bd79bc..40d06db 100644 (file)
@@ -38,6 +38,8 @@
 #define KA_PROBING_DST 8  /*!< checking destination */
 #define KA_STATES_ALL 15  /*!< all bits for the states of destination */
 
+extern int ka_ping_interval;
+
 #define ds_skip_dst(flags) ((flags) & (KA_INACTIVE_DST | KA_DISABLED_DST))
 
 #define KA_PROBE_NONE 0
@@ -64,6 +66,7 @@ typedef struct _ka_dest
        struct ip_addr ip_address; /*!< IP-Address of the entry */
        unsigned short int port;   /*!< Port of the URI */
        unsigned short int proto;  /*!< Protocol of the URI */
+       struct timer_ln *timer;
        struct _ka_dest *next;
 } ka_dest_t;
 
@@ -76,8 +79,10 @@ typedef struct _ka_destinations_list
 extern ka_destinations_list_t *ka_destinations_list;
 extern int ka_counter_del;
 
-int ka_add_dest(str *uri, str *owner, int flags, ka_statechanged_f callback,
-               void *user_attr);
+ticks_t ka_check_timer(ticks_t ticks, struct timer_ln* tl, void* param);
+
+int ka_add_dest(str *uri, str *owner, int flags, int ping_interval,
+        ka_statechanged_f callback, void *user_attr);
 int ka_destination_state(str *uri);
 int ka_str_copy(str *src, str *dest, char *prefix);
 int free_destination(ka_dest_t *dest) ;
index 4ea1d9f..42f0ed8 100644 (file)
@@ -62,8 +62,8 @@ int bind_keepalive(keepalive_api_t *api)
 /*
  * Add a new destination in keepalive pool
  */
-int ka_add_dest(str *uri, str *owner, int flags, ka_statechanged_f callback,
-               void *user_attr)
+int ka_add_dest(str *uri, str *owner, int flags, int ping_interval,
+    ka_statechanged_f callback, void *user_attr)
 {
        struct sip_uri _uri;
        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,
        dest->statechanged_clb = callback;
        dest->user_attr = user_attr;
 
+    dest->timer = timer_alloc();
+       if (dest->timer == NULL) {
+               LM_ERR("failed allocating timer\n");
+               goto err;
+       }
+
+       timer_init(dest->timer, ka_check_timer, dest, 0);
+
+    int actual_ping_interval =  ping_interval == 0 ? ka_ping_interval : ping_interval;
+       if(timer_add(dest->timer, MS_TO_TICKS(actual_ping_interval * 1000)) < 0){
+               LM_ERR("failed to start timer\n");
+               goto err;
+       }
+
        dest->next = ka_destinations_list->first;
        ka_destinations_list->first = dest;
 
@@ -232,6 +246,12 @@ int ka_find_destination(str *uri, str *owner, ka_dest_t **target, ka_dest_t **he
 int free_destination(ka_dest_t *dest){
 
        if(dest){
+        if(timer_del(dest->timer) < 0){
+          LM_ERR("failed to remove timer for destination <%.*s>\n", dest->uri.len, dest->uri.s);
+          return -1;
+        }
+
+        timer_free(dest->timer);
                if(dest->uri.s)
                        shm_free(dest->uri.s);
 
index f641ace..1c19de6 100644 (file)
@@ -48,47 +48,41 @@ static void ka_options_callback(struct cell *t, int type,
 
 extern str ka_ping_from;
 /*! \brief
- * Timer for checking probing destinations
+ * Callback run from timer,  for probing a destination
  *
  * This timer is regularly fired.
  */
-void ka_check_timer(unsigned int ticks, void *param)
+ticks_t ka_check_timer(ticks_t ticks, struct timer_ln* tl, void* param)
 {
        ka_dest_t *ka_dest;
        str ka_ping_method = str_init("OPTIONS");
        str ka_outbound_proxy = {0, 0};
        uac_req_t uac_r;
 
-       LM_DBG("ka check timer\n");
+       ka_dest = (ka_dest_t *)param;
 
-       ka_lock_destination_list();
+    LM_DBG("ka_check_timer dest:%.*s\n", ka_dest->uri.len, ka_dest->uri.s);
 
-       for(ka_dest = ka_destinations_list->first; ka_dest != NULL;
-                       ka_dest = ka_dest->next) {
-               LM_DBG("ka_check_timer dest:%.*s\n", ka_dest->uri.len, ka_dest->uri.s);
+    if(ka_counter_del > 0 && ka_dest->counter > ka_counter_del) {
+        return (ticks_t)(0); /* stops the timer */
+    }
 
-               if(ka_counter_del > 0 && ka_dest->counter > ka_counter_del) {
-                       continue;
-               }
+    /* Send ping using TM-Module.
+     * int request(str* m, str* ruri, str* to, str* from, str* h,
+     *         str* b, str *oburi,
+     *         transaction_cb cb, void* cbp); */
+    set_uac_req(&uac_r, &ka_ping_method, 0, 0, 0, TMCB_LOCAL_COMPLETED,
+            ka_options_callback, (void *)ka_dest);
 
-               /* Send ping using TM-Module.
-                * int request(str* m, str* ruri, str* to, str* from, str* h,
-                *              str* b, str *oburi,
-                *              transaction_cb cb, void* cbp); */
-               set_uac_req(&uac_r, &ka_ping_method, 0, 0, 0, TMCB_LOCAL_COMPLETED,
-                               ka_options_callback, (void *)ka_dest);
-
-               if(tmb.t_request(&uac_r, &ka_dest->uri, &ka_dest->uri, &ka_ping_from,
-                                  &ka_outbound_proxy)
-                               < 0) {
-                       LM_ERR("unable to ping [%.*s]\n", ka_dest->uri.len, ka_dest->uri.s);
-               }
+    if(tmb.t_request(&uac_r, &ka_dest->uri, &ka_dest->uri, &ka_ping_from,
+               &ka_outbound_proxy)
+            < 0) {
+        LM_ERR("unable to ping [%.*s]\n", ka_dest->uri.len, ka_dest->uri.s);
+    }
 
-               ka_dest->last_checked = time(NULL);
-       }
-       ka_unlock_destination_list();
+    ka_dest->last_checked = time(NULL);
 
-       return;
+       return (ticks_t)(-1); /* periodical */
 }
 
 /*! \brief
index 3a10a44..3062149 100644 (file)
@@ -51,7 +51,6 @@ static void mod_destroy(void);
 static int ka_mod_add_destination(modparam_t type, void *val);
 int ka_init_rpc(void);
 int ka_alloc_destinations_list();
-extern void ka_check_timer(unsigned int ticks, void *param);
 static int w_cmd_is_alive(struct sip_msg *msg, char *str1, char *str2);
 static int fixup_add_destination(void** param, int param_no);
 static int w_add_destination(sip_msg_t *msg, char *uri, char *owner);
@@ -125,11 +124,6 @@ static int mod_init(void)
        if(ka_alloc_destinations_list() < 0)
                return -1;
 
-       if(register_timer(ka_check_timer, NULL, ka_ping_interval) < 0) {
-               LM_ERR("failed registering timer\n");
-               return -1;
-       }
-
        return 0;
 }
 
@@ -186,7 +180,7 @@ static int w_add_destination(sip_msg_t *msg, char *uri, char *owner)
                return -1;
        }
 
-       return ka_add_dest(&suri, &sowner, 0, 0, 0);
+       return ka_add_dest(&suri, &sowner, 0, ka_ping_interval, 0, 0);
 }
 
 /*!
@@ -197,7 +191,7 @@ static int ki_add_destination(sip_msg_t *msg, str *uri, str *owner)
        if(ka_alloc_destinations_list() < 0)
                return -1;
 
-       return ka_add_dest(uri, owner, 0, 0, 0);
+       return ka_add_dest(uri, owner, 0, ka_ping_interval, 0, 0);
 }
 
 /*!
@@ -247,7 +241,7 @@ static int ka_mod_add_destination(modparam_t type, void *val)
        str owner = str_init("_params");
        LM_DBG("adding destination %.*s\n", dest.len, dest.s);
 
-       return ka_add_dest(&dest, &owner, 0, 0, 0);
+       return ka_add_dest(&dest, &owner, 0, ka_ping_interval, 0, 0);
 }
 
 /*
index 0e6e6ec..136a150 100644 (file)
@@ -122,7 +122,7 @@ static void keepalive_rpc_add(rpc_t *rpc, void *ctx)
                return;
        }
 
-       if(ka_add_dest(&sip_adress,&table_name,0,0,0) < 0 ){
+       if(ka_add_dest(&sip_adress,&table_name,0,ka_ping_interval,0,0) < 0 ){
                LM_ERR("couldn't add data to list \n"  );
                rpc->fault(ctx, 500, "couldn't add data to list");
                return;