[sr-dev] git:master: registrar(k): store +sip.instance always in contact structure

Daniel-Constantin Mierla miconda at gmail.com
Tue Apr 17 11:53:36 CEST 2012


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

Author: Daniel-Constantin Mierla <miconda at gmail.com>
Committer: Daniel-Constantin Mierla <miconda at gmail.com>
Date:   Tue Apr 17 11:51:15 2012 +0200

registrar(k): store +sip.instance always in contact structure

- if it is provided, keep it, since it used either for gruu or outbound
  extensions
- mirror reg-id to contact in 200ok if provided in REGISTER
- updated the prototype of the usrloc function to match by instance

---

 modules_k/registrar/reply.c |   22 +++++++++++++++++++---
 modules_k/registrar/save.c  |   27 ++++++++++++++++++---------
 2 files changed, 37 insertions(+), 12 deletions(-)

diff --git a/modules_k/registrar/reply.c b/modules_k/registrar/reply.c
index a759aeb..2e27f9a 100644
--- a/modules_k/registrar/reply.c
+++ b/modules_k/registrar/reply.c
@@ -76,6 +76,11 @@
 #define TMP_GRUU_PARAM ";temp-gruu="
 #define TMP_GRUU_PARAM_LEN (sizeof(TMP_GRUU_PARAM) - 1)
 
+#define REG_ID_PARAM ";reg-id="
+#define REG_ID_PARAM_LEN (sizeof(REG_ID_PARAM) - 1)
+
+extern int reg_gruu_enabled;
+
 /*! \brief
  * Buffer for Contact header field
  */
@@ -113,7 +118,7 @@ static inline unsigned int calc_buf_len(ucontact_t* c, str *host, int mode)
 					+ 1 /* dquote */
 					;
 			}
-			if (c->instance.len>0 && mode==1) {
+			if (reg_gruu_enabled==1 && c->instance.len>0 && mode==1) {
 				/* pub-gruu */
 				len += PUB_GRUU_PARAM_LEN
 					+ 1 /* " */
@@ -147,6 +152,10 @@ static inline unsigned int calc_buf_len(ucontact_t* c, str *host, int mode)
 					+ 1 /* " */
 					;
 			}
+			if (c->reg_id>0) {
+				/* reg-id */
+				len += REG_ID_PARAM_LEN + INT2STR_MAX_LEN;
+			}
 		}
 		c = c->next;
 	}
@@ -239,7 +248,7 @@ int build_contact(sip_msg_t *msg, ucontact_t* c, str *host)
 				p += c->received.len;
 				*p++ = '\"';
 			}
-			if (c->instance.len>0 && mode==1) {
+			if (reg_gruu_enabled==1 && c->instance.len>0 && mode==1) {
 				user.s = c->aor->s;
 				a = memchr(c->aor->s, '@', c->aor->len);
 				if(a!=NULL) {
@@ -306,7 +315,14 @@ int build_contact(sip_msg_t *msg, ucontact_t* c, str *host)
 				p += c->instance.len;
 				*p++ = '\"';
 			}
-
+			if (c->reg_id>0) {
+				/* reg-id */
+				memcpy(p, REG_ID_PARAM, REG_ID_PARAM_LEN);
+				p += REG_ID_PARAM_LEN;
+				cp = int2str(c->reg_id, &len);
+				memcpy(p, cp, len);
+				p += len;
+			}
 		}
 
 		c = c->next;
diff --git a/modules_k/registrar/save.c b/modules_k/registrar/save.c
index 78e0c24..8f18ea7 100644
--- a/modules_k/registrar/save.c
+++ b/modules_k/registrar/save.c
@@ -357,9 +357,15 @@ static inline ucontact_info_t* pack_ci( struct sip_msg* _m, contact_t* _c,
 				ci.received = received;
 			}
 		}
-		if(reg_gruu_enabled==1 && _c->instance!=NULL
-				&& _c->instance->body.len>0)
+		if(_c->instance!=NULL && _c->instance->body.len>0)
 			ci.instance = _c->instance->body;
+		if(_c->reg_id!=NULL && _c->reg_id->body.len>0) {
+			if(str2int(&_c->reg_id->body, &ci.reg_id)<0)
+			{
+				LM_ERR("invalid reg-id value\n");
+				goto error;
+			}
+		}
 		if(sruid_next(&_reg_sruid)<0)
 			goto error;
 		ci.ruid = _reg_sruid.uid;
@@ -473,15 +479,20 @@ static inline int insert_contacts(struct sip_msg* _m, udomain_t* _d, str* _a)
 			goto error;
 		}
 
-		if ( r->contacts==0 ||
-		ul.get_ucontact_by_instance(r, &_c->uri, ci->callid, ci->path, ci->cseq+1,
-					&ci->instance, &c) != 0) {
+		/* hack to work with buggy clients having many contacts with same
+		 * address in one REGISTER - increase CSeq to detect if there was
+		 * one alredy added, then update */
+		ci->cseq++;
+		if ( r->contacts==0
+				|| ul.get_ucontact_by_instance(r, &_c->uri, ci, &c) != 0) {
+			ci->cseq--;
 			if (ul.insert_ucontact( r, &_c->uri, ci, &c) < 0) {
 				rerrno = R_UL_INS_C;
 				LM_ERR("failed to insert contact\n");
 				goto error;
 			}
 		} else {
+			ci->cseq--;
 			if (ul.update_ucontact( r, c, ci) < 0) {
 				rerrno = R_UL_UPD_C;
 				LM_ERR("failed to update contact\n");
@@ -552,8 +563,7 @@ static int test_max_contacts(struct sip_msg* _m, urecord_t* _r, contact_t* _c,
 		/* calculate expires */
 		calc_contact_expires(_m, _c->expires, &e);
 
-		ret = ul.get_ucontact_by_instance( _r, &_c->uri, ci->callid, ci->path, ci->cseq,
-				&ci->instance, &cont);
+		ret = ul.get_ucontact_by_instance( _r, &_c->uri, ci, &cont);
 		if (ret==-1) {
 			LM_ERR("invalid cseq for aor <%.*s>\n",_r->aor.len,_r->aor.s);
 			rerrno = R_INV_CSEQ;
@@ -642,8 +652,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_by_instance( _r, &_c->uri, ci->callid, ci->path,
-				ci->cseq, &ci->instance, &c);
+		ret = ul.get_ucontact_by_instance( _r, &_c->uri, ci, &c);
 		if (ret==-1) {
 			LM_ERR("invalid cseq for aor <%.*s>\n",_r->aor.len,_r->aor.s);
 			rerrno = R_INV_CSEQ;




More information about the sr-dev mailing list