Dynamic Routing Module

   Voice Sistem SRL

Edited by

Ovidiu Sas

Edited by

Anca-Maria Vamanu

   Copyright © 2005-2008 Voice Sistem SRL
     __________________________________________________________________

   Table of Contents

   1. Admin Guide

        1. Overview

              1.1. Introduction
              1.2. Features
              1.3. Performance
              1.4. Routing Rule Definition

                    1.4.1. Gateway Addresses
                    1.4.2. Destination/GW lists
                    1.4.3. Routing Rules

              1.5. Routing Rule Processing

        2. Dependencies

              2.1. Kamailio Modules
              2.2. External Libraries or Applications

        3. Parameters

              3.1. db_url(str)
              3.2. drd_table(str)
              3.3. drr_table(str)
              3.4. drg_table(str)
              3.5. drl_table(str)
              3.6. sort_order (int)
              3.7. ruri_avp (str)
              3.8. attrs_avp (str)
              3.9. use_domain (int)
              3.10. drg_user_col (str)
              3.11. drg_domain_col (str)
              3.12. drg_grpid_col (str)
              3.13. fetch_rows (int)
              3.14. force_dns (int)

        4. Functions

              4.1. do_routing("[groupID]")
              4.2. use_next_gw()/next_routing()
              4.3. goes_to_gw([type])
              4.4. is_from_gw([type])
              4.5. is_from_gw( type, [flag])

        5. RPC Commands

              5.1. drouting.reload

        6. Installation

   2. Developer Guide

   List of Tables

   1.1. Definition of table dr_gateways
   1.2. Sample dr_gateways records
   1.3. Definition of dr_rules table
   1.4. Time recurrence attributes
   1.5. Sample dr_rules records

   List of Examples

   1.1. Set db_url parameter
   1.2. Set drd_table parameter
   1.3. Set drr_table parameter
   1.4. Set drg_table parameter
   1.5. Set drl_table parameter
   1.6. Set sort_order parameter
   1.7. Set ruri_avp parameter
   1.8. Set attrs_avp parameter
   1.9. Set use_domain parameter
   1.10. Set drg_user_col parameter
   1.11. Set drg_domain_col parameter
   1.12. Set drg_grpid_col parameter
   1.13. Set fetch_rows parameter
   1.14. Set force_dns parameter
   1.15. do_routing usage
   1.16. use_next_gw usage
   1.17. goes_to_gw usage
   1.18. is_from_gw usage
   1.19. is_from_gw usage

Chapter 1. Admin Guide

   Table of Contents

   1. Overview

        1.1. Introduction
        1.2. Features
        1.3. Performance
        1.4. Routing Rule Definition

              1.4.1. Gateway Addresses
              1.4.2. Destination/GW lists
              1.4.3. Routing Rules

        1.5. Routing Rule Processing

   2. Dependencies

        2.1. Kamailio Modules
        2.2. External Libraries or Applications

   3. Parameters

        3.1. db_url(str)
        3.2. drd_table(str)
        3.3. drr_table(str)
        3.4. drg_table(str)
        3.5. drl_table(str)
        3.6. sort_order (int)
        3.7. ruri_avp (str)
        3.8. attrs_avp (str)
        3.9. use_domain (int)
        3.10. drg_user_col (str)
        3.11. drg_domain_col (str)
        3.12. drg_grpid_col (str)
        3.13. fetch_rows (int)
        3.14. force_dns (int)

   4. Functions

        4.1. do_routing("[groupID]")
        4.2. use_next_gw()/next_routing()
        4.3. goes_to_gw([type])
        4.4. is_from_gw([type])
        4.5. is_from_gw( type, [flag])

   5. RPC Commands

        5.1. drouting.reload

   6. Installation

1. Overview

   1.1. Introduction
   1.2. Features
   1.3. Performance
   1.4. Routing Rule Definition

        1.4.1. Gateway Addresses
        1.4.2. Destination/GW lists
        1.4.3. Routing Rules

   1.5. Routing Rule Processing

1.1. Introduction

   Dynamic Routing is a module for selecting (based on multiple criteria)
   the the best gateway/destination to be used for delivering a certain
   call. Least Cost Routing (LCR) is a special case of dynamic routing -
   when the rules are ordered based on costs. Dynamic Routing comes with
   many features regarding routing rule selection:
     * prefix based
     * caller/group based
     * time based
     * priority based

   , processing :
     * stripping and prefixing
     * default rules
     * inbound and outbound processing
     * script route triggering

   and failure handling:
     * serial forking
     * weight based GW selection
     * random GW selection

1.2. Features

   The dynamic routing implementation for Kamailio is designed with the
   following properties:
     * routing info (destinations, rules, groups) are stored in a database
       and loaded into memory at start up time; reload at runtime via RPC
       command
     * load balancing or random selection of the destinations (from a
       given set)
     * able to handle large volume of routing info (300K of rules) with
       minimal speed/time and memory consumption penalties
     * script integration - Pseudo variables support in functions;
       scripting route triggering when rules are matched
     * bidirectional behavior - inbound and outbound processing (strip and
       prefixing when sending and receiving from a destination/GW)

1.3. Performance

   There were several tests performed regarding the performance of the
   module when dealing with a large number of routing rules.

   The tests were performed with a set of 383000 rules and to values were
   measured:
     * time to load from DB
     * used shared memory

   The time to load was varying between 4 seconds and 8 seconds, depending
   of the caching of the DB client - the first load was the slowest (as
   the DB query hits the disk drive); the following are faster as data is
   already cached in the DB client. So technically speaking, the time to
   load (without the time to query which is DB type dependent) is ~4
   seconds

   After loading the data into shared memory ~ 96M of memory were used
   exclusively for the DR data.

1.4. Routing Rule Definition

   Dynamic routing rules are stored in a database, in four tables:
     * one for storing the gateway definitions
     * one for storing the routing rule definitions
     * one for storing the users mappings over groups
     * one for storing a list of gateways, so you don't have to enter all
       the elements every time you need it

1.4.1. Gateway Addresses

   Default name for the table storing gateway addresses is “dr_gateways”.
   Gateway addresses are stored in a separate table because of need to
   access them independent of Dynamic Routing processing (e.g., adding/
   removing gateway PRI prefix before/after performing other operation --
   receiving/relaying to gateway).

   Table 1.1. Definition of table dr_gateways
   Column name     Type     Default value         Description
   gwid        integer      auto increment unique identifier for GW
   type        unsigned int 0              type/class of GW
   address     varchar(128)                address of the gateway
   strip       unsigned int 0              no of digits to strip
   pri_prefix  varchar(255)                PRI prefix of the gateway
   description varchar(128)                description of the gateway

   Once a rule is matched, the STRIP number of digits are removed from the
   username part of the RURI and then the PRI prefix has to be added to
   the request URI before forwarding the call to the gateway.

   Table 1.2. Sample dr_gateways records
   gwid type     address      strip pri_prefix description
   1    10   10.10.10.10:5080 0     2222       Gateway 1
   2    10   10.10.10.10      2     3333       Gateway 2
   3    20   10.10.10.11      0                Gateway 3

1.4.2. Destination/GW lists

   For each rule, you can set a list of destinations to be used. The list
   is comma or pipe separated enumeration of the destinations. The module
   will use (one by one) each destination from the list (in the given
   order).

   Also the module allows the usage of groups in the destination lists. A
   group of destinations is delimited by semi-colon char. inside the whole
   destination list ( like: 2,4;5,78,23;4;7;2 ). The destinations from
   within a group may be act differently (like load-balancing, random
   selection, etc), depending of the “sort_order” module parameter - more
   about this is available under the module paramters section.

1.4.3. Routing Rules

   Default name for the table storing rule definitions is “dr_rules”.

   Table 1.3. Definition of dr_rules table
   Column name     Type     Default            Description
   ruleid      integer      auto    UID of the rule
   groupid     varchar(255)         list of routing group IDs
   prefix      varchar(64)          destination prefix for this route
   timerec     varchar(255)         time recurrence for this rule
   priority    integer      0       priority of the rule
   routeid     integer      0       route block to be execute
   gwlist      varchar(255)         the list with GWs to be used
   description varchar(128)         description of this rule

    a. groupid column
       Each user must be member of only one routing group. It must be
       specified in user's profile.
    b. prefix column
       Destination URI must start with prefix value to match the rule.
    c. time rec column
       A date-time expression that defines the time recurrence to match
       for current rule. Time recurrences are based closely on the
       specification of recurring intervals of time in the Internet
       Calendaring and Scheduling Core Object Specification (calendar
       COS), RFC 2445. The set of attributes used in routing rule
       specification is subset of time recurrence attributes used by Call
       Processing Language (CPL). These attributes are (extracted from CPL
       draft 09):
       Table 1.4. Time recurrence attributes

   Attribute Description
   dastard Start of interval (RFC 2445 DATE-TIME)
   duration Length of interval (RFC 2445 DURATION)
   freq Frequency of recurrence (secondly,minutely,hourly, daily,weekly,
   monthly, or yearly).
   until bound of recurrence (RFC 2445 DATE-TIME)
   interval How often the recurrence repeats
   byday List of days of the week
   bymonthday List of days of the month
   byyearday List of days of the year
   byweekno List of weeks of the year
   bymonth List of months of the year
       The value stored in database has the format of:
       <dtstart>|<duration>|<freq>|<until>|<interval>|<byday>|<bymonthday>
       |<byyearday>|<byweekno>|<bymonth>
       When an attribute is not specified, the corresponding place must be
       left empty, whenever another attribute that follows in the list has
       to be specified.
       Detailed description of time recurrence attributes:
          + dtstart - specifies the beginning of the first period.
          + duration - specifies the duration of the period. For a
            recurring interval, the “duration” parameter MUST be small
            enough such that subsequent intervals do not overlap. For
            non-recurring intervals, durations of any positive length are
            permitted, zero-length duration means “forever”.
            Negative-length durations are not allowed.
          + freq - takes one of the following values: “daily”, to specify
            repeating periods based on an interval of a day or more;
            “weekly”, to specify repeating periods based on an interval of
            a week or more; “monthly”, to specify repeating periods based
            on an interval of a month or more; and “yearly”, to specify
            repeating periods based on an interval of a year or more.
            These values are not case-sensitive.
          + until - defines an iCalendar COS DATE or DATE-TIME value which
            bounds the recurrence rule in an inclusive manner. If the
            value specified by “until” is synchronized with the specified
            recurrence, this date or date-time becomes the last instance
            of the recurrence. If not present, the recurrence is
            considered to repeat forever.
          + interval - contains a positive integer representing how often
            the recurrence rule repeats. The default value is “1”, meaning
            every day for a “daily” rule, every week for a “weekly” rule,
            every month for a “monthly” rule and every year for a “yearly”
            rule.
          + interval - contains a positive integer representing how often
            the recurrence rule repeats. The default value is “1”, meaning
            every day for a “daily” rule, every week for a “weekly” rule,
            every month for a “monthly” rule and every year for a “yearly”
            rule.
          + byday - specifies a comma-separated list of days of the week.
            “MO” indicates Monday; “TU” indicates Tuesday; “WE” indicates
            Wednesday; “TH” indicates Thursday; “FR” indicates Friday;
            “SA” indicates Saturday; “SU” indicates Sunday. These values
            are not case-sensitive.
            Each “byday” value can also be preceded by a positive (+n) or
            negative (-n) integer. If present, this indicates the nth
            occurrence of the specific day within the “monthly” or
            “yearly” recurrence. For example, within a “monthly” rule,
            +1MO (or simply 1MO) represents the first Monday within the
            month, whereas -1MO represents the last Monday of the month.
            If an integer modifier is not present, it means all days of
            this type within the specified frequency. For example, within
            a “monthly” rule, MO represents all Mondays within the month.
          + bymonthday - parameter specifies a comma-separated list of
            days of the month. Valid values are 1 to 31 or -31 to -1. For
            example, -10 represents the tenth to the last day of the
            month.
          + byyearday - specifies a comma-separated list of days of the
            year. Valid values are 1 to 366 or -366 to -1. For example, -1
            represents the last day of the year (December 31st) and -306
            represents the 306th to the last day of the year (March 1st).
          + byweekno - specifies a comma-separated list of ordinals
            specifying weeks of the year. Valid values are 1 to 53 or -53
            to -1.
          + bymonth - parameter specifies a comma-separated list of months
            of the year. Valid values are 1 to 12.
       A recurrence is specified by including the “freq” parameter, which
       indicates the type of recurrence rule. Parameters other than
       “dtstart” and “duration” SHOULD NOT be specified unless “freq” is
       present.
       If byxxx parameter values are found which are beyond the available
       scope (ie, bymonthday=“30” in February), they are simply ignored.
       Byxxx parameters modify the recurrence in some manner. Byxxx rule
       parts for a period of time which is the same or greater than the
       frequency generally reduce or limit the number of occurrences of
       the recurrence generated. For example, freq=“daily” bymonth=“1”
       reduces the number of recurrence instances from all days (if the
       “bymonth” parameter is not present) to all days in January. Byxxx
       parameters for a period of time less than the frequency generally
       increase or expand the number of occurrences of the recurrence. For
       example, freq=“yearly” bymonth=“1,2” increases the number of days
       within the yearly recurrence set from 1 (if “bymonth” parameter is
       not present) to 2.
       If multiple Byxxx parameters are specified, then after evaluating
       the specified “freq” and “interval” parameters, the Byxxx
       parameters are applied to the current set of evaluated occurrences
       in the following order: “bymonth”, “byweekno”, “byyearday”,
       “bymonthday”, “byday”; then “until” is evaluated.
       Here is an example of evaluating multiple Byxxx parameters.
       dtstart=“19970105T083000” duration=“10M” freq=“yearly” interval=“2”
       bymonth=“1” byday=“SU”
       First, the interval=“2” would be applied to freq=“yearly” to arrive
       at “every other year” . Then, bymonth=“1” would be applied to
       arrive at “every January, every other year”. Then, byday=“SU” would
       be applied to arrive at “every Sunday in January, every other year,
       from 8:30 to 8:40 ”. The appropriate minutes and hours have been
       retrieved from the “dtstart” and “duration” parameters.
    d. priority column
       If many rules are eligible, choose the one with highest priority.
    e. routeid column
       If different than 0, then execute the route with the specified ID.
       That is, a route which can be used to perform custom operations on
       message. At this route, no modification is performed at signaling
       level.
    f. gwlist column
       A comma separated list of gateway identifiers corresponding to a
       row in table “dr_gateways”. You can use a predefined list from the
       table “dr_gw_lists” preceded by the character “#”. The first
       gateway is tried first and if routing to it fails, then the second
       one, and so one. If no gateway is left a negative response is sent
       back to caller.
    g. Routing Rules Examples
       Table 1.5. Sample dr_rules records

   ruleid group prefix timerec priority routeid gwlist description
   1 6 0049 20040101T083000|10H|weekly|||MO,TU,WE,TH,FR 5 23 1,2 Rule 1
   2 8 0049 20040101T083000 0 0 1,2 Rule 2
   3 7,8,9 0049 20040101T083000 0 0 3 Rule 3
       (The time recurrence for first rule is:
       “20040101T083000|10H|weekly|||MO,TU,WE,TH,FR”)

1.5. Routing Rule Processing

   The module can be used to find out which is the best gateway to use for
   new calls terminated to PSTN. The algorithm to select the rule is as
   follows:
     * the module discovers the routing group of the originating user.
       This step is skipped if a routing group is passed from the script
       as parameter.
     * once the group is known, in the subset of the rules for this group
       the module looks for the one that matches the destination based on
       "prefix" column. The set of rules with the longest prefix is
       chosen. If no digit from the prefix matches, the default rules are
       used (rules with no prefix)
     * within the set of rules is applied the time criteria, and the rule
       which has the highest priority and matches the time criteria is
       selected to drive the routing.
     * Once found the rule, it may contain a route ID to execute. If a
       certain flag is set, then the processing is stopped after executing
       the route block.
     * The rule must contain a gateway chain. The module will execute
       serial forking for each address in chain. The next address in chain
       is used only if the previously has failed.
     * With the right gateway address found, the prefix (PRI) of the
       gateway is added to the request URI and then the request is
       forwarded.

   If no rule is found to match the selection criteria an default action
   must be taken (e.g., error response sent back). If the gateway in the
   chain has no prefix the request is forwarded without adding any prefix
   to the request URI.

2. Dependencies

   2.1. Kamailio Modules
   2.2. External Libraries or Applications

2.1. Kamailio Modules

   The following modules must be loaded before this module:
     * a database module.

2.2. External Libraries or Applications

     * none.

3. Parameters

   3.1. db_url(str)
   3.2. drd_table(str)
   3.3. drr_table(str)
   3.4. drg_table(str)
   3.5. drl_table(str)
   3.6. sort_order (int)
   3.7. ruri_avp (str)
   3.8. attrs_avp (str)
   3.9. use_domain (int)
   3.10. drg_user_col (str)
   3.11. drg_domain_col (str)
   3.12. drg_grpid_col (str)
   3.13. fetch_rows (int)
   3.14. force_dns (int)

3.1. db_url(str)

   The database url.

   Default value is “NULL”.

   Example 1.1. Set db_url parameter
...
modparam("drouting", "db_url",
        "mysql://kamailio:kamailiorw@localhost/kamailio")
...

3.2. drd_table(str)

   The name of the db table storing gateway addresses.

   Default value is “dr_gateways”.

   Example 1.2. Set drd_table parameter
...
modparam("drouting", "drd_table", "dr_gateways")
...

3.3. drr_table(str)

   The name of the db table storing routing rules.

   Default value is “dr_rules”.

   Example 1.3. Set drr_table parameter
...
modparam("drouting", "drr_table", "rules")
...

3.4. drg_table(str)

   The name of the db table storing groups.

   Default value is “dr_groups”.

   Example 1.4. Set drg_table parameter
...
modparam("drouting", "drg_table", "groups")
...

3.5. drl_table(str)

   The name of the db table storing definitions of destination lists (to
   be used directly by the routing rules). You will have a identifier to a
   group of gateways instead of having all the members of the group as a
   individual elements. Very useful to reuse a list of gateways in
   different places.

   Default value is “dr_gw_lists”.

   Example 1.5. Set drl_table parameter
...
modparam("drouting", "drl_table", "my_gw_lists")
...

3.6. sort_order (int)

   Defines how the destination list should be processed (ordering of the
   elements). Possible modes are
     * 0 - destination groups are ignored and all the destinations are
       tried in the given order; Ex: list 1,2;3,4,5;6 will lead to usage
       as 1,2,3,4,5,6
     * 1 - the destinations from each group are randomly arranged (only
       the two elements are randomly selected); groups do maintain their
       order (as given); the resulting list is used (with all the defined
       destinations). Ex: 1,2;3,4,5;6 -> randomizer -> (A) 2,1;4,3,5;6 ->
       usage 2,1,4,3,5,6 (B) 1,2;3,5,4;6 -> usage 1,2,3,5,4,6
     * 2 - from each destination group, only a single destination is
       randomly selected; groups do maintain their order (as given); Ex:
       1,2;3,4,5;6 -> randomizer -> (A) 2;4;6 -> usage 2,4,6 (B) 1;5;6 ->
       usage 1,5,6

   Default value is “0”.

   Example 1.6. Set sort_order parameter
...
modparam("drouting", "sort_order", 2)
...

3.7. ruri_avp (str)

   The name of the avp for storing Request URIs to be later used
   (alternative destiantions for the current one).

   Default value is “NULL”.

   Example 1.7. Set ruri_avp parameter
...
modparam("drouting", "ruri_avp", '$avp(dr_ruri)')
modparam("drouting", "ruri_avp", '$avp(i:33)')
...

3.8. attrs_avp (str)

   The name of the avp for storing the attribute of the current selected
   destination - once a new destination is selected (via the use_next_gw()
   function), the AVP will be updated with the attrs of the new used
   destination.

   Default value is “NULL”.

   Example 1.8. Set attrs_avp parameter
...
modparam("drouting", "attrs_avp", '$avp(dr_attrs)')
modparam("drouting", "atrrs_avp", '$avp(i:67)')
...

3.9. use_domain (int)

   Flag to configure whether to use domain match when querying database
   for user's routing group.

   Default value is “1”.

   Example 1.9. Set use_domain parameter
...
modparam("drouting", "use_domain", 0)
...

3.10. drg_user_col (str)

   The name of the column in group db table where the username is stored.

   Default value is “username”.

   Example 1.10. Set drg_user_col parameter
...
modparam("drouting", "drg_user_col", "user")
...

3.11. drg_domain_col (str)

   The name of the column in group db table where the domain is stored.

   Default value is “domain”.

   Example 1.11. Set drg_domain_col parameter
...
modparam("drouting", "drg_domain_col", "host")
...

3.12. drg_grpid_col (str)

   The name of the column in group db table where the group id is stored.

   Default value is “groupid”.

   Example 1.12. Set drg_grpid_col parameter
...
modparam("drouting", "drg_grpid_col", "grpid")
...

3.13. fetch_rows (int)

   The number of rows that should be fetched from the result of a query in
   rules db table.

   Default value is “2000”.

   Example 1.13. Set fetch_rows parameter
...
modparam("drouting", "fetch_rows", 1500)
...

3.14. force_dns (int)

   Force DNS resolving of GW/destination names (if not IPs) during
   startup. If not enabled, the GW name will be blindly used during
   routing.

   Default value is “1 (enabled)”.

   Example 1.14. Set force_dns parameter
...
modparam("drouting", "force_dns", 0)
...

4. Functions

   4.1. do_routing("[groupID]")
   4.2. use_next_gw()/next_routing()
   4.3. goes_to_gw([type])
   4.4. is_from_gw([type])
   4.5. is_from_gw( type, [flag])

4.1.  do_routing("[groupID]")

   Function to trigger routing of the message according to the rules in
   the database table and the configured parameters.

   This function can be used from REQUEST_ROUTE and FAILURE_ROUTE.

   The module can take one optional parameter: the routing group the
   caller belongs to - this may be a static numerical value or an AVP
   specification. If none specified, the function will automatically try
   to query the dr_group table to get this information.

   Example 1.15. do_routing usage
...
do_routing();
...
do_routing("0");
...
do_routing("$avp(i:10)");

4.2.  use_next_gw()/next_routing()

   The function takes the next available destination (set by do_routing,
   as alternative destinations) and push it into RURI. Note that the
   function just sets the RURI (nothing more).

   If a new RURI is set, the used destination is removed from the pending
   set of alternative destinations.

   This function can be used from REQUEST_ROUTE and FAILURE_ROUTE.

   The function returns true only if a new RURI was set. False is returned
   is no other alternative destinations are found or in case of internal
   processing error.

   Example 1.16. use_next_gw usage
...
if (use_next_gw()) {
        t_relay();
        exit;
}
...

4.3.  goes_to_gw([type])

   Function returns true if the destination of the current request
   (destination URI or Request URI) points (as IP) to one of the gateways.
   There no DNS lookups done if the domain part of the URI is not an IP.

   This function does not change anything in the message.

   This function can be used from REQUEST_ROUTE and FAILURE_ROUTE.

   The function can take one optional parameter:
     * type (optional) - GW/destination type to be checked

   Example 1.17. goes_to_gw usage
...
if (goes_to_gw("1")) {
        sl_send_reply("403","Forbidden");
        exit;
}
...

4.4.  is_from_gw([type])

   The function checks if the sender of the message is a gateway from a
   certain group.

   This function can be used from REQUEST_ROUTE, FAILURE_ROUTE and
   ONREPLY_ROUTE

   The function can take one optional parameter:
     * type (optional) - GW/destination type to be checked
     * flags - if message is a request and the GW has a STRIP defined,
       then apply it if GW is source.

   Example 1.18. is_from_gw usage
...
if (is_from_gw("1") {
}
...

4.5.  is_from_gw( type, [flag])

   The function checks if the sender of the message is a gateway from a
   certain group.

   This function can be used from REQUEST_ROUTE and FAILURE_ROUTE.

   The function can take two parameters:
     * type (mandatory) - GW/destination type to be checked
     * flags (optional) - if message is a request and the GW has a STRIP
       defined, then apply it if GW is source.

   Example 1.19. is_from_gw usage
...
if (is_from_gw("3","1") {
}
...

5. RPC Commands

   5.1. drouting.reload

5.1.  drouting.reload

   Command to reload routing rules from database.

   It takes no parameter.

   RPC Command Format:
        kamcmd drouting.reload

6. Installation

   The module requires 3 table in Kamailio database: dr_groups,
   dr_gateways, dr_rules. The SQL syntax to create them can be found in
   drouting-create.sql script in kamctl db directories. You can also find
   the complete database documentation on the project webpage,
   http://www.kamailio.org/docs/db-tables/kamailio-db-devel.html.

Chapter 2. Developer Guide

   The module provides no function to be used by other Kamailio modules.
