[Asterisk-code-review] pjsip: Update ACLs on named ACL changes. (asterisk[13])

Kevin Harwell asteriskteam at digium.com
Thu Feb 27 12:52:52 CST 2020


Kevin Harwell has submitted this change. ( https://gerrit.asterisk.org/c/asterisk/+/13814 )

Change subject: pjsip: Update ACLs on named ACL changes.
......................................................................

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
---
M include/asterisk/sorcery.h
M main/sorcery.c
M res/res_pjsip/pjsip_configuration.c
M res/res_pjsip_acl.c
M res/res_sorcery_config.c
5 files changed, 112 insertions(+), 1 deletion(-)

Approvals:
  George Joseph: Looks good to me, but someone else must approve
  Kevin Harwell: Looks good to me, approved; Approved for Submit



diff --git a/include/asterisk/sorcery.h b/include/asterisk/sorcery.h
index a140cb4..aba2080 100644
--- a/include/asterisk/sorcery.h
+++ b/include/asterisk/sorcery.h
@@ -320,6 +320,9 @@
 			struct ao2_container *objects,
 			const char *prefix,
 			const size_t prefix_len);
+
+	/*! \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 */
@@ -1068,6 +1071,17 @@
 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
  *
  * \param sorcery Pointer to a sorcery structure
@@ -1076,6 +1090,19 @@
 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
  *
  * \param sorcery Pointer to a sorcery structure
diff --git a/main/sorcery.c b/main/sorcery.c
index 12e78f0..bae270c 100644
--- a/main/sorcery.c
+++ b/main/sorcery.c
@@ -237,6 +237,9 @@
 
 	/*! \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 */
@@ -1238,7 +1241,15 @@
 	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,
@@ -1396,6 +1407,23 @@
 
 }
 
+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);
@@ -1411,6 +1439,22 @@
 	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);
diff --git a/res/res_pjsip/pjsip_configuration.c b/res/res_pjsip/pjsip_configuration.c
index db53592..de8c1c8 100644
--- a/res/res_pjsip/pjsip_configuration.c
+++ b/res/res_pjsip/pjsip_configuration.c
@@ -33,6 +33,8 @@
 #include "asterisk/test.h"
 #include "asterisk/statsd.h"
 #include "asterisk/pbx.h"
+#include "asterisk/stasis.h"
+#include "asterisk/security_events.h"
 
 /*! \brief Number of buckets for persistent endpoint information */
 #define PERSISTENT_BUCKETS 53
@@ -48,6 +50,8 @@
 
 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)
 {
@@ -1746,6 +1750,16 @@
 	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(const struct ast_module_info *ast_module_info)
 {
 	if (ast_manager_register_xml(AMI_SHOW_ENDPOINTS, EVENT_FLAG_SYSTEM, ami_show_endpoints) ||
@@ -1960,6 +1974,10 @@
 
 	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;
 }
 
@@ -1969,6 +1987,7 @@
 		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();
diff --git a/res/res_pjsip_acl.c b/res/res_pjsip_acl.c
index a04f2b4..e62eb09 100644
--- a/res/res_pjsip_acl.c
+++ b/res/res_pjsip_acl.c
@@ -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;
@@ -267,6 +271,16 @@
 	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)
 {
 	CHECK_PJSIP_MODULE_LOADED();
@@ -293,12 +307,18 @@
 
 	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;
 }
diff --git a/res/res_sorcery_config.c b/res/res_sorcery_config.c
index a458d91..b9ccc15 100644
--- a/res/res_sorcery_config.c
+++ b/res/res_sorcery_config.c
@@ -105,6 +105,7 @@
 	.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,

-- 
To view, visit https://gerrit.asterisk.org/c/asterisk/+/13814
To unsubscribe, or for help writing mail filters, visit https://gerrit.asterisk.org/settings

Gerrit-Project: asterisk
Gerrit-Branch: 13
Gerrit-Change-Id: Ib8fee9bd9dd490db635132c479127a4114c1ca0b
Gerrit-Change-Number: 13814
Gerrit-PatchSet: 1
Gerrit-Owner: Joshua Colp <jcolp at sangoma.com>
Gerrit-Reviewer: Friendly Automation
Gerrit-Reviewer: George Joseph <gjoseph at digium.com>
Gerrit-Reviewer: Kevin Harwell <kharwell at digium.com>
Gerrit-MessageType: merged
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.digium.com/pipermail/asterisk-code-review/attachments/20200227/5513b97d/attachment-0001.html>


More information about the asterisk-code-review mailing list