Module: sip-router Branch: master Commit: 9cb078da8ff7cba9d2642d949e4e5a10bd851d82 URL: http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=9cb078da...
Author: Peter Dunkley peter.dunkley@crocodile-rcs.com Committer: Peter Dunkley peter.dunkley@crocodile-rcs.com Date: Thu Apr 5 23:21:39 2012 +0100
modules_k/pua, modules_k/rls: Prevent RLS from performing multiple back-end subscriptions to a presentity for a single RLS subscription
---
modules_k/pua/hash.c | 2 +- modules_k/pua/pua_db.c | 2 +- modules_k/pua/send_subscribe.c | 9 +---- modules_k/rls/list.h | 13 +++++++- modules_k/rls/subscribe.c | 70 +++++++++++++++++++++++----------------- 5 files changed, 56 insertions(+), 40 deletions(-)
diff --git a/modules_k/pua/hash.c b/modules_k/pua/hash.c index fe6d82b..1fa6149 100644 --- a/modules_k/pua/hash.c +++ b/modules_k/pua/hash.c @@ -687,7 +687,7 @@ list_entry_t *get_subs_list(str *did) tmp_str->len = dialog->pres_uri->len; tmp_str->s[tmp_str->len] = '\0';
- list = list_insert(tmp_str, list); + list = list_insert(tmp_str, list, NULL); } dialog = dialog->next; } diff --git a/modules_k/pua/pua_db.c b/modules_k/pua/pua_db.c index c9846d0..2bc9e88 100644 --- a/modules_k/pua/pua_db.c +++ b/modules_k/pua/pua_db.c @@ -1560,7 +1560,7 @@ list_entry_t *get_subs_list_puadb(str *did) tmp_str->len = strng.len; tmp_str->s[tmp_str->len] = '\0';
- list = list_insert(tmp_str, list); + list = list_insert(tmp_str, list, NULL); } } while ((db_fetch_next(&pua_dbf, pua_fetch_rows, pua_db, &res)==1) && (RES_ROWS(res)>0)); diff --git a/modules_k/pua/send_subscribe.c b/modules_k/pua/send_subscribe.c index c88db69..a62ba7c 100644 --- a/modules_k/pua/send_subscribe.c +++ b/modules_k/pua/send_subscribe.c @@ -1091,15 +1091,10 @@ insert: if (presentity->to_tag.len == 0) { if (subs->expires > 0) - { - LM_WARN("attempting to re-SUBSCRIBE to temporary (non-established) dialog - skipping\n"); - LM_WARN(" is %.*s in %.*s's contact list more than once?\n", - presentity->pres_uri->len, presentity->pres_uri->s, - presentity->watcher_uri->len, presentity->watcher_uri->s); - } + LM_WARN("attempting to re-SUBSCRIBE to a temporary (non-established) dialog - skipping\n"); else { - LM_WARN("attempting to un-SUBSCRIBE to temporary (non-established) dialog - skipping and deleting dialog\n"); + LM_WARN("attempting to un-SUBSCRIBE from a temporary (non-established) dialog - skipping and deleting dialog\n"); if (dbmode==PUA_DB_ONLY) delete_dialog_puadb(presentity); else diff --git a/modules_k/rls/list.h b/modules_k/rls/list.h index e8580da..c9904aa 100644 --- a/modules_k/rls/list.h +++ b/modules_k/rls/list.h @@ -11,11 +11,14 @@ typedef struct list_entry struct list_entry *next; } list_entry_t;
-static inline list_entry_t *list_insert(str *strng, list_entry_t *list) +static inline list_entry_t *list_insert(str *strng, list_entry_t *list, int *duplicate) { int cmp; list_entry_t *p, *q;
+ if (duplicate != NULL) + *duplicate = 0; + if (strng == NULL || strng->s == NULL || strng->len == 0) { LM_ERR("bad string\n"); @@ -36,7 +39,11 @@ static inline list_entry_t *list_insert(str *strng, list_entry_t *list) cmp = strncmp(list->strng->s, strng->s, strng->len);
if (cmp == 0) + { + if (duplicate != NULL) + *duplicate = 1; return list; + } if (cmp > 0) { p->next = list; @@ -49,7 +56,11 @@ static inline list_entry_t *list_insert(str *strng, list_entry_t *list) q = q->next;
if (cmp == 0) + { + if (duplicate != NULL) + *duplicate = 1; return list; + }
p->next = q->next; q->next = p; diff --git a/modules_k/rls/subscribe.c b/modules_k/rls/subscribe.c index c3dc4a2..eadef7a 100644 --- a/modules_k/rls/subscribe.c +++ b/modules_k/rls/subscribe.c @@ -861,8 +861,10 @@ error:
int send_resource_subs(char* uri, void* param) { - str pres_uri; + str pres_uri, *tmp_str; struct sip_uri parsed_pres_uri; + int duplicate = 0; + subs_info_t *s = (subs_info_t *) param;
pres_uri.s = uri; pres_uri.len = strlen(uri); @@ -877,8 +879,8 @@ int send_resource_subs(char* uri, void* param) { LM_WARN("Unable to subscribe to remote contact %.*s for watcher %.*s\n", pres_uri.len, pres_uri.s, - ((subs_info_t*)param)->watcher_uri->len, - ((subs_info_t*)param)->watcher_uri->s); + s->watcher_uri->len, + s->watcher_uri->s); return 1; }
@@ -887,31 +889,33 @@ int send_resource_subs(char* uri, void* param) if (rls_max_backend_subs > 0 && ++counter > rls_max_backend_subs) return 1;
- ((subs_info_t*)param)->pres_uri = &pres_uri; - ((subs_info_t*)param)->remote_target = &pres_uri; + s->pres_uri = &pres_uri; + s->remote_target = &pres_uri;
- if (((subs_info_t*)param)->internal_update_flag == INTERNAL_UPDATE_TRUE) + /* Build list of contacts... checking each contact exists only once */ + if ((tmp_str = (str *)pkg_malloc(sizeof(str))) == NULL) { - str *tmp_str; - - if ((tmp_str = (str *)pkg_malloc(sizeof(str))) == NULL) - { - LM_ERR("out of private memory\n"); - return -1; - } - if ((tmp_str->s = (char *)pkg_malloc(sizeof(char) * pres_uri.len)) == NULL) - { - pkg_free(tmp_str); - LM_ERR("out of private memory\n"); - return -1; - } - memcpy(tmp_str->s, pres_uri.s, pres_uri.len); - tmp_str->len = pres_uri.len; - - rls_contact_list = list_insert(tmp_str, rls_contact_list); + LM_ERR("out of private memory\n"); + return -1; + } + if ((tmp_str->s = (char *)pkg_malloc(sizeof(char) * pres_uri.len)) == NULL) + { + pkg_free(tmp_str); + LM_ERR("out of private memory\n"); + return -1; + } + memcpy(tmp_str->s, pres_uri.s, pres_uri.len); + tmp_str->len = pres_uri.len; + rls_contact_list = list_insert(tmp_str, rls_contact_list, &duplicate); + if (duplicate != 0) + { + LM_WARN("%.*s has %.*s multiple times in the same resource list\n", + s->watcher_uri->len, s->watcher_uri->s, + s->pres_uri->len, s->pres_uri->s); + return 1; }
- return pua_send_subscribe((subs_info_t*)param); + return pua_send_subscribe(s); }
/** @@ -964,14 +968,14 @@ int resource_subscriptions(subs_t* subs, xmlNodePtr xmlnode)
s.internal_update_flag = subs->internal_update_flag;
- if (subs->internal_update_flag == INTERNAL_UPDATE_TRUE) + if (rls_contact_list != NULL) { - if (rls_contact_list != NULL) - { - LM_WARN("contact list is not empty\n"); - list_free(&rls_contact_list); - } + LM_WARN("contact list is not empty\n"); + list_free(&rls_contact_list); + }
+ if (subs->internal_update_flag == INTERNAL_UPDATE_TRUE) + { if (rls_subs_list != NULL) { LM_WARN("subscriber list is not empty\n"); @@ -1016,6 +1020,10 @@ int resource_subscriptions(subs_t* subs, xmlNodePtr xmlnode) pkg_free(tmp_str); } } + else + { + list_free(&rls_contact_list); + }
pkg_free(wuri.s); pkg_free(did_str.s); @@ -1027,6 +1035,8 @@ error: pkg_free(wuri.s); if(did_str.s) pkg_free(did_str.s); + if(rls_contact_list) + list_free(&rls_contact_list); return -1;
}