manager: Register atexit shutdown routine only once.
authorRichard Mudgett <rmudgett@digium.com>
Fri, 24 Jan 2014 22:18:52 +0000 (22:18 +0000)
committerRichard Mudgett <rmudgett@digium.com>
Fri, 24 Jan 2014 22:18:52 +0000 (22:18 +0000)
* 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

index 09d7e81..9e88628 100644 (file)
@@ -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);