]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
add multicast stuff to sofia reg
authorAnthony Minessale <anthony.minessale@gmail.com>
Wed, 27 Sep 2006 20:18:14 +0000 (20:18 +0000)
committerAnthony Minessale <anthony.minessale@gmail.com>
Wed, 27 Sep 2006 20:18:14 +0000 (20:18 +0000)
git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@2851 d0543943-73ff-0310-b7d9-9358b9ac24b2

conf/freeswitch.xml
src/mod/endpoints/mod_sofia/mod_sofia.c
src/mod/event_handlers/mod_event_multicast/mod_event_multicast.c

index 469595599d55ce219150d8e9a3bb7c689d4cb386..5ab566e96914e5366afa56525fbbb94be5781982 100644 (file)
         </modules>
     </configuration>
 
+    <configuration name="event_multicast.conf" description="Multicast Event">
+      <settings>
+        <param name="address" value="225.1.1.1"/>
+        <param name="port" value="424242"/>
+        <param name="bindings" value="all"/>
+      </settings>
+    </configuration>
+
     <configuration name="event_socket.conf" description="Socket Client">
       <settings>
         <param name="listen-ip" value="127.0.0.1"/>
index cb08499522bcbecd9c6b4f5f6726540d8e550bf3..ba73deff952fac423b4f793433d35a0503d7e475 100644 (file)
@@ -49,6 +49,9 @@ typedef struct private_object private_object_t;
 
 #define MY_EVENT_REGISTER "sofia::register"
 #define MY_EVENT_EXPIRE "sofia::expire"
+#define MULTICAST_EVENT "multicast::event"
+
+
 #include <sofia-sip/nua.h>
 #include <sofia-sip/sip_status.h>
 #include <sofia-sip/sdp.h>
@@ -295,10 +298,11 @@ static int del_callback(void *pArg, int argc, char **argv, char **columnNames){
 
        if (argc >=3 ) {
                if (switch_event_create_subclass(&s_event, SWITCH_EVENT_CUSTOM, MY_EVENT_EXPIRE) == SWITCH_STATUS_SUCCESS) {
-                       switch_event_add_header(s_event, SWITCH_STACK_BOTTOM, "user", "%s", argv[0]);
-                       switch_event_add_header(s_event, SWITCH_STACK_BOTTOM, "host", "%s", argv[1]);
-                       switch_event_add_header(s_event, SWITCH_STACK_BOTTOM, "contact", "%s", argv[2]);
-                       switch_event_add_header(s_event, SWITCH_STACK_BOTTOM, "expires", "%d", argv[3]);
+                       switch_event_add_header(s_event, SWITCH_STACK_BOTTOM, "profile-name", "%s", argv[0]);
+                       switch_event_add_header(s_event, SWITCH_STACK_BOTTOM, "user", "%s", argv[1]);
+                       switch_event_add_header(s_event, SWITCH_STACK_BOTTOM, "host", "%s", argv[2]);
+                       switch_event_add_header(s_event, SWITCH_STACK_BOTTOM, "contact", "%s", argv[3]);
+                       switch_event_add_header(s_event, SWITCH_STACK_BOTTOM, "expires", "%d", argv[4]);
                        switch_event_fire(&s_event);
                }
        }
@@ -317,7 +321,7 @@ static void check_expire(sofia_profile_t *profile, time_t now)
        }
 
        switch_mutex_lock(profile->reg_mutex);
-       snprintf(sql, sizeof(sql), "select * from sip_registrations where expires > 0 and expires < %ld", (long) now);  
+       snprintf(sql, sizeof(sql), "select '%s',* from sip_registrations where expires > 0 and expires < %ld", profile->name, (long) now);      
        switch_core_db_exec(db, sql, del_callback, NULL, &errmsg);
 
        if (errmsg) {
@@ -1746,10 +1750,11 @@ static void sip_i_register(nua_t *nua,
        }
        
        if (switch_event_create_subclass(&s_event, SWITCH_EVENT_CUSTOM, MY_EVENT_REGISTER) == SWITCH_STATUS_SUCCESS) {
-               switch_event_add_header(s_event, SWITCH_STACK_BOTTOM, "from_user", "%s", from_user);
-               switch_event_add_header(s_event, SWITCH_STACK_BOTTOM, "from_host", "%s", from_host);
-               switch_event_add_header(s_event, SWITCH_STACK_BOTTOM, "contact_user", "%s", contact_user);
-               switch_event_add_header(s_event, SWITCH_STACK_BOTTOM, "contact_host", "%s", contact_host);
+               switch_event_add_header(s_event, SWITCH_STACK_BOTTOM, "profile-name", "%s", profile->name);
+               switch_event_add_header(s_event, SWITCH_STACK_BOTTOM, "from-user", "%s", from_user);
+               switch_event_add_header(s_event, SWITCH_STACK_BOTTOM, "from-host", "%s", from_host);
+               switch_event_add_header(s_event, SWITCH_STACK_BOTTOM, "contact-user", "%s", contact_user);
+               switch_event_add_header(s_event, SWITCH_STACK_BOTTOM, "contact-host", "%s", contact_host);
                switch_event_add_header(s_event, SWITCH_STACK_BOTTOM, "expires", "%ld", (long)expires->ex_delta);
                switch_event_fire(&s_event);
        }
@@ -2181,6 +2186,66 @@ static switch_status_t config_sofia(int reload)
 
 }
 
+static void event_handler(switch_event_t *event)
+{
+       char *subclass, *sql;
+
+       if ((subclass = switch_event_get_header(event, "orig-event-subclass")) && !strcmp(subclass, MY_EVENT_REGISTER)) {
+               char *from_user = switch_event_get_header(event, "orig-from-user");
+               char *from_host = switch_event_get_header(event, "orig-from-host");
+               char *contact_user = switch_event_get_header(event, "orig-contact-user");
+               char *contact_host = switch_event_get_header(event, "orig-contact-host");
+               char *exp_str = switch_event_get_header(event, "orig-expires");
+               long expires = time(NULL) + atol(exp_str);
+               char *profile_name = switch_event_get_header(event, "orig-profile-name");
+               sofia_profile_t *profile;
+               char buf[512];
+
+               if (!profile_name || !(profile = (sofia_profile_t *) switch_core_hash_find(globals.profile_hash, profile_name))) {
+                       switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid Profile\n");
+                       return;
+               }
+
+
+               if (!find_reg_url(profile, from_user, from_host, buf, sizeof(buf))) {
+                       sql = switch_core_db_mprintf("insert into sip_registrations values ('%q','%q','sip:%q@%q',%ld)", 
+                                                                                from_user,
+                                                                                from_host,
+                                                                                contact_user,
+                                                                                contact_host,
+                                                                                expires);
+               } else {
+                       sql = switch_core_db_mprintf("update sip_registrations set contact='sip:%q@%q', expires=%ld where user='%q' and host='%q'",
+                                                                                contact_user,
+                                                                                contact_host,
+                                                                                expires,
+                                                                                from_user,
+                                                                                from_host);
+                       
+               }
+       
+               if (sql) {
+                       switch_core_db_t *db;
+
+                       if (!(db = switch_core_db_open_file(profile->dbname))) {
+                               switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error Opening DB %s\n", profile->dbname);
+                               return;
+                       }
+                       switch_mutex_lock(profile->reg_mutex);
+                       switch_core_db_persistant_execute(db, sql, 25);
+                       switch_core_db_free(sql);
+                       sql = NULL;
+                       switch_mutex_unlock(profile->reg_mutex);
+                       switch_core_db_close(db);
+                       switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Propagating registration for %s@%s->%s@%s\n", 
+                                                         from_user, from_host, contact_user, contact_host);
+
+               }
+
+       }
+}
+
+
 SWITCH_MOD_DECLARE(switch_status_t) switch_module_load(const switch_loadable_module_interface_t **module_interface, char *filename)
 {
 
@@ -2192,6 +2257,12 @@ SWITCH_MOD_DECLARE(switch_status_t) switch_module_load(const switch_loadable_mod
        memset(&globals, 0, sizeof(globals));
        switch_mutex_init(&globals.mutex, SWITCH_MUTEX_NESTED, module_pool);
        
+
+       if (switch_event_bind((char *) modname, SWITCH_EVENT_CUSTOM, MULTICAST_EVENT, event_handler, NULL) != SWITCH_STATUS_SUCCESS) {
+               switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't bind!\n");
+               return SWITCH_STATUS_TERM;
+       }
+
        su_init();
 
 
index 5819bf712002fc8b1ab3d5201c7e8015357e6779..c9e0524dd79cc3964b691a2530ce32bc032bd70e 100644 (file)
@@ -39,6 +39,9 @@ static switch_memory_pool_t *module_pool = NULL;
 static struct {
        char *address;
        char *bindings;
+       uint32_t key_count;
+       char hostname[80];
+       uint64_t host_hash;
        switch_port_t port;
        switch_sockaddr_t *addr;
        switch_socket_t *udp_socket;
@@ -50,17 +53,23 @@ static struct {
 SWITCH_DECLARE_GLOBAL_STRING_FUNC(set_global_address, globals.address)
 SWITCH_DECLARE_GLOBAL_STRING_FUNC(set_global_bindings, globals.bindings)
 
+
 #define MULTICAST_EVENT "multicast::event"
 
 
-static switch_status_t load_config(void)
+        static switch_status_t load_config(void)
 {
        switch_status_t status = SWITCH_STATUS_SUCCESS;
        char *cf = "event_multicast.conf";
        switch_xml_t cfg, xml, settings, param;
        char *next, *cur;
-       uint32_t count = 0, key_count = 0;
+       uint32_t count = 0;
        uint8_t custom = 0;
+       apr_ssize_t hlen = APR_HASH_KEY_STRING;
+
+       gethostname(globals.hostname, sizeof(globals.hostname));
+       globals.host_hash = apr_hashfunc_default(globals.hostname, &hlen);
+       globals.key_count = 0;
 
        if (!(xml = switch_xml_open_cfg(cf, &cfg, NULL))) {
                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "open of %s failed\n", cf);
@@ -101,7 +110,7 @@ static switch_status_t load_config(void)
                        if (custom) {
                                switch_core_hash_insert_dup(globals.event_hash, cur, MARKER);
                        } else if (switch_name_event(cur, &type) == SWITCH_STATUS_SUCCESS) {
-                               key_count++;
+                               globals.key_count++;
                                if (type == SWITCH_EVENT_ALL) {
                                        uint32_t x = 0;
                                        for (x = 0; x < SWITCH_EVENT_ALL; x++) {
@@ -118,10 +127,10 @@ static switch_status_t load_config(void)
                }
        }
 
-       if (!key_count) {
-               switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "No Bindings Assuming ALL!\n");
-               globals.event_list[SWITCH_EVENT_ALL] = 1;
+       if (!globals.key_count) {
+               switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "No Bindings\n");
        }
+
        return status;
 
 }
@@ -147,15 +156,21 @@ static void event_handler(switch_event_t *event)
                }
        }
 
-       switch (event->event_id) {
-       case SWITCH_EVENT_LOG:
-               return;
-       default:
-               switch_event_serialize(event, buf, sizeof(buf), NULL);
-               len = strlen(buf);
-               //switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "\nEVENT\n--------------------------------\n%s\n", buf);
-               switch_socket_sendto(globals.udp_socket, globals.addr, 0, buf, &len);
-               break;
+       if (send) {
+               char *packet;
+               memcpy(buf, &globals.host_hash, sizeof(globals.host_hash));
+               packet = buf + sizeof(globals.host_hash);
+               switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Multicast-Sender", globals.hostname);
+               switch (event->event_id) {
+               case SWITCH_EVENT_LOG:
+                       return;
+               default:
+                       switch_event_serialize(event, packet, sizeof(buf) - sizeof(globals.host_hash), NULL);
+                       len = strlen(packet) + sizeof(globals.host_hash);;
+                       //switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "\nEVENT\n--------------------------------\n%s\n", buf);
+                       switch_socket_sendto(globals.udp_socket, globals.addr, 0, buf, &len);
+                       break;
+               }
        }
 }
 
@@ -172,18 +187,21 @@ static switch_loadable_module_interface_t event_test_module_interface = {
 
 SWITCH_MOD_DECLARE(switch_status_t) switch_module_load(const switch_loadable_module_interface_t **module_interface, char *filename)
 {
+
        memset(&globals, 0, sizeof(globals));
-       
-       if (load_config() != SWITCH_STATUS_SUCCESS) {
-               switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Cannot Configure\n");
-               return SWITCH_STATUS_TERM;
-       }
 
        if (switch_core_new_memory_pool(&module_pool) != SWITCH_STATUS_SUCCESS) {
                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "OH OH no pool\n");
                return SWITCH_STATUS_TERM;
        }
 
+       switch_core_hash_init(&globals.event_hash, module_pool);
+       
+       if (load_config() != SWITCH_STATUS_SUCCESS) {
+               switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Cannot Configure\n");
+               return SWITCH_STATUS_TERM;
+       }
+
        if (switch_sockaddr_info_get(&globals.addr, globals.address, SWITCH_UNSPEC, globals.port, 0, module_pool) != SWITCH_STATUS_SUCCESS) {
                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Cannot find address\n");
                return SWITCH_STATUS_TERM;
@@ -212,11 +230,12 @@ SWITCH_MOD_DECLARE(switch_status_t) switch_module_load(const switch_loadable_mod
                return SWITCH_STATUS_TERM;
        }
 
-       switch_core_hash_init(&globals.event_hash, module_pool);
+
 
        /* connect my internal structure to the blank pointer passed to me */
        *module_interface = &event_test_module_interface;
 
+       
        if (switch_event_bind((char *) modname, SWITCH_EVENT_ALL, SWITCH_EVENT_SUBCLASS_ANY, event_handler, NULL) !=
                SWITCH_STATUS_SUCCESS) {
                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't bind!\n");
@@ -224,6 +243,7 @@ SWITCH_MOD_DECLARE(switch_status_t) switch_module_load(const switch_loadable_mod
                return SWITCH_STATUS_GENERR;
        }
 
+
        /* indicate that the module should continue to be loaded */
        return SWITCH_STATUS_SUCCESS;
 }
@@ -246,20 +266,34 @@ SWITCH_MOD_DECLARE(switch_status_t) switch_module_shutdown(void)
 SWITCH_MOD_DECLARE(switch_status_t) switch_module_runtime(void)
 {
        switch_event_t *local_event;
-       char buf[65536];
-
+       char buf[65536] = {0};
+       switch_sockaddr_t *addr;
 
+       switch_sockaddr_info_get(&addr, NULL, SWITCH_UNSPEC, 0, 0, module_pool);
        globals.running = 1;
        while(globals.running == 1) {
-               switch_sockaddr_t addr = {0};
+               char *myaddr;
                size_t len = sizeof(buf);
                memset(buf, 0, len);
                
-               if (switch_socket_recvfrom(&addr, globals.udp_socket, 0, buf, &len) == SWITCH_STATUS_SUCCESS) {
+               switch_sockaddr_ip_get(&myaddr, globals.addr);
+
+               if (switch_socket_recvfrom(addr, globals.udp_socket, 0, buf, &len) == SWITCH_STATUS_SUCCESS) {
+                       char *packet;
+                       uint64_t host_hash = 0;
+
+                       memcpy(&host_hash, buf, sizeof(host_hash));
+                       packet = buf + sizeof(host_hash);
+                       
+                       if (host_hash == globals.host_hash) {
+                               continue;
+                       }
+
+                       //switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "\nEVENT %d\n--------------------------------\n%s\n", (int) len, packet);
                        if (switch_event_create_subclass(&local_event, SWITCH_EVENT_CUSTOM, MULTICAST_EVENT) == SWITCH_STATUS_SUCCESS) {
-                               char *var, *val, *term = NULL;
+                               char *var, *val, *term = NULL, tmpname[128];
                                switch_event_add_header(local_event, SWITCH_STACK_BOTTOM, "Multicast", "yes");
-                               var = buf;
+                               var = packet;
                                while(*var) {
                                        if ((val = strchr(var, ':')) != 0) {
                                                *val++ = '\0';
@@ -272,15 +306,15 @@ SWITCH_MOD_DECLARE(switch_status_t) switch_module_runtime(void)
                                                                term++;
                                                        }
                                                }
-                       
-                                               switch_event_add_header(local_event, SWITCH_STACK_BOTTOM, var, val);
+                                               snprintf(tmpname, sizeof(tmpname), "Orig-%s", var);
+                                               switch_event_add_header(local_event, SWITCH_STACK_BOTTOM, tmpname, val);
                                                var = term + 1;
                                        } else {
                                                break;
                                        }
                                } 
 
-                               if (!switch_strlen_zero(var)) {
+                               if (var && strlen(var) > 1) {
                                        switch_event_add_body(local_event, var);
                                }
 
@@ -288,7 +322,6 @@ SWITCH_MOD_DECLARE(switch_status_t) switch_module_runtime(void)
                        
                        }
                }
-
        }
                
        globals.running = 0;