]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
FSCORE-637 - limit - reset rate and release resource apis
authorRupa Schomaker <rupa@rupa.com>
Wed, 21 Jul 2010 03:21:32 +0000 (22:21 -0500)
committerRupa Schomaker <rupa@rupa.com>
Wed, 21 Jul 2010 03:21:32 +0000 (22:21 -0500)
 Thanks Moy

src/include/switch_limit.h
src/include/switch_loadable_module.h
src/include/switch_module_interfaces.h
src/mod/applications/mod_commands/mod_commands.c
src/mod/applications/mod_db/mod_db.c
src/mod/applications/mod_hash/mod_hash.c
src/mod/applications/mod_redis/mod_redis.c
src/switch_limit.c

index c63ac7fb57e28cf56791938fb45cc0dc9633922f..e798f9c8af97599688e53ba4feff10f6967a3fe2 100644 (file)
@@ -76,6 +76,14 @@ SWITCH_DECLARE(switch_status_t) switch_limit_release(const char *backend, switch
 */
 SWITCH_DECLARE(int) switch_limit_usage(const char *backend, const char *realm, const char *resource, uint32_t *rcount);
 
+/*!
+  \brief reset interval usage counter for a given resource
+  \param backend
+  \param realm
+  \param resource
+*/
+SWITCH_DECLARE(switch_status_t) switch_limit_interval_reset(const char *backend, const char *realm, const char *resource);
+
 /*!
   \brief reset all usage counters
   \param backend to use
@@ -106,6 +114,7 @@ SWITCH_DECLARE(char *) switch_limit_status(const char *backend);
 #define SWITCH_LIMIT_RELEASE(name) static switch_status_t name (switch_core_session_t *session, const char *realm, const char *resource)
 #define SWITCH_LIMIT_USAGE(name) static int name (const char *realm, const char *resource, uint32_t *rcount)
 #define SWITCH_LIMIT_RESET(name) static switch_status_t name (void)
+#define SWITCH_LIMIT_INTERVAL_RESET(name) static switch_status_t name (const char *realm, const char *resource)
 #define SWITCH_LIMIT_STATUS(name) static char * name (void)
 
 #define LIMIT_IGNORE_TRANSFER_VARIABLE "limit_ignore_transfer"
index d1c578b9319cf1e0b795371a1ab3fed7ff2138e7..158de6ce635f244ab6db9d7792ece8712f260a90 100644 (file)
@@ -324,13 +324,14 @@ SWITCH_MOD_DECLARE(switch_status_t) switch_module_shutdown(void);
        break; \
        }
 
-#define SWITCH_ADD_LIMIT(limit_int, int_name, incrptr, releaseptr, usageptr, resetptr, statusptr) \
+#define SWITCH_ADD_LIMIT(limit_int, int_name, incrptr, releaseptr, usageptr, resetptr, statusptr, interval_resetptr) \
        for (;;) { \
        limit_int = (switch_limit_interface_t *)switch_loadable_module_create_interface(*module_interface, SWITCH_LIMIT_INTERFACE); \
        limit_int->incr = incrptr; \
        limit_int->release = releaseptr; \
        limit_int->usage = usageptr; \
        limit_int->reset = resetptr; \
+       limit_int->interval_reset = interval_resetptr; \
        limit_int->status = statusptr; \
        limit_int->interface_name = int_name; \
        break; \
index 64131378de3a47a9fb9a3d70c5acbc307608ba5f..078b83d2fd052adcdbe9760efcb1616849bda900 100644 (file)
@@ -526,6 +526,8 @@ struct switch_limit_interface {
        switch_status_t (*reset) (void);
        /*! freform status */
        char * (*status) (void);
+       /*! reset interval counter */
+       switch_status_t (*interval_reset) (const char *realm, const char *resource);
        /* internal */
        switch_thread_rwlock_t *rwlock;
        int refs;
index a64510599440bba742f06b1963bf34d1d54a1044..07da553cd2ca4686663d6a122cfe06bc6390539d 100644 (file)
@@ -4227,7 +4227,7 @@ SWITCH_STANDARD_API(sql_escape)
 }
 
 /* LIMIT Stuff */
-#define LIMIT_USAGE_USAGE "<backend> <realm> <id> [rate]"
+#define LIMIT_USAGE_SYNTAX "<backend> <realm> <id> [rate]"
 SWITCH_STANDARD_API(limit_usage_function)
 {
        int argc = 0;
@@ -4255,7 +4255,7 @@ SWITCH_STANDARD_API(limit_usage_function)
        }
        
        if (argc < 3) {
-               stream->write_function(stream, "USAGE: limit_usage %s\n", LIMIT_USAGE_USAGE);
+               stream->write_function(stream, "USAGE: limit_usage %s\n", LIMIT_USAGE_SYNTAX);
                goto end;
        }
 
@@ -4279,7 +4279,7 @@ end:
        return SWITCH_STATUS_SUCCESS;
 }
 
-#define LIMIT_HASH_USAGE_USAGE "<realm> <id> [rate] (Using deprecated limit api, check limit_usage with backend param)"
+#define LIMIT_HASH_USAGE_SYNTAX "<realm> <id> [rate] (Using deprecated limit api, check limit_usage with backend param)"
 SWITCH_STANDARD_API(limit_hash_usage_function)
 {
        char *mydata = NULL;
@@ -4290,12 +4290,12 @@ SWITCH_STANDARD_API(limit_hash_usage_function)
                switch_safe_free(mydata);
                return ret;
        } else {
-               stream->write_function(stream, "USAGE: limit_hash_usage %s\n", LIMIT_HASH_USAGE_USAGE);
+               stream->write_function(stream, "USAGE: limit_hash_usage %s\n", LIMIT_HASH_USAGE_SYNTAX);
                return SWITCH_STATUS_SUCCESS;
        }
 }
 
-#define LIMIT_STATUS_USAGE "<backend>"
+#define LIMIT_STATUS_SYNTAX "<backend>"
 SWITCH_STANDARD_API(limit_status_function)
 {
        int argc = 0;
@@ -4310,7 +4310,7 @@ SWITCH_STANDARD_API(limit_status_function)
        }
 
        if (argc < 1) {
-               stream->write_function(stream, "USAGE: limit_status %s\n", LIMIT_STATUS_USAGE);
+               stream->write_function(stream, "USAGE: limit_status %s\n", LIMIT_STATUS_SYNTAX);
                goto end;
        }
        
@@ -4325,7 +4325,7 @@ end:
        return SWITCH_STATUS_SUCCESS;
 }
 
-#define LIMIT_RESET_USAGE "<backend>"
+#define LIMIT_RESET_SYNTAX "<backend>"
 SWITCH_STANDARD_API(limit_reset_function)
 {
        int argc = 0;
@@ -4340,7 +4340,7 @@ SWITCH_STANDARD_API(limit_reset_function)
        }
 
        if (argc < 1) {
-               stream->write_function(stream, "USAGE: limit_reset %s\n", LIMIT_RESET_USAGE);
+               stream->write_function(stream, "USAGE: limit_reset %s\n", LIMIT_RESET_SYNTAX);
                goto end;
        }
        
@@ -4354,6 +4354,81 @@ end:
        return SWITCH_STATUS_SUCCESS;
 }
 
+#define LIMIT_RELEASE_SYNTAX "<uuid> <backend> [realm] [resource]"
+SWITCH_STANDARD_API(uuid_limit_release_function)
+{
+       int argc = 0;
+       char *argv[5] = { 0 };
+       char *mydata = NULL;
+       char *realm = NULL;
+       char *resource = NULL;
+       switch_core_session_t *sess = NULL;
+
+       if (!zstr(cmd)) {
+               mydata = strdup(cmd);
+               switch_assert(mydata);
+               argc = switch_separate_string(mydata, ' ', argv, (sizeof(argv) / sizeof(argv[0])));
+       }
+       
+       if (argc < 2) {
+               stream->write_function(stream, "USAGE: uuid_limit_release %s\n", LIMIT_RELEASE_SYNTAX);
+               goto end;
+       }
+
+       if (argc > 2) {
+               realm = argv[2];
+       }
+
+       if (argc > 3) {
+               resource = argv[3];
+       }
+
+       sess = switch_core_session_locate(argv[0]);
+       if (!sess) {
+               stream->write_function(stream, "-ERR did not find a session with uuid %s\n", argv[0]);
+               goto end;
+       }
+
+       switch_limit_release(argv[1], sess, realm, resource);
+
+       switch_core_session_rwunlock(sess);
+       
+       stream->write_function(stream, "+OK");
+
+end:
+       switch_safe_free(mydata);
+
+       return SWITCH_STATUS_SUCCESS;
+}
+
+#define LIMIT_INTERVAL_RESET_SYNTAX "<backend> <realm> <resource>"
+SWITCH_STANDARD_API(limit_interval_reset_function)
+{
+       int argc = 0;
+       char *argv[5] = { 0 };
+       char *mydata = NULL;
+
+       if (!zstr(cmd)) {
+               mydata = strdup(cmd);
+               switch_assert(mydata);
+               argc = switch_separate_string(mydata, ' ', argv, (sizeof(argv) / sizeof(argv[0])));
+       }
+       
+       if (argc < 3) {
+               stream->write_function(stream, "USAGE: limit_interval_reset %s\n", LIMIT_INTERVAL_RESET_SYNTAX);
+               goto end;
+       }
+
+       switch_limit_interval_reset(argv[0], argv[1], argv[2]);
+
+       stream->write_function(stream, "+OK");
+
+end:
+       switch_safe_free(mydata);
+
+       return SWITCH_STATUS_SUCCESS;
+}
+
 SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_commands_shutdown)
 {
        int x;
@@ -4446,6 +4521,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_commands_load)
        SWITCH_ADD_API(commands_api_interface, "limit_hash_usage", "Deprecated: gets the usage count of a limited resource", limit_hash_usage_function, "<realm> <id>");
        SWITCH_ADD_API(commands_api_interface, "limit_status", "Gets the status of a limit backend", limit_status_function, "<backend>");
        SWITCH_ADD_API(commands_api_interface, "limit_reset", "Reset the counters of a limit backend", limit_reset_function, "<backend>");
+       SWITCH_ADD_API(commands_api_interface, "limit_interval_reset", "Reset the interval counter for a limited resource", limit_interval_reset_function, LIMIT_INTERVAL_RESET_SYNTAX);
        SWITCH_ADD_API(commands_api_interface, "load", "Load Module", load_function, LOAD_SYNTAX);
        SWITCH_ADD_API(commands_api_interface, "log", "Log", log_function, LOG_SYNTAX);
        SWITCH_ADD_API(commands_api_interface, "md5", "md5", md5_function, "<data>");
@@ -4494,6 +4570,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_commands_load)
        SWITCH_ADD_API(commands_api_interface, "uuid_getvar", "uuid_getvar", uuid_getvar_function, GETVAR_SYNTAX);
        SWITCH_ADD_API(commands_api_interface, "uuid_hold", "hold", uuid_hold_function, HOLD_SYNTAX);
        SWITCH_ADD_API(commands_api_interface, "uuid_kill", "Kill Channel", kill_function, KILL_SYNTAX);
+       SWITCH_ADD_API(commands_api_interface, "uuid_limit_release", "Release limit resource", uuid_limit_release_function, LIMIT_RELEASE_SYNTAX);
        SWITCH_ADD_API(commands_api_interface, "uuid_loglevel", "set loglevel on session", uuid_loglevel, UUID_LOGLEVEL_SYNTAX);
        SWITCH_ADD_API(commands_api_interface, "uuid_media", "media", uuid_media_function, MEDIA_SYNTAX);
        SWITCH_ADD_API(commands_api_interface, "uuid_park", "Park Channel", park_function, PARK_SYNTAX);
@@ -4600,6 +4677,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_commands_load)
        switch_console_set_complete("add uuid_getvar ::console::list_uuid");
        switch_console_set_complete("add uuid_hold ::console::list_uuid");
        switch_console_set_complete("add uuid_kill ::console::list_uuid");
+       switch_console_set_complete("add uuid_limit_release ::console::list_uuid");
        switch_console_set_complete("add uuid_loglevel ::console::list_uuid console");
        switch_console_set_complete("add uuid_loglevel ::console::list_uuid alert");
        switch_console_set_complete("add uuid_loglevel ::console::list_uuid crit");
index d22f1a8eecb56d70f917929e7d3645014a0328ab..088d9d0a85bfd6c12f88e5006d5fcc02ef6780bb 100644 (file)
@@ -620,7 +620,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_db_load)
        *module_interface = switch_loadable_module_create_module_interface(pool, modname);
 
        /* register limit interfaces */
-       SWITCH_ADD_LIMIT(limit_interface, "db", limit_incr_db, limit_release_db, limit_usage_db, limit_reset_db, limit_status_db);
+       SWITCH_ADD_LIMIT(limit_interface, "db", limit_incr_db, limit_release_db, limit_usage_db, limit_reset_db, limit_status_db, NULL);
 
        SWITCH_ADD_APP(app_interface, "db", "Insert to the db", DB_DESC, db_function, DB_USAGE, SAF_SUPPORT_NOMEDIA);
        SWITCH_ADD_APP(app_interface, "group", "Manage a group", GROUP_DESC, group_function, GROUP_USAGE, SAF_SUPPORT_NOMEDIA);
index f4eec4f3c161ac4a24b7af11625552bd779dfc72..a13a1874ae12ce8c493bdf4a2fcba7b2bc3525e7 100644 (file)
@@ -360,6 +360,24 @@ SWITCH_LIMIT_RESET(limit_reset_hash)
        return SWITCH_STATUS_GENERR;
 }
 
+SWITCH_LIMIT_INTERVAL_RESET(limit_interval_reset_hash)
+{
+       char *hash_key = NULL;
+       limit_hash_item_t *item = NULL;
+
+       switch_thread_rwlock_rdlock(globals.limit_hash_rwlock);
+
+       hash_key = switch_mprintf("%s_%s", realm, resource);
+       if ((item = switch_core_hash_find(globals.limit_hash, hash_key))) {
+               item->rate_usage = 0;
+               item->last_check = switch_epoch_time_now(NULL);
+       }
+
+       switch_safe_free(hash_key);
+       switch_thread_rwlock_unlock(globals.limit_hash_rwlock);
+       return SWITCH_STATUS_SUCCESS;
+}
+
 SWITCH_LIMIT_STATUS(limit_status_hash)
 {
        /*
@@ -892,7 +910,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_hash_load)
        *module_interface = switch_loadable_module_create_module_interface(pool, modname);
 
        /* register limit interfaces */
-       SWITCH_ADD_LIMIT(limit_interface, "hash", limit_incr_hash, limit_release_hash, limit_usage_hash, limit_reset_hash, limit_status_hash);
+       SWITCH_ADD_LIMIT(limit_interface, "hash", limit_incr_hash, limit_release_hash, limit_usage_hash, limit_reset_hash, limit_status_hash, limit_interval_reset_hash);
 
        switch_scheduler_add_task(switch_epoch_time_now(NULL) + LIMIT_HASH_CLEANUP_INTERVAL, limit_hash_cleanup_callback, "limit_hash_cleanup", "mod_hash", 0, NULL,
                                                  SSHF_NONE);
index ca509520c068e5462c9e8628e9715688ab404003..75dfd6fdd7d5eea897a91cdc8a06426d1ba6eb03 100755 (executable)
@@ -300,7 +300,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_redis_load)
        /* If FreeSWITCH was restarted and we still have active calls, decrement them so our global count stays valid */
        limit_reset_redis();
        
-       SWITCH_ADD_LIMIT(limit_interface, "redis", limit_incr_redis, limit_release_redis, limit_usage_redis, limit_reset_redis, limit_status_redis);
+       SWITCH_ADD_LIMIT(limit_interface, "redis", limit_incr_redis, limit_release_redis, limit_usage_redis, limit_reset_redis, limit_status_redis, NULL);
        
        return SWITCH_STATUS_SUCCESS;
 }
index f76e1de1c085b1caa3b93b8de7c6cee70f58f618..9313ecf5cf38f95f09c0485700041294c9a4f03f 100644 (file)
@@ -196,6 +196,28 @@ end:
        return status;
 }
 
+SWITCH_DECLARE(switch_status_t) switch_limit_interval_reset(const char *backend, const char *realm, const char *resource) {
+       switch_limit_interface_t *limit = NULL;
+       int status = SWITCH_STATUS_SUCCESS;
+       
+       /* locate impl, call appropriate func */
+       if (!(limit = get_backend(backend))) {
+               switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Limit subsystem %s not found!\n", backend);
+               switch_goto_status(SWITCH_STATUS_GENERR, end);
+       }
+       
+       if (!limit->interval_reset) {
+               switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Limit subsystem %s does not implement interval_reset!\n", backend);
+               switch_goto_status(SWITCH_STATUS_GENERR, end);
+       }
+
+       status = limit->interval_reset(realm, resource);
+       
+end:
+       release_backend(limit);
+       return status;
+}
+
 SWITCH_DECLARE(char *) switch_limit_status(const char *backend) {
        switch_limit_interface_t *limit = NULL;
        char *status = NULL;