/* \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 */
*/
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
*
*/
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
*
/*! \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 */
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,
}
+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);
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);
#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
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)
{
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) ||
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;
}
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();
#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">
</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;
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);
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;
}
.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,