<p>Kevin Harwell <strong>submitted</strong> this change.</p><p><a href="https://gerrit.asterisk.org/c/asterisk/+/13815">View Change</a></p><div style="white-space:pre-wrap">Approvals:
  George Joseph: Looks good to me, but someone else must approve
  Kevin Harwell: Looks good to me, approved; Approved for Submit

</div><pre style="font-family: monospace,monospace; white-space: pre-wrap;">pjsip: Update ACLs on named ACL changes.<br><br>This change extends the Sorcery API to allow a wizard to be<br>told to explicitly reload objects or a specific object type<br>even if the wizard believes that nothing has changed.<br><br>This has been leveraged by res_pjsip and res_pjsip_acl to<br>reload endpoints and PJSIP ACLs when a named ACL changes.<br><br>ASTERISK-28697<br><br>Change-Id: Ib8fee9bd9dd490db635132c479127a4114c1ca0b<br>---<br>M include/asterisk/sorcery.h<br>M main/sorcery.c<br>M res/res_pjsip/pjsip_configuration.c<br>M res/res_pjsip_acl.c<br>M res/res_sorcery_config.c<br>5 files changed, 112 insertions(+), 1 deletion(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/include/asterisk/sorcery.h b/include/asterisk/sorcery.h</span><br><span>index 3a0e1b8..a0ec653 100644</span><br><span>--- a/include/asterisk/sorcery.h</span><br><span>+++ b/include/asterisk/sorcery.h</span><br><span>@@ -323,6 +323,9 @@</span><br><span> </span><br><span>      /* \brief Callback for whether or not the wizard believes the object is stale */</span><br><span>     int (*is_stale)(const struct ast_sorcery *sorcery, void *data, void *object);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+       /*! \brief Optional callback for forcing a reload to occur, even if wizard has determined no changes */</span><br><span style="color: hsl(120, 100%, 40%);">+       void (*force_reload)(void *data, const struct ast_sorcery *sorcery, const char *type);</span><br><span> };</span><br><span> </span><br><span> /*! \brief Interface for a sorcery object type observer */</span><br><span>@@ -1060,6 +1063,17 @@</span><br><span> void ast_sorcery_reload(const struct ast_sorcery *sorcery);</span><br><span> </span><br><span> /*!</span><br><span style="color: hsl(120, 100%, 40%);">+ * \brief Inform any wizards to reload persistent objects, even if no changes determined</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param sorcery Pointer to a sorcery structure</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * \since 13.32.0</span><br><span style="color: hsl(120, 100%, 40%);">+ * \since 16.9.0</span><br><span style="color: hsl(120, 100%, 40%);">+ * \since 17.3.0</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+void ast_sorcery_force_reload(const struct ast_sorcery *sorcery);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/*!</span><br><span>  * \brief Inform any wizards of a specific object type to reload persistent objects</span><br><span>  *</span><br><span>  * \param sorcery Pointer to a sorcery structure</span><br><span>@@ -1068,6 +1082,19 @@</span><br><span> void ast_sorcery_reload_object(const struct ast_sorcery *sorcery, const char *type);</span><br><span> </span><br><span> /*!</span><br><span style="color: hsl(120, 100%, 40%);">+ * \brief Inform any wizards of a specific object type to reload persistent objects</span><br><span style="color: hsl(120, 100%, 40%);">+ *        even if no changes determined</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param sorcery Pointer to a sorcery structure</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param type Name of the object type to reload</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * \since 13.32.0</span><br><span style="color: hsl(120, 100%, 40%);">+ * \since 16.9.0</span><br><span style="color: hsl(120, 100%, 40%);">+ * \since 17.3.0</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+void ast_sorcery_force_reload_object(const struct ast_sorcery *sorcery, const char *type);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/*!</span><br><span>  * \brief Increase the reference count of a sorcery structure</span><br><span>  *</span><br><span>  * \param sorcery Pointer to a sorcery structure</span><br><span>diff --git a/main/sorcery.c b/main/sorcery.c</span><br><span>index d837845..0ada81e 100644</span><br><span>--- a/main/sorcery.c</span><br><span>+++ b/main/sorcery.c</span><br><span>@@ -245,6 +245,9 @@</span><br><span> </span><br><span>  /*! \brief Whether this is a reload or not */</span><br><span>        unsigned int reload:1;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      /*! \brief Whether this is forced or not */</span><br><span style="color: hsl(120, 100%, 40%);">+   unsigned int force:1;</span><br><span> };</span><br><span> </span><br><span> /*! \brief Registered sorcery wizards */</span><br><span>@@ -1250,7 +1253,15 @@</span><br><span>         struct sorcery_load_details *details = arg;</span><br><span>  void (*load)(void *data, const struct ast_sorcery *sorcery, const char *type);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-      load = !details->reload ? wizard->wizard->callbacks.load : wizard->wizard->callbacks.reload;</span><br><span style="color: hsl(120, 100%, 40%);">+   if (details->reload) {</span><br><span style="color: hsl(120, 100%, 40%);">+             if (details->force && wizard->wizard->callbacks.force_reload) {</span><br><span style="color: hsl(120, 100%, 40%);">+                      load = wizard->wizard->callbacks.force_reload;</span><br><span style="color: hsl(120, 100%, 40%);">+          } else {</span><br><span style="color: hsl(120, 100%, 40%);">+                      load = wizard->wizard->callbacks.reload;</span><br><span style="color: hsl(120, 100%, 40%);">+                }</span><br><span style="color: hsl(120, 100%, 40%);">+     } else {</span><br><span style="color: hsl(120, 100%, 40%);">+              load = wizard->wizard->callbacks.load;</span><br><span style="color: hsl(120, 100%, 40%);">+  }</span><br><span> </span><br><span>        if (load) {</span><br><span>          NOTIFY_WIZARD_OBSERVERS(wizard->wizard->observers, wizard_loading,</span><br><span>@@ -1408,6 +1419,23 @@</span><br><span> </span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+void ast_sorcery_force_reload(const struct ast_sorcery *sorcery)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+   struct sorcery_load_details details = {</span><br><span style="color: hsl(120, 100%, 40%);">+               .sorcery = sorcery,</span><br><span style="color: hsl(120, 100%, 40%);">+           .reload = 1,</span><br><span style="color: hsl(120, 100%, 40%);">+          .force = 1,</span><br><span style="color: hsl(120, 100%, 40%);">+   };</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  NOTIFY_INSTANCE_OBSERVERS(sorcery->observers, instance_loading,</span><br><span style="color: hsl(120, 100%, 40%);">+            sorcery->module_name, sorcery, 1);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+       ao2_callback(sorcery->types, OBJ_NODATA, sorcery_object_load, &details);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     NOTIFY_INSTANCE_OBSERVERS(sorcery->observers, instance_loaded,</span><br><span style="color: hsl(120, 100%, 40%);">+             sorcery->module_name, sorcery, 1);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> void ast_sorcery_reload_object(const struct ast_sorcery *sorcery, const char *type)</span><br><span> {</span><br><span>       RAII_VAR(struct ast_sorcery_object_type *, object_type, ao2_find(sorcery->types, type, OBJ_KEY), ao2_cleanup);</span><br><span>@@ -1423,6 +1451,22 @@</span><br><span>   sorcery_object_load(object_type, &details, 0);</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+void ast_sorcery_force_reload_object(const struct ast_sorcery *sorcery, const char *type)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+     RAII_VAR(struct ast_sorcery_object_type *, object_type, ao2_find(sorcery->types, type, OBJ_KEY), ao2_cleanup);</span><br><span style="color: hsl(120, 100%, 40%);">+     struct sorcery_load_details details = {</span><br><span style="color: hsl(120, 100%, 40%);">+               .sorcery = sorcery,</span><br><span style="color: hsl(120, 100%, 40%);">+           .reload = 1,</span><br><span style="color: hsl(120, 100%, 40%);">+          .force = 1,</span><br><span style="color: hsl(120, 100%, 40%);">+   };</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  if (!object_type) {</span><br><span style="color: hsl(120, 100%, 40%);">+           return;</span><br><span style="color: hsl(120, 100%, 40%);">+       }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   sorcery_object_load(object_type, &details, 0);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> void ast_sorcery_ref(struct ast_sorcery *sorcery)</span><br><span> {</span><br><span>    ao2_ref(sorcery, +1);</span><br><span>diff --git a/res/res_pjsip/pjsip_configuration.c b/res/res_pjsip/pjsip_configuration.c</span><br><span>index e6937fb..2452e54 100644</span><br><span>--- a/res/res_pjsip/pjsip_configuration.c</span><br><span>+++ b/res/res_pjsip/pjsip_configuration.c</span><br><span>@@ -34,6 +34,8 @@</span><br><span> #include "asterisk/statsd.h"</span><br><span> #include "asterisk/pbx.h"</span><br><span> #include "asterisk/stream.h"</span><br><span style="color: hsl(120, 100%, 40%);">+#include "asterisk/stasis.h"</span><br><span style="color: hsl(120, 100%, 40%);">+#include "asterisk/security_events.h"</span><br><span> </span><br><span> /*! \brief Number of buckets for persistent endpoint information */</span><br><span> #define PERSISTENT_BUCKETS 53</span><br><span>@@ -49,6 +51,8 @@</span><br><span> </span><br><span> static struct ast_sorcery *sip_sorcery;</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+static struct stasis_subscription *acl_change_sub;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> /*! \brief Hashing function for persistent endpoint information */</span><br><span> static int persistent_endpoint_hash(const void *obj, const int flags)</span><br><span> {</span><br><span>@@ -1787,6 +1791,16 @@</span><br><span>         ao2_cleanup(endpoints);</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+static void acl_change_stasis_cb(void *data, struct stasis_subscription *sub,</span><br><span style="color: hsl(120, 100%, 40%);">+       struct stasis_message *message)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+    if (stasis_message_type(message) != ast_named_acl_change_type()) {</span><br><span style="color: hsl(120, 100%, 40%);">+            return;</span><br><span style="color: hsl(120, 100%, 40%);">+       }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   ast_sorcery_force_reload_object(sip_sorcery, "endpoint");</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> int ast_res_pjsip_initialize_configuration(void)</span><br><span> {</span><br><span>    if (ast_manager_register_xml(AMI_SHOW_ENDPOINTS, EVENT_FLAG_SYSTEM, ami_show_endpoints) ||</span><br><span>@@ -2007,6 +2021,10 @@</span><br><span> </span><br><span>      ast_sip_location_prune_boot_contacts();</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+   acl_change_sub = stasis_subscribe(ast_security_topic(), acl_change_stasis_cb, NULL);</span><br><span style="color: hsl(120, 100%, 40%);">+  stasis_subscription_accept_message_type(acl_change_sub, ast_named_acl_change_type());</span><br><span style="color: hsl(120, 100%, 40%);">+ stasis_subscription_set_filter(acl_change_sub, STASIS_SUBSCRIPTION_FILTER_SELECTIVE);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>      return 0;</span><br><span> }</span><br><span> </span><br><span>@@ -2016,6 +2034,7 @@</span><br><span>           return;</span><br><span>      }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+ acl_change_sub = stasis_unsubscribe_and_join(acl_change_sub);</span><br><span>        ast_sip_destroy_sorcery_global();</span><br><span>    ast_sip_destroy_sorcery_location();</span><br><span>  ast_sip_destroy_sorcery_auth();</span><br><span>diff --git a/res/res_pjsip_acl.c b/res/res_pjsip_acl.c</span><br><span>index 8caf703..3bf0f6f 100644</span><br><span>--- a/res/res_pjsip_acl.c</span><br><span>+++ b/res/res_pjsip_acl.c</span><br><span>@@ -31,6 +31,8 @@</span><br><span> #include "asterisk/logger.h"</span><br><span> #include "asterisk/sorcery.h"</span><br><span> #include "asterisk/acl.h"</span><br><span style="color: hsl(120, 100%, 40%);">+#include "asterisk/stasis.h"</span><br><span style="color: hsl(120, 100%, 40%);">+#include "asterisk/security_events.h"</span><br><span> </span><br><span> /*** DOCUMENTATION</span><br><span>  <configInfo name="res_pjsip_acl" language="en_US"></span><br><span>@@ -114,6 +116,8 @@</span><br><span>   </configInfo></span><br><span>  ***/</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+static struct stasis_subscription *acl_change_sub;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> static int apply_acl(pjsip_rx_data *rdata, struct ast_acl_list *acl)</span><br><span> {</span><br><span>  struct ast_sockaddr addr;</span><br><span>@@ -280,6 +284,16 @@</span><br><span>     return sip_acl;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+static void acl_change_stasis_cb(void *data, struct stasis_subscription *sub,</span><br><span style="color: hsl(120, 100%, 40%);">+       struct stasis_message *message)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+    if (stasis_message_type(message) != ast_named_acl_change_type()) {</span><br><span style="color: hsl(120, 100%, 40%);">+            return;</span><br><span style="color: hsl(120, 100%, 40%);">+       }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   ast_sorcery_force_reload_object(ast_sip_get_sorcery(), SIP_SORCERY_ACL_TYPE);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> static int load_module(void)</span><br><span> {</span><br><span>      ast_sorcery_apply_config(ast_sip_get_sorcery(), SIP_SORCERY_ACL_TYPE);</span><br><span>@@ -304,12 +318,18 @@</span><br><span> </span><br><span>   ast_sorcery_load_object(ast_sip_get_sorcery(), SIP_SORCERY_ACL_TYPE);</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+     acl_change_sub = stasis_subscribe(ast_security_topic(), acl_change_stasis_cb, NULL);</span><br><span style="color: hsl(120, 100%, 40%);">+  stasis_subscription_accept_message_type(acl_change_sub, ast_named_acl_change_type());</span><br><span style="color: hsl(120, 100%, 40%);">+ stasis_subscription_set_filter(acl_change_sub, STASIS_SUBSCRIPTION_FILTER_SELECTIVE);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>      ast_sip_register_service(&acl_module);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>         return AST_MODULE_LOAD_SUCCESS;</span><br><span> }</span><br><span> </span><br><span> static int unload_module(void)</span><br><span> {</span><br><span style="color: hsl(120, 100%, 40%);">+       acl_change_sub = stasis_unsubscribe_and_join(acl_change_sub);</span><br><span>        ast_sip_unregister_service(&acl_module);</span><br><span>         return 0;</span><br><span> }</span><br><span>diff --git a/res/res_sorcery_config.c b/res/res_sorcery_config.c</span><br><span>index 8e5ee20..6029789 100644</span><br><span>--- a/res/res_sorcery_config.c</span><br><span>+++ b/res/res_sorcery_config.c</span><br><span>@@ -103,6 +103,7 @@</span><br><span>    .open = sorcery_config_open,</span><br><span>         .load = sorcery_config_load,</span><br><span>         .reload = sorcery_config_reload,</span><br><span style="color: hsl(120, 100%, 40%);">+      .force_reload = sorcery_config_load,</span><br><span>         .retrieve_id = sorcery_config_retrieve_id,</span><br><span>   .retrieve_fields = sorcery_config_retrieve_fields,</span><br><span>   .retrieve_multiple = sorcery_config_retrieve_multiple,</span><br><span></span><br></pre><p>To view, visit <a href="https://gerrit.asterisk.org/c/asterisk/+/13815">change 13815</a>. To unsubscribe, or for help writing mail filters, visit <a href="https://gerrit.asterisk.org/settings">settings</a>.</p><div itemscope itemtype="http://schema.org/EmailMessage"><div itemscope itemprop="action" itemtype="http://schema.org/ViewAction"><link itemprop="url" href="https://gerrit.asterisk.org/c/asterisk/+/13815"/><meta itemprop="name" content="View Change"/></div></div>

<div style="display:none"> Gerrit-Project: asterisk </div>
<div style="display:none"> Gerrit-Branch: 16 </div>
<div style="display:none"> Gerrit-Change-Id: Ib8fee9bd9dd490db635132c479127a4114c1ca0b </div>
<div style="display:none"> Gerrit-Change-Number: 13815 </div>
<div style="display:none"> Gerrit-PatchSet: 1 </div>
<div style="display:none"> Gerrit-Owner: Joshua Colp <jcolp@sangoma.com> </div>
<div style="display:none"> Gerrit-Reviewer: Friendly Automation </div>
<div style="display:none"> Gerrit-Reviewer: George Joseph <gjoseph@digium.com> </div>
<div style="display:none"> Gerrit-Reviewer: Kevin Harwell <kharwell@digium.com> </div>
<div style="display:none"> Gerrit-MessageType: merged </div>