ソースを参照

registrar: execute event route when a contact expires

- the name of the routing block is event_route[usrloc:contact-expired]
Daniel-Constantin Mierla 12 年 前
コミット
8341030426

+ 97 - 72
modules_k/registrar/README

@@ -16,7 +16,7 @@ Edited by
 
 Bogdan-Andre Iancu
 
-   Copyright © 2003 FhG FOKUS
+   Copyright © 2003 FhG FOKUS
      __________________________________________________________________
 
    Table of Contents
@@ -72,17 +72,21 @@ Bogdan-Andre Iancu
               4.7. reg_fetch_contacts(domain, uri, profile)
               4.8. reg_free_contacts(profile)
 
-        5. Statistics
+        5. Event Routes
 
-              5.1. max_expires
-              5.2. max_contacts
-              5.3. defaults_expires
-              5.4. accepted_regs
-              5.5. rejected_regs
+              5.1. event_route[usrloc:contact-expired]
 
-        6. Exported pseudo-variables
+        6. Statistics
 
-              6.1. $ulc(profile=>attr)
+              6.1. max_expires
+              6.2. max_contacts
+              6.3. defaults_expires
+              6.4. accepted_regs
+              6.5. rejected_regs
+
+        7. Pseudo Variables
+
+              7.1. $ulc(profile=>attr)
 
    2. Frequently Asked Questions
 
@@ -120,7 +124,8 @@ Bogdan-Andre Iancu
    1.30. unregister usage
    1.31. reg_fetch_contacts usage
    1.32. reg_free_contacts usage
-   1.33. $ulc(name) usage
+   1.33. event_route[usrloc:contact-expired] usage
+   1.34. $ulc(name) usage
 
 Chapter 1. Admin Guide
 
@@ -175,17 +180,21 @@ Chapter 1. Admin Guide
         4.7. reg_fetch_contacts(domain, uri, profile)
         4.8. reg_free_contacts(profile)
 
-   5. Statistics
+   5. Event Routes
+
+        5.1. event_route[usrloc:contact-expired]
 
-        5.1. max_expires
-        5.2. max_contacts
-        5.3. defaults_expires
-        5.4. accepted_regs
-        5.5. rejected_regs
+   6. Statistics
 
-   6. Exported pseudo-variables
+        6.1. max_expires
+        6.2. max_contacts
+        6.3. defaults_expires
+        6.4. accepted_regs
+        6.5. rejected_regs
 
-        6.1. $ulc(profile=>attr)
+   7. Pseudo Variables
+
+        7.1. $ulc(profile=>attr)
 
 1. Overview
 
@@ -207,8 +216,8 @@ Chapter 1. Admin Guide
      * off - stores the value of the Path headers into usrloc without
        passing it back to the UAC in the reply.
      * lazy - stores the Path header and passes it back to the UAC if
-       Path-support is indicated by the “path� param in the Supported HF.
-     * strict - rejects the registration with “420 Bad Extension� if
+       Path-support is indicated by the "path" param in the Supported HF.
+     * strict - rejects the registration with "420 Bad Extension" if
        there's a Path header but no support for it is indicated by the
        UAC. Otherwise it's stored and passed back to the UAC.
 
@@ -220,8 +229,8 @@ Chapter 1. Admin Guide
    client's NAT).
 
    The whole process is transparent to the user, so no config changes are
-   required beside setting the registrar-parameters “use_path� and
-   “path_mode�.
+   required beside setting the registrar-parameters "use_path" and
+   "path_mode".
 
 1.2. GRUU Support
 
@@ -285,7 +294,7 @@ Chapter 1. Admin Guide
    contact parameters, this value will be used for newly created usrloc
    records. The parameter contains number of second to expire (for example
    use 3600 for one hour). If it is set to a lower value than the
-   “min_expires� parameter then it will be ignored. This parameter can be
+   "min_expires" parameter then it will be ignored. This parameter can be
    modified via ser config framework. A random value in a specific
    interval can be selected by using the default_expires_range parameter
 
@@ -299,9 +308,9 @@ modparam("registrar", "default_expires", 1800)
 3.2. default_expires_range (integer)
 
    This parameter specifies that the expiry used for newly created usrloc
-   records are not fixed(when “default_expires� applies), but a random
-   value in the interval “[default_expires-default_expires_range%,
-   default_expires+default_expires_range%]�. The value is between 0 and
+   records are not fixed(when "default_expires" applies), but a random
+   value in the interval "[default_expires-default_expires_range%,
+   default_expires+default_expires_range%]". The value is between 0 and
    100 and represent the maximim percentage from default_expires that will
    be substracted or added when computing the value. Default in 0, meaning
    default_expires is left unmodified. This parameter can be modified via
@@ -520,7 +529,7 @@ modparam("registrar", "method_filtering", 1)
 3.17. use_path (integer)
 
    If set to 1, the Path header is handled according to the parameter This
-   parameter can be modified via ser config framework. “path_mode�.
+   parameter can be modified via ser config framework. "path_mode".
 
    Default value is 0 (disabled).
 
@@ -537,12 +546,12 @@ modparam("registrar", "use_path", 1)
        the reply.
      * 1 - The Path header is saved into usrloc, but is only included in
        the reply if path support is indicated in the registration request
-       by the “path� option of the “Supported� header.
+       by the "path" option of the "Supported" header.
      * 2 - The path header is only saved into usrloc, if path support is
-       indicated in the registration request by the “path� option of the
-       “Supported� header. If no path support is indicated, the request is
-       rejected with “420 - Bad Extension� and the header “Unsupported:
-       path� is included in the reply along with the received “Path�
+       indicated in the registration request by the "path" option of the
+       "Supported" header. If no path support is indicated, the request is
+       rejected with "420 - Bad Extension" and the header "Unsupported:
+       path" is included in the reply along with the received "Path"
        header. This mode is the one recommended by RFC-3327.
 
    Default value is 2.
@@ -554,10 +563,10 @@ modparam("registrar", "path_mode", 0)
 
 3.19. path_use_received (integer)
 
-   If set to 1, the “received� parameter of the first Path URI of a
+   If set to 1, the "received" parameter of the first Path URI of a
    registration is set as received-uri and the NAT branch flag is set for
    this contact. This is useful if the registrar is placed behind a SIP
-   loadbalancer, which passes the nat'ed UAC address as “received�
+   loadbalancer, which passes the nat'ed UAC address as "received"
    parameter in it's Path uri.
 
    Default value is 0 (disabled).
@@ -618,7 +627,7 @@ modparam("registrar", "xavp_cfg", "ulrcd")
 
 3.23. gruu_enabled (integer)
 
-   If set to 1 and GRUU “+sip.instance� parameter to Contact header of
+   If set to 1 and GRUU "+sip.instance" parameter to Contact header of
    REGISTER is present, then the value of the parameter is saved to
    location and pub-gruu and temp-gruu addresses are generated.
 
@@ -696,7 +705,7 @@ modparam("registrar", "flow_timer", 25)
    4.7. reg_fetch_contacts(domain, uri, profile)
    4.8. reg_free_contacts(profile)
 
-4.1.  save(domain, [, flags [, uri]])
+4.1. save(domain, [, flags [, uri]])
 
    The function processes a REGISTER message. It can add, remove or modify
    usrloc records depending on Contact and Expires HFs in the REGISTER
@@ -740,7 +749,7 @@ save("location", "0x01");
 save("location", "0x00", "sip:[email protected]");
 ...
 
-4.2.  lookup(domain [, uri])
+4.2. lookup(domain [, uri])
 
    The function extracts username from Request-URI and tries to find all
    contacts for the username in usrloc. If there are no such contacts, -1
@@ -780,7 +789,7 @@ switch ($retcode) {
 };
 ...
 
-4.3.  lookup_branches(domain)
+4.3. lookup_branches(domain)
 
    The function performs lookup(domain) on r-uri and additional branches
    (only branches that have no other attributes set than uri).
@@ -797,7 +806,7 @@ switch ($retcode) {
 lookup_branches("location");
 ...
 
-4.4.  registered(domain [, uri])
+4.4. registered(domain [, uri])
 
    The function returns true if the AOR in the Request-URI is registered,
    false otherwise. The function does not modify the message being
@@ -819,9 +828,9 @@ if (registered("location")) {
 };
 ...
 
-4.5.  add_sock_hdr(hdr_name)
+4.5. add_sock_hdr(hdr_name)
 
-   Adds to the current REGISTER request a new header with “hdr_name� which
+   Adds to the current REGISTER request a new header with "hdr_name" which
    contains the description of the received socket (proto:ip:port)
 
    This make sens only in multiple replicated servers scenarios.
@@ -836,7 +845,7 @@ if (registered("location")) {
 add_sock_hdr("Sock-Info");
 ...
 
-4.6.  unregister(domain, uri)
+4.6. unregister(domain, uri)
 
    The function remove all the contact associated to 'uri'.
 
@@ -855,7 +864,7 @@ unregister("location", "$ru");
 unregister("location", "sip:[email protected]");
 ...
 
-4.7.  reg_fetch_contacts(domain, uri, profile)
+4.7. reg_fetch_contacts(domain, uri, profile)
 
    The function fetches the contacts for 'uri' from table 'domain' to
    pseudo-variable $ulc(profile).
@@ -877,7 +886,7 @@ reg_fetch_contacts("location", "$ru", "callee");
 reg_fetch_contacts("location", "sip:[email protected]", "caller");
 ...
 
-4.8.  reg_free_contacts(profile)
+4.8. reg_free_contacts(profile)
 
    The function frees the contacts from pseudo-variable $ulc(profile).
    Should be called to release the content of a profile. Anyhow, fetching
@@ -895,47 +904,63 @@ reg_fetch_contacts("location", "sip:[email protected]", "caller");
 reg_free_contacts("callee");
 ...
 
-5. Statistics
+5. Event Routes
+
+   5.1. event_route[usrloc:contact-expired]
+
+5.1. event_route[usrloc:contact-expired]
+
+   Executed when a contact in location table has expired. The variable
+   $ulc(exp=>...) is filled with the attributes of the expired contact.
+
+   Example 1.33. event_route[usrloc:contact-expired] usage
+...
+event_route[usrloc:contact-expired] {
+    xlog("expired contact for $ulc(exp->aor)\n");
+}
+...
+
+6. Statistics
 
-   5.1. max_expires
-   5.2. max_contacts
-   5.3. defaults_expires
-   5.4. accepted_regs
-   5.5. rejected_regs
+   6.1. max_expires
+   6.2. max_contacts
+   6.3. defaults_expires
+   6.4. accepted_regs
+   6.5. rejected_regs
 
-5.1. max_expires
+6.1. max_expires
 
    Value of max_expires parameter.
 
-5.2. max_contacts
+6.2. max_contacts
 
    The value of max_contacts parameter.
 
-5.3. defaults_expires
+6.3. defaults_expires
 
    The value of default_expires parameter.
 
-5.4. accepted_regs
+6.4. accepted_regs
 
    Number of accepted registrations.
 
-5.5. rejected_regs
+6.5. rejected_regs
 
    Number of rejected registrations.
 
-6. Exported pseudo-variables
+7. Pseudo Variables
 
-   6.1. $ulc(profile=>attr)
+   7.1. $ulc(profile=>attr)
 
-6.1. $ulc(profile=>attr)
+7.1. $ulc(profile=>attr)
 
    Access the attributes of contact addresses stored in 'profile'. It must
-   be used after a call of “reg_fetch_contacts()�.
+   be used after a call of "reg_fetch_contacts()".
 
-   The “profile� has to be one of the values used with
-   “reg_fetch_contacts()�.
+   The "profile" has to be one of the values used with
+   "reg_fetch_contacts()".
 
-   The “attr� can be:
+   The "attr" can be:
      * aor - address of record
      * domain - use location domain name
      * aorhash - hash id for the record
@@ -956,7 +981,7 @@ reg_free_contacts("callee");
    The pseudo-variable accepts positive index value to access a specific
    contact record.
 
-   Example 1.33. $ulc(name) usage
+   Example 1.34. $ulc(name) usage
 ...
 if(reg_fetch_contacts("location", "$fu", "caller"))
 {
@@ -988,9 +1013,9 @@ if(reg_fetch_contacts("location", "$fu", "caller"))
 
 Chapter 2. Frequently Asked Questions
 
-   2.1. What happend with the old “nat_flag� module parameter?
-   2.2. What happend with the old “use_domain� module parameter?
-   2.3. What happend with the old “save_noreply� and “save_memory�
+   2.1. What happend with the old "nat_flag" module parameter?
+   2.2. What happend with the old "use_domain" module parameter?
+   2.3. What happend with the old "save_noreply" and "save_memory"
           functions?
 
    2.4. Where can I find more about Kamailio?
@@ -1000,23 +1025,23 @@ Chapter 2. Frequently Asked Questions
 
    2.1.
 
-   What happend with the old “nat_flag� module parameter?
+   What happend with the old "nat_flag" module parameter?
 
    In was removed, as the module internally loads this value from the
-   “USRLOC� module (see the “nat_bflag� USRLOC parameter).
+   "USRLOC" module (see the "nat_bflag" USRLOC parameter).
 
    2.2.
 
-   What happend with the old “use_domain� module parameter?
+   What happend with the old "use_domain" module parameter?
 
    In was removed, as the module internally loads this option from the
-   “USRLOC� module. This was done in order to simplify the configuration.
+   "USRLOC" module. This was done in order to simplify the configuration.
 
    2.3.
 
-   What happend with the old “save_noreply� and “save_memory� functions?
+   What happend with the old "save_noreply" and "save_memory" functions?
 
-   There functions were merged into the new “save(domain,flags)�
+   There functions were merged into the new "save(domain,flags)"
    functions. If a reply should be sent or if the DB should be updated
    also is controlled via the flags.
 

+ 23 - 1
modules_k/registrar/doc/registrar_admin.xml

@@ -1191,6 +1191,28 @@ reg_free_contacts("callee");
 
 	</section>
 
+<section>
+	<title>Event Routes</title>
+	<section>
+		<title><varname>event_route[usrloc:contact-expired]</varname></title>
+		<para>
+		Executed when a contact in location table has expired. The variable
+		$ulc(exp=&gt;...) is filled with the attributes of the expired contact.
+		</para>
+		<example>
+		<title><function>event_route[usrloc:contact-expired]</function> usage</title>
+		<programlisting format="linespecific">
+...
+event_route[usrloc:contact-expired] {
+    xlog("expired contact for $ulc(exp->aor)\n");
+}
+...
+</programlisting>
+		</example>
+
+	</section>
+</section>
+
 <section>
 	<title>Statistics</title>
 	<section>
@@ -1227,7 +1249,7 @@ reg_free_contacts("callee");
 </section>
 
 	<section>
-	<title>Exported pseudo-variables</title>
+	<title>Pseudo Variables</title>
 		
 		<section>
 			<title><varname>$ulc(profile=>attr)</varname></title>

+ 17 - 0
modules_k/registrar/reg_mod.c

@@ -139,6 +139,9 @@ int reg_use_domain = 0;
 int sock_flag = -1;
 str sock_hdr_name = {0,0};
 
+/* where to go for event route ("usrloc:contact-expired") */
+int reg_expire_event_rt = -1; /* default disabled */
+
 #define RCV_NAME "received"
 str rcv_param = str_init(RCV_NAME);
 
@@ -358,6 +361,20 @@ static int mod_init(void)
 		return -1;
 	}
 
+	if(ul.register_ulcb != NULL)
+	{
+		reg_expire_event_rt = route_lookup(&event_rt, "usrloc:expired-contact");
+		if (reg_expire_event_rt>=0 && event_rt.rlist[reg_expire_event_rt]==0)
+			reg_expire_event_rt=-1; /* disable */
+		if (reg_expire_event_rt>=0) {
+			set_child_rpc_sip_mode();
+			if(ul.register_ulcb(UL_CONTACT_EXPIRE, reg_ul_expired_contact, 0)< 0)
+			{
+				LM_ERR("can not register callback for expired contacts\n");
+				return -1;
+			}
+		}
+	}
 	/*
 	 * Import use_domain parameter from usrloc
 	 */

+ 2 - 0
modules_k/registrar/reg_mod.h

@@ -106,6 +106,8 @@ extern usrloc_api_t ul;/*!< Structure containing pointers to usrloc functions*/
 
 extern sl_api_t slb;
 
+extern int reg_expire_event_rt;
+
 extern stat_var *accepted_registrations;
 extern stat_var *rejected_registrations;
 extern stat_var *default_expire_stat;

+ 127 - 0
modules_k/registrar/regpv.c

@@ -33,6 +33,9 @@
 #include "../../dprint.h"
 #include "../../mem/mem.h"
 #include "../../mod_fix.h"
+#include "../../route.h"
+#include "../../action.h"
+#include "../../lib/kcore/faked_msg.h"
 #include "../usrloc/usrloc.h"
 #include "reg_mod.h"
 #include "common.h"
@@ -572,3 +575,127 @@ int pv_free_contacts(struct sip_msg* msg, char* profile, char* s2)
 
 	return 1;
 }
+
+void reg_ul_expired_contact(ucontact_t* ptr, int type, void* param)
+{
+	str profile = {"exp", 3};
+	regpv_profile_t *rpp;
+	ucontact_t* c0;
+	int rt, backup_rt;
+	struct run_act_ctx ctx;
+	sip_msg_t *fmsg;
+	int olen;
+	int ilen;
+	char *p;
+
+	if(reg_expire_event_rt<0)
+		return;
+
+	if (faked_msg_init() < 0)
+	{
+		LM_ERR("faked_msg_init() failed\n");
+		return;
+	}
+
+	rpp = regpv_get_profile(&profile);
+	if(rpp==0)
+	{
+		LM_ERR("error getting profile structure\n");
+		return;
+	}
+	/* check and free if profile already set */
+	if(rpp->flags)
+		regpv_free_profile(rpp);
+
+	/* copy aor and ul domain */
+	rpp->aor.s = (char*)pkg_malloc(ptr->aor->len*sizeof(char));
+	if(rpp->aor.s==NULL)
+	{
+		LM_ERR("no more pkg\n");
+		return;
+	}
+	memcpy(rpp->aor.s, ptr->aor->s, ptr->aor->len);
+	rpp->aor.len = ptr->aor->len;
+	rpp->domain = *ptr->domain;
+	rpp->flags = 1;
+
+	/* copy contact */
+	ilen = sizeof(ucontact_t);
+
+	olen = (ptr->c.len + ptr->received.len + ptr->path.len
+			+ ptr->callid.len + ptr->user_agent.len + ptr->ruid.len
+			+ ptr->instance.len)*sizeof(char) + ilen;
+	c0 = (ucontact_t*)pkg_malloc(olen);
+	if(c0==NULL)
+	{
+		LM_ERR("no more pkg\n");
+		goto error;
+	}
+	memcpy(c0, ptr, ilen);
+	c0->domain = NULL;
+	c0->aor = NULL;
+	c0->next = NULL;
+	c0->prev = NULL;
+
+	c0->c.s = (char*)c0 + ilen;
+	memcpy(c0->c.s, ptr->c.s, ptr->c.len);
+	c0->c.len = ptr->c.len;
+	p = c0->c.s + c0->c.len;
+
+	if(ptr->received.s!=NULL)
+	{
+		c0->received.s = p;
+		memcpy(c0->received.s, ptr->received.s, ptr->received.len);
+		c0->received.len = ptr->received.len;
+		p += c0->received.len;
+	}
+	if(ptr->path.s!=NULL)
+	{
+		c0->path.s = p;
+		memcpy(c0->path.s, ptr->path.s, ptr->path.len);
+		c0->path.len = ptr->path.len;
+		p += c0->path.len;
+	}
+	c0->callid.s = p;
+	memcpy(c0->callid.s, ptr->callid.s, ptr->callid.len);
+	c0->callid.len = ptr->callid.len;
+	p += c0->callid.len;
+	if(ptr->user_agent.s!=NULL)
+	{
+		c0->user_agent.s = p;
+		memcpy(c0->user_agent.s, ptr->user_agent.s, ptr->user_agent.len);
+		c0->user_agent.len = ptr->user_agent.len;
+		p += c0->user_agent.len;
+	}
+	if(ptr->ruid.s!=NULL)
+	{
+		c0->ruid.s = p;
+		memcpy(c0->ruid.s, ptr->ruid.s, ptr->ruid.len);
+		c0->ruid.len = ptr->ruid.len;
+		p += c0->ruid.len;
+	}
+	if(ptr->instance.s!=NULL)
+	{
+		c0->instance.s = p;
+		memcpy(c0->instance.s, ptr->instance.s, ptr->instance.len);
+		c0->instance.len = ptr->instance.len;
+		p += c0->instance.len;
+	}
+
+	rpp->contacts = c0;
+	rpp->nrc = 1;
+	LM_DBG("saved contact for <%.*s> in [%.*s]\n",
+			ptr->aor->len, ptr->aor->s, rpp->pname.len, rpp->pname.s);
+
+	fmsg = faked_msg_next();
+	backup_rt = get_route_type();
+	set_route_type(REQUEST_ROUTE);
+	init_run_actions_ctx(&ctx);
+	run_top_route(event_rt.rlist[rt], fmsg, 0);
+	set_route_type(backup_rt);
+
+	return;
+error:
+	regpv_free_profile(rpp);
+	return;
+}

+ 3 - 0
modules_k/registrar/regpv.h

@@ -33,6 +33,7 @@
 #define _REGPV_H_
 
 #include "../../pvar.h"
+#include "../../modules_k/usrloc/usrloc.h"
 
 int pv_get_ulc(struct sip_msg *msg,  pv_param_t *param,
 		pv_value_t *res);
@@ -46,4 +47,6 @@ int pv_free_contacts(struct sip_msg* msg, char* profile, char *s2);
 
 void regpv_free_profiles(void);
 
+void reg_ul_expired_contact(ucontact_t* c, int type, void* param);
+
 #endif

+ 2 - 2
modules_k/registrar/reply.c

@@ -598,9 +598,9 @@ static int add_flow_timer(struct sip_msg* _m)
  	}
 	lump_len = snprintf(buf, FLOW_TIMER_LEN + 3 + CRLF_LEN,
 				"%.*s%d%.*s",
-				FLOW_TIMER_LEN, FLOW_TIMER,
+				(int)FLOW_TIMER_LEN, FLOW_TIMER,
 				reg_flow_timer,
-				CRLF_LEN, CRLF);
+				(int)CRLF_LEN, CRLF);
  	add_lump_rpl(_m, buf, lump_len, LUMP_RPL_HDR | LUMP_RPL_NODUP);
  	return 0;
 }