[sr-dev] git:master: modules_k/usrloc Added Contact and Path matching mode

Marius Zbihlei marius.zbihlei at 1and1.ro
Wed Apr 21 12:17:21 CEST 2010


Module: sip-router
Branch: master
Commit: d6fbd5a146c01aa0fa856fcb4279d9883f3b12b9
URL:    http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=d6fbd5a146c01aa0fa856fcb4279d9883f3b12b9

Author: Marius Zbihlei <marius.zbihlei at 1and1.ro>
Committer: Marius Zbihlei <marius.zbihlei at 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 at openser.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




More information about the sr-dev mailing list