modules_s/lcr/README
32076aef
 
 Least Cost Routing Module
 
 Juha Heinanen
 
 Edited by
 
 Juha Heinanen
 
    Copyright � 2005 Juha Heinanen
      _________________________________________________________
 
    Table of Contents
 
    1. User's Guide
 
         1.1. Overview
         1.2. Dependencies
         1.3. Exported Parameters
         1.4. Exported Functions
         1.5. FIFO Commands
         1.6. Known Limitations
 
    2. TODO
      _________________________________________________________
 
 Chapter 1. User's Guide
 
 1.1. Overview
 
    Least cost routing (LCR) module implements two related capabilities:
 
    (1) sequential forwarding of a request to one or more gateways
        (functions load_gws and next_gw),
 
    (2) sequential forwarding to contacts if they don't share the
        the same qvalue (functions load_contacts and next_contacts).
 
    Gateway selection is based on caller's RPID URI (if available in
    caller's RPID AVP after authentication) or From URI and user part of
    Request-URI (telephone number).  Gateway patterns matching RPID or
    From URI and telephone number are ordered for forwarding purpose (1)
    according to longest user part match, (2) according to priority, and
    (3) randomly.
 
    Each gateway belongs to a gateway group either alone or among other
    gateways.  All gateways in a group share the same priority.
 
    Gateway and routing information is kept in two tables:  gw and lcr.
 
    When a gateway is selected, Request-URI is rewritten with information
    from gw table: URI scheme, prefix, IP address, port, and transport
    protocol.  Valid URI scheme values are NULL = sip, 1 = sip and 2 =
    sips.  Prefix is appended in front of Request-URI user part.
    Currently valid transport protocol values are NULL = none, 1 = udp, 2
    = tcp, and 3 = tls.
 
    Table lcr contains prefix of user part of Request-URI, From URI,
    gateway group id, and priority.  From URI can contain special
    characters % and _ matching any number of any characters and any one
    character, respectively.  
 
    In addition to gw and lcr tables there is third table gw_grp that is
    used for administrative purposes only to associate names with gateway
    group ids.
    _________________________________________________________
 
 1.2. Dependencies
 
    The module depends on the following modules (in the other
    words the listed modules must be loaded before this module):
 
      * tm module
      * mysql module
      _________________________________________________________
 
 1.3. Exported Parameters
 
    LCR module exports the following database related parameters that
    have usual purpose:
 
      * db_url (default system default)
      * gw_table (default "gw")
      * gw_name_column (default "gw_name")
      * ip_addr_column (default "ip_addr")
      * port_column (default "port")
      * uri_scheme_column (default "uri_scheme")
      * transport_column (default "transport")
      * grp_id_column (default "grp_id")
      * lcr_table (default "lcr")
      * prefix_column (default "prefix")
      * from_uri_column (default "from_uri")
      * priority_column (default "priority")
 
    In addition there are parameters that can be used to override names
    of the AVPs used by LCR module:
 
      * gw_uri_avp	  (default "1400")
      * contact_avp	  (default "1401")
      * fr_inv_timer_avp	  (default "fr_inv_timer_avp")
      * rpid_avp		  (default "rpid")
 
    If string value of an AVP parameter contains only digits, the name of
    the AVP is int value of the string.
 
    Finally, the parameters used by sequential forwarding:
 
      * fr_inv_timer		(default 90)
      * fr_inv_timer_next	(default 30)
      * fr_inv_timer_param	(default "")
      * fr_inv_timer_next_param	(default "")
 
    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. fr_inv_timer_param can define an AVP
    overwriting fr_inv_timer value, and similarly, AVP defined by
    fr_inv_timer_next_param can overwrite fr_inv_timer_next value.
     _________________________________________________________
 
 1.4. Exported Functions
 
 1.4.1. load_gws()
 
    Loads URIs of gateways matching RPID AVP (if available) or From URI
    and user part of Request-URI to gw_uri_avp AVPs.  Returns 1 or -1
    depending on success.
 
    Example:
 
    if (!load_gws()) {
       sl_send_reply("500", "Server Internal Error - Cannot load gateways");
       break;
    };
 
 1.4.2. next_gw()
 
    If called from a route block, replaces Request-URI by the first
    gw_uri_avp AVP value and destroys that AVP.
 
    If called from a failure route block, appends a new branch to request,
    whose Request-URI is the first gw_uri_avp AVP value, and destroys that
    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.
 
    Example from route block:
    
    if (!next_gw()) {
       sl_send_reply("503", "Service not available - No gateways");
       break;
     };
 
    Example from failure route block:
 
    if (!next_gw()) {
       t_reply("503", "Service not available - No more gateways");
       break;	     
     };
 
 1.4.3. from_gw()
 
    Checks if request came from IP address of a gateway.
 
    Example:
    
    if (from_gw()) {
       ...
       break;
    };
 
 1.4.4. to_gw()
 
    Checks if in-dialog request goes to a gateway.
 
    Example:
    
    if (to_gw()) {
       ...
       break;
    };
 
 1.4.5. 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).
 
    Example:
 
    if (!load_contacts()) {
       sl_send_reply("500", "Server Internal Error - Cannot load contacts");
       break;
    };
 
 1.4.6. 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.
 
    Example from route block:
    
    if (!next_contacts()) {
        sl_send_reply("500", "Server Internal Error");
         break;
    } else {
       t_relay();
    };
 
    Example from failure route block:
    
    if (next_contacts()) {
        t_relay();
    };
 
 
 1.5. FIFO Commands
 
 1.5.1. lcr_reload
 
    Causes lcr module to re-read the contents of gateway table
    into memory.
 
 1.5.2. lcr_dump
 
    Causes lcr module to dump the contents of its in-memory gateway
    table. 
 
 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.
    _________________________________________________________
 
 2.0. TODO
 
    Function load_gws() currently makes an SQL query for the matching
    gateways.  In order to avoid the query, also lcr table should be
    read into memory and the corresponding query should be rewritten in
    C.