Browse Source

modules/lcr: added 'defunct' column to 'gw' table

- Added 'defunct' column to 'gw' table that can be used to defunct
  a gateway until the given time.
Juha Heinanen 16 years ago
parent
commit
cd18b51a06
3 changed files with 181 additions and 125 deletions
  1. 125 107
      modules/lcr/README
  2. 25 2
      modules/lcr/doc/lcr_admin.xml
  3. 31 16
      modules/lcr/lcr_mod.c

+ 125 - 107
modules/lcr/README

@@ -41,19 +41,20 @@ Juha Heinanen
               3.12. tag_column (string)
               3.13. weight_column (string)
               3.14. flags_column (string)
-              3.15. lcr_table (string)
-              3.16. prefix_column (string)
-              3.17. from_uri_column (string)
-              3.18. priority_column (string)
-              3.19. lcr_count (integer)
-              3.20. gw_uri_avp (AVP string)
-              3.21. ruri_user_avp (AVP string)
-              3.22. flags_avp (AVP string)
-              3.23. defunct_capability (integer)
-              3.24. lcr_id_avp (AVP string)
-              3.25. defunct_gw_avp (AVP string)
-              3.26. lcr_hash_size (integer)
-              3.27. fetch_rows (integer)
+              3.15. defunct_column (string)
+              3.16. lcr_table (string)
+              3.17. prefix_column (string)
+              3.18. from_uri_column (string)
+              3.19. priority_column (string)
+              3.20. lcr_count (integer)
+              3.21. gw_uri_avp (AVP string)
+              3.22. ruri_user_avp (AVP string)
+              3.23. flags_avp (AVP string)
+              3.24. defunct_capability (integer)
+              3.25. lcr_id_avp (AVP string)
+              3.26. defunct_gw_avp (AVP string)
+              3.27. lcr_hash_size (integer)
+              3.28. fetch_rows (integer)
 
         4. Exported Functions
 
@@ -95,30 +96,31 @@ Juha Heinanen
    1.12. Setting tag_column module parameter
    1.13. Setting weight_column module parameter
    1.14. Setting flags_column module parameter
-   1.15. Setting lcr_table module parameter
-   1.16. Setting prefix_column module parameter
-   1.17. Setting from_uri_column module parameter
-   1.18. Setting priority_column module parameter
-   1.19. Setting lcr_count module parameter
-   1.20. Setting gw_uri_avp module parameter
-   1.21. Setting ruri_user_avp module parameter
-   1.22. Setting flags_avp module parameter
-   1.23. Setting defunct_capability module parameter
-   1.24. Setting lcr_id_avp module parameter
-   1.25. Setting defunct_gw_avp module parameter
-   1.26. Setting lcr_hash_size module parameter
-   1.27. Set fetch_rows parameter
-   1.28. load_gws usage
-   1.29. next_gw usage from a route block
-   1.30. next_gw usage from a failure route block
-   1.31. defunct_gw usage
-   1.32. from_gw usage
+   1.15. Setting defunct_column module parameter
+   1.16. Setting lcr_table module parameter
+   1.17. Setting prefix_column module parameter
+   1.18. Setting from_uri_column module parameter
+   1.19. Setting priority_column module parameter
+   1.20. Setting lcr_count module parameter
+   1.21. Setting gw_uri_avp module parameter
+   1.22. Setting ruri_user_avp module parameter
+   1.23. Setting flags_avp module parameter
+   1.24. Setting defunct_capability module parameter
+   1.25. Setting lcr_id_avp module parameter
+   1.26. Setting defunct_gw_avp module parameter
+   1.27. Setting lcr_hash_size module parameter
+   1.28. Set fetch_rows parameter
+   1.29. load_gws usage
+   1.30. next_gw usage from a route block
+   1.31. next_gw usage from a failure route block
+   1.32. defunct_gw usage
    1.33. from_gw usage
-   1.34. to_gw usage
+   1.34. from_gw usage
    1.35. to_gw usage
-   1.36. lcr.reload RPC example
-   1.37. lcr.dump_gws RPC example
-   1.38. lcr.dump_lcr RPC example
+   1.36. to_gw usage
+   1.37. lcr.reload RPC example
+   1.38. lcr.dump_gws RPC example
+   1.39. lcr.dump_lcr RPC example
 
 Chapter 1. Admin Guide
 
@@ -146,19 +148,20 @@ Chapter 1. Admin Guide
         3.12. tag_column (string)
         3.13. weight_column (string)
         3.14. flags_column (string)
-        3.15. lcr_table (string)
-        3.16. prefix_column (string)
-        3.17. from_uri_column (string)
-        3.18. priority_column (string)
-        3.19. lcr_count (integer)
-        3.20. gw_uri_avp (AVP string)
-        3.21. ruri_user_avp (AVP string)
-        3.22. flags_avp (AVP string)
-        3.23. defunct_capability (integer)
-        3.24. lcr_id_avp (AVP string)
-        3.25. defunct_gw_avp (AVP string)
-        3.26. lcr_hash_size (integer)
-        3.27. fetch_rows (integer)
+        3.15. defunct_column (string)
+        3.16. lcr_table (string)
+        3.17. prefix_column (string)
+        3.18. from_uri_column (string)
+        3.19. priority_column (string)
+        3.20. lcr_count (integer)
+        3.21. gw_uri_avp (AVP string)
+        3.22. ruri_user_avp (AVP string)
+        3.23. flags_avp (AVP string)
+        3.24. defunct_capability (integer)
+        3.25. lcr_id_avp (AVP string)
+        3.26. defunct_gw_avp (AVP string)
+        3.27. lcr_hash_size (integer)
+        3.28. fetch_rows (integer)
 
    4. Exported Functions
 
@@ -200,14 +203,15 @@ Chapter 1. Admin Guide
    a prefix and caller's URI matches a from pattern in a tuple that
    belongs to the group of the gateway.
 
-   When function load_gws() is called, matching gateways are ordered for
-   forwarding purpose (1) according to longest user part match, (2)
-   according to tuple's priority, and (3) gateway's randomized weight
-   within its group. Prefix is a string of characters or NULL. From
-   pattern is a regular expression (see 'man pcresyntax' for syntax), an
-   empty string, or NULL. Empty or NULL from pattern or prefix matches
-   anything. Smaller priority value means higher priority (highest
-   priority value being 0). Weight is an integer value from 1 to 254.
+   When function load_gws() is called, matching gateways (that are not
+   currently designated as defunct) are ordered for forwarding purpose (1)
+   according to longest user part match, (2) according to tuple's
+   priority, and (3) gateway's randomized weight within its group. Prefix
+   is a string of characters or NULL. From pattern is a regular expression
+   (see 'man pcresyntax' for syntax), an empty string, or NULL. Empty or
+   NULL from pattern or prefix matches anything. Smaller priority value
+   means higher priority (highest priority value being 0). Weight is an
+   integer value from 1 to 254.
 
    Function next_gw() can then be used to select one gateway at a time for
    forwarding. Upon each call, user part of original Request URI is first
@@ -261,19 +265,20 @@ Chapter 1. Admin Guide
    3.12. tag_column (string)
    3.13. weight_column (string)
    3.14. flags_column (string)
-   3.15. lcr_table (string)
-   3.16. prefix_column (string)
-   3.17. from_uri_column (string)
-   3.18. priority_column (string)
-   3.19. lcr_count (integer)
-   3.20. gw_uri_avp (AVP string)
-   3.21. ruri_user_avp (AVP string)
-   3.22. flags_avp (AVP string)
-   3.23. defunct_capability (integer)
-   3.24. lcr_id_avp (AVP string)
-   3.25. defunct_gw_avp (AVP string)
-   3.26. lcr_hash_size (integer)
-   3.27. fetch_rows (integer)
+   3.15. defunct_column (string)
+   3.16. lcr_table (string)
+   3.17. prefix_column (string)
+   3.18. from_uri_column (string)
+   3.19. priority_column (string)
+   3.20. lcr_count (integer)
+   3.21. gw_uri_avp (AVP string)
+   3.22. ruri_user_avp (AVP string)
+   3.23. flags_avp (AVP string)
+   3.24. defunct_capability (integer)
+   3.25. lcr_id_avp (AVP string)
+   3.26. defunct_gw_avp (AVP string)
+   3.27. lcr_hash_size (integer)
+   3.28. fetch_rows (integer)
 
 3.1. db_url (string)
 
@@ -436,62 +441,74 @@ modparam("lcr","weight_column","gw_weight")
 modparam("lcr","flags_column","gw_flags")
 ...
 
-3.15. lcr_table (string)
+3.15. defunct_column (string)
+
+   Name of the column holding UNIX timestamp telling the time until which
+   the gw is considered as defunct.
+
+   Default value is "defunct".
+
+   Example 1.15. Setting defunct_column module parameter
+...
+modparam("lcr","defunct_column","defunct_until")
+...
+
+3.16. lcr_table (string)
 
    Name of the table holding the LCR rules.
 
    Default value is "lcr".
 
-   Example 1.15. Setting lcr_table module parameter
+   Example 1.16. Setting lcr_table module parameter
 ...
 modparam("lcr","lcr_table","lcr")
 ...
 
-3.16. prefix_column (string)
+3.17. prefix_column (string)
 
    Name of the column holding prefix of Request URI user part.
 
    Default value is "prefix".
 
-   Example 1.16. Setting prefix_column module parameter
+   Example 1.17. Setting prefix_column module parameter
 ...
 modparam("lcr","prefix_column","prefix")
 ...
 
-3.17. from_uri_column (string)
+3.18. from_uri_column (string)
 
    Name of the column holding the FROM (source) URI.
 
    Default value is "from_uri".
 
-   Example 1.17. Setting from_uri_column module parameter
+   Example 1.18. Setting from_uri_column module parameter
 ...
 modparam("lcr","from_uri_column","from_uri")
 ...
 
-3.18. priority_column (string)
+3.19. priority_column (string)
 
    Name of the column holding the priority of the rule.
 
    Default value is "priority".
 
-   Example 1.18. Setting priority_column module parameter
+   Example 1.19. Setting priority_column module parameter
 ...
 modparam("lcr","priority_column","priority")
 ...
 
-3.19. lcr_count (integer)
+3.20. lcr_count (integer)
 
    Number of LCR instances.
 
    Default value is 1.
 
-   Example 1.19.  Setting lcr_count module parameter
+   Example 1.20.  Setting lcr_count module parameter
 ...
 modparam("lcr", "lcr_count", 10)
 ...
 
-3.20. gw_uri_avp (AVP string)
+3.21. gw_uri_avp (AVP string)
 
    Internal AVP that load_gws() function uses to store information of
    matching gateways.
@@ -499,12 +516,12 @@ modparam("lcr", "lcr_count", 10)
    There is NO default value, thus this variable must be defined in
    sip-router.cfg.
 
-   Example 1.20. Setting gw_uri_avp module parameter
+   Example 1.21. Setting gw_uri_avp module parameter
 ...
 modparam("lcr", "gw_uri_avp", "$avp(i:709)")
 ...
 
-3.21. ruri_user_avp (AVP string)
+3.22. ruri_user_avp (AVP string)
 
    Internal AVP that next_gw function uses to store Request-URI user for
    subsequent next_gw calls.
@@ -512,12 +529,12 @@ modparam("lcr", "gw_uri_avp", "$avp(i:709)")
    There is NO default value, thus this variable must be defined in
    sip-router.cfg.
 
-   Example 1.21. Setting ruri_user_avp module parameter
+   Example 1.22. Setting ruri_user_avp module parameter
 ...
 modparam("lcr", "ruri_user_avp", "$avp(i:500)")
 ...
 
-3.22. flags_avp (AVP string)
+3.23. flags_avp (AVP string)
 
    An AVP where successful next_gw and from_gw functions store gateway's
    flags.
@@ -525,24 +542,24 @@ modparam("lcr", "ruri_user_avp", "$avp(i:500)")
    There is NO default value, thus this variable must be defined in
    sip-router.cfg.
 
-   Example 1.22. Setting flags_avp module parameter
+   Example 1.23. Setting flags_avp module parameter
 ...
 modparam("lcr", "flags_avp", "$avp(i:712)")
 ...
 
-3.23. defunct_capability (integer)
+3.24. defunct_capability (integer)
 
    Tells if defunct capability of (non-responsive) gateways is supported.
    Non-zero value turns on defunct capability.
 
    Default value is 0.
 
-   Example 1.23.  Setting defunct_capability module parameter
+   Example 1.24.  Setting defunct_capability module parameter
 ...
 modparam("lcr", "defunct_capability", 1)
 ...
 
-3.24. lcr_id_avp (AVP string)
+3.25. lcr_id_avp (AVP string)
 
    Internal AVP that load_gws() function uses to store LCR instance
    identifier of loaded gateways. Only needed if gateway defunct
@@ -550,12 +567,12 @@ modparam("lcr", "defunct_capability", 1)
 
    There is NO default value.
 
-   Example 1.24. Setting lcr_id_avp module parameter
+   Example 1.25. Setting lcr_id_avp module parameter
 ...
 modparam("lcr", "lcr_id_avp", "$avp(s:lcr_id_avp)")
 ...
 
-3.25. defunct_gw_avp (AVP string)
+3.26. defunct_gw_avp (AVP string)
 
    Internal AVP that next_gw() function uses to store IP address of the
    selected gateway for later use by defunct_gw() function. Only needed if
@@ -563,12 +580,12 @@ modparam("lcr", "lcr_id_avp", "$avp(s:lcr_id_avp)")
 
    There is NO default value.
 
-   Example 1.25. Setting defunct_gw_avp module parameter
+   Example 1.26. Setting defunct_gw_avp module parameter
 ...
 modparam("lcr", "defunct_gw_avp", "$avp(s:defunct_gw_avp)")
 ...
 
-3.26. lcr_hash_size (integer)
+3.27. lcr_hash_size (integer)
 
    Defines the size of hash table used to store <prefix, from_pattern,
    priority> tuples. Hashing is done based on prefix. Larger value means
@@ -577,12 +594,12 @@ modparam("lcr", "defunct_gw_avp", "$avp(s:defunct_gw_avp)")
 
    Default value is 128.
 
-   Example 1.26.  Setting lcr_hash_size module parameter
+   Example 1.27.  Setting lcr_hash_size module parameter
 ...
 modparam("lcr", "lcr_hash_size", 1024)
 ...
 
-3.27. fetch_rows (integer)
+3.28. fetch_rows (integer)
 
    The number of the rows to be fetched at once from database when loading
    data from lcr table. This value can be used to tune the load time at
@@ -592,7 +609,7 @@ modparam("lcr", "lcr_hash_size", 1024)
 
    Default value is "2000".
 
-   Example 1.27. Set fetch_rows parameter
+   Example 1.28. Set fetch_rows parameter
 ...
 modparam("lcr", "fetch_rows", 3000)
 ...
@@ -623,7 +640,7 @@ modparam("lcr", "fetch_rows", 3000)
 
    This function can be used from REQUEST_ROUTE.
 
-   Example 1.28. load_gws usage
+   Example 1.29. load_gws usage
 ...
 if (!load_gws("1", "$var(caller_uri)")) {
         sl_send_reply("500", "Server Internal Error - Cannot load gateways");
@@ -652,7 +669,7 @@ if (!load_gws("1", "$var(caller_uri)")) {
 
    This function can be used from REQUEST_ROUTE, FAILURE_ROUTE.
 
-   Example 1.29. next_gw usage from a route block
+   Example 1.30. next_gw usage from a route block
 ...
 if (!next_gw()) {
         sl_send_reply("503", "Service not available - No gateways");
@@ -660,7 +677,7 @@ if (!next_gw()) {
 };
 ...
 
-   Example 1.30. next_gw usage from a failure route block
+   Example 1.31. next_gw usage from a failure route block
 ...
 if (!next_gw()) {
         t_reply("503", "Service not available - No more gateways");
@@ -672,7 +689,8 @@ if (!next_gw()) {
 
    Defuncts gateway selected by preceding next_gw() call for a period of
    seconds given as argument. Argument must be a positive integer constant
-   or a pseudo variable with positive integer value.
+   or a pseudo variable with positive integer value. Value of defunct
+   column in database is not updated.
 
    Returns 1 on success and -1 in case of error (see syslog).
 
@@ -680,7 +698,7 @@ if (!next_gw()) {
 
    This function can be used from REQUEST_ROUTE, FAILURE_ROUTE.
 
-   Example 1.31. defunct_gw usage
+   Example 1.32. defunct_gw usage
 ...
 defunct_gw("60");
 ...
@@ -704,7 +722,7 @@ defunct_gw("60");
    This function can be used from REQUEST_ROUTE, FAILURE_ROUTE,
    ONREPLY_ROUTE.
 
-   Example 1.32. from_gw usage
+   Example 1.33. from_gw usage
 ...
 if (from_gw("1", "$avp(s:real_source_addr)") {
         ...
@@ -730,7 +748,7 @@ if (from_gw("1", "$avp(s:real_source_addr)") {
    This function can be used from REQUEST_ROUTE, FAILURE_ROUTE,
    ONREPLY_ROUTE.
 
-   Example 1.33. from_gw usage
+   Example 1.34. from_gw usage
 ...
 $var(lcr_id) = from_any_gw();
 ...
@@ -749,7 +767,7 @@ $var(lcr_id) = from_any_gw();
 
    This function can be used from REQUEST_ROUTE, FAILURE_ROUTE.
 
-   Example 1.34. to_gw usage
+   Example 1.35. to_gw usage
 ...
 if (to_gw("1")) {
         ...
@@ -772,7 +790,7 @@ if (to_gw("1")) {
 
    This function can be used from REQUEST_ROUTE, FAILURE_ROUTE.
 
-   Example 1.35. to_gw usage
+   Example 1.36. to_gw usage
 ...
 if (to_gw("1")) {
         ...
@@ -838,7 +856,7 @@ if (to_gw("1")) {
 
    Parameters: none
 
-   Example 1.36. lcr.reload RPC example
+   Example 1.37. lcr.reload RPC example
                 $ sercmd lcr.reload
 
 6.2. lcr.dump_gws
@@ -847,7 +865,7 @@ if (to_gw("1")) {
 
    Parameters: none
 
-   Example 1.37. lcr.dump_gws RPC example
+   Example 1.38. lcr.dump_gws RPC example
                 $ sercmd lcr.dump_gws
 
 6.3. lcr.dump_lcrs
@@ -856,7 +874,7 @@ if (to_gw("1")) {
 
    Parameters: none
 
-   Example 1.38. lcr.dump_lcr RPC example
+   Example 1.39. lcr.dump_lcr RPC example
                 $ sercmd lcr.dump_lcrs
 
 7. Known Limitations

+ 25 - 2
modules/lcr/doc/lcr_admin.xml

@@ -36,7 +36,8 @@
 	tuple that belongs to the group of the gateway.
 	</para>
 	<para>
-	When function load_gws() is called, matching gateways are ordered
+	When function load_gws() is called, matching gateways (that are
+	not currently designated as defunct) are ordered
 	for forwarding purpose (1) according to longest user part match,
 	(2) according to  
 	tuple's priority, and (3) gateway's randomized weight within its
@@ -405,6 +406,27 @@ modparam("lcr","flags_column","gw_flags")
 		</example>
 	</section>
 
+	<section>
+		<title><varname>defunct_column</varname> (string)</title>
+		<para>
+		Name of the column holding UNIX timestamp telling the
+		time until which the gw is considered as defunct.
+		</para>
+		<para>
+		<emphasis>
+			Default value is <quote>defunct</quote>.
+		</emphasis>
+		</para>
+		<example>
+		<title>Setting <varname>defunct_column</varname> module parameter</title>
+		<programlisting format="linespecific">
+...
+modparam("lcr","defunct_column","defunct_until")
+...
+</programlisting>
+		</example>
+	</section>
+
 	<section>
 		<title><varname>lcr_table</varname> (string)</title>
 		<para>
@@ -803,7 +825,8 @@ if (!next_gw()) {
 		Defuncts gateway selected by preceding next_gw() call
 		for a period of seconds given as argument.  Argument
 		must be a positive integer constant or a pseudo variable
-		with positive integer value.
+		with positive integer value.  Value of defunct column in
+		database is not updated.
 		</para>
 		<para>
 		Returns 1 on success and -1 in case of error (see syslog).

+ 31 - 16
modules/lcr/lcr_mod.c

@@ -84,8 +84,8 @@ MODULE_VERSION
  * increment this value if you change the table in
  * an backwards incompatible way
  */
-#define GW_TABLE_VERSION 9
-#define LCR_TABLE_VERSION 2
+#define GW_TABLE_VERSION 10
+#define LCR_TABLE_VERSION 3
 
 static void destroy(void);       /* Module destroy function */
 static int mi_child_init(void);
@@ -119,6 +119,8 @@ static void free_shared_memory(void);
 
 #define FLAGS_COL "flags"
 
+#define DEFUNCT_COL "defunct"
+
 #define LCR_TABLE "lcr"
 
 #define PREFIX_COL "prefix"
@@ -182,6 +184,7 @@ static str strip_col        = str_init(STRIP_COL);
 static str tag_col          = str_init(TAG_COL);
 static str weight_col       = str_init(WEIGHT_COL);
 static str flags_col        = str_init(FLAGS_COL);
+static str defunct_col      = str_init(DEFUNCT_COL);
 static str lcr_table        = str_init(LCR_TABLE);
 static str prefix_col       = str_init(PREFIX_COL);
 static str from_uri_col     = str_init(FROM_URI_COL);
@@ -631,7 +634,7 @@ static int mod_init(void)
     for (i = 1; i <= lcr_count; i++) {
 	if (reload_gws_and_lcrs(i) < 0) {
 	    lock_release(reload_lock);
-	    LM_CRIT("failed to reload gateways of lcr_id %if\n", i);
+	    LM_CRIT("failed to reload gateways of lcr_id %i\n", i);
 	    goto err;
 	}
     }
@@ -808,7 +811,8 @@ static int insert_gw(struct gw_info *gws, unsigned int i, unsigned int ip_addr,
 		     unsigned int grp_id, char *ip_string, unsigned int port,
 		     unsigned int scheme, unsigned int transport,
 		     unsigned int flags, unsigned int strip, char *tag,
-		     unsigned int tag_len, unsigned short weight)
+		     unsigned int tag_len, unsigned short weight,
+		     unsigned int defunct_until)
 {
     if (gw_unique(gws, i - 1, ip_addr, grp_id) == 0) {
 	LM_ERR("ip_addr/grp_id <%s/%u> of gw is not unique\n",
@@ -828,7 +832,7 @@ static int insert_gw(struct gw_info *gws, unsigned int i, unsigned int ip_addr,
     gws[i].tag_len = tag_len;
     if (tag_len) memcpy(&(gws[i].tag[0]), tag, tag_len);
     gws[i].weight = weight;
-    gws[i].defunct_until = 0;
+    gws[i].defunct_until = defunct_until;
     gws[i].next = 0;
 
     return 1;
@@ -932,7 +936,7 @@ int reload_gws_and_lcrs(int lcr_id)
 {
     unsigned int i, n, port, strip, tag_len, prefix_len, from_uri_len,
 	grp_id,	grp_cnt, priority, flags, first_gw, weight, gw_cnt,
-	hostname_len;
+	hostname_len, defunct_until;
     struct in_addr ip_addr;
     uri_type scheme;
     uri_transport transport;
@@ -966,6 +970,7 @@ int reload_gws_and_lcrs(int lcr_id)
     gw_cols[7] = &flags_col;
     gw_cols[8] = &weight_col;
     gw_cols[9] = &hostname_col;
+    gw_cols[10] = &defunct_col;
 
     lcr_cols[0] = &prefix_col;
     lcr_cols[1] = &from_uri_col;
@@ -991,7 +996,7 @@ int reload_gws_and_lcrs(int lcr_id)
 	return -1;
     }
 
-    if (lcr_dbf.query(dbh, key_cols, op, vals, gw_cols, 1, 10, 0, &res) < 0) {
+    if (lcr_dbf.query(dbh, key_cols, op, vals, gw_cols, 1, 11, 0, &res) < 0) {
 	LM_ERR("failed to query gw data\n");
 	lcr_dbf.close(dbh);
 	return -1;
@@ -1015,7 +1020,7 @@ int reload_gws_and_lcrs(int lcr_id)
 		   ip_string, i);
 	    goto gw_err;
 	}
-	if (VAL_NULL(ROW_VALUES(row) + 1) == 1) {
+	if (VAL_NULL(ROW_VALUES(row) + 1)) {
 	    port = 0;
 	} else {
 	    if (VAL_TYPE(ROW_VALUES(row) + 1) != DB1_INT) {
@@ -1030,7 +1035,7 @@ int reload_gws_and_lcrs(int lcr_id)
 		   port, ip_string, i);
 	    goto gw_err;
 	}
-	if (VAL_NULL(ROW_VALUES(row) + 2) == 1) {
+	if (VAL_NULL(ROW_VALUES(row) + 2)) {
 	    scheme = SIP_URI_T;
 	} else {
 	    if (VAL_TYPE(ROW_VALUES(row) + 2) != DB1_INT) {
@@ -1045,7 +1050,7 @@ int reload_gws_and_lcrs(int lcr_id)
 		   "row <%u>\n", (unsigned int)scheme, ip_string, i);
 	    goto gw_err;
 	}
-	if (VAL_NULL(ROW_VALUES(row) + 3) == 1) {
+	if (VAL_NULL(ROW_VALUES(row) + 3)) {
 	    transport = PROTO_NONE;
 	} else {
 	    if (VAL_TYPE(ROW_VALUES(row) + 3) != DB1_INT) {
@@ -1067,7 +1072,7 @@ int reload_gws_and_lcrs(int lcr_id)
 		   "row <%u>\n", transport, ip_string, i); 
 	    goto gw_err;
 	}
-	if (VAL_NULL(ROW_VALUES(row) + 4) == 1) {
+	if (VAL_NULL(ROW_VALUES(row) + 4)) {
 	    strip = 0;
 	} else {
 	    if (VAL_TYPE(ROW_VALUES(row) + 4) != DB1_INT) {
@@ -1082,7 +1087,7 @@ int reload_gws_and_lcrs(int lcr_id)
 		   strip, ip_string, i);
 	    goto gw_err;
 	}
-	if (VAL_NULL(ROW_VALUES(row) + 5) == 1) {
+	if (VAL_NULL(ROW_VALUES(row) + 5)) {
 	    tag_len = 0;
 	    tag = (char *)0;
 	} else {
@@ -1099,7 +1104,7 @@ int reload_gws_and_lcrs(int lcr_id)
 		   tag_len, ip_string, i);
 	    goto gw_err;
 	}
-	if (VAL_NULL(ROW_VALUES(row) + 6) == 1) {
+	if (VAL_NULL(ROW_VALUES(row) + 6)) {
 	    grp_id = 0;
 	} else {
 	    if (VAL_TYPE(ROW_VALUES(row) + 6) != DB1_INT) {
@@ -1117,7 +1122,7 @@ int reload_gws_and_lcrs(int lcr_id)
 		   ip_string, i);
 	    goto gw_err;
 	}
-	if (VAL_NULL(ROW_VALUES(row) + 8) == 1) {
+	if (VAL_NULL(ROW_VALUES(row) + 8)) {
 	    weight = 1;
 	} else {
 	    if (VAL_TYPE(ROW_VALUES(row) + 8) != DB1_INT) {
@@ -1132,7 +1137,7 @@ int reload_gws_and_lcrs(int lcr_id)
 		   weight, ip_string, i);
 	    goto gw_err;
 	}
-	if (VAL_NULL(ROW_VALUES(row) + 9) == 1) {
+	if (VAL_NULL(ROW_VALUES(row) + 9)) {
 	    hostname_len = 0;
 	    hostname = (char *)0;
 	} else {
@@ -1149,10 +1154,20 @@ int reload_gws_and_lcrs(int lcr_id)
 		   hostname_len, ip_string, i);
 	    goto gw_err;
 	}
+	if (VAL_NULL(ROW_VALUES(row) + 10)) {
+	    defunct_until = 0;
+	} else {
+	    if (VAL_TYPE(ROW_VALUES(row) + 10) != DB1_INT) {
+		LM_ERR("defunct of gw <%s> at row <%u> is not int\n",
+		       ip_string, i);
+		goto gw_err;
+	    }
+	    defunct_until = (unsigned int)VAL_INT(ROW_VALUES(row) + 10);
+	}
 	if (!insert_gw(gws, i + 1, (unsigned int)ip_addr.s_addr, 
 		       hostname, hostname_len, grp_id,
 		       ip_string, port, scheme, transport, flags, strip,
-		       tag, tag_len, weight)) {
+		       tag, tag_len, weight, defunct_until)) {
 	    goto gw_err;
 	}
     }