]> git.ipfire.org Git - thirdparty/asterisk.git/commitdiff
Update qualifies when AOR configuration changes. 60/4860/1
authorMark Michelson <mmichelson@digium.com>
Wed, 1 Feb 2017 19:54:50 +0000 (13:54 -0600)
committerMark Michelson <mmichelson@digium.com>
Wed, 1 Feb 2017 20:20:26 +0000 (14:20 -0600)
Prior to this change, qualifies would only update in the following
cases:
* A reload of res_pjsip.so was issued.
* A dynamic contact was re-registered after its AOR's qualify_frequency
  had been changed
This does not work well if you are using realtime for your AORs. You can
update your database to have a new qualify_frequency, but the permanent
contacts on that AOR will not have their qualifies updated. And the
dynamic contacts on that AOR will not have their qualifies updated until
the next registration, which could be a long time.

This change seeks to fix this problem by making it so that whenever AOR
configuration is applied, the contacts pertaining to that AOR have their
qualifies updated.

Additions from this patch:
* AOR sorcery objects now have an apply handler that calls into a newly
  added function in the OPTIONS code. This causes all contacts
  associated with that AOR to re-schedule qualifies.
* When it is time to qualify a contact, the OPTIONS code checks to see
  if the AOR can still be retrieved. If not, then qualification is
  canceled on the contact.

Alterations from this patch:
* The registrar code no longer updates contact's qualify_frequence and
  qualify_timeout. There is no point to this since those values already
  get updated when the AOR changes.
* Reloading res_pjsip.so no longer calls the OPTIONS initialization
  function. Reloading res_pjsip.so results in re-loading AORs, which
  results in re-scheduling qualifies.

Change-Id: I2e7c3316da28f389c45954f24c4e9389abac1121

res/res_pjsip.c
res/res_pjsip/include/res_pjsip_private.h
res/res_pjsip/location.c
res/res_pjsip/pjsip_options.c
res/res_pjsip_registrar.c

index b27bbb9bbfc4edfe14ee0438547e5d41b7ad7453..6cdd416990491210502965833fafce83842d0fe7 100644 (file)
@@ -4362,7 +4362,6 @@ AST_TEST_DEFINE(xml_sanitization_exceeds_buffer)
 static int reload_configuration_task(void *obj)
 {
        ast_res_pjsip_reload_configuration();
-       ast_res_pjsip_init_options_handling(1);
        ast_sip_initialize_dns();
        return 0;
 }
index 0bdb63325af1f280bb1f57c2ffb736bf7e509f01..6ddbd1f269d92585ec3c7f1b2629e61b26a73db5 100644 (file)
@@ -183,6 +183,18 @@ void ast_sip_destroy_global_headers(void);
  */
 int ast_res_pjsip_init_options_handling(int reload);
 
+/*!
+ * \internal
+ * \brief Indicate OPTIONS handling for this AOR needs updating.
+ *
+ * When AOR configuration is retrieved, it is possible that the
+ * qualify frequency has changed. The OPTIONs code needs to update
+ * its qualifies to reflect these changes.
+ *
+ * \param aor The AOR that has been retrieved
+ */
+void ast_res_pjsip_update_options(struct ast_sip_aor *aor);
+
 /*!
  * \internal Initialize message IP updating handling.
  *
index 5abfcabadfcdd38b97fa00bab71b5d8a0edb3b38..cfe65b18e3703dbf833dbc7e2dd184f81d45ff02 100644 (file)
@@ -1137,6 +1137,12 @@ static int contact_apply_handler(const struct ast_sorcery *sorcery, void *object
        return status ? 0 : -1;
 }
 
+static int aor_apply_handler(const struct ast_sorcery *sorcery, void *object)
+{
+       ast_res_pjsip_update_options(object);
+       return 0;
+}
+
 /*! \brief Initialize sorcery with location support */
 int ast_sip_initialize_sorcery_location(void)
 {
@@ -1153,7 +1159,7 @@ int ast_sip_initialize_sorcery_location(void)
        ast_sorcery_apply_default(sorcery, "aor", "config", "pjsip.conf,criteria=type=aor");
 
        if (ast_sorcery_object_register(sorcery, "contact", contact_alloc, NULL, contact_apply_handler) ||
-               ast_sorcery_object_register(sorcery, "aor", aor_alloc, NULL, NULL)) {
+               ast_sorcery_object_register(sorcery, "aor", aor_alloc, NULL, aor_apply_handler)) {
                return -1;
        }
 
index 6fd3c25757a20bd54fa14240f72a4e869db80035..51987f4de4523260d806c4ade2d72a377d8024bb 100644 (file)
@@ -518,6 +518,18 @@ static int qualify_contact_task(void *obj)
 static int qualify_contact_sched(const void *obj)
 {
        struct sched_data *data = (struct sched_data *) obj;
+       struct ast_sip_aor *aor;
+
+       /* This helps us to determine if an AOR has been removed
+        * from configuration, and if so, stop qualifying the
+        * contact
+        */
+       aor = ast_sip_location_retrieve_aor(data->contact->aor);
+       if (!aor) {
+               ao2_ref(data, -1);
+               return 0;
+       }
+       ao2_ref(aor, -1);
 
        ao2_ref(data->contact, +1);
        if (ast_sip_push_task(NULL, qualify_contact_task, data->contact)) {
@@ -1164,12 +1176,10 @@ static int qualify_and_schedule_all_cb(void *obj, void *arg, int flags)
        struct ast_sip_aor *aor = obj;
        struct ao2_container *contacts;
 
-       if (aor->permanent_contacts) {
-               contacts = ast_sip_location_retrieve_aor_contacts(aor);
-               if (contacts) {
-                       ao2_callback(contacts, OBJ_NODATA, qualify_and_schedule_cb_with_aor, aor);
-                       ao2_ref(contacts, -1);
-               }
+       contacts = ast_sip_location_retrieve_aor_contacts(aor);
+       if (contacts) {
+               ao2_callback(contacts, OBJ_NODATA, qualify_and_schedule_cb_with_aor, aor);
+               ao2_ref(contacts, -1);
        }
 
        return 0;
@@ -1496,6 +1506,29 @@ int ast_res_pjsip_init_options_handling(int reload)
        return 0;
 }
 
+static int unschedule_for_aor_cb(void *obj, void *arg, int flags)
+{
+       struct sched_data *data = obj;
+       struct ast_sip_aor *aor = arg;
+
+       if (!strcmp(ast_sorcery_object_get_id(aor), data->contact->aor)) {
+               AST_SCHED_DEL_UNREF(sched, data->id, ao2_ref(data, -1));
+       }
+
+       return 0;
+}
+
+void ast_res_pjsip_update_options(struct ast_sip_aor *aor)
+{
+       /* This can happen if an AOR is created and applied before OPTIONs code has been initialized */
+       if (!sched_qualifies) {
+               return;
+       }
+
+       ao2_callback(sched_qualifies, OBJ_NODATA | OBJ_UNLINK, unschedule_for_aor_cb, aor);
+       qualify_and_schedule_all_cb(aor, NULL, 0);
+}
+
 void ast_res_pjsip_cleanup_options_handling(void)
 {
        ast_cli_unregister_multiple(cli_options, ARRAY_LEN(cli_options));
index 2db753889007aaf6fbdda8b319ef80b2ca42e7e5..d190487ac87756395d87053f20f302cdcc4dd9b2 100644 (file)
@@ -456,8 +456,6 @@ static int register_aor_core(pjsip_rx_data *rdata,
                        }
 
                        contact_update->expiration_time = ast_tvadd(ast_tvnow(), ast_samp2tv(expiration, 1));
-                       contact_update->qualify_frequency = aor->qualify_frequency;
-                       contact_update->authenticate_qualify = aor->authenticate_qualify;
                        if (path_str) {
                                ast_string_field_set(contact_update, path, ast_str_buffer(path_str));
                        }