Menu

#135 New usrloc matching mode for Contact & Path

1.5.x
open
nobody
modules (179)
5
2010-03-24
2010-03-24
Anonymous
No

I had a problem with usrloc matching_mode and made this patch to add a new option 'matching_mode 2' to match on Contact and Path header. Since I am using two proxies with Path feeding into a Registrar for redundancy, the system was not accepting a duplicate registration that came through independent paths for redundancy in matching_mode 0. matching_mode 1 caused other problems by making a huge number of registrations with both buggy clients and clients that reloaded / refreshed registrations.

I've pasted a patch below and have been testing it extensively. The changes are minimal and it is quite stable.

-B

Index: modules/registrar/save.c

--- modules/registrar/save.c (revision 5958)
+++ modules/registrar/save.c (working copy)
@@ -412,7 +412,7 @@
}

if ( r->contacts==0 ||
- ul.get_ucontact(r, &_c->uri, ci->callid, ci->cseq+1, &c)!=0 ) {
+ ul.get_ucontact(r, &_c->uri, ci->callid, ci->path, ci->cseq+1, &c)!=0 ) {
if (ul.insert_ucontact( r, &_c->uri, ci, &c) < 0) {
rerrno = R_UL_INS_C;
LM_ERR("failed to insert contact\n");
@@ -486,7 +486,7 @@
/* calculate expires */
calc_contact_expires(_m, _c->expires, &e);

- ret = ul.get_ucontact( _r, &_c->uri, ci->callid, ci->cseq, &cont);
+ ret = ul.get_ucontact( _r, &_c->uri, ci->callid, ci->path, ci->cseq, &cont);
if (ret==-1) {
LM_ERR("invalid cseq for aor <%.*s>\n",_r->aor.len,_r->aor.s);
rerrno = R_INV_CSEQ;
@@ -564,7 +564,7 @@
calc_contact_expires(_m, _c->expires, &expires);

/* search for the contact*/
- ret = ul.get_ucontact( _r, &_c->uri, ci->callid, ci->cseq, &c);
+ ret = ul.get_ucontact( _r, &_c->uri, ci->callid, ci->path, ci->cseq, &c);
if (ret==-1) {
LM_ERR("invalid cseq for aor <%.*s>\n",_r->aor.len,_r->aor.s);
rerrno = R_INV_CSEQ;
Index: modules/usrloc/urecord.c
===================================================================
--- modules/usrloc/urecord.c (revision 5958)
+++ modules/usrloc/urecord.c (working copy)
@@ -554,16 +554,41 @@

/*!
+ * \brief Match a contact record to a contact string and path
+ * \param ptr contact record
+ * \param _c contact string
+ * \param _path path
+ * \return ptr on successfull match, 0 when they not match
+ */
+static inline struct ucontact* contact_path_match( ucontact_t* ptr,
+ str* _c, str *_path)
+{
+ while(ptr) {
+ if ( (_c->len==ptr->c.len) && (_path->len==ptr->path.len)
+ && !memcmp(_c->s, ptr->c.s, _c->len)
+ && !memcmp(_path->s, ptr->path.s, _path->len)
+ ) {
+ return ptr;
+ }
+
+ ptr = ptr->next;
+ }
+ return 0;
+}
+
+
+/*!
* \brief Get pointer to ucontact with given contact
* \param _r record where to search the contacts
* \param _c contact string
* \param _callid callid
+ * \param _path path
* \param _cseq CSEQ number
* \param _co found contact
* \return 0 - found, 1 - not found, -1 - invalid found,
* -2 - found, but to be skipped (same cseq)
*/
-int get_ucontact(urecord_t* _r, str* _c, str* _callid, int _cseq,
+int get_ucontact(urecord_t* _r, str* _c, str* _callid, str* _path, int _cseq,
struct ucontact** _co)
{
ucontact_t* ptr;
@@ -581,6 +606,9 @@
ptr = contact_callid_match( _r->contacts, _c, _callid);
no_callid = 1;
break;
+ case CONTACT_PATH:
+ ptr = contact_path_match( _r->contacts, _c, _path);
+ break;
default:
LM_CRIT("unknown matching_mode %d\n", matching_mode);
return -1;
Index: modules/usrloc/ul_mi.c
===================================================================
--- modules/usrloc/ul_mi.c (revision 5958)
+++ modules/usrloc/ul_mi.c (working copy)
@@ -50,6 +50,8 @@
#define MI_UL_CSEQ 1
/*! call-id used for ul_add and ul_rm_contact */
static str mi_ul_cid = str_init("dfjrewr12386fd6-343@openser.mi");
+/*! path used for ul_add and ul_rm_contact */
+static str mi_ul_path = str_init("dummypath");
/*! user agent used for ul_add */
static str mi_ul_ua = str_init("Kamailio MI Server");

@@ -312,7 +314,7 @@
}

contact = &node->next->next->value;
- ret = get_ucontact( rec, contact, &mi_ul_cid, MI_UL_CSEQ+1, &con);
+ ret = get_ucontact( rec, contact, &mi_ul_cid, &mi_ul_path, MI_UL_CSEQ+1, &con);
if (ret < 0) {
unlock_udomain( dom, aor);
return 0;
@@ -518,7 +520,7 @@
goto lock_error;
c = 0;
} else {
- if (get_ucontact( r, contact, &mi_ul_cid, MI_UL_CSEQ+1, &c) < 0)
+ if (get_ucontact( r, contact, &mi_ul_cid, &mi_ul_path, MI_UL_CSEQ+1, &c) < 0)
goto lock_error;
}

Index: modules/usrloc/urecord.h

--- modules/usrloc/urecord.h (revision 5958)
+++ modules/usrloc/urecord.h (working copy)
@@ -182,9 +182,9 @@
* \return 0 - found, 1 - not found, -1 - invalid found,
* -2 - found, but to be skipped (same cseq)
*/
-typedef int (*get_ucontact_t)(urecord_t* _r, str* _c, str* _callid, int _cseq,
+typedef int (*get_ucontact_t)(urecord_t* _r, str* _c, str* _callid, str* _path, int _cseq,
struct ucontact** _co);
-int get_ucontact(urecord_t* _r, str* _c, str* _callid, int _cseq,
+int get_ucontact(urecord_t* _r, str* _c, str* _callid, str* _path, int _cseq,
struct ucontact** _co);

Index: modules/usrloc/ul_mod.c

--- modules/usrloc/ul_mod.c (revision 5958)
+++ modules/usrloc/ul_mod.c (working copy)
@@ -242,6 +242,7 @@
switch (matching_mode) {
case CONTACT_ONLY:
case CONTACT_CALLID:
+ case CONTACT_PATH:
break;
default:
LM_ERR("invalid matching mode %d\n", matching_mode);
Index: modules/usrloc/doc/usrloc_admin.xml
===================================================================
--- modules/usrloc/doc/usrloc_admin.xml (revision 5958)
+++ modules/usrloc/doc/usrloc_admin.xml (working copy)
@@ -573,6 +573,11 @@
matching algorithm.
</para>
</listitem>
+ <listitem>
+ <para><emphasis>2</emphasis> - CONTACT and PATH based
+ matching algorithm. This mode is like mode <emphasis>0</emphasis> but allows for duplicate contacts from differing paths.
+ </para>
+ </listitem>
</itemizedlist>
<para>
<emphasis>
Index: modules/usrloc/ul_mod.h
===================================================================
--- modules/usrloc/ul_mod.h (revision 5958)
+++ modules/usrloc/ul_mod.h (working copy)
@@ -84,6 +84,7 @@
*/
#define CONTACT_ONLY (0)
#define CONTACT_CALLID (1)
+#define CONTACT_PATH (2)

extern int matching_mode;

Discussion


Log in to post a comment.