Jelajahi Sumber

registrar(k): new parameter xavp_cfg

- defines the name of an XAVP container to hold per-REGISTER parameters
- for now, max_contacts can be set for each registration, overwriting
  the module parameter value. For example:

modparam("registrar", "xavp_cfg", "reg")
...
request_route {
...
	if(is_method("REGISTER"))
		$xavp(reg=>max_contacts) = 2;
...
}
Daniel-Constantin Mierla 13 tahun lalu
induk
melakukan
71348e9c97

+ 37 - 14
modules_k/registrar/README

@@ -54,6 +54,7 @@ Bogdan-Andre Iancu
               3.18. path_mode (integer)
               3.19. path_use_received (integer)
               3.20. reg_callid_avp (string)
+              3.21. xavp_cfg (string)
 
         4. Functions
 
@@ -100,14 +101,15 @@ Bogdan-Andre Iancu
    1.17. Set path_mode parameter
    1.18. Set path_use_received parameter
    1.19. Set reg_callid_avp parameter
-   1.20. save usage
-   1.21. lookup usage
-   1.22. registered usage
-   1.23. add_sock_hdr usage
-   1.24. registered usage
+   1.20. Set xavp_cfg parameter
+   1.21. save usage
+   1.22. lookup usage
+   1.23. registered usage
+   1.24. add_sock_hdr usage
    1.25. registered usage
    1.26. registered usage
-   1.27. $ulc(name) usage
+   1.27. registered usage
+   1.28. $ulc(name) usage
 
 Chapter 1. Admin Guide
 
@@ -144,6 +146,7 @@ Chapter 1. Admin Guide
         3.18. path_mode (integer)
         3.19. path_use_received (integer)
         3.20. reg_callid_avp (string)
+        3.21. xavp_cfg (string)
 
    4. Functions
 
@@ -240,6 +243,7 @@ Chapter 1. Admin Guide
    3.18. path_mode (integer)
    3.19. path_use_received (integer)
    3.20. reg_callid_avp (string)
+   3.21. xavp_cfg (string)
 
 3.1. default_expires (integer)
 
@@ -541,6 +545,25 @@ modparam("registrar", "path_use_received", 1)
 modparam("registrar", "reg_callid_avp", "$avp(s:avp)")
 ...
 
+3.21. xavp_cfg (string)
+
+   Defines the name of XAVP class to store runtime module config values.
+   The values are stored as inner XAVPs, like $xavp(class=>attribute).
+   Valid inner XAVP names:
+     * max_contacts - the number of maximum contacts to be stored for
+       current registration AoR. It overwrites the 'max_contacts' module
+       parameter value.
+
+   For example. if this parameter is set to 'reg', then the number of
+   maximum contacts can be set in $xavp(reg=>max_contacts).
+
+   Default value is NULL (disabled).
+
+   Example 1.20. Set xavp_cfg parameter
+...
+modparam("registrar", "xavp_cfg", "reg")
+...
+
 4. Functions
 
    4.1. save(domain, [, flags [, uri]])
@@ -588,7 +611,7 @@ modparam("registrar", "reg_callid_avp", "$avp(s:avp)")
 
    This function can be used from REQUEST_ROUTE and REPLY_ROUTE.
 
-   Example 1.20. save usage
+   Example 1.21. save usage
 ...
 save("location");
 save("location", "0x01");
@@ -621,7 +644,7 @@ save("location", "0x00", "sip:[email protected]");
 
    This function can be used from REQUEST_ROUTE, FAILURE_ROUTE.
 
-   Example 1.21. lookup usage
+   Example 1.22. lookup usage
 ...
 lookup("location");
 switch ($retcode) {
@@ -649,7 +672,7 @@ switch ($retcode) {
 
    This function can be used from REQUEST_ROUTE, FAILURE_ROUTE.
 
-   Example 1.22. registered usage
+   Example 1.23. registered usage
 ...
 if (registered("location")) {
         sl_send_reply("100", "Trying");
@@ -669,7 +692,7 @@ if (registered("location")) {
 
    This function can be used from REQUEST_ROUTE.
 
-   Example 1.23. add_sock_hdr usage
+   Example 1.24. add_sock_hdr usage
 ...
 add_sock_hdr("Sock-Info");
 ...
@@ -687,7 +710,7 @@ add_sock_hdr("Sock-Info");
 
    This function can be used from REQUEST_ROUTE, FAILURE_ROUTE.
 
-   Example 1.24. registered usage
+   Example 1.25. registered usage
 ...
 unregister("location", "$ru");
 unregister("location", "sip:[email protected]");
@@ -709,7 +732,7 @@ unregister("location", "sip:[email protected]");
 
    This function can be used from REQUEST_ROUTE, FAILURE_ROUTE.
 
-   Example 1.25. registered usage
+   Example 1.26. registered usage
 ...
 reg_fetch_contacts("location", "$ru", "callee");
 reg_fetch_contacts("location", "sip:[email protected]", "caller");
@@ -728,7 +751,7 @@ reg_fetch_contacts("location", "sip:[email protected]", "caller");
 
    This function can be used from REQUEST_ROUTE, FAILURE_ROUTE.
 
-   Example 1.26. registered usage
+   Example 1.27. registered usage
 ...
 reg_free_contacts("callee");
 ...
@@ -794,7 +817,7 @@ reg_free_contacts("callee");
    The pseudo-variable accepts positive index value to access a specific
    contact record.
 
-   Example 1.27. $ulc(name) usage
+   Example 1.28. $ulc(name) usage
 ...
 if(reg_fetch_contacts("location", "$fu", "caller"))
 {

+ 35 - 0
modules_k/registrar/doc/registrar_admin.xml

@@ -602,6 +602,41 @@ modparam("registrar", "path_use_received", 1)
 		<programlisting format="linespecific">
 ...
 modparam("registrar", "reg_callid_avp", "$avp(s:avp)")
+...
+		</programlisting>
+		</example>
+	</section>
+
+	<section>
+		<title><varname>xavp_cfg</varname> (string)</title>
+		<para>
+			Defines the name of XAVP class to store runtime module config
+			values. The values are stored as inner XAVPs, like
+			$xavp(class=&gt;attribute). Valid inner XAVP names:
+		</para>
+		<itemizedlist>
+		<listitem>
+			<para>
+				<emphasis>max_contacts</emphasis> - the number of maximum
+				contacts to be stored for current registration AoR. It
+				overwrites the 'max_contacts' module parameter value.
+			</para>
+		</listitem>
+		</itemizedlist>
+		<para>
+			For example. if this parameter is set to 'reg', then the number
+			of maximum contacts can be set in $xavp(reg=&gt;max_contacts).
+		</para>
+		<para>
+		<emphasis>
+			Default value is NULL (disabled).
+		</emphasis>
+		</para>
+		<example>
+		<title>Set <varname>xavp_cfg</varname> parameter</title>
+		<programlisting format="linespecific">
+...
+modparam("registrar", "xavp_cfg", "reg")
 ...
 		</programlisting>
 		</example>

+ 6 - 0
modules_k/registrar/reg_mod.c

@@ -122,6 +122,8 @@ char* rcv_avp_param = 0;
 unsigned short rcv_avp_type = 0;
 int_str rcv_avp_name;
 
+str reg_xavp_cfg = {0};
+
 int reg_use_domain = 0;
 
 int sock_flag = -1;
@@ -207,6 +209,7 @@ static param_export_t params[] = {
 	{"use_path",           INT_PARAM, &path_enabled        					},
 	{"path_mode",          INT_PARAM, &path_mode           					},
 	{"path_use_received",  INT_PARAM, &path_use_params     					},
+	{"xavp_cfg",           STR_PARAM, &reg_xavp_cfg.s     					},
 	{0, 0, 0}
 };
 
@@ -359,6 +362,9 @@ static int mod_init(void)
 	sock_flag = (sock_flag!=-1)?(1<<sock_flag):0;
 	tcp_persistent_flag = (tcp_persistent_flag!=-1)?(1<<tcp_persistent_flag):0;
 
+	if (reg_xavp_cfg.s) {
+		reg_xavp_cfg.len = strlen(reg_xavp_cfg.s);
+	}
 	return 0;
 }
 

+ 2 - 0
modules_k/registrar/reg_mod.h

@@ -87,6 +87,8 @@ extern int path_use_params;
 extern str sock_hdr_name;
 extern int sock_flag;
 
+extern str reg_xavp_cfg;
+
 extern usrloc_api_t ul;/*!< Structure containing pointers to usrloc functions*/
 
 extern sl_api_t slb;

+ 49 - 8
modules_k/registrar/save.c

@@ -57,6 +57,7 @@
 #include "../../ut.h"
 #include "../../qvalue.h"
 #include "../../dset.h"
+#include "../../xavp.h"
 #include "../../mod_fix.h"
 #include "../../lib/kcore/cmpapi.h"
 #include "../../lib/kcore/statistics.h"
@@ -362,6 +363,40 @@ error:
 }
 
 
+int reg_get_crt_max_contacts(void)
+{
+	int n;
+	sr_xavp_t *ravp=NULL;
+	sr_xavp_t *vavp=NULL;
+	str vname = {"max_contacts", 12};
+
+	n = 0;
+
+	if(reg_xavp_cfg.s!=NULL)
+	{
+		ravp = xavp_get(&reg_xavp_cfg, NULL);
+		if(ravp!=NULL && ravp->val.type==SR_XTYPE_XAVP)
+		{
+			vavp = xavp_get(&vname, ravp->val.v.xavp);
+			if(vavp!=NULL && vavp->val.type==SR_XTYPE_INT)
+			{
+				n = vavp->val.v.i;
+				LM_ERR("using max contacts value from xavp: %d\n", n);
+			} else {
+				ravp = NULL;
+			}
+		} else {
+			ravp = NULL;
+		}
+	}
+
+	if(ravp==NULL)
+	{
+		n = cfg_get(registrar, registrar_cfg, max_contacts);
+	}
+
+	return n;
+}
 
 /*! \brief
  * Message contained some contacts, but record with same address
@@ -377,6 +412,7 @@ static inline int insert_contacts(struct sip_msg* _m, udomain_t* _d, str* _a)
 	contact_t* _c;
 	unsigned int flags;
 	int num, expires;
+	int maxc;
 #ifdef USE_TCP
 	int e_max, tcp_check;
 	struct sip_uri uri;
@@ -393,6 +429,7 @@ static inline int insert_contacts(struct sip_msg* _m, udomain_t* _d, str* _a)
 	}
 #endif
 	_c = get_first_contact(_m);
+	maxc = reg_get_crt_max_contacts();
 	for( num=0,r=0,ci=0 ; _c ; _c = get_next_contact(_c) ) {
 		/* calculate expires */
 		calc_contact_expires(_m, _c->expires, &expires);
@@ -400,8 +437,8 @@ static inline int insert_contacts(struct sip_msg* _m, udomain_t* _d, str* _a)
 		if (expires == 0)
 			continue;
 
-		if (cfg_get(registrar, registrar_cfg, max_contacts)
-				&& (num >= cfg_get(registrar, registrar_cfg, max_contacts))) {
+
+		if (maxc > 0 && num >= maxc) {
 			LM_INFO("too many contacts (%d) for AOR <%.*s>\n", 
 					num, _a->len, _a->s);
 			rerrno = R_TOO_MANY;
@@ -480,7 +517,7 @@ error:
 
 
 static int test_max_contacts(struct sip_msg* _m, urecord_t* _r, contact_t* _c,
-														ucontact_info_t *ci)
+										ucontact_info_t *ci, int mc)
 {
 	int num;
 	int e;
@@ -518,7 +555,7 @@ static int test_max_contacts(struct sip_msg* _m, urecord_t* _r, contact_t* _c,
 	}
 	
 	LM_DBG("%d contacts after commit\n", num);
-	if (num > cfg_get(registrar, registrar_cfg, max_contacts)) {
+	if (num > mc) {
 		LM_INFO("too many contacts for AOR <%.*s>\n", _r->aor.len, _r->aor.s);
 		rerrno = R_TOO_MANY;
 		return -1;
@@ -552,6 +589,7 @@ static inline int update_contacts(struct sip_msg* _m, urecord_t* _r,
 #endif
 	int rc;
 	contact_t* _c;
+	int maxc;
 
 	/* mem flag */
 	flags = mem_only;
@@ -563,10 +601,13 @@ static inline int update_contacts(struct sip_msg* _m, urecord_t* _r,
 		goto error;
 	}
 
-	if (!_mode && cfg_get(registrar, registrar_cfg, max_contacts)) {
-		_c = get_first_contact(_m);
-		if(test_max_contacts(_m, _r, _c, ci) != 0)
-			goto error;
+	if (!_mode) {
+		maxc = reg_get_crt_max_contacts();
+		if(maxc>0) {
+			_c = get_first_contact(_m);
+			if(test_max_contacts(_m, _r, _c, ci, maxc) != 0)
+				goto error;
+		}
 	}
 
 #ifdef USE_TCP