|
|
|
@ -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;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|