From a9911f027e09167c2653b7c301136287322dbccc Mon Sep 17 00:00:00 2001 From: Richard Mudgett Date: Fri, 24 Jan 2014 22:18:52 +0000 Subject: [PATCH] manager: Register atexit shutdown routine only once. * Made register atexit shutdown routine only once in __init_manager(). * Fixed some initial load failure conditions in __init_manager(). * Made reset options to defaults on reload when the reload will actually happen. * Removed unnecessary container traversals of the white/black filters during manager_free_user(). * ast_free() does not need a NULL check before calling. ........ Merged revisions 406359 from http://svn.asterisk.org/svn/asterisk/branches/1.8 ........ Merged revisions 406400 from http://svn.asterisk.org/svn/asterisk/branches/11 ........ Merged revisions 406401 from http://svn.asterisk.org/svn/asterisk/branches/12 git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@406407 65c4cc65-6c06-0410-ace0-fbb531ad65f3 --- main/manager.c | 259 +++++++++++++++++++++++-------------------------- 1 file changed, 122 insertions(+), 137 deletions(-) diff --git a/main/manager.c b/main/manager.c index 09d7e81194..9e88628aab 100644 --- a/main/manager.c +++ b/main/manager.c @@ -1773,11 +1773,11 @@ static void session_destructor(void *obj) } if (session->whitefilters) { - ao2_t_ref(session->whitefilters, -1 , "decrement ref for white container, should be last one"); + ao2_t_ref(session->whitefilters, -1, "decrement ref for white container, should be last one"); } if (session->blackfilters) { - ao2_t_ref(session->blackfilters, -1 , "decrement ref for black container, should be last one"); + ao2_t_ref(session->blackfilters, -1, "decrement ref for black container, should be last one"); } } @@ -6936,12 +6936,8 @@ generic_callback_out: if (method == AST_HTTP_POST && params) { ast_variables_destroy(params); } - if (http_header) { - ast_free(http_header); - } - if (out) { - ast_free(out); - } + ast_free(http_header); + ast_free(out); if (session && blastaway) { session_destroy(session); @@ -7452,7 +7448,6 @@ static struct ast_custom_function managerclient_function = { .read_max = 12, }; -static int registered = 0; static int webregged = 0; /*! \brief cleanup code called at each iteration of server_root, @@ -7797,16 +7792,14 @@ static void test_suite_event_cb(void *data, struct stasis_subscription *sub, */ static void manager_free_user(struct ast_manager_user *user) { - if (user->a1_hash) { - ast_free(user->a1_hash); + ast_free(user->a1_hash); + ast_free(user->secret); + if (user->whitefilters) { + ao2_t_ref(user->whitefilters, -1, "decrement ref for white container, should be last one"); } - if (user->secret) { - ast_free(user->secret); + if (user->blackfilters) { + ao2_t_ref(user->blackfilters, -1, "decrement ref for black container, should be last one"); } - ao2_t_callback(user->whitefilters, OBJ_UNLINK | OBJ_NODATA | OBJ_MULTIPLE, NULL, NULL, "unlink all white filters"); - ao2_t_callback(user->blackfilters, OBJ_UNLINK | OBJ_NODATA | OBJ_MULTIPLE, NULL, NULL, "unlink all black filters"); - ao2_t_ref(user->whitefilters, -1, "decrement ref for white container, should be last one"); - ao2_t_ref(user->blackfilters, -1, "decrement ref for black container, should be last one"); user->acl = ast_free_acl_list(user->acl); ast_variables_destroy(user->chanvars); ast_free(user); @@ -7820,46 +7813,44 @@ static void manager_shutdown(void) { struct ast_manager_user *user; - if (registered) { - ast_manager_unregister("Ping"); - ast_manager_unregister("Events"); - ast_manager_unregister("Logoff"); - ast_manager_unregister("Login"); - ast_manager_unregister("Challenge"); - ast_manager_unregister("Hangup"); - ast_manager_unregister("Status"); - ast_manager_unregister("Setvar"); - ast_manager_unregister("Getvar"); - ast_manager_unregister("GetConfig"); - ast_manager_unregister("GetConfigJSON"); - ast_manager_unregister("UpdateConfig"); - ast_manager_unregister("CreateConfig"); - ast_manager_unregister("ListCategories"); - ast_manager_unregister("Redirect"); - ast_manager_unregister("Atxfer"); - ast_manager_unregister("Originate"); - ast_manager_unregister("Command"); - ast_manager_unregister("ExtensionState"); - ast_manager_unregister("PresenceState"); - ast_manager_unregister("AbsoluteTimeout"); - ast_manager_unregister("MailboxStatus"); - ast_manager_unregister("MailboxCount"); - ast_manager_unregister("ListCommands"); - ast_manager_unregister("SendText"); - ast_manager_unregister("UserEvent"); - ast_manager_unregister("WaitEvent"); - ast_manager_unregister("CoreSettings"); - ast_manager_unregister("CoreStatus"); - ast_manager_unregister("Reload"); - ast_manager_unregister("CoreShowChannels"); - ast_manager_unregister("ModuleLoad"); - ast_manager_unregister("ModuleCheck"); - ast_manager_unregister("AOCMessage"); - ast_manager_unregister("Filter"); - ast_manager_unregister("BlindTransfer"); - ast_custom_function_unregister(&managerclient_function); - ast_cli_unregister_multiple(cli_manager, ARRAY_LEN(cli_manager)); - } + ast_manager_unregister("Ping"); + ast_manager_unregister("Events"); + ast_manager_unregister("Logoff"); + ast_manager_unregister("Login"); + ast_manager_unregister("Challenge"); + ast_manager_unregister("Hangup"); + ast_manager_unregister("Status"); + ast_manager_unregister("Setvar"); + ast_manager_unregister("Getvar"); + ast_manager_unregister("GetConfig"); + ast_manager_unregister("GetConfigJSON"); + ast_manager_unregister("UpdateConfig"); + ast_manager_unregister("CreateConfig"); + ast_manager_unregister("ListCategories"); + ast_manager_unregister("Redirect"); + ast_manager_unregister("Atxfer"); + ast_manager_unregister("Originate"); + ast_manager_unregister("Command"); + ast_manager_unregister("ExtensionState"); + ast_manager_unregister("PresenceState"); + ast_manager_unregister("AbsoluteTimeout"); + ast_manager_unregister("MailboxStatus"); + ast_manager_unregister("MailboxCount"); + ast_manager_unregister("ListCommands"); + ast_manager_unregister("SendText"); + ast_manager_unregister("UserEvent"); + ast_manager_unregister("WaitEvent"); + ast_manager_unregister("CoreSettings"); + ast_manager_unregister("CoreStatus"); + ast_manager_unregister("Reload"); + ast_manager_unregister("CoreShowChannels"); + ast_manager_unregister("ModuleLoad"); + ast_manager_unregister("ModuleCheck"); + ast_manager_unregister("AOCMessage"); + ast_manager_unregister("Filter"); + ast_manager_unregister("BlindTransfer"); + ast_custom_function_unregister(&managerclient_function); + ast_cli_unregister_multiple(cli_manager, ARRAY_LEN(cli_manager)); #ifdef AST_XML_DOCS ao2_t_global_obj_release(event_docs, "Dispose of event_docs"); @@ -7880,18 +7871,12 @@ static void manager_shutdown(void) ast_tcptls_server_stop(&ami_desc); ast_tcptls_server_stop(&amis_desc); - if (ami_tls_cfg.certfile) { - ast_free(ami_tls_cfg.certfile); - ami_tls_cfg.certfile = NULL; - } - if (ami_tls_cfg.pvtfile) { - ast_free(ami_tls_cfg.pvtfile); - ami_tls_cfg.pvtfile = NULL; - } - if (ami_tls_cfg.cipher) { - ast_free(ami_tls_cfg.cipher); - ami_tls_cfg.cipher = NULL; - } + ast_free(ami_tls_cfg.certfile); + ami_tls_cfg.certfile = NULL; + ast_free(ami_tls_cfg.pvtfile); + ami_tls_cfg.pvtfile = NULL; + ast_free(ami_tls_cfg.cipher); + ami_tls_cfg.cipher = NULL; ao2_global_obj_release(mgr_sessions); @@ -7965,12 +7950,33 @@ static int subscribe_all(void) return 0; } +static void manager_set_defaults(void) +{ + manager_enabled = 0; + displayconnects = 1; + broken_events_action = 0; + authtimeout = 30; + authlimit = 50; + manager_debug = 0; /* Debug disabled by default */ + + /* default values */ + ast_copy_string(global_realm, S_OR(ast_config_AST_SYSTEM_NAME, DEFAULT_REALM), + sizeof(global_realm)); + ast_sockaddr_setnull(&ami_desc.local_address); + ast_sockaddr_setnull(&amis_desc.local_address); + + ami_tls_cfg.enabled = 0; + ast_free(ami_tls_cfg.certfile); + ami_tls_cfg.certfile = ast_strdup(AST_CERTFILE); + ast_free(ami_tls_cfg.pvtfile); + ami_tls_cfg.pvtfile = ast_strdup(""); + ast_free(ami_tls_cfg.cipher); + ami_tls_cfg.cipher = ast_strdup(""); +} + static int __init_manager(int reload, int by_external_config) { struct ast_config *ucfg = NULL, *cfg = NULL; -#ifdef AST_XML_DOCS - struct ao2_container *temp_event_docs; -#endif const char *val; char *cat = NULL; int newhttptimeout = 60; @@ -7984,10 +7990,16 @@ static int __init_manager(int reload, int by_external_config) int tls_was_enabled = 0; int acl_subscription_flag = 0; - manager_enabled = 0; - if (!reload) { - int res = STASIS_MESSAGE_TYPE_INIT(ast_manager_get_generic_type); + struct ao2_container *sessions; +#ifdef AST_XML_DOCS + struct ao2_container *temp_event_docs; +#endif + int res; + + ast_register_atexit(manager_shutdown); + + res = STASIS_MESSAGE_TYPE_INIT(ast_manager_get_generic_type); if (res != 0) { return -1; } @@ -7995,9 +8007,7 @@ static int __init_manager(int reload, int by_external_config) if (!manager_topic) { return -1; } - } - if (!registered) { /* Register default actions */ ast_manager_register_xml_core("Ping", 0, action_ping); ast_manager_register_xml_core("Events", 0, action_events); @@ -8043,33 +8053,37 @@ static int __init_manager(int reload, int by_external_config) ast_cli_register_multiple(cli_manager, ARRAY_LEN(cli_manager)); __ast_custom_function_register(&managerclient_function, NULL); ast_extension_state_add(NULL, NULL, manager_state_cb, NULL); - registered = 1; + /* Append placeholder event so master_eventq never runs dry */ - append_event("Event: Placeholder\r\n\r\n", 0); - } + if (append_event("Event: Placeholder\r\n\r\n", 0)) { + return -1; + } #ifdef AST_XML_DOCS - temp_event_docs = ast_xmldoc_build_documentation("managerEvent"); - if (temp_event_docs) { - ao2_t_global_obj_replace_unref(event_docs, temp_event_docs, "Toss old event docs"); - ao2_t_ref(temp_event_docs, -1, "Remove creation ref - container holds only ref now"); - } + temp_event_docs = ast_xmldoc_build_documentation("managerEvent"); + if (temp_event_docs) { + ao2_t_global_obj_replace_unref(event_docs, temp_event_docs, "Toss old event docs"); + ao2_t_ref(temp_event_docs, -1, "Remove creation ref - container holds only ref now"); + } #endif - ast_register_atexit(manager_shutdown); + /* If you have a NULL hash fn, you only need a single bucket */ + sessions = ao2_container_alloc(1, NULL, mansession_cmp_fn); + if (!sessions) { + return -1; + } + ao2_global_obj_replace_unref(mgr_sessions, sessions); + ao2_ref(sessions, -1); - if ((cfg = ast_config_load2("manager.conf", "manager", config_flags)) == CONFIG_STATUS_FILEUNCHANGED) { - return 0; + /* Initialize all settings before first configuration load. */ + manager_set_defaults(); } - displayconnects = 1; - broken_events_action = 0; - authtimeout = 30; - authlimit = 50; - manager_debug = 0; /* Debug disabled by default */ - - if (!cfg || cfg == CONFIG_STATUS_FILEINVALID) { - ast_log(LOG_NOTICE, "Unable to open AMI configuration manager.conf, or configuration is invalid. Asterisk management interface (AMI) disabled.\n"); + cfg = ast_config_load2("manager.conf", "manager", config_flags); + if (cfg == CONFIG_STATUS_FILEUNCHANGED) { + return 0; + } else if (!cfg || cfg == CONFIG_STATUS_FILEINVALID) { + ast_log(LOG_NOTICE, "Unable to open AMI configuration manager.conf, or configuration is invalid.\n"); return 0; } @@ -8078,30 +8092,15 @@ static int __init_manager(int reload, int by_external_config) acl_change_stasis_unsubscribe(); } - /* default values */ - ast_copy_string(global_realm, S_OR(ast_config_AST_SYSTEM_NAME, DEFAULT_REALM), sizeof(global_realm)); - ast_sockaddr_setnull(&ami_desc.local_address); - ast_sockaddr_setnull(&amis_desc.local_address); + if (reload) { + /* Reset all settings before reloading configuration */ + tls_was_enabled = ami_tls_cfg.enabled; + manager_set_defaults(); + } ast_sockaddr_parse(&ami_desc_local_address_tmp, "[::]", 0); ast_sockaddr_set_port(&ami_desc_local_address_tmp, DEFAULT_MANAGER_PORT); - tls_was_enabled = (reload && ami_tls_cfg.enabled); - - ami_tls_cfg.enabled = 0; - if (ami_tls_cfg.certfile) { - ast_free(ami_tls_cfg.certfile); - } - ami_tls_cfg.certfile = ast_strdup(AST_CERTFILE); - if (ami_tls_cfg.pvtfile) { - ast_free(ami_tls_cfg.pvtfile); - } - ami_tls_cfg.pvtfile = ast_strdup(""); - if (ami_tls_cfg.cipher) { - ast_free(ami_tls_cfg.cipher); - } - ami_tls_cfg.cipher = ast_strdup(""); - for (var = ast_variable_browse(cfg, "general"); var; var = var->next) { val = var->value; @@ -8273,9 +8272,7 @@ static int __init_manager(int reload, int by_external_config) } if (!ast_strlen_zero(user_secret)) { - if (user->secret) { - ast_free(user->secret); - } + ast_free(user->secret); user->secret = ast_strdup(user_secret); } @@ -8331,6 +8328,10 @@ static int __init_manager(int reload, int by_external_config) user->writetimeout = 100; user->whitefilters = ao2_container_alloc(1, NULL, NULL); user->blackfilters = ao2_container_alloc(1, NULL, NULL); + if (!user->whitefilters || !user->blackfilters) { + manager_free_user(user); + break; + } /* Insert into list */ AST_RWLIST_INSERT_TAIL(&users, user, list); @@ -8348,9 +8349,7 @@ static int __init_manager(int reload, int by_external_config) var = ast_variable_browse(cfg, cat); for (; var; var = var->next) { if (!strcasecmp(var->name, "secret")) { - if (user->secret) { - ast_free(user->secret); - } + ast_free(user->secret); user->secret = ast_strdup(var->value); } else if (!strcasecmp(var->name, "deny") || !strcasecmp(var->name, "permit") || @@ -8412,9 +8411,7 @@ static int __init_manager(int reload, int by_external_config) /* Calculate A1 for Digest auth */ snprintf(a1, sizeof(a1), "%s:%s:%s", user->username, global_realm, user->secret); ast_md5_hash(a1_hash,a1); - if (user->a1_hash) { - ast_free(user->a1_hash); - } + ast_free(user->a1_hash); user->a1_hash = ast_strdup(a1_hash); continue; } @@ -8427,20 +8424,8 @@ static int __init_manager(int reload, int by_external_config) AST_RWLIST_UNLOCK(&users); - if (!reload) { - struct ao2_container *sessions; - - /* If you have a NULL hash fn, you only need a single bucket */ - sessions = ao2_container_alloc(1, NULL, mansession_cmp_fn); - if (sessions) { - ao2_global_obj_replace_unref(mgr_sessions, sessions); - ao2_ref(sessions, -1); - } - } - if (webmanager_enabled && manager_enabled) { if (!webregged) { - ast_http_uri_link(&rawmanuri); ast_http_uri_link(&manageruri); ast_http_uri_link(&managerxmluri);