Module: sip-router
Branch: master
Commit: d6fbd5a146c01aa0fa856fcb4279d9883f3b12b9
URL:
http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=d6fbd5a…
Author: Marius Zbihlei <marius.zbihlei(a)1and1.ro>
Committer: Marius Zbihlei <marius.zbihlei(a)1and1.ro>
Date: Wed Apr 21 13:16:45 2010 +0300
modules_k/usrloc Added Contact and Path matching mode
The binding is matched against Contact and Path
Patch provided by Bayan Towfiq ( bayan at flowroute dot com )
---
modules_k/registrar/save.c | 8 ++++----
modules_k/usrloc/doc/usrloc_admin.xml | 18 +++++++++++++++++-
modules_k/usrloc/ul_mi.c | 7 ++++---
modules_k/usrloc/ul_mod.c | 1 +
modules_k/usrloc/ul_mod.h | 1 +
modules_k/usrloc/urecord.c | 31 ++++++++++++++++++++++++++++++-
modules_k/usrloc/urecord.h | 8 +++++---
7 files changed, 62 insertions(+), 12 deletions(-)
diff --git a/modules_k/registrar/save.c b/modules_k/registrar/save.c
index 71c8021..4483972 100644
--- a/modules_k/registrar/save.c
+++ b/modules_k/registrar/save.c
@@ -420,7 +420,7 @@ static inline int insert_contacts(struct sip_msg* _m, contact_t* _c,
}
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");
@@ -494,8 +494,8 @@ static int test_max_contacts(struct sip_msg* _m, urecord_t* _r,
contact_t* _c,
for( ; _c ; _c = get_next_contact(_c) ) {
/* 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;
@@ -575,7 +575,7 @@ static inline int update_contacts(struct sip_msg* _m, urecord_t* _r,
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;
diff --git a/modules_k/usrloc/doc/usrloc_admin.xml
b/modules_k/usrloc/doc/usrloc_admin.xml
index fc7d730..ff040a5 100644
--- a/modules_k/usrloc/doc/usrloc_admin.xml
+++ b/modules_k/usrloc/doc/usrloc_admin.xml
@@ -48,13 +48,22 @@
</listitem>
<listitem>
<para>
- <emphasis>contact nad callid based</emphasis> - it an extension
+ <emphasis>contact and callid based</emphasis> - it an extension
of the first case - the contact and callid must matched as
string; the cseg must be higher than the previous one - so be
careful how you deal with REGISTER retransmissions in this
case.
</para>
</listitem>
+ <listitem>
+ <para>
+ <emphasis>contact and patch based</emphasis> - it an extension
+ of the first case - the contact and patch must matched as
+ string; the cseg must be higher than the previous one - so be
+ careful how you deal with REGISTER retransmissions in this
+ case.
+ </para>
+ </listitem>
</itemizedlist>
<para>
How to control/select the contact maching algorithm, please see the
@@ -582,6 +591,13 @@ modparam("usrloc", "db_mode", 2)
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.
+ If no path is available, it defaults to mode 0.
+ </para>
+ </listitem>
</itemizedlist>
<para>
<emphasis>
diff --git a/modules_k/usrloc/ul_mi.c b/modules_k/usrloc/ul_mi.c
index 1f1f0d9..bb7d50a 100644
--- a/modules_k/usrloc/ul_mi.c
+++ b/modules_k/usrloc/ul_mi.c
@@ -52,7 +52,8 @@
static str mi_ul_cid = str_init("dfjrewr12386fd6-343(a)openser.mi").mi");
/*! user agent used for ul_add */
static str mi_ul_ua = str_init("SIP Router MI Server");
-
+/*! path used for ul_add and ul_rm_contact */
+static str mi_ul_path = str_init("dummypath");
/************************ helper functions ****************************/
@@ -312,7 +313,7 @@ struct mi_root* mi_usrloc_rm_contact(struct mi_root *cmd, void
*param)
}
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 +519,7 @@ struct mi_root* mi_usrloc_add(struct mi_root *cmd, void *param)
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;
}
diff --git a/modules_k/usrloc/ul_mod.c b/modules_k/usrloc/ul_mod.c
index 865763a..3c74008 100644
--- a/modules_k/usrloc/ul_mod.c
+++ b/modules_k/usrloc/ul_mod.c
@@ -264,6 +264,7 @@ static int mod_init(void)
switch (matching_mode) {
case CONTACT_ONLY:
case CONTACT_CALLID:
+ case CONTACT_PATH:
break;
default:
LM_ERR("invalid matching mode %d\n", matching_mode);
diff --git a/modules_k/usrloc/ul_mod.h b/modules_k/usrloc/ul_mod.h
index c181111..fbe56cb 100644
--- a/modules_k/usrloc/ul_mod.h
+++ b/modules_k/usrloc/ul_mod.h
@@ -84,6 +84,7 @@ extern db_func_t ul_dbf;
*/
#define CONTACT_ONLY (0)
#define CONTACT_CALLID (1)
+#define CONTACT_PATH (2)
extern int matching_mode;
diff --git a/modules_k/usrloc/urecord.c b/modules_k/usrloc/urecord.c
index fe01f9f..e0ff894 100644
--- a/modules_k/usrloc/urecord.c
+++ b/modules_k/usrloc/urecord.c
@@ -552,18 +552,44 @@ static inline struct ucontact* contact_callid_match( ucontact_t*
ptr,
return 0;
}
+ /*!
++ * \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)
+{
+ /* if no path is preset (in REGISTER request) or use_path is not configured
+ in registrar module, default to contact_match() */
+ if( _path == NULL) return contact_match(ptr, _c);
+
+ 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 +607,9 @@ int get_ucontact(urecord_t* _r, str* _c, str* _callid, int _cseq,
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;
diff --git a/modules_k/usrloc/urecord.h b/modules_k/usrloc/urecord.h
index 53a79b9..610306f 100644
--- a/modules_k/usrloc/urecord.h
+++ b/modules_k/usrloc/urecord.h
@@ -177,15 +177,17 @@ int delete_ucontact(urecord_t* _r, struct ucontact* _c);
* \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)
*/
-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);
-
#endif