summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--res/res_pjsip.c1
-rw-r--r--res/res_pjsip/include/res_pjsip_private.h12
-rw-r--r--res/res_pjsip/location.c8
-rw-r--r--res/res_pjsip/pjsip_options.c45
-rw-r--r--res/res_pjsip_registrar.c2
5 files changed, 58 insertions, 10 deletions
diff --git a/res/res_pjsip.c b/res/res_pjsip.c
index a7dd09ee8..ee78732c9 100644
--- a/res/res_pjsip.c
+++ b/res/res_pjsip.c
@@ -4368,7 +4368,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;
}
diff --git a/res/res_pjsip/include/res_pjsip_private.h b/res/res_pjsip/include/res_pjsip_private.h
index 0bdb63325..6ddbd1f26 100644
--- a/res/res_pjsip/include/res_pjsip_private.h
+++ b/res/res_pjsip/include/res_pjsip_private.h
@@ -184,6 +184,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.
*
* \retval 0 on success
diff --git a/res/res_pjsip/location.c b/res/res_pjsip/location.c
index 5abfcabad..cfe65b18e 100644
--- a/res/res_pjsip/location.c
+++ b/res/res_pjsip/location.c
@@ -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;
}
diff --git a/res/res_pjsip/pjsip_options.c b/res/res_pjsip/pjsip_options.c
index 6fd3c2575..51987f4de 100644
--- a/res/res_pjsip/pjsip_options.c
+++ b/res/res_pjsip/pjsip_options.c
@@ -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));
diff --git a/res/res_pjsip_registrar.c b/res/res_pjsip_registrar.c
index 2db753889..d190487ac 100644
--- a/res/res_pjsip_registrar.c
+++ b/res/res_pjsip_registrar.c
@@ -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));
}