Module: sip-router
Branch: master
Commit: 9cb078da8ff7cba9d2642d949e4e5a10bd851d82
URL:
http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=9cb078d…
Author: Peter Dunkley <peter.dunkley(a)crocodile-rcs.com>
Committer: Peter Dunkley <peter.dunkley(a)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;
}