]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
add xml user caching mechanism
authorAnthony Minessale <anthm@freeswitch.org>
Mon, 23 May 2011 22:15:32 +0000 (17:15 -0500)
committerAnthony Minessale <anthm@freeswitch.org>
Mon, 23 May 2011 22:15:37 +0000 (17:15 -0500)
src/include/switch_xml.h
src/mod/applications/mod_commands/mod_commands.c
src/mod/endpoints/mod_sofia/sofia_reg.c
src/switch_xml.c

index 2d3f99487815028257df544a56b1099dd80aa986..cf8da02870e411b1025502ed69e2fb4328894a81 100644 (file)
@@ -378,7 +378,7 @@ SWITCH_DECLARE(switch_status_t) switch_xml_locate_user_in_domain(_In_z_ const ch
 
 SWITCH_DECLARE(switch_status_t) switch_xml_locate_user_merged(const char *key, const char *user_name, const char *domain_name,
                                                                                                                          const char *ip, switch_xml_t *user, switch_event_t *params);
-
+SWITCH_DECLARE(uint32_t) switch_xml_clear_user_cache(const char *key, const char *user_name, const char *domain_name);
 SWITCH_DECLARE(void) switch_xml_merge_user(switch_xml_t user, switch_xml_t domain, switch_xml_t group);
 
 SWITCH_DECLARE(switch_xml_t) switch_xml_dup(switch_xml_t xml);
index d7d67223e41f3cd6a610195ce11375b0c31a0db2..86d1e46d65a574e48a29f866e71e38a3428fb738 100644 (file)
@@ -4720,6 +4720,30 @@ SWITCH_STANDARD_API(hupall_api_function)
        return SWITCH_STATUS_SUCCESS;
 }
 
+
+SWITCH_STANDARD_API(xml_flush_function)
+{
+       char *mycmd = NULL, *argv[3] = { 0 };
+       int argc = 0;
+       int r = 0;
+
+       if (!zstr(cmd) && (mycmd = strdup(cmd))) {
+               argc = switch_split(mycmd, ' ', argv);
+       }
+
+       if (argc == 3) {
+               r = switch_xml_clear_user_cache(argv[0], argv[1], argv[2]);
+       } else {
+               r = switch_xml_clear_user_cache(NULL, NULL, NULL);
+       }
+
+
+       stream->write_function(stream, "+OK cleared %u entr%s\n", r, r == 1 ? "y" : "ies");
+
+       switch_safe_free(mycmd);
+       return SWITCH_STATUS_SUCCESS;
+}
+
 SWITCH_STANDARD_API(escape_function)
 {
        int len;
@@ -5233,8 +5257,11 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_commands_load)
        SWITCH_ADD_API(commands_api_interface, "uuid_simplify", "Try to cut out of a call path / attended xfer", uuid_simplify_function, SIMPLIFY_SYNTAX);
        SWITCH_ADD_API(commands_api_interface, "uuid_jitterbuffer", "Try to cut out of a call path / attended xfer", 
                                   uuid_jitterbuffer_function, JITTERBUFFER_SYNTAX);
+       SWITCH_ADD_API(commands_api_interface, "xml_flush_cache", "clear xml cache", xml_flush_function, "<id> <key> <val>");
        SWITCH_ADD_API(commands_api_interface, "xml_locate", "find some xml", xml_locate_function, "[root | <section> <tag> <tag_attr_name> <tag_attr_val>]");
        SWITCH_ADD_API(commands_api_interface, "xml_wrap", "Wrap another api command in xml", xml_wrap_api_function, "<command> <args>");
+
+
        switch_console_set_complete("add alias add");
        switch_console_set_complete("add alias del");
        switch_console_set_complete("add complete add");
index 9130ceb5691fb19b1e5c22e16d18eb844b0d304a..c757a9e43e0676db91e66668b436b5fbe21d4f82 100644 (file)
@@ -2002,7 +2002,7 @@ auth_res_t sofia_reg_parse_auth(sofia_profile_t *profile,
        const char *call_id = NULL;
        char *sql;
        char *number_alias = NULL;
-       switch_xml_t domain, xml = NULL, user, param, uparams, dparams, group = NULL, gparams = NULL;
+       switch_xml_t user = NULL, param, uparams;
        char hexdigest[2 * SU_MD5_DIGEST_SIZE + 1] = "";
        char *domain_name = NULL;
        switch_event_t *params = NULL;
@@ -2179,7 +2179,7 @@ auth_res_t sofia_reg_parse_auth(sofia_profile_t *profile,
                domain_name = realm;
        }
 
-       if (switch_xml_locate_user("id", zstr(username) ? "nobody" : username, domain_name, ip, &xml, &domain, &user, &group, params) != SWITCH_STATUS_SUCCESS) {
+       if (switch_xml_locate_user_merged("id", zstr(username) ? "nobody" : username, domain_name, ip, &user, params) != SWITCH_STATUS_SUCCESS) {
                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Can't find user [%s@%s]\n"
                                                  "You must define a domain called '%s' in your directory and add a user with the id=\"%s\" attribute\n"
                                                  "and you must configure your device to use the proper domain in it's authentication credentials.\n", username, domain_name,
@@ -2200,90 +2200,10 @@ auth_res_t sofia_reg_parse_auth(sofia_profile_t *profile,
                number_alias = zstr(username) ? "nobody" : username;
        }
 
-       dparams = switch_xml_child(domain, "params");
-       uparams = switch_xml_child(user, "params");
-       if (group) {
-               gparams = switch_xml_child(group, "params");
-       }
-
-       if (!(dparams || uparams)) {
+       if (!(uparams = switch_xml_child(user, "params"))) {
                ret = AUTH_OK;
                goto skip_auth;
-       }
-
-       if (dparams) {
-               for (param = switch_xml_child(dparams, "param"); param; param = param->next) {
-                       const char *var = switch_xml_attr_soft(param, "name");
-                       const char *val = switch_xml_attr_soft(param, "value");
-
-                       if (!strcasecmp(var, "sip-forbid-register") && switch_true(val)) {
-                               ret = AUTH_FORBIDDEN;
-                               goto end;
-                       }
-
-                       if (!strcasecmp(var, "password")) {
-                               passwd = val;
-                       }
-
-                       if (!strcasecmp(var, "auth-acl")) {
-                               auth_acl = val;
-                       }
-
-                       if (!strcasecmp(var, "a1-hash")) {
-                               a1_hash = val;
-                       }
-                       if (!strcasecmp(var, "mwi-account")) {
-                               mwi_account = val;
-                       }
-                       if (!strcasecmp(var, "allow-empty-password")) {
-                               allow_empty_password = switch_true(val);
-                       }
-                       if (!strcasecmp(var, "user-agent-filter")) {
-                               user_agent_filter = val;
-                       }
-                       if (!strcasecmp(var, "max-registrations-per-extension")) {
-                               max_registrations_perext = atoi(val);
-                       }
-               }
-       }
-
-       if (gparams) {
-               for (param = switch_xml_child(gparams, "param"); param; param = param->next) {
-                       const char *var = switch_xml_attr_soft(param, "name");
-                       const char *val = switch_xml_attr_soft(param, "value");
-
-                       if (!strcasecmp(var, "sip-forbid-register") && switch_true(val)) {
-                               ret = AUTH_FORBIDDEN;
-                               goto end;
-                       }
-
-                       if (!strcasecmp(var, "password")) {
-                               passwd = val;
-                       }
-
-                       if (!strcasecmp(var, "auth-acl")) {
-                               auth_acl = val;
-                       }
-
-                       if (!strcasecmp(var, "a1-hash")) {
-                               a1_hash = val;
-                       }
-                       if (!strcasecmp(var, "mwi-account")) {
-                               mwi_account = val;
-                       }
-                       if (!strcasecmp(var, "allow-empty-password")) {
-                               allow_empty_password = switch_true(val);
-                       }
-                       if (!strcasecmp(var, "user-agent-filter")) {
-                               user_agent_filter = val;
-                       }
-                       if (!strcasecmp(var, "max-registrations-per-extension")) {
-                               max_registrations_perext = atoi(val);
-                       }
-               }
-       }
-
-       if (uparams) {
+       } else {
                for (param = switch_xml_child(uparams, "param"); param; param = param->next) {
                        const char *var = switch_xml_attr_soft(param, "name");
                        const char *val = switch_xml_attr_soft(param, "value");
@@ -2504,31 +2424,11 @@ auth_res_t sofia_reg_parse_auth(sofia_profile_t *profile,
                                switch_event_add_header_string(*v_event, SWITCH_STACK_BOTTOM, "mwi-account", mwi_account);
                        }
 
-                       if ((dparams = switch_xml_child(domain, "params"))) {
-                               xparams_type[i] = 0;
-                               xparams[i++] = dparams;
-                       }
-
-                       if (group && (gparams = switch_xml_child(group, "params"))) {
-                               xparams_type[i] = 0;
-                               xparams[i++] = gparams;
-                       }
-
                        if ((uparams = switch_xml_child(user, "params"))) {
                                xparams_type[i] = 0;
                                xparams[i++] = uparams;
                        }
 
-                       if ((dparams = switch_xml_child(domain, "variables"))) {
-                               xparams_type[i] = 1;
-                               xparams[i++] = dparams;
-                       }
-
-                       if (group && (gparams = switch_xml_child(group, "variables"))) {
-                               xparams_type[i] = 1;
-                               xparams[i++] = gparams;
-                       }
-
                        if ((uparams = switch_xml_child(user, "variables"))) {
                                xparams_type[i] = 1;
                                xparams[i++] = uparams;
@@ -2632,8 +2532,8 @@ auth_res_t sofia_reg_parse_auth(sofia_profile_t *profile,
 
        switch_event_destroy(&params);
 
-       if (xml) {
-               switch_xml_free(xml);
+       if (user) {
+               switch_xml_free(user);
        }
 
        switch_safe_free(input);
index 243494aa7c3fee7fe5f10691b55e17e41978936a..2d2ba4d240f3373dc67418dc4c95f7b7902ea43c 100644 (file)
@@ -136,10 +136,12 @@ static switch_memory_pool_t *XML_MEMORY_POOL = NULL;
 
 static switch_thread_rwlock_t *B_RWLOCK = NULL;
 static switch_mutex_t *XML_LOCK = NULL;
+static switch_mutex_t *CACHE_MUTEX = NULL;
 static switch_mutex_t *REFLOCK = NULL;
 static switch_mutex_t *FILE_LOCK = NULL;
 static switch_mutex_t *XML_GEN_LOCK = NULL;
 
+static switch_hash_t *CACHE_HASH = NULL;
 
 struct xml_section_t {
        const char *name;
@@ -1826,15 +1828,92 @@ SWITCH_DECLARE(void) switch_xml_merge_user(switch_xml_t user, switch_xml_t domai
        do_merge(user, domain, "variables", "variable");
 }
 
+SWITCH_DECLARE(uint32_t) switch_xml_clear_user_cache(const char *key, const char *user_name, const char *domain_name)
+{
+       switch_hash_index_t *hi;
+       void *val;
+       const void *var;
+       char mega_key[1024];
+       int r = 0;
+       switch_xml_t lookup;
+
+       switch_mutex_lock(CACHE_MUTEX);
+
+       if (key && user_name && domain_name) {
+               switch_snprintf(mega_key, sizeof(mega_key), "%s%s%s", key, user_name, domain_name);
+
+               if ((lookup = switch_core_hash_find(CACHE_HASH, mega_key))) {
+                       switch_core_hash_delete(CACHE_HASH, mega_key);
+                       switch_xml_free(lookup);
+                       r++;
+               }
+               
+       } else {
+               
+       top:
+               for (hi = switch_hash_first(NULL, CACHE_HASH); hi; hi = switch_hash_next(hi)) {
+                       switch_hash_this(hi, &var, NULL, &val);
+                       switch_xml_free(val);
+                       switch_core_hash_delete(CACHE_HASH, var);
+                       r++;
+                       goto top;
+               }
+       }
+
+       switch_mutex_unlock(CACHE_MUTEX);
+               
+       return r;
+       
+}
+
+static switch_status_t switch_xml_locate_user_cache(const char *key, const char *user_name, const char *domain_name, switch_xml_t *user)
+{
+       char mega_key[1024];
+       switch_xml_t lookup;
+       switch_status_t status = SWITCH_STATUS_FALSE;
+
+       switch_snprintf(mega_key, sizeof(mega_key), "%s%s%s", key, user_name, domain_name);
+
+       switch_mutex_lock(CACHE_MUTEX);
+       if ((lookup = switch_core_hash_find(CACHE_HASH, mega_key))) {
+               *user = switch_xml_dup(lookup);
+               status = SWITCH_STATUS_SUCCESS;
+       }
+       switch_mutex_unlock(CACHE_MUTEX);
+
+       return status;
+}
+
+static void switch_xml_user_cache(const char *key, const char *user_name, const char *domain_name, switch_xml_t user)
+{
+       char mega_key[1024];
+       switch_xml_t lookup;
+
+       switch_snprintf(mega_key, sizeof(mega_key), "%s%s%s", key, user_name, domain_name);
+       switch_mutex_lock(CACHE_MUTEX);
+       if ((lookup = switch_core_hash_find(CACHE_HASH, mega_key))) {
+               switch_core_hash_delete(CACHE_HASH, mega_key);
+               switch_xml_free(lookup);
+       }
+       
+       switch_core_hash_insert(CACHE_HASH, mega_key, switch_xml_dup(user));
+       switch_mutex_unlock(CACHE_MUTEX);
+}
+
 SWITCH_DECLARE(switch_status_t) switch_xml_locate_user_merged(const char *key, const char *user_name, const char *domain_name,
                                                                                                                          const char *ip, switch_xml_t *user, switch_event_t *params)
 {
        switch_xml_t xml, domain, group, x_user, x_user_dup;
        switch_status_t status = SWITCH_STATUS_FALSE;
 
-       if ((status = switch_xml_locate_user(key, user_name, domain_name, ip, &xml, &domain, &x_user, &group, params)) == SWITCH_STATUS_SUCCESS) {
+       if ((status = switch_xml_locate_user_cache(key, user_name, domain_name, &x_user)) == SWITCH_STATUS_SUCCESS) {
+               *user = x_user;
+       } else if ((status = switch_xml_locate_user(key, user_name, domain_name, ip, &xml, &domain, &x_user, &group, params)) == SWITCH_STATUS_SUCCESS) {
                x_user_dup = switch_xml_dup(x_user);
                switch_xml_merge_user(x_user_dup, domain, group);
+               if (switch_true(switch_xml_attr(x_user_dup, "cacheable"))) {
+                       switch_xml_user_cache(key, user_name, domain_name, x_user_dup);
+               }
                *user = x_user_dup;
                switch_xml_free(xml);
        }
@@ -2057,10 +2136,12 @@ SWITCH_DECLARE(switch_status_t) switch_xml_init(switch_memory_pool_t *pool, cons
        XML_MEMORY_POOL = pool;
        *err = "Success";
 
+       switch_mutex_init(&CACHE_MUTEX, SWITCH_MUTEX_NESTED, XML_MEMORY_POOL);
        switch_mutex_init(&XML_LOCK, SWITCH_MUTEX_NESTED, XML_MEMORY_POOL);
        switch_mutex_init(&REFLOCK, SWITCH_MUTEX_NESTED, XML_MEMORY_POOL);
        switch_mutex_init(&FILE_LOCK, SWITCH_MUTEX_NESTED, XML_MEMORY_POOL);
        switch_mutex_init(&XML_GEN_LOCK, SWITCH_MUTEX_NESTED, XML_MEMORY_POOL);
+       switch_core_hash_init(&CACHE_HASH, XML_MEMORY_POOL);
 
        switch_thread_rwlock_create(&B_RWLOCK, XML_MEMORY_POOL);
 
@@ -2078,6 +2159,7 @@ SWITCH_DECLARE(switch_status_t) switch_xml_destroy(void)
 {
        switch_status_t status = SWITCH_STATUS_FALSE;
 
+
        switch_mutex_lock(XML_LOCK);
        switch_mutex_lock(REFLOCK);
 
@@ -2091,6 +2173,10 @@ SWITCH_DECLARE(switch_status_t) switch_xml_destroy(void)
        switch_mutex_unlock(XML_LOCK);
        switch_mutex_unlock(REFLOCK);
 
+       switch_xml_clear_user_cache(NULL, NULL, NULL);
+
+       switch_core_hash_destroy(&CACHE_HASH);
+
        return status;
 }