Explorar o código

keepalive: added uuid to ka_dest structure to avoid passing the whole struct to tm

- This avoids a race condition that may happen processing tm_request callbacl
- Allows to identify uniquely a ka_dest record
Nacho Garcia Segovia %!s(int64=5) %!d(string=hai) anos
pai
achega
9a3a8f1538

+ 5 - 0
src/modules/keepalive/keepalive.h

@@ -31,6 +31,8 @@
 #include <time.h>
 #include "../../core/sr_module.h"
 #include "../../core/locking.h"
+#include "../../core/str.h"
+#include "../../core/utils/sruid.h"
 #include "../tm/tm_load.h"
 
 #define KA_INACTIVE_DST 1 /*!< inactive destination */
@@ -60,6 +62,7 @@ typedef struct _ka_dest
 	str uri;
 	str owner; // name of destination "owner"
 			   // (module asking to monitor this destination
+	str  uuid; // Universal id for this record
 	int flags;
 	int state;
 	time_t last_checked, last_up, last_down;
@@ -85,6 +88,7 @@ typedef struct _ka_destinations_list
 
 extern ka_destinations_list_t *ka_destinations_list;
 extern int ka_counter_del;
+extern sruid_t ka_sruid;
 
 ticks_t ka_check_timer(ticks_t ticks, struct timer_ln* tl, void* param);
 
@@ -96,6 +100,7 @@ int ka_str_copy(str *src, str *dest, char *prefix);
 int free_destination(ka_dest_t *dest) ;
 int ka_del_destination(str *uri, str *owner) ;
 int ka_find_destination(str *uri, str *owner, ka_dest_t **target ,ka_dest_t **head);
+int ka_find_destination_by_uuid(str uuid, ka_dest_t **target, ka_dest_t **head);
 int ka_lock_destination_list();
 int ka_unlock_destination_list();
 #endif

+ 39 - 0
src/modules/keepalive/keepalive_api.c

@@ -103,6 +103,10 @@ int ka_add_dest(str *uri, str *owner, int flags, int ping_interval,
 	if(ka_str_copy(owner, &(dest->owner), NULL) < 0)
 		goto err;
 
+	if(sruid_next(&ka_sruid) < 0)
+		goto err;
+	ka_str_copy(&(ka_sruid.uid), &(dest->uuid), NULL);
+
 	dest->flags = flags;
 	dest->statechanged_clb = statechanged_clb;
 	dest->response_clb = response_clb;
@@ -236,6 +240,38 @@ int ka_find_destination(str *uri, str *owner, ka_dest_t **target, ka_dest_t **he
 	return 0;
 
 }
+
+/*!
+* @function ka_find_destination_by_uuid
+*
+* @param *uuid uuid of ka_dest record
+* @param **target searched address in stack
+* @param **head which points target
+*	*
+* @result 1 successful  , 0 fail
+*/
+int ka_find_destination_by_uuid(str uuid, ka_dest_t **target, ka_dest_t **head){
+	ka_dest_t  *dest=0 ,*temp=0;
+
+	LM_DBG("finding destination with uuid:%.*s\n", uuid.len, uuid.s);
+
+	for(dest = ka_destinations_list->first ;dest ; temp = dest, dest = dest->next ){
+		if(!dest)
+			break;
+
+		if (STR_EQ(uuid, dest->uuid)){
+			*head = temp;
+			*target = dest;
+			LM_DBG("destination is found [target : %p] [head : %p] \r\n",target,temp);
+			return 1;
+		}
+	}
+
+	return 0;
+
+}
+
+
 /*!
 * @function free_destination
 * @abstract free ka_dest_t members
@@ -259,6 +295,9 @@ int free_destination(ka_dest_t *dest){
 		if(dest->owner.s)
 			shm_free(dest->owner.s);
 
+		if(dest->uuid.s)
+			shm_free(dest->uuid.s);
+		
 		shm_free(dest);
 	}
 

+ 12 - 3
src/modules/keepalive/keepalive_core.c

@@ -67,12 +67,14 @@ ticks_t ka_check_timer(ticks_t ticks, struct timer_ln* tl, void* param)
         return (ticks_t)(0); /* stops the timer */
     }
 
+	str *uuid = shm_malloc(sizeof(str));
+	ka_str_copy(&(ka_dest->uuid), uuid, NULL);
     /* 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);
+            ka_options_callback, (void *)uuid);
 
     if(tmb.t_request(&uac_r, &ka_dest->uri, &ka_dest->uri, &ka_ping_from,
                &ka_outbound_proxy)
@@ -99,8 +101,15 @@ static void ka_options_callback(
 
 	char *state_routes[] = {"", "keepalive:dst-up", "keepalive:dst-down"};
 
-	//NOTE: how to be sure destination is still allocated ?
-	ka_dest_t *ka_dest = (ka_dest_t *)(*ps->param);
+	str *uuid = (str *)(*ps->param);
+
+	// Retrieve ka_dest by uuid from destination list
+	ka_dest_t *ka_dest=0,*hollow=0;
+	if (!ka_find_destination_by_uuid(*uuid, &ka_dest, &hollow)) {
+		LM_ERR("Couldn't find destination \r\n");
+		return;
+	}
+	shm_free(uuid);
 
 	uri.s = t->to.s + 5;
 	uri.len = t->to.len - 8;

+ 5 - 0
src/modules/keepalive/keepalive_mod.c

@@ -61,6 +61,7 @@ extern struct tm_binds tmb;
 
 int ka_ping_interval = 30;
 ka_destinations_list_t *ka_destinations_list = NULL;
+sruid_t ka_sruid;
 str ka_ping_from = str_init("sip:[email protected]");
 int ka_counter_del = 5;
 
@@ -124,6 +125,10 @@ static int mod_init(void)
 	if(ka_alloc_destinations_list() < 0)
 		return -1;
 
+	if(sruid_init(&ka_sruid, '-', "ka", SRUID_INC) < 0) {
+		return -1;
+	}
+
 	return 0;
 }