pjsip: Update ACLs on named ACL changes.
This change extends the Sorcery API to allow a wizard to be told to explicitly reload objects or a specific object type even if the wizard believes that nothing has changed. This has been leveraged by res_pjsip and res_pjsip_acl to reload endpoints and PJSIP ACLs when a named ACL changes. ASTERISK-28697 Change-Id: Ib8fee9bd9dd490db635132c479127a4114c1ca0b
This commit is contained in:
parent
78b01f41ae
commit
d6712790cd
|
@ -323,6 +323,9 @@ struct ast_sorcery_wizard {
|
|||
|
||||
/* \brief Callback for whether or not the wizard believes the object is stale */
|
||||
int (*is_stale)(const struct ast_sorcery *sorcery, void *data, void *object);
|
||||
|
||||
/*! \brief Optional callback for forcing a reload to occur, even if wizard has determined no changes */
|
||||
void (*force_reload)(void *data, const struct ast_sorcery *sorcery, const char *type);
|
||||
};
|
||||
|
||||
/*! \brief Interface for a sorcery object type observer */
|
||||
|
@ -1059,6 +1062,17 @@ void ast_sorcery_load_object(const struct ast_sorcery *sorcery, const char *type
|
|||
*/
|
||||
void ast_sorcery_reload(const struct ast_sorcery *sorcery);
|
||||
|
||||
/*!
|
||||
* \brief Inform any wizards to reload persistent objects, even if no changes determined
|
||||
*
|
||||
* \param sorcery Pointer to a sorcery structure
|
||||
*
|
||||
* \since 13.32.0
|
||||
* \since 16.9.0
|
||||
* \since 17.3.0
|
||||
*/
|
||||
void ast_sorcery_force_reload(const struct ast_sorcery *sorcery);
|
||||
|
||||
/*!
|
||||
* \brief Inform any wizards of a specific object type to reload persistent objects
|
||||
*
|
||||
|
@ -1067,6 +1081,19 @@ void ast_sorcery_reload(const struct ast_sorcery *sorcery);
|
|||
*/
|
||||
void ast_sorcery_reload_object(const struct ast_sorcery *sorcery, const char *type);
|
||||
|
||||
/*!
|
||||
* \brief Inform any wizards of a specific object type to reload persistent objects
|
||||
* even if no changes determined
|
||||
*
|
||||
* \param sorcery Pointer to a sorcery structure
|
||||
* \param type Name of the object type to reload
|
||||
*
|
||||
* \since 13.32.0
|
||||
* \since 16.9.0
|
||||
* \since 17.3.0
|
||||
*/
|
||||
void ast_sorcery_force_reload_object(const struct ast_sorcery *sorcery, const char *type);
|
||||
|
||||
/*!
|
||||
* \brief Increase the reference count of a sorcery structure
|
||||
*
|
||||
|
|
|
@ -245,6 +245,9 @@ struct sorcery_load_details {
|
|||
|
||||
/*! \brief Whether this is a reload or not */
|
||||
unsigned int reload:1;
|
||||
|
||||
/*! \brief Whether this is forced or not */
|
||||
unsigned int force:1;
|
||||
};
|
||||
|
||||
/*! \brief Registered sorcery wizards */
|
||||
|
@ -1250,7 +1253,15 @@ static int sorcery_wizard_load(void *obj, void *arg, int flags)
|
|||
struct sorcery_load_details *details = arg;
|
||||
void (*load)(void *data, const struct ast_sorcery *sorcery, const char *type);
|
||||
|
||||
load = !details->reload ? wizard->wizard->callbacks.load : wizard->wizard->callbacks.reload;
|
||||
if (details->reload) {
|
||||
if (details->force && wizard->wizard->callbacks.force_reload) {
|
||||
load = wizard->wizard->callbacks.force_reload;
|
||||
} else {
|
||||
load = wizard->wizard->callbacks.reload;
|
||||
}
|
||||
} else {
|
||||
load = wizard->wizard->callbacks.load;
|
||||
}
|
||||
|
||||
if (load) {
|
||||
NOTIFY_WIZARD_OBSERVERS(wizard->wizard->observers, wizard_loading,
|
||||
|
@ -1408,6 +1419,23 @@ void ast_sorcery_reload(const struct ast_sorcery *sorcery)
|
|||
|
||||
}
|
||||
|
||||
void ast_sorcery_force_reload(const struct ast_sorcery *sorcery)
|
||||
{
|
||||
struct sorcery_load_details details = {
|
||||
.sorcery = sorcery,
|
||||
.reload = 1,
|
||||
.force = 1,
|
||||
};
|
||||
|
||||
NOTIFY_INSTANCE_OBSERVERS(sorcery->observers, instance_loading,
|
||||
sorcery->module_name, sorcery, 1);
|
||||
|
||||
ao2_callback(sorcery->types, OBJ_NODATA, sorcery_object_load, &details);
|
||||
|
||||
NOTIFY_INSTANCE_OBSERVERS(sorcery->observers, instance_loaded,
|
||||
sorcery->module_name, sorcery, 1);
|
||||
}
|
||||
|
||||
void ast_sorcery_reload_object(const struct ast_sorcery *sorcery, const char *type)
|
||||
{
|
||||
RAII_VAR(struct ast_sorcery_object_type *, object_type, ao2_find(sorcery->types, type, OBJ_KEY), ao2_cleanup);
|
||||
|
@ -1423,6 +1451,22 @@ void ast_sorcery_reload_object(const struct ast_sorcery *sorcery, const char *ty
|
|||
sorcery_object_load(object_type, &details, 0);
|
||||
}
|
||||
|
||||
void ast_sorcery_force_reload_object(const struct ast_sorcery *sorcery, const char *type)
|
||||
{
|
||||
RAII_VAR(struct ast_sorcery_object_type *, object_type, ao2_find(sorcery->types, type, OBJ_KEY), ao2_cleanup);
|
||||
struct sorcery_load_details details = {
|
||||
.sorcery = sorcery,
|
||||
.reload = 1,
|
||||
.force = 1,
|
||||
};
|
||||
|
||||
if (!object_type) {
|
||||
return;
|
||||
}
|
||||
|
||||
sorcery_object_load(object_type, &details, 0);
|
||||
}
|
||||
|
||||
void ast_sorcery_ref(struct ast_sorcery *sorcery)
|
||||
{
|
||||
ao2_ref(sorcery, +1);
|
||||
|
|
|
@ -34,6 +34,8 @@
|
|||
#include "asterisk/statsd.h"
|
||||
#include "asterisk/pbx.h"
|
||||
#include "asterisk/stream.h"
|
||||
#include "asterisk/stasis.h"
|
||||
#include "asterisk/security_events.h"
|
||||
|
||||
/*! \brief Number of buckets for persistent endpoint information */
|
||||
#define PERSISTENT_BUCKETS 53
|
||||
|
@ -49,6 +51,8 @@ static struct ao2_container *persistent_endpoints;
|
|||
|
||||
static struct ast_sorcery *sip_sorcery;
|
||||
|
||||
static struct stasis_subscription *acl_change_sub;
|
||||
|
||||
/*! \brief Hashing function for persistent endpoint information */
|
||||
static int persistent_endpoint_hash(const void *obj, const int flags)
|
||||
{
|
||||
|
@ -1787,6 +1791,16 @@ static void load_all_endpoints(void)
|
|||
ao2_cleanup(endpoints);
|
||||
}
|
||||
|
||||
static void acl_change_stasis_cb(void *data, struct stasis_subscription *sub,
|
||||
struct stasis_message *message)
|
||||
{
|
||||
if (stasis_message_type(message) != ast_named_acl_change_type()) {
|
||||
return;
|
||||
}
|
||||
|
||||
ast_sorcery_force_reload_object(sip_sorcery, "endpoint");
|
||||
}
|
||||
|
||||
int ast_res_pjsip_initialize_configuration(void)
|
||||
{
|
||||
if (ast_manager_register_xml(AMI_SHOW_ENDPOINTS, EVENT_FLAG_SYSTEM, ami_show_endpoints) ||
|
||||
|
@ -2007,6 +2021,10 @@ int ast_res_pjsip_initialize_configuration(void)
|
|||
|
||||
ast_sip_location_prune_boot_contacts();
|
||||
|
||||
acl_change_sub = stasis_subscribe(ast_security_topic(), acl_change_stasis_cb, NULL);
|
||||
stasis_subscription_accept_message_type(acl_change_sub, ast_named_acl_change_type());
|
||||
stasis_subscription_set_filter(acl_change_sub, STASIS_SUBSCRIPTION_FILTER_SELECTIVE);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -2016,6 +2034,7 @@ void ast_res_pjsip_destroy_configuration(void)
|
|||
return;
|
||||
}
|
||||
|
||||
acl_change_sub = stasis_unsubscribe_and_join(acl_change_sub);
|
||||
ast_sip_destroy_sorcery_global();
|
||||
ast_sip_destroy_sorcery_location();
|
||||
ast_sip_destroy_sorcery_auth();
|
||||
|
|
|
@ -31,6 +31,8 @@
|
|||
#include "asterisk/logger.h"
|
||||
#include "asterisk/sorcery.h"
|
||||
#include "asterisk/acl.h"
|
||||
#include "asterisk/stasis.h"
|
||||
#include "asterisk/security_events.h"
|
||||
|
||||
/*** DOCUMENTATION
|
||||
<configInfo name="res_pjsip_acl" language="en_US">
|
||||
|
@ -114,6 +116,8 @@
|
|||
</configInfo>
|
||||
***/
|
||||
|
||||
static struct stasis_subscription *acl_change_sub;
|
||||
|
||||
static int apply_acl(pjsip_rx_data *rdata, struct ast_acl_list *acl)
|
||||
{
|
||||
struct ast_sockaddr addr;
|
||||
|
@ -280,6 +284,16 @@ static void *acl_alloc(const char *name)
|
|||
return sip_acl;
|
||||
}
|
||||
|
||||
static void acl_change_stasis_cb(void *data, struct stasis_subscription *sub,
|
||||
struct stasis_message *message)
|
||||
{
|
||||
if (stasis_message_type(message) != ast_named_acl_change_type()) {
|
||||
return;
|
||||
}
|
||||
|
||||
ast_sorcery_force_reload_object(ast_sip_get_sorcery(), SIP_SORCERY_ACL_TYPE);
|
||||
}
|
||||
|
||||
static int load_module(void)
|
||||
{
|
||||
ast_sorcery_apply_config(ast_sip_get_sorcery(), SIP_SORCERY_ACL_TYPE);
|
||||
|
@ -304,12 +318,18 @@ static int load_module(void)
|
|||
|
||||
ast_sorcery_load_object(ast_sip_get_sorcery(), SIP_SORCERY_ACL_TYPE);
|
||||
|
||||
acl_change_sub = stasis_subscribe(ast_security_topic(), acl_change_stasis_cb, NULL);
|
||||
stasis_subscription_accept_message_type(acl_change_sub, ast_named_acl_change_type());
|
||||
stasis_subscription_set_filter(acl_change_sub, STASIS_SUBSCRIPTION_FILTER_SELECTIVE);
|
||||
|
||||
ast_sip_register_service(&acl_module);
|
||||
|
||||
return AST_MODULE_LOAD_SUCCESS;
|
||||
}
|
||||
|
||||
static int unload_module(void)
|
||||
{
|
||||
acl_change_sub = stasis_unsubscribe_and_join(acl_change_sub);
|
||||
ast_sip_unregister_service(&acl_module);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -103,6 +103,7 @@ static struct ast_sorcery_wizard config_object_wizard = {
|
|||
.open = sorcery_config_open,
|
||||
.load = sorcery_config_load,
|
||||
.reload = sorcery_config_reload,
|
||||
.force_reload = sorcery_config_load,
|
||||
.retrieve_id = sorcery_config_retrieve_id,
|
||||
.retrieve_fields = sorcery_config_retrieve_fields,
|
||||
.retrieve_multiple = sorcery_config_retrieve_multiple,
|
||||
|
|
Loading…
Reference in New Issue