mirror of
https://github.com/asterisk/asterisk.git
synced 2025-10-22 20:56:39 +00:00
Stasis Core: Refactor ACL Change events to go out over the stasis core msg bus
(issue ASTERISK-21103) Reported by: Matt Jordan Review: https://reviewboard.asterisk.org/r/2481/ git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@387037 65c4cc65-6c06-0410-ace0-fbb531ad65f3
This commit is contained in:
@@ -217,7 +217,6 @@ static const char * const event_names[AST_EVENT_TOTAL] = {
|
||||
[AST_EVENT_SECURITY] = "Security",
|
||||
[AST_EVENT_NETWORK_CHANGE] = "NetworkChange",
|
||||
[AST_EVENT_PRESENCE_STATE] = "PresenceState",
|
||||
[AST_EVENT_ACL_CHANGE] = "ACLChange",
|
||||
[AST_EVENT_PING] = "Ping",
|
||||
};
|
||||
|
||||
|
21
main/json.c
21
main/json.c
@@ -39,6 +39,7 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
|
||||
#include "asterisk/localtime.h"
|
||||
#include "asterisk/module.h"
|
||||
#include "asterisk/utils.h"
|
||||
#include "asterisk/astobj2.h"
|
||||
|
||||
#include <jansson.h>
|
||||
#include <time.h>
|
||||
@@ -531,3 +532,23 @@ void ast_json_init(void)
|
||||
/* Setup to use Asterisk custom allocators */
|
||||
ast_json_reset_alloc_funcs();
|
||||
}
|
||||
|
||||
static void json_payload_destructor(void *obj)
|
||||
{
|
||||
struct ast_json_payload *payload = obj;
|
||||
ast_json_unref(payload->json);
|
||||
}
|
||||
|
||||
struct ast_json_payload *ast_json_payload_create(struct ast_json *json)
|
||||
{
|
||||
struct ast_json_payload *payload;
|
||||
|
||||
if (!(payload = ao2_alloc(sizeof(*payload), json_payload_destructor))) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ast_json_ref(json);
|
||||
payload->json = json;
|
||||
|
||||
return payload;
|
||||
}
|
||||
|
@@ -1040,7 +1040,7 @@ static char global_realm[MAXHOSTNAMELEN]; /*!< Default realm */
|
||||
|
||||
static int block_sockets;
|
||||
static int unauth_sessions = 0;
|
||||
static struct ast_event_sub *acl_change_event_subscription;
|
||||
static struct stasis_subscription *acl_change_sub;
|
||||
|
||||
#define MGR_SHOW_TERMINAL_WIDTH 80
|
||||
|
||||
@@ -1065,20 +1065,20 @@ static const struct {
|
||||
{{ "restart", "gracefully", NULL }},
|
||||
};
|
||||
|
||||
static void acl_change_event_cb(const struct ast_event *event, void *userdata);
|
||||
static void acl_change_stasis_cb(void *data, struct stasis_subscription *sub, struct stasis_topic *topic, struct stasis_message *message);
|
||||
|
||||
static void acl_change_event_subscribe(void)
|
||||
static void acl_change_stasis_subscribe(void)
|
||||
{
|
||||
if (!acl_change_event_subscription) {
|
||||
acl_change_event_subscription = ast_event_subscribe(AST_EVENT_ACL_CHANGE,
|
||||
acl_change_event_cb, "Manager must react to Named ACL changes", NULL, AST_EVENT_IE_END);
|
||||
if (!acl_change_sub) {
|
||||
acl_change_sub = stasis_subscribe(ast_acl_topic(),
|
||||
acl_change_stasis_cb, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
static void acl_change_event_unsubscribe(void)
|
||||
static void acl_change_stasis_unsubscribe(void)
|
||||
{
|
||||
if (acl_change_event_subscription) {
|
||||
acl_change_event_subscription = ast_event_unsubscribe(acl_change_event_subscription);
|
||||
if (acl_change_sub) {
|
||||
acl_change_sub = stasis_unsubscribe(acl_change_sub);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7587,7 +7587,7 @@ static int __init_manager(int reload, int by_external_config)
|
||||
|
||||
/* If this wasn't performed due to a forced reload (because those can be created by ACL change events, we need to unsubscribe to ACL change events. */
|
||||
if (!by_external_config) {
|
||||
acl_change_event_unsubscribe();
|
||||
acl_change_stasis_unsubscribe();
|
||||
}
|
||||
|
||||
/* default values */
|
||||
@@ -7893,7 +7893,7 @@ static int __init_manager(int reload, int by_external_config)
|
||||
|
||||
/* Check the flag for named ACL event subscription and if we need to, register a subscription. */
|
||||
if (acl_subscription_flag && !by_external_config) {
|
||||
acl_change_event_subscribe();
|
||||
acl_change_stasis_subscribe();
|
||||
}
|
||||
|
||||
/* Perform cleanup - essentially prune out old users that no longer exist */
|
||||
@@ -7965,8 +7965,13 @@ static int __init_manager(int reload, int by_external_config)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void acl_change_event_cb(const struct ast_event *event, void *userdata)
|
||||
static void acl_change_stasis_cb(void *data, struct stasis_subscription *sub,
|
||||
struct stasis_topic *topic, struct stasis_message *message)
|
||||
{
|
||||
if (stasis_message_type(message) != ast_named_acl_change_type()) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* For now, this is going to be performed simply and just execute a forced reload. */
|
||||
ast_log(LOG_NOTICE, "Reloading manager in response to ACL change event.\n");
|
||||
__init_manager(1, 1);
|
||||
|
@@ -33,13 +33,14 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
|
||||
|
||||
#include "asterisk/config.h"
|
||||
#include "asterisk/config_options.h"
|
||||
#include "asterisk/event.h"
|
||||
#include "asterisk/utils.h"
|
||||
#include "asterisk/module.h"
|
||||
#include "asterisk/cli.h"
|
||||
#include "asterisk/acl.h"
|
||||
#include "asterisk/astobj2.h"
|
||||
#include "asterisk/paths.h"
|
||||
#include "asterisk/stasis.h"
|
||||
#include "asterisk/json.h"
|
||||
|
||||
#define NACL_CONFIG "acl.conf"
|
||||
#define ACL_FAMILY "acls"
|
||||
@@ -355,9 +356,39 @@ struct ast_ha *ast_named_acl_find(const char *name, int *is_realtime, int *is_un
|
||||
return ha;
|
||||
}
|
||||
|
||||
/*! \brief Topic for ACLs */
|
||||
static struct stasis_topic *acl_topic;
|
||||
|
||||
/*! \brief Message type for named ACL changes */
|
||||
static struct stasis_message_type *named_acl_change_type;
|
||||
|
||||
/*!
|
||||
* \internal
|
||||
* \brief Sends an update event corresponding to a given named ACL that has changed.
|
||||
* \brief Initialize Named ACL related stasis topics/messages
|
||||
*/
|
||||
static void ast_acl_stasis_init(void)
|
||||
{
|
||||
acl_topic = stasis_topic_create("ast_acl");
|
||||
named_acl_change_type = stasis_message_type_create("ast_named_acl_change");
|
||||
}
|
||||
|
||||
struct stasis_topic *ast_acl_topic(void)
|
||||
{
|
||||
return acl_topic;
|
||||
}
|
||||
|
||||
struct stasis_message_type *ast_named_acl_change_type(void)
|
||||
{
|
||||
return named_acl_change_type;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \internal
|
||||
* \brief Sends a stasis message corresponding to a given named ACL that has changed or
|
||||
* that all ACLs have been updated and old copies must be refreshed. Consumers of
|
||||
* named ACLs should subscribe to the ast_acl_topic and respond to messages of the
|
||||
* ast_named_acl_change_type stasis message type in order to be able to accomodate
|
||||
* changes to named ACLs.
|
||||
*
|
||||
* \param name Name of the ACL that has changed. May be an empty string (but not NULL)
|
||||
* If name is an empty string, then all ACLs must be refreshed.
|
||||
@@ -365,23 +396,38 @@ struct ast_ha *ast_named_acl_find(const char *name, int *is_realtime, int *is_un
|
||||
* \retval 0 success
|
||||
* \retval 1 failure
|
||||
*/
|
||||
static int push_acl_change_event(char *name)
|
||||
static int publish_acl_change(const char *name)
|
||||
{
|
||||
struct ast_event *event = ast_event_new(AST_EVENT_ACL_CHANGE,
|
||||
AST_EVENT_IE_DESCRIPTION, AST_EVENT_IE_PLTYPE_STR, name,
|
||||
AST_EVENT_IE_END);
|
||||
if (!event) {
|
||||
ast_log(LOG_ERROR, "Failed to allocate acl.conf reload event. Some modules will have out of date ACLs.\n");
|
||||
return -1;
|
||||
RAII_VAR(struct stasis_message *, msg, NULL, ao2_cleanup);
|
||||
RAII_VAR(struct ast_json_payload *, json_payload, NULL, ao2_cleanup);
|
||||
RAII_VAR(struct ast_json *, json_object, ast_json_object_create(), ast_json_unref);
|
||||
|
||||
if (!json_object) {
|
||||
goto publish_failure;
|
||||
}
|
||||
|
||||
if (ast_event_queue(event)) {
|
||||
ast_event_destroy(event);
|
||||
ast_log(LOG_ERROR, "Failed to queue acl.conf reload event. Some modules will have out of date ACLs.\n");
|
||||
return -1;
|
||||
if (ast_json_object_set(json_object, "name", ast_json_string_create(name))) {
|
||||
goto publish_failure;
|
||||
}
|
||||
|
||||
if (!(json_payload = ast_json_payload_create(json_object))) {
|
||||
goto publish_failure;
|
||||
}
|
||||
|
||||
msg = stasis_message_create(ast_named_acl_change_type(), json_payload);
|
||||
|
||||
if (!msg) {
|
||||
goto publish_failure;
|
||||
}
|
||||
|
||||
stasis_publish(ast_acl_topic(), msg);
|
||||
|
||||
return 0;
|
||||
|
||||
publish_failure:
|
||||
ast_log(LOG_ERROR, "Failed to to issue ACL change message for %s.\n",
|
||||
ast_strlen_zero(name) ? "all named ACLs" : name);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*!
|
||||
@@ -409,7 +455,7 @@ int ast_named_acl_reload(void)
|
||||
}
|
||||
|
||||
/* We need to push an ACL change event with no ACL name so that all subscribers update with all ACLs */
|
||||
push_acl_change_event("");
|
||||
publish_acl_change("");
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -549,6 +595,8 @@ int ast_named_acl_init()
|
||||
return 0;
|
||||
}
|
||||
|
||||
ast_acl_stasis_init();
|
||||
|
||||
/* Register the per level options. */
|
||||
aco_option_register(&cfg_info, "permit", ACO_EXACT, named_acl_types, NULL, OPT_ACL_T, 1, FLDSET(struct named_acl, ha));
|
||||
aco_option_register(&cfg_info, "deny", ACO_EXACT, named_acl_types, NULL, OPT_ACL_T, 0, FLDSET(struct named_acl, ha));
|
||||
|
Reference in New Issue
Block a user