]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
Add initial support for multicast peer up/down state tracking
authorAndrew Thompson <andrew@hijacked.us>
Tue, 23 Jun 2009 00:59:03 +0000 (00:59 +0000)
committerAndrew Thompson <andrew@hijacked.us>
Tue, 23 Jun 2009 00:59:03 +0000 (00:59 +0000)
git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@13901 d0543943-73ff-0310-b7d9-9358b9ac24b2

src/mod/event_handlers/mod_event_multicast/mod_event_multicast.c

index 4e26c1c34b48e7649c5c47cbf7f7e18214db482e..d977f6162e5082993251859ea8b4bdeea88d58dc 100644 (file)
@@ -63,14 +63,22 @@ static struct {
        uint8_t ttl;
        char *psk;
        switch_mutex_t *mutex;
+       switch_hash_t *peer_hash;
 } globals;
 
+struct peer_status {
+       switch_bool_t active;
+       int lastseen;
+};
+
 SWITCH_DECLARE_GLOBAL_STRING_FUNC(set_global_address, globals.address);
 SWITCH_DECLARE_GLOBAL_STRING_FUNC(set_global_bindings, globals.bindings);
 #ifdef HAVE_OPENSSL
 SWITCH_DECLARE_GLOBAL_STRING_FUNC(set_global_psk, globals.psk);
 #endif
 #define MULTICAST_EVENT "multicast::event"
+#define MULTICAST_PEERUP "multicast::peerup"
+#define MULTICAST_PEERDOWN "multicast::peerdown"
 static switch_status_t load_config(void)
 {
        switch_status_t status = SWITCH_STATUS_SUCCESS;
@@ -169,6 +177,42 @@ static void event_handler(switch_event_t *event)
        }
 
        if (event->subclass_name && !strcmp(event->subclass_name, MULTICAST_EVENT)) {
+               char * event_name;
+               if ((event_name = switch_event_get_header(event, "orig-event-name")) && !strcasecmp(event_name, "HEARTBEAT")) {
+                       char *sender = switch_event_get_header(event, "orig-multicast-sender");
+                       struct peer_status *p;
+                       int now = switch_epoch_time_now(NULL);
+                       
+                       if (!(p = switch_core_hash_find(globals.peer_hash, sender))) {
+                               switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Host %s not already in hash\n", sender);
+                               p = switch_core_alloc(module_pool, sizeof(struct peer_status));
+                               p->active = SWITCH_FALSE;
+                               p->lastseen = 0;
+                       /*} else {*/
+                               /*switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Host %s last seen %d seconds ago\n", sender, now - p->lastseen);*/
+                       }
+
+                       if (!p->active) {
+                               switch_event_t *local_event;
+                               if (switch_event_create_subclass(&local_event, SWITCH_EVENT_CUSTOM, MULTICAST_PEERUP) == SWITCH_STATUS_SUCCESS) {
+                                       char lastseen[21];
+                                       switch_event_add_header_string(local_event, SWITCH_STACK_BOTTOM, "Peer", sender);
+                                       if (p->lastseen) {
+                                               switch_snprintf(lastseen, sizeof(lastseen), "%d", p->lastseen);
+                                       } else {
+                                               switch_snprintf(lastseen, sizeof(lastseen), "%s", "Never");
+                                       }
+                                       switch_event_add_header_string(local_event, SWITCH_STACK_BOTTOM, "Lastseen", lastseen);
+                                       switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Peer %s has come up; last seen: %s\n", sender, lastseen);
+
+                                       switch_event_fire(&local_event);
+                               }
+                       }
+                       p->active = SWITCH_TRUE;
+                       p->lastseen = now;
+
+                       switch_core_hash_insert(globals.peer_hash, sender, p);
+               }
                /* ignore our own events to avoid ping pong */
                return;
        }
@@ -187,6 +231,36 @@ static void event_handler(switch_event_t *event)
                switch_mutex_unlock(globals.mutex);
        }
 
+       if (event->event_id == SWITCH_EVENT_HEARTBEAT) {
+               switch_hash_index_t *cur;
+               switch_ssize_t keylen;
+               const void *key;
+               void *value;
+               int now = switch_epoch_time_now(NULL);
+               struct peer_status *last;
+               char *host;
+               
+               for (cur = switch_hash_first(NULL, globals.peer_hash); cur; cur = switch_hash_next(cur)) {
+                       switch_hash_this(cur, &key, &keylen, &value);
+                       host = (char*) key;
+                       last = (struct peer_status*) value;
+                       if (last->active && (now - (last->lastseen)) > 60) {
+                               switch_event_t *local_event;
+
+                               last->active = SWITCH_FALSE;
+                               if (switch_event_create_subclass(&local_event, SWITCH_EVENT_CUSTOM, MULTICAST_PEERDOWN) == SWITCH_STATUS_SUCCESS) {
+                                       char lastseen[21];
+                                       switch_event_add_header_string(local_event, SWITCH_STACK_BOTTOM, "Peer", host);
+                                       switch_snprintf(lastseen, sizeof(lastseen), "%d", last->lastseen);
+                                       switch_event_add_header_string(local_event, SWITCH_STACK_BOTTOM, "Lastseen", lastseen);
+                                       switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Peer %s has gone down; last seen: %s\n", host, lastseen);
+
+                                       switch_event_fire(&local_event);
+                               }
+                       }
+               }
+       }
+
        switch_mutex_lock(globals.mutex);
        if (globals.event_list[(uint8_t) SWITCH_EVENT_ALL]) {
                send = 1;
@@ -271,6 +345,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_event_multicast_load)
        module_pool = pool;
 
        switch_core_hash_init(&globals.event_hash, module_pool);
+       switch_core_hash_init(&globals.peer_hash, module_pool);
 
        gethostname(globals.hostname, sizeof(globals.hostname));
        globals.host_hash = switch_hashfunc_default(globals.hostname, &hlen);
@@ -319,7 +394,17 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_event_multicast_load)
        *module_interface = switch_loadable_module_create_module_interface(pool, modname);
 
        if (switch_event_reserve_subclass(MULTICAST_EVENT) != SWITCH_STATUS_SUCCESS) {
-               switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't register subclass!\n");
+               switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't register subclass %s!\n", MULTICAST_EVENT);
+               return SWITCH_STATUS_GENERR;
+       }
+
+       if (switch_event_reserve_subclass(MULTICAST_PEERUP) != SWITCH_STATUS_SUCCESS) {
+               switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't register subclass %s!\n", MULTICAST_PEERUP);
+               return SWITCH_STATUS_GENERR;
+       }
+
+       if (switch_event_reserve_subclass(MULTICAST_PEERDOWN) != SWITCH_STATUS_SUCCESS) {
+               switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't register subclass %s!\n", MULTICAST_PEERDOWN);
                return SWITCH_STATUS_GENERR;
        }