Module: sip-router Branch: master Commit: d6fbd5a146c01aa0fa856fcb4279d9883f3b12b9 URL: http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=d6fbd5a1...
Author: Marius Zbihlei marius.zbihlei@1and1.ro Committer: Marius Zbihlei marius.zbihlei@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@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
Marius Zbihlei writes:
<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.
should it read 'path' instead of 'patch'?
-- juha
Juha Heinanen wrote:
Marius Zbihlei writes:
<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.
should it read 'path' instead of 'patch'?
-- juha
Yes, sorry I should be double careful the next time...
Thanks Marius