]> git.ipfire.org Git - thirdparty/asterisk.git/commitdiff
res_pjsip/location: Destroy contact_status objects on contact deletion 57/1557/2
authorMatt Jordan <mjordan@digium.com>
Tue, 3 Nov 2015 17:15:09 +0000 (11:15 -0600)
committerMatt Jordan <mjordan@digium.com>
Wed, 4 Nov 2015 13:44:26 +0000 (07:44 -0600)
The contact_status Sorcery objects are currently not destroyed when a contact
is deleted. This causes the contact's last known RTT/status to be 'sticky'
when the contact itself may no longer exist. This patch causes the
contact_status objects associated with both dynamic and static contacts to
be destroyed if the AoR holding those contacts is also destroyed (or via
other paths where a contact may be deleted.)

Change-Id: I7feec8b9278cac3c5263a4c0483f4a0f3b62426e

res/res_pjsip/location.c

index b6f88d20d43a92402a68c03b1407ab43b4d679d3..eef1d43d2cc90e6949d7f709f625dfef32e75492 100644 (file)
@@ -59,17 +59,20 @@ static int destroy_contact(void *obj, void *arg, int flags)
 
 static void aor_deleted_observer(const void *object)
 {
+       const struct ast_sip_aor *aor = object;
        const char *aor_id = ast_sorcery_object_get_id(object);
        /* Give enough space for ^ at the beginning and ;@ at the end, since that is our object naming scheme */
        char regex[strlen(aor_id) + 4];
        struct ao2_container *contacts;
 
-       snprintf(regex, sizeof(regex), "^%s;@", aor_id);
+       if (aor->permanent_contacts) {
+               ao2_callback(aor->permanent_contacts, OBJ_NODATA | OBJ_MULTIPLE | OBJ_UNLINK, destroy_contact, NULL);
+       }
 
+       snprintf(regex, sizeof(regex), "^%s;@", aor_id);
        if (!(contacts = ast_sorcery_retrieve_by_regex(ast_sip_get_sorcery(), "contact", regex))) {
                return;
        }
-
        /* Destroy any contacts that may still exist that were made for this AoR */
        ao2_callback(contacts, OBJ_NODATA | OBJ_MULTIPLE | OBJ_UNLINK, destroy_contact, NULL);
 
@@ -302,6 +305,14 @@ int ast_sip_location_update_contact(struct ast_sip_contact *contact)
 
 int ast_sip_location_delete_contact(struct ast_sip_contact *contact)
 {
+       void *contact_status_obj;
+
+       contact_status_obj = ast_sorcery_retrieve_by_id(ast_sip_get_sorcery(), CONTACT_STATUS, ast_sorcery_object_get_id(contact));
+       if (contact_status_obj) {
+               ast_sorcery_delete(ast_sip_get_sorcery(), contact_status_obj);
+               ao2_ref(contact_status_obj, -1);
+       }
+
        return ast_sorcery_delete(ast_sip_get_sorcery(), contact);
 }