Module: sip-router Branch: 3.2 Commit: 047f66369f0c3eaa75592942f56565eb0f39f848 URL: http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=047f6636...
Author: pd peter.dunkley@crocodile-rcs.com Committer: pd peter.dunkley@crocodile-rcs.com Date: Fri Jan 27 15:34:16 2012 +0000
modules_k/pua: Fixed race hazard relating to RLS back-end SUBSCRIBEs
- This resulted in the "no presence dialog record for non-TERMINATED state..." error message coming out of RLS a lot. - On the sending side you have can have two dialogs (one temporary and one full) stored for a short period of time. This is because the full dialog is written before the temporary one is deleted. This can make the lookup when a back-end NOTIFY is received fail because only one record is expected. This is now fixed - instead of inserting and then deleting we do a swap (while the hash table is locked). - Based on... (cherry picked from commit e627bc31776b521a1078b2a004e8ed179521cae2)
---
modules_k/pua/hash.c | 48 ++++++++++++++++++++++++++------------- modules_k/pua/hash.h | 1 + modules_k/pua/send_subscribe.c | 16 ++++++++----- 3 files changed, 43 insertions(+), 22 deletions(-)
diff --git a/modules_k/pua/hash.c b/modules_k/pua/hash.c index 805be74..1b6784c 100644 --- a/modules_k/pua/hash.c +++ b/modules_k/pua/hash.c @@ -215,33 +215,28 @@ void update_htable(ua_pres_t* p, time_t desired_expires, int expires, } } /* insert in front; so when searching the most recent result is returned*/ -void insert_htable(ua_pres_t* presentity) +void _insert_htable(ua_pres_t* presentity, unsigned int hash_code) { ua_pres_t* p= NULL; - unsigned int hash_code; - - hash_code= core_hash(presentity->pres_uri,presentity->watcher_uri, - HASH_SIZE); - - lock_get(&HashT->p_records[hash_code].lock);
-/* - * useless since always checking before calling insert - if(get_dialog(presentity, hash_code)!= NULL ) - { - LM_DBG("Dialog already found- do not insert\n"); - return; - } -*/ p= HashT->p_records[hash_code].entity;
presentity->db_flag= INSERTDB_FLAG; presentity->next= p->next; p->next= presentity; +}
- lock_release(&HashT->p_records[hash_code].lock); +void insert_htable(ua_pres_t* presentity) +{ + unsigned int hash_code; + + hash_code= core_hash(presentity->pres_uri,presentity->watcher_uri, HASH_SIZE); + lock_get(&HashT->p_records[hash_code].lock); + + _insert_htable(presentity, hash_code);
+ lock_release(&HashT->p_records[hash_code].lock); }
/* This function used to perform a search to find the hash table @@ -302,6 +297,27 @@ void destroy_htable(void) return; }
+int convert_temporary_dialog(ua_pres_t *dialog) +{ + ua_pres_t *temp_dialog; + unsigned int hash_code; + + hash_code= core_hash(dialog->pres_uri,dialog->watcher_uri, HASH_SIZE); + lock_get(&HashT->p_records[hash_code].lock); + + temp_dialog = get_temporary_dialog(dialog, hash_code); + if (temp_dialog) + delete_htable(temp_dialog, hash_code); + else + return -1; + + _insert_htable(dialog, hash_code); + + lock_release(&HashT->p_records[hash_code].lock); + + return 1; +} + /* must lock the record line before calling this function*/ ua_pres_t* get_dialog(ua_pres_t* dialog, unsigned int hash_code) { diff --git a/modules_k/pua/hash.h b/modules_k/pua/hash.h index 141296f..c2204c4 100644 --- a/modules_k/pua/hash.h +++ b/modules_k/pua/hash.h @@ -126,6 +126,7 @@ int is_dialog(ua_pres_t* dialog);
ua_pres_t* get_dialog(ua_pres_t* dialog, unsigned int hash_code); ua_pres_t* get_temporary_dialog(ua_pres_t* dialog, unsigned int hash_code); +int convert_temporary_dialog(ua_pres_t *dialog);
int get_record_id(ua_pres_t* dialog, str** rec_id); typedef int (*get_record_id_t)(ua_pres_t* dialog, str** rec_id); diff --git a/modules_k/pua/send_subscribe.c b/modules_k/pua/send_subscribe.c index 08e3d3d..c4caad1 100644 --- a/modules_k/pua/send_subscribe.c +++ b/modules_k/pua/send_subscribe.c @@ -612,7 +612,11 @@ void subs_cback_func(struct cell *t, int cb_type, struct tmcb_params *ps) LM_DBG("record for subscribe from %.*s to %.*s inserted in datatbase\n", presentity->watcher_uri->len, presentity->watcher_uri->s, presentity->pres_uri->len, presentity->pres_uri->s); - insert_htable(presentity); + if (convert_temporary_dialog(presentity) < 0) + { + LM_ERR("Could not convert temporary dialog into a dialog\n"); + goto error; + }
done: if(hentity->ua_flag == REQ_OTHER) @@ -620,13 +624,13 @@ done: hentity->flag= flag; run_pua_callbacks( hentity, msg); } + goto end; + error: - lock_get(&HashT->p_records[hash_code].lock); - presentity = get_temporary_dialog(hentity, hash_code); - if (presentity!=NULL) - delete_htable(presentity, hash_code); - lock_release(&HashT->p_records[hash_code].lock); + if (presentity->remote_contact.s) shm_free(presentity->remote_contact.s); + if (presentity) shm_free(presentity);
+end: if(hentity) { shm_free(hentity);