From: Matt Jordan Date: Tue, 3 Nov 2015 17:15:09 +0000 (-0600) Subject: res_pjsip/location: Destroy contact_status objects on contact deletion X-Git-Tag: 13.7.0-rc1~88 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=refs%2Fchanges%2F57%2F1557%2F2;p=thirdparty%2Fasterisk.git res_pjsip/location: Destroy contact_status objects on contact deletion 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 --- diff --git a/res/res_pjsip/location.c b/res/res_pjsip/location.c index b6f88d20d4..eef1d43d2c 100644 --- a/res/res_pjsip/location.c +++ b/res/res_pjsip/location.c @@ -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); }