]> git.ipfire.org Git - thirdparty/asterisk.git/commitdiff
res_pjsip: qualify/unqualify added/deleted realtime endpoints 32/3732/2
authorAlexei Gradinari <alex2grad@gmail.com>
Fri, 26 Aug 2016 15:39:11 +0000 (11:39 -0400)
committerAlexei Gradinari <alex2grad@gmail.com>
Tue, 30 Aug 2016 19:02:05 +0000 (15:02 -0400)
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

res/res_pjsip/pjsip_options.c

index 6f7455d507eeb2849d7ed24c5aad2eac283e46b6..d871883636b5784a62e3502361ce37b4c2262c0b 100644 (file)
@@ -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];
@@ -106,6 +109,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);
 
 /*!
@@ -147,6 +173,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));
 
@@ -378,8 +416,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;
                }
        }