summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexei Gradinari <alex2grad@gmail.com>2016-08-26 11:39:11 -0400
committerAlexei Gradinari <alex2grad@gmail.com>2016-08-30 15:58:56 -0500
commitfaf9bdebb770ac3bd7dffa477998ccbbb070b0e1 (patch)
tree2db69bd7554daecdd6716bcec88da22c1394c2d0
parente7d06a80978f9e87b91a5009dde97c0cff355ceb (diff)
res_pjsip: qualify/unqualify added/deleted realtime endpoints
If the PJSIP endpoint's AOR with the permanent contact was deleted from the realtime storage the res_pjsip module continues trying to qualify this contact. The error 'Unable to find an endpoint to qualify contact' appeares every 'qualify_frequency' seconds. This patch deletes this contact in this case. The PJSIP endpoint's AOR with the permanent contact is never qualified if it is added to realtime storage after asterisk started. This patch adds qualifying for the AOR's permanent contacts on the first handling of this AOR. ASTERISK-26319 #close Change-Id: Ib93dded9121edb113076903d1aa95402f799f8fe
-rw-r--r--res/res_pjsip/pjsip_options.c41
1 files changed, 40 insertions, 1 deletions
diff --git a/res/res_pjsip/pjsip_options.c b/res/res_pjsip/pjsip_options.c
index 5e0fc76cb..a282224c9 100644
--- a/res/res_pjsip/pjsip_options.c
+++ b/res/res_pjsip/pjsip_options.c
@@ -53,6 +53,9 @@ static const char *short_status_map [] = {
[REMOVED] = "Removed",
};
+static void contact_deleted(const void *obj);
+static void qualify_and_schedule(struct ast_sip_contact *contact);
+
const char *ast_sip_get_contact_status_label(const enum ast_sip_contact_status_type status)
{
return status_map[status];
@@ -108,6 +111,29 @@ static void *contact_status_alloc(const char *name)
return status;
}
+static int qualify_and_schedule_aor_contact(void *obj)
+{
+ struct ast_sip_contact *contact = obj;
+ struct ast_sip_aor *aor;
+
+ if (!contact || ast_strlen_zero(contact->aor) ||
+ !(aor = ast_sip_location_retrieve_aor(contact->aor))) {
+ ao2_ref(contact, -1);
+ return -1;
+ }
+
+ contact->qualify_frequency = aor->qualify_frequency;
+ contact->qualify_timeout = aor->qualify_timeout;
+ contact->authenticate_qualify = aor->authenticate_qualify;
+
+ ao2_ref(aor, -1);
+
+ qualify_and_schedule(contact);
+ ao2_ref(contact, -1);
+
+ return 0;
+}
+
AST_MUTEX_DEFINE_STATIC(creation_lock);
/*!
@@ -144,6 +170,18 @@ struct ast_sip_contact_status *ast_res_pjsip_find_or_create_contact_status(const
return NULL;
}
+ /* The permanent contact added after asterisk start should be qualified. */
+ if (ast_test_flag(&ast_options, AST_OPT_FLAG_FULLY_BOOTED) && ast_tvzero(contact->expiration_time)) {
+ /*
+ * The FULLY_BOOTED to filter out contacts that already existed when asterisk started.
+ * The zero expiration_time to select only permanent contacts.
+ */
+ ao2_ref((struct ast_sip_contact *) contact, +1);
+ if (ast_sip_push_task(NULL, qualify_and_schedule_aor_contact, (struct ast_sip_contact *) contact)) {
+ ao2_ref((struct ast_sip_contact *) contact, -1);
+ }
+ }
+
ast_statsd_log_string_va("PJSIP.contacts.states.%s", AST_STATSD_GAUGE,
"+1", 1.0, ast_sip_get_contact_status_label(status->status));
@@ -368,8 +406,9 @@ static int qualify_contact(struct ast_sip_endpoint *endpoint, struct ast_sip_con
endpoint_local = find_an_endpoint(contact);
}
if (!endpoint_local) {
- ast_log(LOG_ERROR, "Unable to find an endpoint to qualify contact %s\n",
+ ast_log(LOG_WARNING, "Unable to find an endpoint to qualify contact %s. Deleting this contact\n",
contact->uri);
+ contact_deleted(contact);
return -1;
}
}