LCR (Least Cost Routing) Module

Juha Heinanen

   <jh@tutpro.com>

Edited by

Juha Heinanen

   <jh@tutpro.com>

   Copyright © 2005-2007 Juha Heinanen
   Revision History
   Revision $Revision: 5906 $ $Date: 2009-07-21 10:45:05 +0300
                              (Tue, 21 Jul 2009) $
     __________________________________________________________

   Table of Contents

   1. Admin Guide

        1.1. Overview
        1.2. Dependencies

              1.2.1. OpenSIPS modules
              1.2.2. External libraries or applications

        1.3. Exported Parameters

              1.3.1. db_url (string)
              1.3.2. gw_table (string)
              1.3.3. gw_name_column (string)
              1.3.4. grp_id_column (string)
              1.3.5. ip_addr_column (string)
              1.3.6. port_column (string)
              1.3.7. uri_scheme_column (string)
              1.3.8. transport_column (string)
              1.3.9. strip_column (string)
              1.3.10. tag_column (string)
              1.3.11. flags_column (string)
              1.3.12. lcr_table (string)
              1.3.13. prefix_column (string)
              1.3.14. from_uri_column (string)
              1.3.15. priority_column (string)
              1.3.16. contact_avp (AVP string)
              1.3.17. fr_inv_timer_avp (AVP string)
              1.3.18. gw_uri_avp (AVP string)
              1.3.19. rpid_avp (AVP string)
              1.3.20. ruri_user_avp (AVP string)
              1.3.21. fr_inv_timer (integer)
              1.3.22. fr_inv_timer_next (integer)
              1.3.23. flags_avp (AVP string)
              1.3.24. prefix_mode (integer)

        1.4. Exported Functions

              1.4.1. load_gws([pvar])
              1.4.2. load_gws_from_grp(group-id)
              1.4.3. next_gw()
              1.4.4. from_gw([pvar])
              1.4.5. from_gw_grp(group-id)
              1.4.6. to_gw([group-id])
              1.4.7. load_contacts()
              1.4.8. next_contacts()

        1.5. Exported MI Commands

              1.5.1. lcr_reload
              1.5.2. lcr_dump

        1.6. Known Limitations

   List of Examples

   1.1. Setting db_url module parameter
   1.2. Setting gw_table module parameter
   1.3. Setting gw_name_column module parameter
   1.4. Setting grp_id_column module parameter
   1.5. Setting ip_addr_column module parameter
   1.6. Setting port_column module parameter
   1.7. Setting uri_scheme_column module parameter
   1.8. Setting transport_column module parameter
   1.9. Setting strip_column module parameter
   1.10. Setting tag_column module parameter
   1.11. Setting flags_column module parameter
   1.12. Setting lcr_table module parameter
   1.13. Setting prefix_column module parameter
   1.14. Setting from_uri_column module parameter
   1.15. Setting priority_column module parameter
   1.16. Setting contact_avp module parameter
   1.17. Setting fr_inv_timer_avp module parameter
   1.18. Setting gw_uri_avp module parameter
   1.19. Setting rpid_avp module parameter
   1.20. Setting ruri_user_avp module parameter
   1.21. Setting fr_inv_timer module parameter
   1.22. Setting fr_inv_timer_next module parameter
   1.23. Setting flags_avp module parameter
   1.24. Setting prefix_mode module parameter
   1.25. load_gws usage
   1.26. load_gws_from_grp usage
   1.27. next_gw usage from a route block
   1.28. next_gw usage from a failure route block
   1.29. from_gw usage
   1.30. from_gw usage with pseudo variable argument
   1.31. from_gw_grp usage
   1.32. to_gw usage
   1.33. to_gw usage with group-id
   1.34. load_contacts usage
   1.35. next_contacts usage from route block
   1.36. next_contacts usage from failure route block

Chapter 1. Admin Guide

1.1. Overview

   Least cost routing (LCR) module implements two vaguely related
   capabilities:

     * sequential forwarding of a request to one or more gateways
       (functions load_gws and next_gw)
     * sequential forwarding to contacts according to their q
       value (functions load_contacts and next_contacts).

   For the purpose of facilitating least cost routing of requests,
   each gateway belongs to a gateway group and each gateway group
   is associated with one or more <prefix, from pattern, priority>
   tuples. A gateway matches a request if user part of Request URI
   matches a prefix and caller's URI matches a from pattern in a
   tuple that belongs to the group of the gateway.

   Matching gateways are then ordered for forwarding purpose (1)
   according to longest user part match, (2) according to tuple's
   priority, and (3) randomly (prefix_mode = 0) or (1) according
   to gateway's priority and (2) randomly (prefix_mode = 1). In
   prefix_mode 0, prefix is a string of characters and in
   prefix_mode 1, prefix is a regular expression. From pattern is
   always a regular expression or empty. Empty from pattern
   matches anything. Smaller priority value means higher priority
   (highest priority value being 0).

   When a gateway is selected, Request URI user part is stripped
   by the number of characters as specified by the gateways strip
   count. Subsequently, Request URI is rewritten based on
   gateway's URI scheme, tag, IP address, port, and transport
   protocol. Valid URI scheme values are NULL = sip, 1 = sip and 2
   = sips. Tag is inserted in front of Request URI user part.
   Currently valid transport protocol values are NULL = none, 1 =
   udp, 2 = tcp, and 3 = tls.

   As a side effect of gateway selection, gateway's flags (that
   may contain information about capabilities of the gateway) are
   stored into an AVP.

1.2. Dependencies

1.2.1. OpenSIPS modules

   The following modules must be loaded before this module:
     * TM module
     * A database module like mysql, postgres or dbtext.

1.2.2. External libraries or applications

   The following libraries or applications must be installed
   before running OpenSIPS with this module:
     * none.

1.3. Exported Parameters

1.3.1. db_url (string)

   URL of the database table to be used.

   Default value is
   "mysql://opensipsro:opensipsro@localhost/opensips".

   Example 1.1. Setting db_url module parameter
...
modparam("lcr","db_url","dbdriver://username:password@dbhost/dbname")
...

1.3.2. gw_table (string)

   Name of the table holding the gateways definitions.

   Default value is "gw".

   Example 1.2. Setting gw_table module parameter
...
modparam("lcr","gw_table","gw")
...

1.3.3. gw_name_column (string)

   Name of the column holding the gateway name.

   Default value is "gw_name".

   Example 1.3. Setting gw_name_column module parameter
...
modparam("lcr","gw_name_column","gw_name")
...

1.3.4. grp_id_column (string)

   Name of the column holding the group ID of gateway both in gw
   and lcr tables.

   Default value is "grp_id".

   Example 1.4. Setting grp_id_column module parameter
...
modparam("lcr","grp_id_column","grp_id")
...

1.3.5. ip_addr_column (string)

   Name of the column holding the IP address of the gateway.

   Default value is "ip_addr".

   Example 1.5. Setting ip_addr_column module parameter
...
modparam("lcr","ip_addr_column","ip_addr")
...

1.3.6. port_column (string)

   Name of the column holding the port number of the gateway.

   Default value is "port".

   Example 1.6. Setting port_column module parameter
...
modparam("lcr","port_column","port")
...

1.3.7. uri_scheme_column (string)

   Name of the column holding the uri scheme of the gateway.

   Default value is "uri_scheme".

   Example 1.7. Setting uri_scheme_column module parameter
...
modparam("lcr","uri_scheme_column","scheme")
...

1.3.8. transport_column (string)

   Name of the column holding the transport type to be used for
   the gateway.

   Default value is "transport".

   Example 1.8. Setting transport_column module parameter
...
modparam("lcr","transport_column","transport")
...

1.3.9. strip_column (string)

   Name of the column holding the number of characters to be
   stripped from the front of Request URI user part before
   inserting tag.

   Default value is "strip".

   Example 1.9. Setting strip_column module parameter
...
modparam("lcr","strip_column","strip_count")
...

1.3.10. tag_column (string)

   Name of the column holding gateway specific tag string.

   Default value is "tag".

   Example 1.10. Setting tag_column module parameter
...
modparam("lcr","tag_column","gw_tag")
...

1.3.11. flags_column (string)

   Name of the column holding gateway specific flag values.

   Default value is "flags".

   Example 1.11. Setting flags_column module parameter
...
modparam("lcr","flags_column","gw_flags")
...

1.3.12. lcr_table (string)

   Name of the table holding the LCR rules.

   Default value is "lcr".

   Example 1.12. Setting lcr_table module parameter
...
modparam("lcr","lcr_table","lcr")
...

1.3.13. prefix_column (string)

   Name of the column holding prefix of Request URI user part.

   Default value is "prefix".

   Example 1.13. Setting prefix_column module parameter
...
modparam("lcr","prefix_column","prefix")
...

1.3.14. from_uri_column (string)

   Name of the column holding the FROM (source) URI.

   Default value is "from_uri".

   Example 1.14. Setting from_uri_column module parameter
...
modparam("lcr","from_uri_column","from_uri")
...

1.3.15. priority_column (string)

   Name of the column holding the priority of the rule.

   Default value is "priority".

   Example 1.15. Setting priority_column module parameter
...
modparam("lcr","priority_column","priority")
...

1.3.16. contact_avp (AVP string)

   Internal AVP that load_contacts function uses to store contacts
   of the destination set.

   There is NO default value, thus this variable must be defined
   in opensips.cfg.

   Example 1.16. Setting contact_avp module parameter
...
modparam("lcr", "contact_avp", "$avp(i:711)")
...

1.3.17. fr_inv_timer_avp (AVP string)

   An AVP that contains a final response timeout for INVITEs. Its
   value must be the same as that of the corresponding tm module
   parameter.

   There is NO default value, thus this variable must be defined
   in opensips.cfg.

   Example 1.17. Setting fr_inv_timer_avp module parameter
...
modparam("lcr|tm", "fr_inv_timer_avp", "$avp(i:704)")
...

1.3.18. gw_uri_avp (AVP string)

   Internal AVP that load_gws function uses to store information
   of matching gateways.

   There is NO default value, thus this variable must be defined
   in opensips.cfg.

   Example 1.18. Setting gw_uri_avp module parameter
...
modparam("lcr", "gw_uri_avp", "$avp(i:709)")
...

1.3.19. rpid_avp (AVP string)

   An AVP that contains caller's RPID (if any).

   There is NO default value, thus this variable must be defined
   in opensips.cfg.

   Example 1.19. Setting rpid_avp module parameter
...
modparam("^auth$|lcr", "rpid_avp", "$avp(i:302)")
...

1.3.20. ruri_user_avp (AVP string)

   Internal AVP that next_gw function uses to store Request-URI
   user for subsequent next_gw calls.

   There is NO default value, thus this variable must be defined
   in opensips.cfg.

   Example 1.20. Setting ruri_user_avp module parameter
...
modparam("lcr", "ruri_user_avp", "$avp(i:500)")
...

1.3.21. fr_inv_timer (integer)

   Sets the value of the fist INVITE's Final Response timeout to
   be used during sequential forwarding:

   Default value is 90.

   Example 1.21. Setting fr_inv_timer module parameter
...
modparam("lcr","fr_inv_timer",90)
...

1.3.22. fr_inv_timer_next (integer)

   Sets the value of the next INVITE's Final Response timeouts to
   be used during sequential forwarding:

   Function next_contacts() sets tm fr_inv_timer to
   fr_inv_timer_next value if, after next contacts, there are
   still lower qvalue contacts available, and to fr_inv_timer
   value if next contacts are the last ones left.

   Default value is 30.

   Example 1.22. Setting fr_inv_timer_next module parameter
...
modparam("lcr","fr_inv_timer_next",30)
...

1.3.23. flags_avp (AVP string)

   An AVP where successful next_gw and from_gw functions store
   gateway's flags.

   There is NO default value, thus this variable must be defined
   in opensips.cfg.

   Example 1.23. Setting flags_avp module parameter
...
modparam("lcr", "flags_avp", "$avp(i:712)")
...

1.3.24. prefix_mode (integer)

   Defines the prefix mode: string or regular expression. When set
   to 0, the prefix mode is set to string and matching is
   implemented as a simple string comparison. When set to 1, the
   prefix mode is set to regex and matching is implemented as
   regular expression match.

   Default value is 0.

   Example 1.24. Setting prefix_mode module parameter
...
/* Turning on the regex mode for prefix */
modparam("lcr", "prefix_mode", 1)
...

1.4. Exported Functions

1.4.1.  load_gws([pvar])

   Loads URI schemes, addresses, ports, and transports of matching
   gateways to gw_uri_avp AVPs (see Overview section). If optional
   pseudo variable argument is included, caller's URI is taken
   from it. If pseudo variable argument is not included, caller's
   URI is taken from rpid_avp AVP or, if rpid_avp value is empty,
   from From URI. Returns 1 or -1 depending on success.

   This function can be used from REQUEST_ROUTE.

   Example 1.25. load_gws usage
...
if (!load_gws("$var(caller_uri)")) {
        sl_send_reply("500", "Server Internal Error - Cannot load gatewa
ys");
        exit;
};
...

1.4.2.  load_gws_from_grp(group-id)

   Loads URI schemes, addresses, ports, and transports of matching
   gateways to gw_uri_avp AVPs (see Overview section), but only
   gateways belonging to the group given in group-id argument are
   loaded. group-id argument is a string and may contain
   pseudo-variables that are replaced at runtime. Caller's URI is
   taken from rpid_avp AVP or, if rpid_avp value is empty, from
   From URI. Returns 1 or -1 depending on success.

   This function can be used from REQUEST_ROUTE.

   Example 1.26. load_gws_from_grp usage
...
if (!load_gws_from_grp("1")) {
        sl_send_reply("500", "Server Internal Error - Cannot load gatewa
ys from group 1");
        exit;
};
...

if (!load_gws_from_grp("$avp(s:gateway_group)")) {
        sl_send_reply("500", "Server Internal Error - Cannot load gatewa
ys");
        exit;
};
...

1.4.3.  next_gw()

   Replaces URI scheme, host, port, and transport of Request-URI
   by the values stored in first gw_uri_avp AVP and destroys that
   AVP. If called first time, it also saves the user part of
   Request-URI into ruri_user_avp AVP for use in subsequent
   next_gw() calls.

   As a side effect, stores gateway's flags to flags_avp.

   Returns 1 on success and -1 if there were no gateways left or
   if an error occurred (see syslog).

   Must be preceded by successful load_gws() call.

   This function can be used from REQUEST_ROUTE, FAILURE_ROUTE.

   Example 1.27. next_gw usage from a route block
...
if (!next_gw()) {
        sl_send_reply("503", "Service not available - No gateways");
        exit;
};
...

   Example 1.28. next_gw usage from a failure route block
...
if (!next_gw()) {
        t_reply("503", "Service not available - No more gateways");
        exit;
};
...

1.4.4.  from_gw([pvar])

   Checks if request came from IP address of a gateway. IP address
   to be checked is either taken from source IP address of the
   request or (if present) from pseudo variable argument. As a
   side effect, stores gateway's flags to flags_avp.

   This function can be used from REQUEST_ROUTE, FAILURE_ROUTE,
   ONREPLY_ROUTE.

   Example 1.29. from_gw usage
...
if (from_gw()) {
        ...
};
...

   Example 1.30. from_gw usage with pseudo variable argument
...
if (from_gw("$si")) {
        ...
};
...

1.4.5.  from_gw_grp(group-id)

   Checks if request came from IP address of a gateway that
   belongs to the given group. Sets or resets a message flag
   depending on whether the gateway supports directed media.

   This function can be used from REQUEST_ROUTE, FAILURE_ROUTE,
   ONREPLY_ROUTE.

   Example 1.31. from_gw_grp usage
...
if (from_gw_grp("1")) {
        ...
};
...

1.4.6.  to_gw([group-id])

   Checks if in-dialog request goes to a gateway. If an optional
   group-id is given, only gateways belonging to this group are
   checked.

   This function can be used from REQUEST_ROUTE, FAILURE_ROUTE.

   Example 1.32. to_gw usage
...
if (to_gw()) {
        ...
        exit;
};
...

   Example 1.33. to_gw usage with group-id
...
if (to_gw("1")) {
        ...
        exit;
};
...

1.4.7.  load_contacts()

   Loads contacts in destination set in increasing qvalue order as
   values of lcr_contact AVP. If all contacts in the destination
   set have the same qvalue, load_contacts() does not do anything
   thus minimizing performance impact of sequential forking
   capability when it is not needed. Returns 1 if loading of
   contacts succeeded or there was nothing to do. Returns -1 on
   error (see syslog).

   This function can be used from REQUEST_ROUTE.

   Example 1.34. load_contacts usage
...
if (!load_contacts()) {
        sl_send_reply("500", "Server Internal Error - Cannot load contac
ts");
        exit;
};
...

1.4.8.  next_contacts()

   If called from a route block, replaces Request-URI with the
   first lcr_contact AVP value, adds the remaining lcr_contact AVP
   values with the same qvalue as branches, and destroys those
   AVPs. It does nothing if there are no lcr_contact AVPs. Returns
   1 if there were no errors and -1 if an error occurred (see
   syslog).

   If called from a failure route block, adds the first
   lcr_contact AVP value and all following lcr_contact AVP values
   with the same qvalue as new branches to request and destroys
   those AVPs. Returns 1 if new branches were successfully added
   and -1 on error (see syslog) or if there were no more
   lcr_contact AVPs.

   Must be preceded by successful load_contacts() call.

   This function can be used from REQUEST_ROUTE, FAILURE_ROUTE.

   Example 1.35. next_contacts usage from route block
...
if (!next_contacts()) {
        sl_send_reply("500", "Server Internal Error");
        exit;
} else {
        t_relay();
};
...

   Example 1.36. next_contacts usage from failure route block
if (next_contacts()) {
        t_relay();
};

1.5. Exported MI Commands

1.5.1. lcr_reload

   Causes lcr module to re-read the contents of gateway table into
   memory.

   Name: lcr_reload

   Parameters: none

   MI FIFO Command Format:
                :lcr_reload:_reply_fifo_file_
                _empty_line_

1.5.2. lcr_dump

   Causes lcr module to dump the contents of its in-memory gateway
   table.

   Name: lcr_dump

   Parameters: none

   MI FIFO Command Format:
                :lcr_dump:_reply_fifo_file_
                _empty_line_

1.6. Known Limitations

   There is an unlikely race condition on lcr reload. If a process
   uses in memory gw table, which is reloaded at the same time
   twice through FIFO, the second reload will delete the original
   table still in use by the process.
