Преглед изворни кода

modules/lcr: Add support for R-URI matching.

- An additional request_uri column has been introduced. If other than
  NULL, it also needs to match beside prefix and from_uri in order
  for the rule to be selected.
Richard Fuchs пре 13 година
родитељ
комит
c47d39153c

+ 9 - 0
lib/srdb1/schema/lcr_rule.xml

@@ -52,6 +52,15 @@
         <description>PCRE regular expression that is matched to caller's URI</description>
     </column>
 
+    <column id="request_uri">
+        <name>request_uri</name>
+        <type>string</type>
+        <size>&domain_len;</size>
+        <null/>
+        <default><null/></default>
+        <description>PCRE regular expression that is matched to full request URI</description>
+    </column>
+
     <column id="stopper">
         <name>stopper</name>
         <type>unsigned int</type>

+ 7 - 0
lib/srdb2/schema/lcr.xml

@@ -24,6 +24,13 @@
 	<size>&uri_len;</size>
   </column>
 
+  <column id="lcr.request_uri">
+	<name>request_uri</name>
+	<type>string</type>
+	<default>%</default>
+	<size>&uri_len;</size>
+  </column>
+
   <column id="lcr.grp_id">
 	<name>grp_id</name>
 	<type>int</type>

+ 164 - 145
modules/lcr/README

@@ -43,25 +43,26 @@ Juha Heinanen
               3.16. lcr_rule_table (string)
               3.17. prefix_column (string)
               3.18. from_uri_column (string)
-              3.19. stopper_column (string)
-              3.20. enabled_column (string)
-              3.21. lcr_rule_target_table (string)
-              3.22. rule_id_column (string)
-              3.23. gw_id_column (string)
-              3.24. priority_column (string)
-              3.25. weight_column (string)
-              3.26. lcr_count (integer)
-              3.27. gw_uri_avp (AVP string)
-              3.28. ruri_user_avp (AVP string)
-              3.29. tag_avp (AVP string)
-              3.30. flags_avp (AVP string)
-              3.31. defunct_capability (integer)
-              3.32. lcr_id_avp (AVP string)
-              3.33. defunct_gw_avp (AVP string)
-              3.34. lcr_rule_hash_size (integer)
-              3.35. lcr_gw_count (integer)
-              3.36. dont_strip_or_tag_flag (integer)
-              3.37. fetch_rows (integer)
+              3.19. request_uri_column (string)
+              3.20. stopper_column (string)
+              3.21. enabled_column (string)
+              3.22. lcr_rule_target_table (string)
+              3.23. rule_id_column (string)
+              3.24. gw_id_column (string)
+              3.25. priority_column (string)
+              3.26. weight_column (string)
+              3.27. lcr_count (integer)
+              3.28. gw_uri_avp (AVP string)
+              3.29. ruri_user_avp (AVP string)
+              3.30. tag_avp (AVP string)
+              3.31. flags_avp (AVP string)
+              3.32. defunct_capability (integer)
+              3.33. lcr_id_avp (AVP string)
+              3.34. defunct_gw_avp (AVP string)
+              3.35. lcr_rule_hash_size (integer)
+              3.36. lcr_gw_count (integer)
+              3.37. dont_strip_or_tag_flag (integer)
+              3.38. fetch_rows (integer)
 
         4. Functions
 
@@ -102,37 +103,38 @@ Juha Heinanen
    1.16. Setting lcr_rule_table module parameter
    1.17. Setting prefix_column module parameter
    1.18. Setting from_uri_column module parameter
-   1.19. Setting stopper_column module parameter
-   1.20. Setting enabled_column module parameter
-   1.21. Setting lcr_rule_target_table module parameter
-   1.22. Setting rule_id_column module parameter
-   1.23. Setting gw_id_column module parameter
-   1.24. Setting priority_column module parameter
-   1.25. Setting weight_column module parameter
-   1.26. Setting lcr_count module parameter
-   1.27. Setting gw_uri_avp module parameter
-   1.28. Setting ruri_user_avp module parameter
-   1.29. Setting tag_avp module parameter
-   1.30. Setting flags_avp module parameter
-   1.31. Setting defunct_capability module parameter
-   1.32. Setting lcr_id_avp module parameter
-   1.33. Setting defunct_gw_avp module parameter
-   1.34. Setting lcr_rule_hash_size module parameter
-   1.35. Setting lcr_gw_count module parameter
-   1.36. Setting dont_strip_or_tag_flag module parameter
-   1.37. Set fetch_rows parameter
-   1.38. load_gws usage
-   1.39. next_gw usage from a route block
-   1.40. next_gw usage from a failure route block
-   1.41. defunct_gw usage
-   1.42. from_gw usage
+   1.19. Setting request_uri_column module parameter
+   1.20. Setting stopper_column module parameter
+   1.21. Setting enabled_column module parameter
+   1.22. Setting lcr_rule_target_table module parameter
+   1.23. Setting rule_id_column module parameter
+   1.24. Setting gw_id_column module parameter
+   1.25. Setting priority_column module parameter
+   1.26. Setting weight_column module parameter
+   1.27. Setting lcr_count module parameter
+   1.28. Setting gw_uri_avp module parameter
+   1.29. Setting ruri_user_avp module parameter
+   1.30. Setting tag_avp module parameter
+   1.31. Setting flags_avp module parameter
+   1.32. Setting defunct_capability module parameter
+   1.33. Setting lcr_id_avp module parameter
+   1.34. Setting defunct_gw_avp module parameter
+   1.35. Setting lcr_rule_hash_size module parameter
+   1.36. Setting lcr_gw_count module parameter
+   1.37. Setting dont_strip_or_tag_flag module parameter
+   1.38. Set fetch_rows parameter
+   1.39. load_gws usage
+   1.40. next_gw usage from a route block
+   1.41. next_gw usage from a failure route block
+   1.42. defunct_gw usage
    1.43. from_gw usage
-   1.44. to_gw usage
+   1.44. from_gw usage
    1.45. to_gw usage
-   1.46. lcr.reload RPC example
-   1.47. lcr.dump_gws RPC example
-   1.48. lcr.dump_rules RPC example
-   1.49. lcr.defunct_gw RPC example
+   1.46. to_gw usage
+   1.47. lcr.reload RPC example
+   1.48. lcr.dump_gws RPC example
+   1.49. lcr.dump_rules RPC example
+   1.50. lcr.defunct_gw RPC example
 
 Chapter 1. Admin Guide
 
@@ -164,25 +166,26 @@ Chapter 1. Admin Guide
         3.16. lcr_rule_table (string)
         3.17. prefix_column (string)
         3.18. from_uri_column (string)
-        3.19. stopper_column (string)
-        3.20. enabled_column (string)
-        3.21. lcr_rule_target_table (string)
-        3.22. rule_id_column (string)
-        3.23. gw_id_column (string)
-        3.24. priority_column (string)
-        3.25. weight_column (string)
-        3.26. lcr_count (integer)
-        3.27. gw_uri_avp (AVP string)
-        3.28. ruri_user_avp (AVP string)
-        3.29. tag_avp (AVP string)
-        3.30. flags_avp (AVP string)
-        3.31. defunct_capability (integer)
-        3.32. lcr_id_avp (AVP string)
-        3.33. defunct_gw_avp (AVP string)
-        3.34. lcr_rule_hash_size (integer)
-        3.35. lcr_gw_count (integer)
-        3.36. dont_strip_or_tag_flag (integer)
-        3.37. fetch_rows (integer)
+        3.19. request_uri_column (string)
+        3.20. stopper_column (string)
+        3.21. enabled_column (string)
+        3.22. lcr_rule_target_table (string)
+        3.23. rule_id_column (string)
+        3.24. gw_id_column (string)
+        3.25. priority_column (string)
+        3.26. weight_column (string)
+        3.27. lcr_count (integer)
+        3.28. gw_uri_avp (AVP string)
+        3.29. ruri_user_avp (AVP string)
+        3.30. tag_avp (AVP string)
+        3.31. flags_avp (AVP string)
+        3.32. defunct_capability (integer)
+        3.33. lcr_id_avp (AVP string)
+        3.34. defunct_gw_avp (AVP string)
+        3.35. lcr_rule_hash_size (integer)
+        3.36. lcr_gw_count (integer)
+        3.37. dont_strip_or_tag_flag (integer)
+        3.38. fetch_rows (integer)
 
    4. Functions
 
@@ -217,15 +220,17 @@ Chapter 1. Admin Guide
 
    For the purpose of facilitating least cost routing of requests, each
    gateway of an LCR instance is associated with one or more <prefix, from
-   pattern, priority, weight> tuples. A gateway matches a request if user
-   part of the Request-URI matches a "prefix" and the caller's URI matches
-   a "from" pattern in a tuple that is associated with the gateway.
+   uri pattern, request uri pattern, priority, weight> tuples. A gateway
+   matches a request if user part of the Request-URI matches a "prefix",
+   the caller's URI matches a "From-URI" pattern and the callee's URI
+   matches a "Request-URI" pattern in a tuple that is associated with the
+   gateway.
 
    When the function load_gws() is called, matching gateways (that are not
    currently designated as defunct) are ordered for forwarding purposes as
    follows:
 
-     * (1) according to longest user part match
+     * (1) according to longest Request-URI user part match
      * (2) according to tuple's priority
      * (3) according to tuple's randomized weight
 
@@ -233,11 +238,12 @@ Chapter 1. Admin Guide
    matches, then matching stops at it and all other tuples with shorter
    prefixes are not considered.
 
-   Prefix is a string of characters or NULL. From pattern is a regular
-   expression (see 'man pcresyntax' for syntax), an empty string, or NULL.
-   An empty or NULL from pattern or prefix matches anything. Smaller
-   priority value means higher priority (highest priority value being 0
-   and lowest being 255).
+   Prefix is a string of characters or NULL. From-URI pattern and
+   Request-URI pattern are regular expressions (see 'man pcresyntax' for
+   syntax), an empty string, or NULL. An empty or NULL From-URI pattern,
+   Request-URI pattern or prefix matches anything. Smaller priority value
+   means higher priority (highest priority value being 0 and lowest being
+   255).
 
    Weight is an integer value from 1 to 254. Weight implementation is
    fast, but unfair favoring larger weight values at the expense smaller
@@ -306,25 +312,26 @@ Chapter 1. Admin Guide
    3.16. lcr_rule_table (string)
    3.17. prefix_column (string)
    3.18. from_uri_column (string)
-   3.19. stopper_column (string)
-   3.20. enabled_column (string)
-   3.21. lcr_rule_target_table (string)
-   3.22. rule_id_column (string)
-   3.23. gw_id_column (string)
-   3.24. priority_column (string)
-   3.25. weight_column (string)
-   3.26. lcr_count (integer)
-   3.27. gw_uri_avp (AVP string)
-   3.28. ruri_user_avp (AVP string)
-   3.29. tag_avp (AVP string)
-   3.30. flags_avp (AVP string)
-   3.31. defunct_capability (integer)
-   3.32. lcr_id_avp (AVP string)
-   3.33. defunct_gw_avp (AVP string)
-   3.34. lcr_rule_hash_size (integer)
-   3.35. lcr_gw_count (integer)
-   3.36. dont_strip_or_tag_flag (integer)
-   3.37. fetch_rows (integer)
+   3.19. request_uri_column (string)
+   3.20. stopper_column (string)
+   3.21. enabled_column (string)
+   3.22. lcr_rule_target_table (string)
+   3.23. rule_id_column (string)
+   3.24. gw_id_column (string)
+   3.25. priority_column (string)
+   3.26. weight_column (string)
+   3.27. lcr_count (integer)
+   3.28. gw_uri_avp (AVP string)
+   3.29. ruri_user_avp (AVP string)
+   3.30. tag_avp (AVP string)
+   3.31. flags_avp (AVP string)
+   3.32. defunct_capability (integer)
+   3.33. lcr_id_avp (AVP string)
+   3.34. defunct_gw_avp (AVP string)
+   3.35. lcr_rule_hash_size (integer)
+   3.36. lcr_gw_count (integer)
+   3.37. dont_strip_or_tag_flag (integer)
+   3.38. fetch_rows (integer)
 
 3.1. db_url (string)
 
@@ -537,98 +544,110 @@ modparam("lcr", "prefix_column", "number_prefix")
 modparam("lcr", "from_uri_column", "caller_uri")
 ...
 
-3.19. stopper_column (string)
+3.19. request_uri_column (string)
+
+   Name of the column holding the regular expression to match against the
+   complete request URI (including the "sip:" prefix).
+
+   Default value is “request_uri”.
+
+   Example 1.19. Setting request_uri_column module parameter
+...
+modparam("lcr", "request_uri_column", "callee_uri")
+...
+
+3.20. stopper_column (string)
 
    Name of the column holding rule's stopper attribute.
 
    Default value is “stopper”.
 
-   Example 1.19. Setting stopper_column module parameter
+   Example 1.20. Setting stopper_column module parameter
 ...
 modparam("lcr", "stopper_column", "stop")
 ...
 
-3.20. enabled_column (string)
+3.21. enabled_column (string)
 
    Name of the column telling is the rule is currently enabled or
    disabled.
 
    Default value is “enabled”.
 
-   Example 1.20. Setting enabled_column module parameter
+   Example 1.21. Setting enabled_column module parameter
 ...
 modparam("lcr", "enabled_column", "in_use")
 ...
 
-3.21. lcr_rule_target_table (string)
+3.22. lcr_rule_target_table (string)
 
    Name of the table holding information about the LCR rule targets
    (gateways).
 
    Default value is “lcr_rule_target”.
 
-   Example 1.21. Setting lcr_rule_target_table module parameter
+   Example 1.22. Setting lcr_rule_target_table module parameter
 ...
 modparam("lcr", "lcr_rule_target_table", "rules")
 ...
 
-3.22. rule_id_column (string)
+3.23. rule_id_column (string)
 
    Name of lcr_rule_target_table column containing an id of lcr_rule
    table.
 
    Default value is “rule_id”.
 
-   Example 1.22. Setting rule_id_column module parameter
+   Example 1.23. Setting rule_id_column module parameter
 ...
 modparam("lcr", "rule_id_column", "rule")
 ...
 
-3.23. gw_id_column (string)
+3.24. gw_id_column (string)
 
    Name of lcr_rule_target_table column containing an id of lcr_gw table.
 
    Default value is “gw_id”.
 
-   Example 1.23. Setting gw_id_column module parameter
+   Example 1.24. Setting gw_id_column module parameter
 ...
 modparam("lcr", "gw_id_column", "gw")
 ...
 
-3.24. priority_column (string)
+3.25. priority_column (string)
 
    Name of the column holding the priority of the rule target.
 
    Default value is “priority”.
 
-   Example 1.24. Setting priority_column module parameter
+   Example 1.25. Setting priority_column module parameter
 ...
 modparam("lcr", "priority_column", "priority")
 ...
 
-3.25. weight_column (string)
+3.26. weight_column (string)
 
    Name of the column holding weight of rule target.
 
    Default value is “weight”.
 
-   Example 1.25. Setting weight_column module parameter
+   Example 1.26. Setting weight_column module parameter
 ...
 modparam("lcr","weight_column", "target_weight")
 ...
 
-3.26. lcr_count (integer)
+3.27. lcr_count (integer)
 
    Number of LCR instances.
 
    Default value is 1.
 
-   Example 1.26.  Setting lcr_count module parameter
+   Example 1.27.  Setting lcr_count module parameter
 ...
 modparam("lcr", "lcr_count", 10)
 ...
 
-3.27. gw_uri_avp (AVP string)
+3.28. gw_uri_avp (AVP string)
 
    Internal AVP that load_gws() function uses to store information of
    matching gateways.
@@ -636,12 +655,12 @@ modparam("lcr", "lcr_count", 10)
    There is NO default value, thus this variable must be defined in
    sip-router.cfg.
 
-   Example 1.27. Setting gw_uri_avp module parameter
+   Example 1.28. Setting gw_uri_avp module parameter
 ...
 modparam("lcr", "gw_uri_avp", "$avp(i:709)")
 ...
 
-3.28. ruri_user_avp (AVP string)
+3.29. ruri_user_avp (AVP string)
 
    Internal AVP that next_gw function uses to store Request-URI user for
    subsequent next_gw calls.
@@ -649,12 +668,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.28. Setting ruri_user_avp module parameter
+   Example 1.29. Setting ruri_user_avp module parameter
 ...
 modparam("lcr", "ruri_user_avp", "$avp(i:500)")
 ...
 
-3.29. tag_avp (AVP string)
+3.30. tag_avp (AVP string)
 
    If defined, an AVP where successful next_gw and from_gw functions store
    gateway's tag.
@@ -662,12 +681,12 @@ modparam("lcr", "ruri_user_avp", "$avp(i:500)")
    There is NO default value, i.e, if not defined, gateway's tag is not
    stored anywhere.
 
-   Example 1.29. Setting tag_avp module parameter
+   Example 1.30. Setting tag_avp module parameter
 ...
 modparam("lcr", "tag_avp", "$avp(lcr_tag)")
 ...
 
-3.30. flags_avp (AVP string)
+3.31. flags_avp (AVP string)
 
    If defined, an AVP where successful next_gw and from_gw functions store
    gateway's flags.
@@ -675,24 +694,24 @@ modparam("lcr", "tag_avp", "$avp(lcr_tag)")
    There is NO default value, i.e, if not defined, gateway's flags are not
    stored anywhere.
 
-   Example 1.30. Setting flags_avp module parameter
+   Example 1.31. Setting flags_avp module parameter
 ...
 modparam("lcr", "flags_avp", "$avp(i:712)")
 ...
 
-3.31. defunct_capability (integer)
+3.32. 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.31.  Setting defunct_capability module parameter
+   Example 1.32.  Setting defunct_capability module parameter
 ...
 modparam("lcr", "defunct_capability", 1)
 ...
 
-3.32. lcr_id_avp (AVP string)
+3.33. 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
@@ -700,12 +719,12 @@ modparam("lcr", "defunct_capability", 1)
 
    There is NO default value.
 
-   Example 1.32. Setting lcr_id_avp module parameter
+   Example 1.33. Setting lcr_id_avp module parameter
 ...
 modparam("lcr", "lcr_id_avp", "$avp(s:lcr_id_avp)")
 ...
 
-3.33. defunct_gw_avp (AVP string)
+3.34. defunct_gw_avp (AVP string)
 
    Internal AVP that next_gw() function uses to store internal index of
    the selected gateway for later use by defunct_gw() function. Only
@@ -713,12 +732,12 @@ modparam("lcr", "lcr_id_avp", "$avp(s:lcr_id_avp)")
 
    There is NO default value.
 
-   Example 1.33. Setting defunct_gw_avp module parameter
+   Example 1.34. Setting defunct_gw_avp module parameter
 ...
 modparam("lcr", "defunct_gw_avp", "$avp(s:defunct_gw_avp)")
 ...
 
-3.34. lcr_rule_hash_size (integer)
+3.35. lcr_rule_hash_size (integer)
 
    Defines the size of hash table used to store LCR rules. Hashing is done
    based on rule's prefix. Larger value means less collisions with other
@@ -726,35 +745,35 @@ modparam("lcr", "defunct_gw_avp", "$avp(s:defunct_gw_avp)")
 
    Default value is 128.
 
-   Example 1.34.  Setting lcr_rule_hash_size module parameter
+   Example 1.35.  Setting lcr_rule_hash_size module parameter
 ...
 modparam("lcr", "lcr_rule_hash_size", 1024)
 ...
 
-3.35. lcr_gw_count (integer)
+3.36. lcr_gw_count (integer)
 
    Defines the maximum number of gateways in lcr_gw table.
 
    Default value is 128.
 
-   Example 1.35.  Setting lcr_gw_count module parameter
+   Example 1.36.  Setting lcr_gw_count module parameter
 ...
 modparam("lcr", "lcr_gw_count", 1024)
 ...
 
-3.36. dont_strip_or_tag_flag (integer)
+3.37. dont_strip_or_tag_flag (integer)
 
    Defines the flag number used to tell if stripping and tagging is done
    for the selected gateway.
 
    Default value is -1 meaning that the flag is not defined.
 
-   Example 1.36.  Setting dont_strip_or_tag_flag module parameter
+   Example 1.37.  Setting dont_strip_or_tag_flag module parameter
 ...
 modparam("lcr", "dont_strip_or_tag_flag", 10)
 ...
 
-3.37. fetch_rows (integer)
+3.38. fetch_rows (integer)
 
    The number of the rows to be fetched at once from database when loading
    data from lcr_rule table. This value can be used to tune the load time
@@ -764,7 +783,7 @@ modparam("lcr", "dont_strip_or_tag_flag", 10)
 
    Default value is “1024”.
 
-   Example 1.37. Set fetch_rows parameter
+   Example 1.38. Set fetch_rows parameter
 ...
 modparam("lcr", "fetch_rows", 3000)
 ...
@@ -799,7 +818,7 @@ modparam("lcr", "fetch_rows", 3000)
 
    This function can be used from REQUEST_ROUTE.
 
-   Example 1.38. load_gws usage
+   Example 1.39. load_gws usage
 ...
 if (!load_gws(1, $rU, $var(caller_uri))) {
         sl_send_reply("500", "Server Internal Error - Cannot load gateways");
@@ -829,7 +848,7 @@ if (!load_gws(1, $rU, $var(caller_uri))) {
 
    This function can be used from REQUEST_ROUTE, FAILURE_ROUTE.
 
-   Example 1.39. next_gw usage from a route block
+   Example 1.40. next_gw usage from a route block
 ...
 if (!next_gw()) {
         sl_send_reply("503", "Service not available - No gateways");
@@ -837,7 +856,7 @@ if (!next_gw()) {
 };
 ...
 
-   Example 1.40. next_gw usage from a failure route block
+   Example 1.41. next_gw usage from a failure route block
 ...
 if (!next_gw()) {
         t_reply("503", "Service not available - No more gateways");
@@ -857,7 +876,7 @@ if (!next_gw()) {
 
    This function can be used from REQUEST_ROUTE, FAILURE_ROUTE.
 
-   Example 1.41. defunct_gw usage
+   Example 1.42. defunct_gw usage
 ...
 defunct_gw(60);
 ...
@@ -889,7 +908,7 @@ defunct_gw(60);
    This function can be used from REQUEST_ROUTE, FAILURE_ROUTE,
    ONREPLY_ROUTE.
 
-   Example 1.42. from_gw usage
+   Example 1.43. from_gw usage
 ...
 if (from_gw(1, $avp(s:real_source_addr), 2) {
         ...
@@ -919,7 +938,7 @@ if (from_gw(1, $avp(s:real_source_addr), 2) {
    This function can be used from REQUEST_ROUTE, FAILURE_ROUTE,
    ONREPLY_ROUTE.
 
-   Example 1.43. from_gw usage
+   Example 1.44. from_gw usage
 ...
 $var(lcr_id) = from_any_gw("192.168.1.1", 3);
 ...
@@ -940,7 +959,7 @@ $var(lcr_id) = from_any_gw("192.168.1.1", 3);
 
    This function can be used from REQUEST_ROUTE, FAILURE_ROUTE.
 
-   Example 1.44. to_gw usage
+   Example 1.45. to_gw usage
 ...
 if (to_gw("1")) {
         ...
@@ -966,7 +985,7 @@ if (to_gw("1")) {
 
    This function can be used from REQUEST_ROUTE, FAILURE_ROUTE.
 
-   Example 1.45. to_gw usage
+   Example 1.46. to_gw usage
 ...
 if (to_any_gw("192.55.66.2", 1)) {
         ...
@@ -989,7 +1008,7 @@ if (to_any_gw("192.55.66.2", 1)) {
 
    Parameters: none
 
-   Example 1.46. lcr.reload RPC example
+   Example 1.47. lcr.reload RPC example
                 $ sercmd lcr.reload
 
 5.2. lcr.dump_gws
@@ -998,7 +1017,7 @@ if (to_any_gw("192.55.66.2", 1)) {
 
    Parameters: none
 
-   Example 1.47. lcr.dump_gws RPC example
+   Example 1.48. lcr.dump_gws RPC example
                 $ sercmd lcr.dump_gws
 
 5.3. lcr.dump_rules
@@ -1008,7 +1027,7 @@ if (to_any_gw("192.55.66.2", 1)) {
 
    Parameters: none
 
-   Example 1.48. lcr.dump_rules RPC example
+   Example 1.49. lcr.dump_rules RPC example
                 $ sercmd lcr.dump_rules
 
 5.4. lcr.defunct_gw
@@ -1021,7 +1040,7 @@ if (to_any_gw("192.55.66.2", 1)) {
 
    Parameters: lcr_id gw_id period
 
-   Example 1.49. lcr.defunct_gw RPC example
+   Example 1.50. lcr.defunct_gw RPC example
                 $ sercmd lcr.defunct_gw 1 4 120
 
 6. Known Limitations

+ 29 - 7
modules/lcr/doc/lcr_admin.xml

@@ -32,10 +32,11 @@
 	<para>
 	For the purpose of facilitating least cost routing of requests,
 	each gateway of an LCR instance is associated with one or more 
-	&lt;prefix, from pattern, priority, weight&gt;
+	&lt;prefix, from uri pattern, request uri pattern, priority, weight&gt;
 	tuples.  A gateway matches a request if user part of the Request-URI
-	matches a "prefix" and the caller's URI matches a "from" pattern in a
-	tuple that is associated with the gateway.
+	matches a "prefix", the caller's URI matches a "From-URI" pattern and
+	the callee's URI matches a "Request-URI" pattern in a tuple that is
+	associated with the gateway.
 	</para>
 	<para>
 	When the function <emphasis>load_gws()</emphasis> is called,
@@ -45,7 +46,7 @@
 	<para>
 	<itemizedlist>
             <listitem>
-                <para>(1) according to longest user part match
+                <para>(1) according to longest Request-URI user part match
                 </para>
             </listitem>
             <listitem>
@@ -64,10 +65,10 @@
 	with shorter prefixes are not considered.
 	</para>
 	<para>
-	Prefix is a string of characters or NULL.  From
-	pattern is a regular expression (see 'man 
+	Prefix is a string of characters or NULL.  From-URI
+	pattern and Request-URI pattern are regular expressions (see 'man 
 	pcresyntax' for syntax), an empty string, or NULL.  An empty or
-	NULL from pattern or prefix matches anything.
+	NULL From-URI pattern, Request-URI pattern or prefix matches anything.
 	Smaller priority value means higher priority (highest priority
 	value being 0 and lowest being 255).
 	</para>
@@ -535,6 +536,27 @@ modparam("lcr", "from_uri_column", "caller_uri")
 		</example>
 	</section>
 
+	<section>
+		<title><varname>request_uri_column</varname> (string)</title>
+		<para>
+		Name of the column holding the regular expression to match
+		against the complete request URI (including the "sip:" prefix).
+		</para>
+		<para>
+		<emphasis>
+			Default value is <quote>request_uri</quote>.
+		</emphasis>
+		</para>
+		<example>
+		<title>Setting <varname>request_uri_column</varname> module parameter</title>
+		<programlisting format="linespecific">
+...
+modparam("lcr", "request_uri_column", "callee_uri")
+...
+</programlisting>
+		</example>
+	</section>
+
 	<section>
 		<title><varname>stopper_column</varname> (string)</title>
 		<para>

+ 14 - 3
modules/lcr/hash.c

@@ -38,7 +38,9 @@ int rule_hash_table_insert(struct rule_info **hash_table,
 			   unsigned int lcr_id, unsigned int rule_id,
 			   unsigned short prefix_len, char *prefix,
 			   unsigned short from_uri_len, char *from_uri,
-			   pcre *from_uri_re, unsigned short stopper)
+			   pcre *from_uri_re, unsigned short request_uri_len,
+			   char *request_uri, pcre *request_uri_re,
+			   unsigned short stopper)
 {
     struct rule_info *rule;
     str prefix_str;
@@ -48,6 +50,7 @@ int rule_hash_table_insert(struct rule_info **hash_table,
     if (rule == NULL) {
 	LM_ERR("Cannot allocate memory for rule hash table entry\n");
 	if (from_uri_re) shm_free(from_uri_re);
+	if (request_uri_re) shm_free(request_uri_re);
 	return 0;
     }
     memset(rule, 0, sizeof(struct rule_info));
@@ -63,6 +66,12 @@ int rule_hash_table_insert(struct rule_info **hash_table,
 	(rule->from_uri)[from_uri_len] = '\0';
 	rule->from_uri_re = from_uri_re;
     }
+    rule->request_uri_len = request_uri_len;
+    if (request_uri_len) {
+	memcpy(rule->request_uri, request_uri, request_uri_len);
+	(rule->request_uri)[request_uri_len] = '\0';
+	rule->request_uri_re = request_uri_re;
+    }
     rule->stopper = stopper;
     rule->targets = (struct target *)NULL;
 
@@ -73,9 +82,9 @@ int rule_hash_table_insert(struct rule_info **hash_table,
     rule->next = hash_table[hash_val];
     hash_table[hash_val] = rule;
     
-    LM_DBG("inserted rule <%u>, prefix <%.*s>, from_uri <%.*s>, stopper <%u>, "
+    LM_DBG("inserted rule <%u>, prefix <%.*s>, from_uri <%.*s>, request_uri <%.*s>, stopper <%u>, "
 	   "into index <%u>\n",
-	   rule_id, prefix_len, prefix, from_uri_len, from_uri, stopper,
+	   rule_id, prefix_len, prefix, from_uri_len, from_uri, request_uri_len, request_uri, stopper,
 	   hash_val);
 
     return 1;
@@ -177,6 +186,8 @@ void rule_hash_table_contents_free(struct rule_info **hash_table)
 	    if (r->from_uri_re) {
 		shm_free(r->from_uri_re);
 	    }
+	    if (r->request_uri_re)
+		shm_free(r->request_uri_re);
 	    t = r->targets;
 	    while (t) {
 		next_t = t->next;

+ 3 - 1
modules/lcr/hash.h

@@ -36,7 +36,9 @@ int rule_hash_table_insert(struct rule_info **hash_table,
 			   unsigned int lcr_id, unsigned int rule_id,
 			   unsigned short prefix_len, char *prefix,
 			   unsigned short from_uri_len, char *from_uri,
-			   pcre *from_uri_re, unsigned short stopper);
+			   pcre *from_uri_re, unsigned short request_uri_len,
+			   char *request_uri, pcre *request_uri_re,
+			   unsigned short stopper);
 
 int rule_hash_table_insert_target(struct rule_info **hash_table,
 				  struct gw_info *gws,

+ 94 - 44
modules/lcr/lcr_mod.c

@@ -89,7 +89,7 @@ MODULE_VERSION
 /*
  * versions of database tables required by the module.
  */
-#define LCR_RULE_TABLE_VERSION 1
+#define LCR_RULE_TABLE_VERSION 2
 #define LCR_RULE_TARGET_TABLE_VERSION 1
 #define LCR_GW_TABLE_VERSION 2
 
@@ -103,6 +103,7 @@ MODULE_VERSION
 #define LCR_ID_COL "lcr_id"
 #define PREFIX_COL "prefix"
 #define FROM_URI_COL "from_uri"
+#define REQUEST_URI_COL "request_uri"
 #define STOPPER_COL "stopper"
 #define ENABLED_COL "enabled"
 #define RULE_ID_COL "rule_id"
@@ -164,6 +165,7 @@ static str id_col           = str_init(ID_COL);
 static str lcr_id_col       = str_init(LCR_ID_COL);
 static str prefix_col       = str_init(PREFIX_COL);
 static str from_uri_col     = str_init(FROM_URI_COL);
+static str request_uri_col  = str_init(REQUEST_URI_COL);
 static str stopper_col      = str_init(STOPPER_COL);
 static str enabled_col      = str_init(ENABLED_COL);
 static str rule_id_col      = str_init(RULE_ID_COL);
@@ -293,6 +295,7 @@ static param_export_t params[] = {
     {"id_column",                STR_PARAM, &id_col.s},
     {"prefix_column",            STR_PARAM, &prefix_col.s},
     {"from_uri_column",          STR_PARAM, &from_uri_col.s},
+    {"request_uri_column",       STR_PARAM, &request_uri_col.s},
     {"stopper_column",           STR_PARAM, &stopper_col.s},
     {"enabled_column",           STR_PARAM, &enabled_col.s},
     {"rule_id_column",           STR_PARAM, &rule_id_col.s},
@@ -416,6 +419,7 @@ static int mod_init(void)
     lcr_id_col.len = strlen(lcr_id_col.s);
     prefix_col.len = strlen(prefix_col.s);
     from_uri_col.len = strlen(from_uri_col.s);
+    request_uri_col.len = strlen(request_uri_col.s);
     stopper_col.len = strlen(stopper_col.s);
     enabled_col.len = strlen(enabled_col.s);
     rule_id_col.len = strlen(rule_id_col.s);
@@ -1127,18 +1131,19 @@ static int insert_gws(db1_res_t *res, struct gw_info *gws,
  */
 int reload_tables()
 {
-    unsigned int i, n, lcr_id, rule_id, gw_id, from_uri_len, stopper,
-	prefix_len, enabled, gw_cnt, null_gw_ip_addr, priority, weight, tmp;
-    char *prefix, *from_uri;
+    unsigned int i, n, lcr_id, rule_id, gw_id, from_uri_len, request_uri_len,
+	stopper, prefix_len, enabled, gw_cnt, null_gw_ip_addr, priority,
+	weight, tmp;
+    char *prefix, *from_uri, *request_uri;
     db1_res_t* res = NULL;
     db_row_t* row;
     db_key_t key_cols[1];
     db_op_t op[1];
     db_val_t vals[1];
     db_key_t gw_cols[13];
-    db_key_t rule_cols[5];
+    db_key_t rule_cols[6];
     db_key_t target_cols[4];
-    pcre *from_uri_re;
+    pcre *from_uri_re, *request_uri_re;
     struct gw_info *gws, *gw_pt_tmp;
     struct rule_info **rules, **rule_pt_tmp;
 
@@ -1152,6 +1157,7 @@ int reload_tables()
     rule_cols[2] = &from_uri_col;
     rule_cols[3] = &stopper_col;
     rule_cols[4] = &enabled_col;
+    rule_cols[5] = &request_uri_col;
 	
     gw_cols[0] = &gw_name_col;
     gw_cols[1] = &ip_addr_col;
@@ -1172,7 +1178,7 @@ int reload_tables()
     target_cols[2] = &priority_col;
     target_cols[3] = &weight_col;
 
-    from_uri_re = 0;
+    request_uri_re = from_uri_re = 0;
 
     if (lcr_db_init(&db_url) < 0) {
 	LM_ERR("unable to open database connection\n");
@@ -1193,7 +1199,7 @@ int reload_tables()
 
 	VAL_INT(vals) = lcr_id;
 	if (DB_CAPABILITY(lcr_dbf, DB_CAP_FETCH)) {
-	    if (lcr_dbf.query(dbh, key_cols, op, vals, rule_cols, 1, 5, 0, 0)
+	    if (lcr_dbf.query(dbh, key_cols, op, vals, rule_cols, 1, 6, 0, 0)
 		< 0) {
 		LM_ERR("db query on lcr_rule table failed\n");
 		goto err;
@@ -1203,7 +1209,7 @@ int reload_tables()
 		goto err;
 	    }
 	} else {
-	    if (lcr_dbf.query(dbh, key_cols, op, vals, rule_cols, 1, 5, 0, &res)
+	    if (lcr_dbf.query(dbh, key_cols, op, vals, rule_cols, 1, 6, 0, &res)
 		< 0) {
 		LM_ERR("db query on lcr_rule table failed\n");
 		goto err;
@@ -1211,13 +1217,13 @@ int reload_tables()
 	}
 
 	n = 0;
-	from_uri_re = 0;
+	request_uri_re = from_uri_re = 0;
     
 	do {
 	    LM_DBG("loading, cycle %d with <%d> rows", n++, RES_ROW_N(res));
 	    for (i = 0; i < RES_ROW_N(res); i++) {
 
-		from_uri_re = 0;
+		request_uri_re = from_uri_re = 0;
 		row = RES_ROWS(res) + i;
 
 		if ((VAL_NULL(ROW_VALUES(row)) == 1) ||
@@ -1299,9 +1305,37 @@ int reload_tables()
 		    from_uri_re = 0;
 		}
 
+		if (VAL_NULL(ROW_VALUES(row) + 5) == 1) {
+		    request_uri_len = 0;
+		    request_uri = 0;
+		} else {
+		    if (VAL_TYPE(ROW_VALUES(row) + 5) != DB1_STRING) {
+			LM_ERR("lcr rule <%u> request_uri is not string\n",
+			       rule_id);
+			goto err;
+		    }
+		    request_uri = (char *)VAL_STRING(ROW_VALUES(row) + 5);
+		    request_uri_len = strlen(request_uri);
+		}
+		if (request_uri_len > MAX_URI_LEN) {
+		    LM_ERR("lcr rule <%u> request_uri is too long\n", rule_id);
+		    goto err;
+		}
+		if (request_uri_len > 0) {
+		    request_uri_re = reg_ex_comp(request_uri);
+		    if (request_uri_re == 0) {
+			LM_ERR("failed to compile lcr rule <%u> request_uri "
+			       "<%s>\n", rule_id, request_uri);
+			goto err;
+		    }
+		} else {
+		    request_uri_re = 0;
+		}
+
 		if (!rule_hash_table_insert(rules, lcr_id, rule_id, prefix_len,
 					    prefix, from_uri_len, from_uri,
-					    from_uri_re, stopper) ||
+					    from_uri_re, request_uri_len,
+					    request_uri, request_uri_re, stopper) ||
 		    !prefix_len_insert(rules, prefix_len)) {
 		    goto err;
 		}
@@ -1757,7 +1791,7 @@ void add_gws_into_avps(struct gw_info *gws, struct matched_gw_info *matched_gws,
  */
 static int load_gws(struct sip_msg* _m, int argc, action_u_t argv[])
 {
-    str ruri_user, from_uri;
+    str ruri_user, from_uri, *request_uri;
     int i, j, lcr_id;
     unsigned int gw_index, now, dex;
     int_str val;
@@ -1803,6 +1837,8 @@ static int load_gws(struct sip_msg* _m, int argc, action_u_t argv[])
     LM_DBG("load_gws(%u, %.*s, %.*s)\n", lcr_id, ruri_user.len, ruri_user.s,
 	   from_uri.len, from_uri.s);
 
+    request_uri = GET_RURI(_m);
+
     /* Use rules and gws with index lcr_id */
     rules = rule_pt[lcr_id];
     gws = gw_pt[lcr_id];
@@ -1831,38 +1867,52 @@ static int load_gws(struct sip_msg* _m, int argc, action_u_t argv[])
 	rule = rule_hash_table_lookup(rules, pl->prefix_len, ruri_user.s);
 	while (rule) {
 	    /* Match prefix */
-	    if ((rule->prefix_len == pl->prefix_len) && 
-		(strncmp(rule->prefix, ruri_user.s, pl->prefix_len) == 0)) {
-		/* Match from uri */
-		if ((rule->from_uri_len == 0) ||
-		    (pcre_exec(rule->from_uri_re, NULL, from_uri.s,
-			       from_uri.len, 0, 0, NULL, 0) >= 0)) {
-		    /* Load gws associated with this rule */
-		    t = rule->targets;
-		    while (t) {
-                        /* If this gw is defunct, skip it */
-		        if (gws[t->gw_index].defunct_until > now) goto skip_gw;
-			matched_gws[gw_index].gw_index = t->gw_index;
-			matched_gws[gw_index].prefix_len = pl->prefix_len;
-			matched_gws[gw_index].priority = t->priority;
-			matched_gws[gw_index].weight = t->weight *
-			    (rand() >> 8);
-			matched_gws[gw_index].duplicate = 0;
-			LM_DBG("added matched_gws[%d]=[%u, %u, %u, %u]\n",
-			       gw_index, t->gw_index, pl->prefix_len,
-			       t->priority, matched_gws[gw_index].weight);
-			gw_index++;
-		    skip_gw:
-			t = t->next;
-		    }
-		    /* Do not look further if this matching rule was stopper */
-		    if (rule->stopper == 1) goto done;
-		} else {
-		    LM_DBG("from uri <%.*s> did not match to from regex <%.*s>",
-			   from_uri.len, from_uri.s, rule->from_uri_len,
-			   rule->from_uri);
-		}
+	    if ((rule->prefix_len != pl->prefix_len) ||
+		(strncmp(rule->prefix, ruri_user.s, pl->prefix_len)))
+		    goto next;
+
+	    /* Match from uri */
+	    if ((rule->from_uri_len != 0) &&
+		(pcre_exec(rule->from_uri_re, NULL, from_uri.s,
+			   from_uri.len, 0, 0, NULL, 0) < 0)) {
+		LM_DBG("from uri <%.*s> did not match to from regex <%.*s>",
+		       from_uri.len, from_uri.s, rule->from_uri_len,
+		       rule->from_uri);
+		goto next;
 	    }
+
+	    /* Match request uri */
+	    if ((rule->request_uri_len != 0) &&
+		(pcre_exec(rule->request_uri_re, NULL, request_uri->s,
+			   request_uri->len, 0, 0, NULL, 0) < 0)) {
+		LM_DBG("request uri <%.*s> did not match to request regex <%.*s>",
+		       request_uri->len, request_uri->s, rule->request_uri_len,
+		       rule->request_uri);
+		goto next;
+	    }
+
+	    /* Load gws associated with this rule */
+	    t = rule->targets;
+	    while (t) {
+		/* If this gw is defunct, skip it */
+		if (gws[t->gw_index].defunct_until > now) goto skip_gw;
+		matched_gws[gw_index].gw_index = t->gw_index;
+		matched_gws[gw_index].prefix_len = pl->prefix_len;
+		matched_gws[gw_index].priority = t->priority;
+		matched_gws[gw_index].weight = t->weight *
+		    (rand() >> 8);
+		matched_gws[gw_index].duplicate = 0;
+		LM_DBG("added matched_gws[%d]=[%u, %u, %u, %u]\n",
+		       gw_index, t->gw_index, pl->prefix_len,
+		       t->priority, matched_gws[gw_index].weight);
+		gw_index++;
+	    skip_gw:
+		t = t->next;
+	    }
+	    /* Do not look further if this matching rule was stopper */
+	    if (rule->stopper == 1) goto done;
+
+next:
 	    rule = rule->next;
 	}
 	pl = pl->next;

+ 3 - 0
modules/lcr/lcr_mod.h

@@ -62,6 +62,9 @@ struct rule_info {
     char from_uri[MAX_URI_LEN + 1];
     unsigned short from_uri_len;
     pcre *from_uri_re;
+    char request_uri[MAX_URI_LEN + 1];
+    unsigned short request_uri_len;
+    pcre *request_uri_re;
     unsigned short stopper;
     unsigned int enabled;
     struct target *targets;

+ 5 - 2
modules/lcr/lcr_rpc.c

@@ -160,7 +160,7 @@ static void dump_rules(rpc_t* rpc, void* c)
     struct rule_info **rules, *rule;
     struct target *t;
     void* st;
-    str prefix, from_uri;
+    str prefix, from_uri, request_uri;
 
     for (j = 1; j <= lcr_count_param; j++) {
 	    
@@ -174,11 +174,14 @@ static void dump_rules(rpc_t* rpc, void* c)
 		prefix.len=rule->prefix_len;
 		from_uri.s=rule->from_uri;
 		from_uri.len=rule->from_uri_len;
-		rpc->struct_add(st, "ddSSd",
+		request_uri.s=rule->request_uri;
+		request_uri.len=rule->request_uri_len;
+		rpc->struct_add(st, "ddSSSd",
 				"lcr_id", j,
 				"rule_id", rule->rule_id,
 				"prefix", &prefix,
 				"from_uri", &from_uri,
+				"request_uri", &request_uri,
 				"stopper", rule->stopper
 				);
 		t = rule->targets;

+ 2 - 2
utils/kamctl/db_berkeley/kamailio/lcr_rule

@@ -1,5 +1,5 @@
 METADATA_COLUMNS
-id(int) lcr_id(int) prefix(str) from_uri(str) stopper(int) enabled(int)
+id(int) lcr_id(int) prefix(str) request_uri(str) from_uri(str) stopper(int) enabled(int)
 METADATA_KEY
 2 
 METADATA_READONLY
@@ -7,4 +7,4 @@ METADATA_READONLY
 METADATA_LOGFLAGS
 0
 METADATA_DEFAULTS
-NIL|NIL|NULL|NULL|0|1
+NIL|NIL|NULL|NULL|NULL|0|1

+ 1 - 1
utils/kamctl/db_berkeley/kamailio/version

@@ -63,7 +63,7 @@ imc_rooms|1
 lcr_gw|
 lcr_gw|2
 lcr_rule|
-lcr_rule|1
+lcr_rule|2
 lcr_rule_target|
 lcr_rule_target|1
 location|

+ 3 - 2
utils/kamctl/db_sqlite/lcr-create.sql

@@ -31,14 +31,15 @@ CREATE TABLE lcr_rule_target (
 
 CREATE INDEX lcr_rule_target_lcr_id_idx ON lcr_rule_target (lcr_id);
 
-INSERT INTO version (table_name, table_version) values ('lcr_rule','1');
+INSERT INTO version (table_name, table_version) values ('lcr_rule','2');
 CREATE TABLE lcr_rule (
     id INTEGER PRIMARY KEY NOT NULL,
     lcr_id SMALLINT NOT NULL,
     prefix VARCHAR(16) DEFAULT NULL,
+    request_uri VARCHAR(64) DEFAULT NULL,
     from_uri VARCHAR(64) DEFAULT NULL,
     stopper INTEGER DEFAULT 0 NOT NULL,
     enabled INTEGER DEFAULT 1 NOT NULL,
-    CONSTRAINT lcr_rule_lcr_id_prefix_from_uri_idx UNIQUE (lcr_id, prefix, from_uri)
+    CONSTRAINT lcr_rule_lcr_id_prefix_from_uri_idx UNIQUE (lcr_id, prefix, request_uri, from_uri)
 );
 

+ 1 - 1
utils/kamctl/dbtext/kamailio/lcr_rule

@@ -1 +1 @@
-id(int,auto) lcr_id(int) prefix(string,null) from_uri(string,null) stopper(int) enabled(int) 
+id(int,auto) lcr_id(int) prefix(string,null) request_uri(string,null) from_uri(string,null) stopper(int) enabled(int) 

+ 1 - 1
utils/kamctl/dbtext/kamailio/version

@@ -26,7 +26,7 @@ htable:2
 imc_members:1
 imc_rooms:1
 lcr_gw:2
-lcr_rule:1
+lcr_rule:2
 lcr_rule_target:1
 location:5
 matrix:1

+ 3 - 2
utils/kamctl/mysql/lcr-create.sql

@@ -31,14 +31,15 @@ CREATE TABLE lcr_rule_target (
 
 CREATE INDEX lcr_id_idx ON lcr_rule_target (lcr_id);
 
-INSERT INTO version (table_name, table_version) values ('lcr_rule','1');
+INSERT INTO version (table_name, table_version) values ('lcr_rule','2');
 CREATE TABLE lcr_rule (
     id INT(10) UNSIGNED AUTO_INCREMENT PRIMARY KEY NOT NULL,
     lcr_id SMALLINT UNSIGNED NOT NULL,
     prefix VARCHAR(16) DEFAULT NULL,
+    request_uri VARCHAR(64) DEFAULT NULL,
     from_uri VARCHAR(64) DEFAULT NULL,
     stopper INT UNSIGNED DEFAULT 0 NOT NULL,
     enabled INT UNSIGNED DEFAULT 1 NOT NULL,
-    CONSTRAINT lcr_id_prefix_from_uri_idx UNIQUE (lcr_id, prefix, from_uri)
+    CONSTRAINT lcr_id_prefix_from_uri_idx UNIQUE (lcr_id, prefix, request_uri, from_uri)
 ) ENGINE=MyISAM;
 

+ 3 - 2
utils/kamctl/oracle/lcr-create.sql

@@ -47,15 +47,16 @@ BEGIN map2users('lcr_rule_target'); END;
 /
 CREATE INDEX lcr_rule_target_lcr_id_idx  ON lcr_rule_target (lcr_id);
 
-INSERT INTO version (table_name, table_version) values ('lcr_rule','1');
+INSERT INTO version (table_name, table_version) values ('lcr_rule','2');
 CREATE TABLE lcr_rule (
     id NUMBER(10) PRIMARY KEY,
     lcr_id NUMBER(5),
     prefix VARCHAR2(16) DEFAULT NULL,
+    request_uri VARCHAR2(64) DEFAULT NULL,
     from_uri VARCHAR2(64) DEFAULT NULL,
     stopper NUMBER(10) DEFAULT 0 NOT NULL,
     enabled NUMBER(10) DEFAULT 1 NOT NULL,
-    CONSTRAINT ORA_lcr_id_prefix_from_uri_idx  UNIQUE (lcr_id, prefix, from_uri)
+    CONSTRAINT ORA_lcr_id_prefix_from_uri_idx  UNIQUE (lcr_id, prefix, request_uri, from_uri)
 );
 
 CREATE OR REPLACE TRIGGER lcr_rule_tr

+ 3 - 2
utils/kamctl/postgres/lcr-create.sql

@@ -31,14 +31,15 @@ CREATE TABLE lcr_rule_target (
 
 CREATE INDEX lcr_rule_target_lcr_id_idx ON lcr_rule_target (lcr_id);
 
-INSERT INTO version (table_name, table_version) values ('lcr_rule','1');
+INSERT INTO version (table_name, table_version) values ('lcr_rule','2');
 CREATE TABLE lcr_rule (
     id SERIAL PRIMARY KEY NOT NULL,
     lcr_id SMALLINT NOT NULL,
     prefix VARCHAR(16) DEFAULT NULL,
+    request_uri VARCHAR(64) DEFAULT NULL,
     from_uri VARCHAR(64) DEFAULT NULL,
     stopper INTEGER DEFAULT 0 NOT NULL,
     enabled INTEGER DEFAULT 1 NOT NULL,
-    CONSTRAINT lcr_rule_lcr_id_prefix_from_uri_idx UNIQUE (lcr_id, prefix, from_uri)
+    CONSTRAINT lcr_rule_lcr_id_prefix_from_uri_idx UNIQUE (lcr_id, prefix, request_uri, from_uri)
 );