Răsfoiți Sursa

modules/registrar Added default_expires_range parameter, which specifies randomisation of the Expire parameter
returned to the UA(in case the UAC doesn't specify an own expiry value) in a certain interval.

This new parameters adds the posibility to randomize the Expiry parameter in a certain interval,
(+- default_expires_range%*default_expires). This is helpful to avoid syncronization of re-registration
of the UACs after an outage.

Parameter is configurable via ser cfg framework.

Old behaviour (fixed default_registrar value), is enabled by default, by leaving the parameter 0.

Marius Zbihlei 15 ani în urmă
părinte
comite
4480f807dc

+ 147 - 124
modules_k/registrar/README

@@ -37,24 +37,25 @@ Bogdan-Andre Iancu
         3. Exported Parameters
 
               3.1. default_expires (integer)
-              3.2. min_expires (integer)
-              3.3. max_expires (integer)
-              3.4. default_q (integer)
-              3.5. realm_prefix (string)
-              3.6. append_branches (integer)
-              3.7. aor_avp (str)
-              3.8. case_sensitive (integer)
-              3.9. received_avp (str)
-              3.10. received_param (string)
-              3.11. max_contacts (integer)
-              3.12. retry_after (integer)
-              3.13. sock_flag (integer)
-              3.14. sock_hdr_name (string)
-              3.15. method_filtering (integer)
-              3.16. use_path (integer)
-              3.17. path_mode (integer)
-              3.18. path_use_received (integer)
-              3.19. reg_callid_avp (string)
+              3.2. default_expires_range (integer)
+              3.3. min_expires (integer)
+              3.4. max_expires (integer)
+              3.5. default_q (integer)
+              3.6. realm_prefix (string)
+              3.7. append_branches (integer)
+              3.8. aor_avp (str)
+              3.9. case_sensitive (integer)
+              3.10. received_avp (str)
+              3.11. received_param (string)
+              3.12. max_contacts (integer)
+              3.13. retry_after (integer)
+              3.14. sock_flag (integer)
+              3.15. sock_hdr_name (string)
+              3.16. method_filtering (integer)
+              3.17. use_path (integer)
+              3.18. path_mode (integer)
+              3.19. path_use_received (integer)
+              3.20. reg_callid_avp (string)
 
         4. Exported Functions
 
@@ -84,33 +85,34 @@ Bogdan-Andre Iancu
    List of Examples
 
    1.1. Set default_expires parameter
-   1.2. Set min_expires parameter
-   1.3. Set max_expires parameter
-   1.4. Set default_q parameter
-   1.5. Set realm_prefix parameter
-   1.6. Set append_branches parameter
-   1.7. Set aor_avp parameter
-   1.8. Set case_sensitive parameter
-   1.9. Set received_avp parameter
-   1.10. Set received_param parameter
-   1.11. Set max_contacts parameter
-   1.12. Set retry_after parameter
-   1.13. Set sock_flag parameter
-   1.14. Set sock_hdr_namer parameter
-   1.15. Set method_filtering parameter
-   1.16. Set use_path parameter
-   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.2. Set default_expires_range parameter
+   1.3. Set min_expires parameter
+   1.4. Set max_expires parameter
+   1.5. Set default_q parameter
+   1.6. Set realm_prefix parameter
+   1.7. Set append_branches parameter
+   1.8. Set aor_avp parameter
+   1.9. Set case_sensitive parameter
+   1.10. Set received_avp parameter
+   1.11. Set received_param parameter
+   1.12. Set max_contacts parameter
+   1.13. Set retry_after parameter
+   1.14. Set sock_flag parameter
+   1.15. Set sock_hdr_namer parameter
+   1.16. Set method_filtering parameter
+   1.17. Set use_path parameter
+   1.18. Set path_mode parameter
+   1.19. Set path_use_received parameter
+   1.20. Set reg_callid_avp parameter
    1.21. save usage
-   1.22. lookup usage
-   1.23. registered usage
-   1.24. add_sock_hdr usage
-   1.25. registered usage
+   1.22. save usage
+   1.23. lookup usage
+   1.24. registered usage
+   1.25. add_sock_hdr usage
    1.26. registered usage
    1.27. registered usage
-   1.28. $ulc(name) usage
+   1.28. registered usage
+   1.29. $ulc(name) usage
 
 Chapter 1. Admin Guide
 
@@ -128,24 +130,25 @@ Chapter 1. Admin Guide
    3. Exported Parameters
 
         3.1. default_expires (integer)
-        3.2. min_expires (integer)
-        3.3. max_expires (integer)
-        3.4. default_q (integer)
-        3.5. realm_prefix (string)
-        3.6. append_branches (integer)
-        3.7. aor_avp (str)
-        3.8. case_sensitive (integer)
-        3.9. received_avp (str)
-        3.10. received_param (string)
-        3.11. max_contacts (integer)
-        3.12. retry_after (integer)
-        3.13. sock_flag (integer)
-        3.14. sock_hdr_name (string)
-        3.15. method_filtering (integer)
-        3.16. use_path (integer)
-        3.17. path_mode (integer)
-        3.18. path_use_received (integer)
-        3.19. reg_callid_avp (string)
+        3.2. default_expires_range (integer)
+        3.3. min_expires (integer)
+        3.4. max_expires (integer)
+        3.5. default_q (integer)
+        3.6. realm_prefix (string)
+        3.7. append_branches (integer)
+        3.8. aor_avp (str)
+        3.9. case_sensitive (integer)
+        3.10. received_avp (str)
+        3.11. received_param (string)
+        3.12. max_contacts (integer)
+        3.13. retry_after (integer)
+        3.14. sock_flag (integer)
+        3.15. sock_hdr_name (string)
+        3.16. method_filtering (integer)
+        3.17. use_path (integer)
+        3.18. path_mode (integer)
+        3.19. path_use_received (integer)
+        3.20. reg_callid_avp (string)
 
    4. Exported Functions
 
@@ -224,24 +227,25 @@ Chapter 1. Admin Guide
 3. Exported Parameters
 
    3.1. default_expires (integer)
-   3.2. min_expires (integer)
-   3.3. max_expires (integer)
-   3.4. default_q (integer)
-   3.5. realm_prefix (string)
-   3.6. append_branches (integer)
-   3.7. aor_avp (str)
-   3.8. case_sensitive (integer)
-   3.9. received_avp (str)
-   3.10. received_param (string)
-   3.11. max_contacts (integer)
-   3.12. retry_after (integer)
-   3.13. sock_flag (integer)
-   3.14. sock_hdr_name (string)
-   3.15. method_filtering (integer)
-   3.16. use_path (integer)
-   3.17. path_mode (integer)
-   3.18. path_use_received (integer)
-   3.19. reg_callid_avp (string)
+   3.2. default_expires_range (integer)
+   3.3. min_expires (integer)
+   3.4. max_expires (integer)
+   3.5. default_q (integer)
+   3.6. realm_prefix (string)
+   3.7. append_branches (integer)
+   3.8. aor_avp (str)
+   3.9. case_sensitive (integer)
+   3.10. received_avp (str)
+   3.11. received_param (string)
+   3.12. max_contacts (integer)
+   3.13. retry_after (integer)
+   3.14. sock_flag (integer)
+   3.15. sock_hdr_name (string)
+   3.16. method_filtering (integer)
+   3.17. use_path (integer)
+   3.18. path_mode (integer)
+   3.19. path_use_received (integer)
+   3.20. reg_callid_avp (string)
 
 3.1. default_expires (integer)
 
@@ -250,7 +254,8 @@ Chapter 1. Admin Guide
    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
-   modified via ser config framework.
+   modified via ser config framework. A random value in a specific
+   interval can be selected by using the default_expires_range parameter
 
    Default value is 3600.
 
@@ -259,7 +264,25 @@ Chapter 1. Admin Guide
 modparam("registrar", "default_expires", 1800)
 ...
 
-3.2. min_expires (integer)
+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
+   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
+   ser config framework.
+
+   Default value is 0.
+
+   Example 1.2. Set default_expires_range parameter
+...
+modparam("registrar", "default_expires", 30) # +- 30% from default_expires
+...
+
+3.3. min_expires (integer)
 
    The minimum expires value of a Contact, values lower than this minimum
    will be automatically set to the minimum. Value 0 disables the
@@ -267,12 +290,12 @@ modparam("registrar", "default_expires", 1800)
 
    Default value is 60.
 
-   Example 1.2. Set min_expires parameter
+   Example 1.3. Set min_expires parameter
 ...
 modparam("registrar", "min_expires", 60)
 ...
 
-3.3. max_expires (integer)
+3.4. max_expires (integer)
 
    The maximum expires value of a Contact, values higher than this maximum
    will be automatically set to the maximum. Value 0 disables the
@@ -280,12 +303,12 @@ modparam("registrar", "min_expires", 60)
 
    Default value is 0.
 
-   Example 1.3. Set max_expires parameter
+   Example 1.4. Set max_expires parameter
 ...
 modparam("registrar", "max_expires", 120)
 ...
 
-3.4. default_q (integer)
+3.5. default_q (integer)
 
    The parameter represents default q value for new contacts. Because
    Kamailio doesn't support float parameter types, the value in the
@@ -295,12 +318,12 @@ modparam("registrar", "max_expires", 120)
 
    Default value is 0.
 
-   Example 1.4. Set default_q parameter
+   Example 1.5. Set default_q parameter
 ...
 modparam("registrar", "default_q", 1000)
 ...
 
-3.5. realm_prefix (string)
+3.6. realm_prefix (string)
 
    Prefix to be automatically strip from realm. As an alternative to SRV
    records (not all SIP clients support SRV lookup), a subdomain of the
@@ -312,12 +335,12 @@ modparam("registrar", "default_q", 1000)
 
    Default value is NULL (none).
 
-   Example 1.5. Set realm_prefix parameter
+   Example 1.6. Set realm_prefix parameter
 ...
 modparam("registrar", "realm_prefix", "sip.")
 ...
 
-3.6. append_branches (integer)
+3.7. append_branches (integer)
 
    The parameter controls how lookup function processes multiple contacts.
    If there are multiple contacts for the given username in usrloc and
@@ -330,12 +353,12 @@ modparam("registrar", "realm_prefix", "sip.")
 
    Default value is 1.
 
-   Example 1.6. Set append_branches parameter
+   Example 1.7. Set append_branches parameter
 ...
 modparam("registrar", "append_branches", 0)
 ...
 
-3.7. aor_avp (str)
+3.8. aor_avp (str)
 
    If set, the module will try first to get the AOR from this AVP instead
    of fetching it form the processed request.
@@ -345,12 +368,12 @@ modparam("registrar", "append_branches", 0)
 
    Default value is "NULL" (disabled).
 
-   Example 1.7. Set aor_avp parameter
+   Example 1.8. Set aor_avp parameter
 ...
 modparam("registrar", "aor_avp", "$avp(i:3223)")
 ...
 
-3.8. case_sensitive (integer)
+3.9. case_sensitive (integer)
 
    If set to 1 then AOR comparison will be case sensitive, if set to 0
    then AOR comparison will be case insensitive--This is recommended.This
@@ -358,12 +381,12 @@ modparam("registrar", "aor_avp", "$avp(i:3223)")
 
    Default value is 0.
 
-   Example 1.8. Set case_sensitive parameter
+   Example 1.9. Set case_sensitive parameter
 ...
 modparam("registrar", "case_sensitive", 1)
 ...
 
-3.9. received_avp (str)
+3.10. received_avp (str)
 
    Registrar will store the value of the AVP configured by this parameter
    in the received column in the user location database. It will leave the
@@ -378,24 +401,24 @@ Note
 
    Default value is "NULL" (disabled).
 
-   Example 1.9. Set received_avp parameter
+   Example 1.10. Set received_avp parameter
 ...
 modparam("registrar", "received_avp", "$avp(s:rcv)")
 ...
 
-3.10. received_param (string)
+3.11. received_param (string)
 
    The name of the parameter that will be appended to Contacts of 200 OK
    when the received URI was set by nathelper module.
 
    Default value is "received".
 
-   Example 1.10. Set received_param parameter
+   Example 1.11. Set received_param parameter
 ...
 modparam("registrar", "received_param", "rcv")
 ...
 
-3.11. max_contacts (integer)
+3.12. max_contacts (integer)
 
    The parameter can be used to limit the number of contacts per AOR
    (Address of Record) in the user location database. Value 0 disables the
@@ -403,13 +426,13 @@ modparam("registrar", "received_param", "rcv")
 
    Default value is 0.
 
-   Example 1.11. Set max_contacts parameter
+   Example 1.12. Set max_contacts parameter
 ...
 # Allow no more than 10 contacts per AOR
 modparam("registrar", "max_contacts", 10)
 ...
 
-3.12. retry_after (integer)
+3.13. retry_after (integer)
 
    The registrar can generate 5xx reply to REGISTER in various situations.
    It can, for example, happen when the max_contacts parameter is set and
@@ -423,12 +446,12 @@ modparam("registrar", "max_contacts", 10)
 
    Default value is 0 (disabled).
 
-   Example 1.12. Set retry_after parameter
+   Example 1.13. Set retry_after parameter
 ...
 modparam("registrar", "retry_after", 30)
 ...
 
-3.13. sock_flag (integer)
+3.14. sock_flag (integer)
 
    Message flag to signal to register module to look into REGISTER request
    for a header which contains a socket description (IP:port). This socket
@@ -438,12 +461,12 @@ modparam("registrar", "retry_after", 30)
 
    Default value is -1 (no flag).
 
-   Example 1.13. Set sock_flag parameter
+   Example 1.14. Set sock_flag parameter
 ...
 modparam("registrar", "sock_flag", 18)
 ...
 
-3.14. sock_hdr_name (string)
+3.15. sock_hdr_name (string)
 
    Header which contains a socket description (proto:IP:port) to override
    the received socket info. The header will be read only if the flag
@@ -453,36 +476,36 @@ modparam("registrar", "sock_flag", 18)
 
    Default value is NULL.
 
-   Example 1.14. Set sock_hdr_namer parameter
+   Example 1.15. Set sock_hdr_namer parameter
 ...
 modparam("registrar", "sock_hdr_name", "Sock-Info")
 ...
 
-3.15. method_filtering (integer)
+3.16. method_filtering (integer)
 
    Tells if the contact filtering based on supported methods should be
    performed during lookup. It's enabled only if it has a non zero value.
 
    Default value is 0 (disabled).
 
-   Example 1.15. Set method_filtering parameter
+   Example 1.16. Set method_filtering parameter
 ...
 modparam("registrar", "method_filtering", 1)
 ...
 
-3.16. use_path (integer)
+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”.
 
    Default value is 0 (disabled).
 
-   Example 1.16. Set use_path parameter
+   Example 1.17. Set use_path parameter
 ...
 modparam("registrar", "use_path", 1)
 ...
 
-3.17. path_mode (integer)
+3.18. path_mode (integer)
 
    The registrar module implements three different modes regarding the
    response to a registration which includes one or more Path headers:
@@ -500,12 +523,12 @@ modparam("registrar", "use_path", 1)
 
    Default value is 2.
 
-   Example 1.17. Set path_mode parameter
+   Example 1.18. Set path_mode parameter
 ...
 modparam("registrar", "path_mode", 0)
 ...
 
-3.18. path_use_received (integer)
+3.19. path_use_received (integer)
 
    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
@@ -515,12 +538,12 @@ modparam("registrar", "path_mode", 0)
 
    Default value is 0 (disabled).
 
-   Example 1.18. Set path_use_received parameter
+   Example 1.19. Set path_use_received parameter
 ...
 modparam("registrar", "path_use_received", 1)
 ...
 
-3.19. reg_callid_avp (string)
+3.20. reg_callid_avp (string)
 
    If reg_callid_avp is defined and populated when registered() is
    invoked, the result is TRUE only if an active registration with the
@@ -528,7 +551,7 @@ modparam("registrar", "path_use_received", 1)
 
    Default value is NULL (disabled).
 
-   Example 1.19. Set reg_callid_avp parameter
+   Example 1.20. Set reg_callid_avp parameter
 ...
 modparam("registrar", "reg_callid_avp", "$avp(s:avp)")
 ...
@@ -566,7 +589,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");
 ...
@@ -593,7 +616,7 @@ save("location");
 
    This function can be used from REQUEST_ROUTE and ONREPLY_ROUTE.
 
-   Example 1.21. save usage
+   Example 1.22. save usage
 ...
 save("location","0x01");
 ...
@@ -622,7 +645,7 @@ save("location","0x01");
 
    This function can be used from REQUEST_ROUTE, FAILURE_ROUTE.
 
-   Example 1.22. lookup usage
+   Example 1.23. lookup usage
 ...
 lookup("location");
 switch ($retcode) {
@@ -648,7 +671,7 @@ switch ($retcode) {
 
    This function can be used from REQUEST_ROUTE, FAILURE_ROUTE.
 
-   Example 1.23. registered usage
+   Example 1.24. registered usage
 ...
 if (registered("location")) {
         sl_send_reply("100", "Trying");
@@ -668,7 +691,7 @@ if (registered("location")) {
 
    This function can be used from REQUEST_ROUTE.
 
-   Example 1.24. add_sock_hdr usage
+   Example 1.25. add_sock_hdr usage
 ...
 add_sock_hdr("Sock-Info");
 ...
@@ -686,7 +709,7 @@ add_sock_hdr("Sock-Info");
 
    This function can be used from REQUEST_ROUTE, FAILURE_ROUTE.
 
-   Example 1.25. registered usage
+   Example 1.26. registered usage
 ...
 unregister("location", "$ru");
 unregister("location", "sip:[email protected]");
@@ -708,7 +731,7 @@ unregister("location", "sip:[email protected]");
 
    This function can be used from REQUEST_ROUTE, FAILURE_ROUTE.
 
-   Example 1.26. registered usage
+   Example 1.27. registered usage
 ...
 reg_fetch_contacts("location", "$ru", "callee");
 reg_fetch_contacts("location", "sip:[email protected]", "caller");
@@ -727,7 +750,7 @@ reg_fetch_contacts("location", "sip:[email protected]", "caller");
 
    This function can be used from REQUEST_ROUTE, FAILURE_ROUTE.
 
-   Example 1.27. registered usage
+   Example 1.28. registered usage
 ...
 reg_free_contacts("callee");
 ...
@@ -793,7 +816,7 @@ reg_free_contacts("callee");
    The pseudo-variable accepts positive index value to access a specific
    contact record.
 
-   Example 1.28. $ulc(name) usage
+   Example 1.29. $ulc(name) usage
 ...
 if(reg_fetch_contacts("location", "$fu", "caller"))
 {

+ 5 - 5
modules_k/registrar/config.c

@@ -16,9 +16,6 @@
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  *
- * History
- * -------
- *  2008-02-05	adapting tm module for the configuration framework (Miklos)
  */
 
 /*!
@@ -35,6 +32,7 @@
 
 struct cfg_group_registrar	default_registrar_cfg = {
 		3600, 	/* default_expires */
+		0,	/* default_expires_range */
 		60,	/* min_expires */
 		0,	/* max_expires */
 		0,	/* max_contacts */
@@ -42,7 +40,7 @@ struct cfg_group_registrar	default_registrar_cfg = {
 		0,	/* case_sensitive */
 		Q_UNSPECIFIED,	/* default_q */
 		1,	/* append_branches */
-		"",	/* realm_pref */
+		""	/* realm_pref */
 	    };
 
 void	*registrar_cfg = &default_registrar_cfg;
@@ -50,6 +48,8 @@ void	*registrar_cfg = &default_registrar_cfg;
 cfg_def_t	registrar_cfg_def[] = {
 	{"default_expires",	CFG_VAR_INT | CFG_CB_ONLY_ONCE,	0, 0, 0, default_expires_stats_update,
 		"Contains number of second to expire if no expire hf or contact expire present" },
+	{"default_expires_range",	CFG_VAR_INT | CFG_CB_ONLY_ONCE,	0, 100, 0, default_expires_range_update,
+		"Procent from default_expires that will be used in generating the range for the expire interval"},
 	{"min_expires",		CFG_VAR_INT | CFG_CB_ONLY_ONCE,	0, 0, 0, 0,
 		"The minimum expires value of a Contact. Value 0 disables the checking. "},
 	{"max_expires",		CFG_VAR_INT | CFG_CB_ONLY_ONCE,	0, 0, 0, max_expires_stats_update,
@@ -64,7 +64,7 @@ cfg_def_t	registrar_cfg_def[] = {
 		"The parameter represents default q value for new contacts."}, /* Q_UNSPECIFIED is -1 */
 	{"append_branches",	CFG_VAR_INT ,			0, 0, 0, 0,
 		"If set to 1(default), lookup will put all contacts found in msg structure"},
-	{"realm_pref",		CFG_VAR_STR ,			0, 0, 0, 0,
+	{"realm_pref",		CFG_VAR_STRING ,			0, 0, 0, 0,
 		"Realm prefix to be removed. Default is \"\""},
 	{0, 0, 0, 0, 0, 0}
 };

+ 2 - 1
modules_k/registrar/config.h

@@ -28,6 +28,7 @@
 
 struct cfg_group_registrar {
 	unsigned int	default_expires;
+	unsigned int	default_expires_range;
 	unsigned int	min_expires;
 	unsigned int	max_expires;
 	unsigned int	max_contacts;
@@ -36,7 +37,6 @@ struct cfg_group_registrar {
 	qvalue_t	default_q;
 	unsigned int	append_branches;
 	char* 		realm_pref;
-	char*		rcv_param;
 };
 
 extern struct cfg_group_registrar	default_registrar_cfg;
@@ -44,6 +44,7 @@ extern void	*registrar_cfg;
 extern cfg_def_t	registrar_cfg_def[];
 
 extern void default_expires_stats_update(str*, str*);
+extern void default_expires_range_update(str*, str*);
 extern void max_expires_stats_update(str*, str*);
 
 #endif

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

@@ -118,6 +118,8 @@
 		number of second to expire (for example use 3600 for one hour). If it
 		is set to a lower value than the <quote>min_expires</quote> 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
 		</para>
 		<para>
 		<emphasis>
@@ -133,6 +135,32 @@ modparam("registrar", "default_expires", 1800)
 </programlisting>
 		</example>
 	</section>
+		<section>
+		<title><varname>default_expires_range</varname> (integer)</title>
+		<para>
+		This parameter specifies that the expiry used for newly created usrloc records
+		are not fixed(when <quote>default_expires</quote> applies), but a random value in the interval 
+		<quote>[default_expires-default_expires_range%, default_expires+default_expires_range%]</quote>.
+		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 ser config framework.
+		</para>
+		<para>
+		<emphasis>
+			Default value is 0.
+		</emphasis>
+		</para>
+		<example>
+		<title>Set <varname>default_expires_range</varname> parameter</title>
+		<programlisting format="linespecific">
+...
+modparam("registrar", "default_expires", 30) # +- 30% from default_expires
+...
+</programlisting>
+		</example>
+	</section>
+	
+
 	<section>
 		<title><varname>min_expires</varname> (integer)</title>
 		<para>

+ 26 - 20
modules_k/registrar/reg_mod.c

@@ -132,7 +132,7 @@ stat_var *rejected_registrations;
 stat_var *max_expires_stat;
 stat_var *max_contacts_stat;
 stat_var *default_expire_stat;
-
+stat_var *default_expire_range_stat;
 /** SL binds */
 struct sl_binds slb;
 
@@ -176,26 +176,27 @@ static cmd_export_t cmds[] = {
  * Exported parameters
  */
 static param_export_t params[] = {
-	{"default_expires",    INT_PARAM, &default_registrar_cfg.default_expires     	},
-	{"default_q",          INT_PARAM, &default_registrar_cfg.default_q		},
-	{"append_branches",    INT_PARAM, &default_registrar_cfg.append_branches	},
-	{"case_sensitive",     INT_PARAM, &default_registrar_cfg.case_sensitive		},
+	{"default_expires",    INT_PARAM, &default_registrar_cfg.default_expires     		},
+	{"default_expires_range", INT_PARAM, &default_registrar_cfg.default_expires_range	},
+	{"default_q",          INT_PARAM, &default_registrar_cfg.default_q			},
+	{"append_branches",    INT_PARAM, &default_registrar_cfg.append_branches		},
+	{"case_sensitive",     INT_PARAM, &default_registrar_cfg.case_sensitive			},
 	/*	{"tcp_persistent_flag",INT_PARAM, &tcp_persistent_flag }, */
-	{"realm_prefix",       STR_PARAM, &default_registrar_cfg.realm_pref          	},
-	{"min_expires",        INT_PARAM, &default_registrar_cfg.min_expires		},
-	{"max_expires",        INT_PARAM, &default_registrar_cfg.max_expires		},
-	{"received_param",     STR_PARAM, &rcv_param           				},
-	{"received_avp",       STR_PARAM, &rcv_avp_param       				},
-	{"aor_avp",            STR_PARAM, &aor_avp_param       				},
-	{"reg_callid_avp",     STR_PARAM, &reg_callid_avp_param				},
-	{"max_contacts",       INT_PARAM, &default_registrar_cfg.max_contacts		},
-	{"retry_after",        INT_PARAM, &default_registrar_cfg.retry_after		},
-	{"sock_flag",          INT_PARAM, &sock_flag           				},
-	{"sock_hdr_name",      STR_PARAM, &sock_hdr_name.s     				},
-	{"method_filtering",   INT_PARAM, &method_filtering    				},
-	{"use_path",           INT_PARAM, &path_enabled        				},
-	{"path_mode",          INT_PARAM, &path_mode           				},
-	{"path_use_received",  INT_PARAM, &path_use_params     				},
+	{"realm_prefix",       STR_PARAM, &default_registrar_cfg.realm_pref          		},
+	{"min_expires",        INT_PARAM, &default_registrar_cfg.min_expires			},
+	{"max_expires",        INT_PARAM, &default_registrar_cfg.max_expires			},
+	{"received_param",     STR_PARAM, &rcv_param           					},
+	{"received_avp",       STR_PARAM, &rcv_avp_param       					},
+	{"aor_avp",            STR_PARAM, &aor_avp_param       					},
+	{"reg_callid_avp",     STR_PARAM, &reg_callid_avp_param					},
+	{"max_contacts",       INT_PARAM, &default_registrar_cfg.max_contacts			},
+	{"retry_after",        INT_PARAM, &default_registrar_cfg.retry_after			},
+	{"sock_flag",          INT_PARAM, &sock_flag           					},
+	{"sock_hdr_name",      STR_PARAM, &sock_hdr_name.s     					},
+	{"method_filtering",   INT_PARAM, &method_filtering    					},
+	{"use_path",           INT_PARAM, &path_enabled        					},
+	{"path_mode",          INT_PARAM, &path_mode           					},
+	{"path_use_received",  INT_PARAM, &path_use_params     					},
 	{0, 0, 0}
 };
 
@@ -205,6 +206,7 @@ stat_export_t mod_stats[] = {
 	{"max_expires",       STAT_NO_RESET, &max_expires_stat        },
 	{"max_contacts",      STAT_NO_RESET, &max_contacts_stat       },
 	{"default_expire",    STAT_NO_RESET, &default_expire_stat     },
+	{"default_expires_range", STAT_NO_RESET, &default_expire_range_stat },
 	{"accepted_regs",                 0, &accepted_registrations  },
 	{"rejected_regs",                 0, &rejected_registrations  },
 	{0, 0, 0}
@@ -535,3 +537,7 @@ void default_expires_stats_update(str* gname, str* name){
 void max_expires_stats_update(str* gname, str* name){
 	update_stat(max_expires_stat, cfg_get(registrar, registrar_cfg, max_expires));
 }
+
+void default_expires_range_update(str* gname, str* name){
+	update_stat(default_expire_range_stat, cfg_get(registrar, registrar_cfg, default_expires_range));
+}

+ 20 - 6
modules_k/registrar/sip_msg.c

@@ -40,9 +40,23 @@
 #include "rerrno.h"
 #include "sip_msg.h"
 #include "config.h"
+#include <stdlib.h>
 
 static struct hdr_field* act_contact;
 
+/*! \brief
+ *  Return an expire value in the range [ default_expires - range%, default_expires + range% ]
+ */
+static inline int get_expire_val(void)
+{
+	int expires = cfg_get(registrar, registrar_cfg, default_expires);
+	int range = cfg_get(registrar, registrar_cfg, default_expires_range);
+	/* if no range is given just return default_expires */
+	if(range == 0) return expires;
+	/* select a random value in the range */
+	return expires - (float)range/100 * expires + (float)(rand()%100)/100 * 2 * (float)range/100 * expires;
+}
+
 
 /*! \brief
  * Return value of Expires header field
@@ -53,17 +67,17 @@ static struct hdr_field* act_contact;
 static inline int get_expires_hf(struct sip_msg* _m)
 {
 	exp_body_t* p;
-	
 	if (_m->expires) {
 		p = (exp_body_t*)_m->expires->parsed;
 		if (p->valid) {
 			if (p->val != 0) {
 				return p->val + act_time;
 			} else return 0;
-		} else return act_time + cfg_get(registrar, registrar_cfg, default_expires);
-	} else {
-		return act_time + cfg_get(registrar, registrar_cfg, default_expires);
-	}
+		} else {
+			return act_time + get_expire_val();
+		}
+	} else
+		return act_time + get_expire_val();
 }
 
 
@@ -237,7 +251,7 @@ void calc_contact_expires(struct sip_msg* _m, param_t* _ep, int* _e)
 		*_e = get_expires_hf(_m);
 	} else {
 		if (str2int(&_ep->body, (unsigned int*)_e) < 0) {
-			*_e = cfg_get(registrar, registrar_cfg, default_expires);
+			*_e = get_expire_val();
 		}
 		/* Convert to absolute value */
 		if (*_e != 0) *_e += act_time;