diff options
author | Jonathan Rose <jrose@digium.com> | 2013-04-30 22:37:24 +0000 |
---|---|---|
committer | Jonathan Rose <jrose@digium.com> | 2013-04-30 22:37:24 +0000 |
commit | 8e257fe8196544ff962f1032a73134ad7c8cc4b4 (patch) | |
tree | 7683b460e67a9e1e50f5ada8991f2216ae6c8aa6 | |
parent | 6f5733388a93d01124c62233184691b53e886b3b (diff) |
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
-rw-r--r-- | channels/chan_iax2.c | 31 | ||||
-rw-r--r-- | channels/chan_sip.c | 27 | ||||
-rw-r--r-- | include/asterisk/acl.h | 18 | ||||
-rw-r--r-- | include/asterisk/event_defs.h | 6 | ||||
-rw-r--r-- | include/asterisk/json.h | 15 | ||||
-rw-r--r-- | main/event.c | 1 | ||||
-rw-r--r-- | main/json.c | 21 | ||||
-rw-r--r-- | main/manager.c | 29 | ||||
-rw-r--r-- | main/named_acl.c | 76 |
9 files changed, 169 insertions, 55 deletions
diff --git a/channels/chan_iax2.c b/channels/chan_iax2.c index c15aa85a2..94573908c 100644 --- a/channels/chan_iax2.c +++ b/channels/chan_iax2.c @@ -284,7 +284,7 @@ static char language[MAX_LANGUAGE] = ""; static char regcontext[AST_MAX_CONTEXT] = ""; static struct ast_event_sub *network_change_event_subscription; /*!< subscription id for network change events */ -static struct ast_event_sub *acl_change_event_subscription; /*!< subscription id for ACL change events */ +static struct stasis_subscription *acl_change_sub; /*!< subscription id for ACL change events */ static int network_change_event_sched_id = -1; static int maxauthreq = 3; @@ -1255,7 +1255,7 @@ static int get_unused_callno(enum callno_type type, int validated, callno_entry static int replace_callno(const void *obj); static void sched_delay_remove(struct sockaddr_in *sin, callno_entry entry); static void network_change_event_cb(const struct ast_event *, void *); -static void acl_change_event_cb(const struct ast_event *, void *); +static void acl_change_stasis_cb(void *data, struct stasis_subscription *sub, struct stasis_topic *topic, struct stasis_message *message); static struct ast_channel_tech iax2_tech = { .type = "IAX2", @@ -1338,18 +1338,18 @@ static void network_change_event_unsubscribe(void) } } -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, "IAX2 ACL Change", 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); } } @@ -1375,8 +1375,13 @@ static void network_change_event_cb(const struct ast_event *event, void *userdat } -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; + } + ast_log(LOG_NOTICE, "Reloading chan_iax2 in response to ACL change event.\n"); reload_config(1); } @@ -12700,7 +12705,7 @@ static struct iax2_peer *build_peer(const char *name, struct ast_variable *v, st } if (subscribe_acl_change) { - acl_change_event_subscribe(); + acl_change_stasis_subscribe(); } return peer; @@ -12972,7 +12977,7 @@ cleanup: } if (subscribe_acl_change) { - acl_change_event_subscribe(); + acl_change_stasis_subscribe(); } return user; @@ -14284,7 +14289,7 @@ static int __unload_module(void) int x; network_change_event_unsubscribe(); - acl_change_event_unsubscribe(); + acl_change_stasis_unsubscribe(); ast_manager_unregister("IAXpeers"); ast_manager_unregister("IAXpeerlist"); diff --git a/channels/chan_sip.c b/channels/chan_sip.c index c03f98ed7..931155130 100644 --- a/channels/chan_sip.c +++ b/channels/chan_sip.c @@ -844,7 +844,7 @@ static struct ast_flags global_flags[3] = {{0}}; /*!< global SIP_ flags */ static int global_t38_maxdatagram; /*!< global T.38 FaxMaxDatagram override */ static struct ast_event_sub *network_change_event_subscription; /*!< subscription id for network change events */ -static struct ast_event_sub *acl_change_event_subscription; /*!< subscription id for named ACL system change events */ +static struct stasis_subscription *acl_change_sub; /*!< subscription id for named ACL system change events */ static int network_change_event_sched_id = -1; static char used_context[AST_MAX_CONTEXT]; /*!< name of automatically created context for unloading */ @@ -1285,7 +1285,7 @@ static void sip_poke_all_peers(void); static void sip_peer_hold(struct sip_pvt *p, int hold); static void mwi_event_cb(void *, struct stasis_subscription *, struct stasis_topic *, struct stasis_message *); static void network_change_event_cb(const struct ast_event *, void *); -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 sip_keepalive_all_peers(void); /*--- Applications, functions, CLI and manager command helpers */ @@ -16719,19 +16719,19 @@ static void network_change_event_unsubscribe(void) } } -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) { - 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); } } @@ -29238,8 +29238,13 @@ static int restart_monitor(void) 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; + } + ast_log(LOG_NOTICE, "Reloading chan_sip in response to ACL change event.\n"); ast_mutex_lock(&sip_reload_lock); @@ -31383,7 +31388,7 @@ static struct sip_peer *build_peer(const char *name, struct ast_variable *v, str /* If an ACL change subscription is needed and doesn't exist, we need one. */ if (acl_change_subscription_needed) { - acl_change_event_subscribe(); + acl_change_stasis_subscribe(); } return peer; @@ -32621,7 +32626,7 @@ static int reload_config(enum channelreloadreason reason) /* If an ACL change subscription is needed and doesn't exist, we need one. */ if (acl_change_subscription_needed) { - acl_change_event_subscribe(); + acl_change_stasis_subscribe(); } return 0; diff --git a/include/asterisk/acl.h b/include/asterisk/acl.h index 50510a765..537a30d32 100644 --- a/include/asterisk/acl.h +++ b/include/asterisk/acl.h @@ -385,6 +385,24 @@ int ast_named_acl_init(void); */ int ast_named_acl_reload(void); +/*! + * \brief accessor for the ACL stasis topic + * \since 12 + * + * \retval NULL if the stasis topic hasn't been created or has been disabled + * \retval a pointer to the ACL stasis topic + */ +struct stasis_topic *ast_acl_topic(void); + +/*! + * \brief accessor for the named ACL change stasis message type + * \since 12 + * + * \retval NULL if the ACL change message type hasn't been created or has been canceled + * \retval a pointer to the ACL change message type + */ +struct stasis_message_type *ast_named_acl_change_type(void); + #if defined(__cplusplus) || defined(c_plusplus) } #endif diff --git a/include/asterisk/event_defs.h b/include/asterisk/event_defs.h index 10c76d0da..83fc98889 100644 --- a/include/asterisk/event_defs.h +++ b/include/asterisk/event_defs.h @@ -56,12 +56,10 @@ enum ast_event_type { AST_EVENT_NETWORK_CHANGE = 0x09, /*! The presence state for a presence provider */ AST_EVENT_PRESENCE_STATE = 0x0a, - /*! Used to alert listeners when a named ACL has changed. */ - AST_EVENT_ACL_CHANGE = 0x0b, /*! Send out a ping for debugging distributed events */ - AST_EVENT_PING = 0x0c, + AST_EVENT_PING = 0x0b, /*! Number of event types. This should be the last event type + 1 */ - AST_EVENT_TOTAL = 0x0d, + AST_EVENT_TOTAL = 0x0c, }; /*! \brief Event Information Element types */ diff --git a/include/asterisk/json.h b/include/asterisk/json.h index d06416f58..7b89d8270 100644 --- a/include/asterisk/json.h +++ b/include/asterisk/json.h @@ -830,6 +830,21 @@ struct ast_json *ast_json_timeval(const struct timeval tv, const char *zone); */ struct ast_json *ast_json_dialplan_cep(const char *context, const char *exten, int priority); +struct ast_json_payload { + struct ast_json *json; +}; + +/*! + * \brief Create an ao2 object to pass json blobs as data payloads for stasis + * \since 12.0.0 + * + * \param json the ast_json blob we are loading + * + * \retval NULL if we fail to alloc it + * \retval pointer to the ast_json_payload created + */ +struct ast_json_payload *ast_json_payload_create(struct ast_json *json); + /*!@}*/ #endif /* _ASTERISK_JSON_H */ diff --git a/main/event.c b/main/event.c index d97b04336..fa2557a77 100644 --- a/main/event.c +++ b/main/event.c @@ -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", }; diff --git a/main/json.c b/main/json.c index 1ff563871..87971f04a 100644 --- a/main/json.c +++ b/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; +} diff --git a/main/manager.c b/main/manager.c index dd920e26d..9e500e8de 100644 --- a/main/manager.c +++ b/main/manager.c @@ -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); diff --git a/main/named_acl.c b/main/named_acl.c index 142693194..7bc859769 100644 --- a/main/named_acl.c +++ b/main/named_acl.c @@ -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)); |