forked from Mirrors/freeswitch
FSCORE-637 - limit - reset rate and release resource apis
Thanks Moy
This commit is contained in:
parent
fca93f2910
commit
a7c31e6fe9
@ -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"
|
||||
|
@ -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; \
|
||||
|
@ -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;
|
||||
|
@ -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");
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user