carrierroute

Henning Westerholt

   1&1 Internet AG

Edited by

Lucian Balaceanu

   1&1 Internet AG
   <lucian.balaceanu@1and1.ro>

   Copyright © 2007 1&1 Internet AG
     __________________________________________________________________

   Table of Contents

   1. Admin Guide

        1. Overview
        2. Dependencies

              2.1. Kamailio Modules

        3. Parameters

              3.1. subscriber_table (string)
              3.2. subscriber_user_col (string)
              3.3. subscriber_domain_col (string)
              3.4. subscriber_carrier_col (string)
              3.5. config_source (string)
              3.6. config_file (string)
              3.7. default_tree (string)
              3.8. use_domain (int)
              3.9. fallback_default (int)
              3.10. fetch_rows (integer)
              3.11. db_load_description (integer)
              3.12. match_mode (integer)
              3.13. avoid_failed_destinations (integer)

        4. Functions

              4.1. cr_user_carrier(user, domain, dstavp)
              4.2. cr_route(carrier, domain, prefix_matching,
                      rewrite_user, hash_source, descavp)

              4.3. cr_nofallback_route(carrier, domain, prefix_matching,
                      rewrite_user, hash_source, descavp)

              4.4. cr_next_domain(carrier, domain, prefix_matching, host,
                      reply_code, dstavp)

        5. RPC Commands

              5.1. cr.reload_routes
              5.2. cr.dump_routes
              5.3. cr.add_host
              5.4. cr.delete_host
              5.5. cr.activate_host
              5.6. cr.deactivate_host
              5.7. cr.replace_host

        6. Configuration examples
        7. Installation and Running

              7.1. Database setup
              7.2. Database examples
              7.3. User specific routing

   2. Module parameter for database access.

        1. db_url (String)
        2. carrierroute_table (String)
        3. carrierroute_id_col (string)
        4. carrierroute_carrier_col (string)
        5. carrierroute_domain_col (string)
        6. carrierroute_scan_prefix_col (string)
        7. carrierroute_flags_col (string)
        8. carrierroute_mask_col (string)
        9. carrierroute_prob_col (string)
        10. carrierroute_strip_col (string)
        11. carrierroute_rewrite_host_col (string)
        12. carrierroute_rewrite_prefix_col (string)
        13. carrierroute_rewrite_suffix_col (string)
        14. carrierroute_description_col (string)
        15. carrierfailureroute_table (String)
        16. carrierfailureroute_id_col (string)
        17. carrierfailureroute_carrier_col (string)
        18. carrierfailureroute_domain_col (string)
        19. carrierfailureroute_scan_prefix_col (string)
        20. carrierfailureroute_host_name_col (string)
        21. carrierfailureroute_reply_code_col (string)
        22. carrierfailureroute_flags_col (string)
        23. carrierfailureroute_mask_col (string)
        24. carrierfailureroute_next_domain_col (string)
        25. carrierfailureroute_description_col (string)
        26. carrier_name_table (String)
        27. carrier_name_id_col (string)
        28. carrier_name_carrier_col (string)
        29. domain_name_table (String)
        30. domain_name_id_col (string)
        31. domain_name_domain_col (string)

   List of Examples

   1.1. Set subscriber_table parameter
   1.2. Set subscriber_user_col parameter
   1.3. Set subscriber_domain_col parameter
   1.4. Set subscriber_carrier_col parameter
   1.5. Set config_source parameter
   1.6. Set config_file parameter
   1.7. Set default_tree parameter
   1.8. Set use_domain parameter
   1.9. Set fallback_default parameter
   1.10. Set fetch_rows parameter
   1.11. Unset db_load_description parameter
   1.12. Set match_mode parameter
   1.13. Set avoid_failed_destinations parameter
   1.14. Configuration example - Routing to default tree
   1.15. Configuration example - Routing to user tree
   1.16. Configuration example - module configuration
   1.17. Example database content - carrierroute table
   1.18. Example database content - simple carrierfailureroute table
   1.19. Example database content - more complex carrierfailureroute table
   1.20. Example database content - carrier_name table
   1.21. Example database content - domain_name table
   1.22. Necessary extensions for the user table
   2.1. Set db_url parameter
   2.2. Set carrierroute_table parameter
   2.3. Set carrierroute_id_col parameter
   2.4. Set carrierroute_carrier_col parameter
   2.5. Set carrierroute_domain_col parameter
   2.6. Set carrierroute_scan_prefix_col parameter
   2.7. Set carrierroute_flags_col parameter
   2.8. Set carrierroute_mask_col parameter
   2.9. Set carrierroute_prob_col parameter
   2.10. Set carrierroute_strip_col parameter
   2.11. Set carrierroute_rewrite_host_col parameter
   2.12. Set carrierroute_rewrite_prefix_col parameter
   2.13. Set carrierroute_rewrite_suffix_col parameter
   2.14. Set carrierroute_description_col parameter
   2.15. Set carrierfailureroute_table parameter
   2.16. Set carrierfailureroute_id_col parameter
   2.17. Set carrierfailureroute_carrier_col parameter
   2.18. Set carrierfailureroute_domain_col parameter
   2.19. Set carrierfailureroute_scan_prefix_col parameter
   2.20. Set carrierfailureroute_host_name_col parameter
   2.21. Set carrierfailureroute_reply_code_col parameter
   2.22. Set carrierfailureroute_flags_col parameter
   2.23. Set carrierfailureroute_mask_col parameter
   2.24. Set carrierfailureroute_next_domain_col parameter
   2.25. Set carrierfailureroute_description_col parameter
   2.26. Set carrier_name_table parameter
   2.27. Set carrier_name_id_col parameter
   2.28. Set carrier_name_carrier_col parameter
   2.29. Set domain_name_table parameter
   2.30. Set domain_name_id_col parameter
   2.31. Set domain_name_domain_col parameter

Chapter 1. Admin Guide

   Table of Contents

   1. Overview
   2. Dependencies

        2.1. Kamailio Modules

   3. Parameters

        3.1. subscriber_table (string)
        3.2. subscriber_user_col (string)
        3.3. subscriber_domain_col (string)
        3.4. subscriber_carrier_col (string)
        3.5. config_source (string)
        3.6. config_file (string)
        3.7. default_tree (string)
        3.8. use_domain (int)
        3.9. fallback_default (int)
        3.10. fetch_rows (integer)
        3.11. db_load_description (integer)
        3.12. match_mode (integer)
        3.13. avoid_failed_destinations (integer)

   4. Functions

        4.1. cr_user_carrier(user, domain, dstavp)
        4.2. cr_route(carrier, domain, prefix_matching, rewrite_user,
                hash_source, descavp)

        4.3. cr_nofallback_route(carrier, domain, prefix_matching,
                rewrite_user, hash_source, descavp)

        4.4. cr_next_domain(carrier, domain, prefix_matching, host,
                reply_code, dstavp)

   5. RPC Commands

        5.1. cr.reload_routes
        5.2. cr.dump_routes
        5.3. cr.add_host
        5.4. cr.delete_host
        5.5. cr.activate_host
        5.6. cr.deactivate_host
        5.7. cr.replace_host

   6. Configuration examples
   7. Installation and Running

        7.1. Database setup
        7.2. Database examples
        7.3. User specific routing

1. Overview

   A module which provides routing, balancing and blocklisting
   capabilities.

   The module provides routing, balancing and blocklisting capabilities.
   It reads routing entries from a database source or from a config file
   at Kamailio startup. It can uses one routing tree (for one carrier), or
   if needed for every user a different routing tree (unique for each
   carrier) for number prefix based routing. It supports several route
   tree domains, e.g. for fallback routes or different routing rules for
   VoIP and PSTN targets.

   Based on the tree, the module decides which number prefixes are
   forwarded to which gateway. It can also distribute the traffic by ratio
   parameters. Furthermore, the requests can be distributed by a hash
   function to predictable destinations. The hash source is configurable,
   two different hash functions are available.

   This modules scales up to more than a few million users, and is able to
   handle more than several hundred thousand routing table entries. We
   received reports of some setups that used more than a million routing
   table entries. It also supports a large number of carriers and domains
   which can be efficiently looked up in most of the cases (see below for
   more informations). In load balancing scenarios the usage of the config
   file mode is recommended, to avoid the additional complexity that the
   database driven routing creates.

   Routing tables can be reloaded and edited (in config file mode) with
   the RPC interface, the config file is updated according the changes.
   This is not implemented for the db interface, because its easier to do
   the changes directly on the db. But the reload and dump functions works
   of course here too.

   Some module functionality is not fully available in the config file
   mode, as it is not possible to specify all information that can be
   stored in the database tables in the config file. Further information
   about these limitations is given in later sections. For user based
   routing or LCR you should use the database mode.

   In database mode, this module supports names and IDs for the carriers
   and domains. When using IDs for the routing functions, efficient binary
   search is used to find the needed data structures. If you are using
   constant strings as parameter, these will be converted to IDs during
   the fixup procedure. However, if you are using AVPs as parameter and
   they contain strings, this cannot be converted to IDs during the fixup
   procedure. In that case linear search is performed to find the needed
   data structures. So from a performance point of view it is better to
   pass only IDs in AVPs to the routing functions.

   Basically this module could be used as an replacement for the lcr and
   the dispatcher module, if you have certain flexibility, integration
   and/or performance requirements that can't be satisfied with these
   modules. But for smaller installations it probably make more sense to
   use the lcr and dispatcher module.

   Starting with version 3.1 , if you want to use this module in failure
   routes, it is not needed to call“append_branch()” after rewriting the
   request URI in order to relay the message to the new target. Its also
   supports the usage of database derived failure routing decisions with
   the carrierfailureroute table.

2. Dependencies

   2.1. Kamailio Modules

2.1. Kamailio Modules

   The following module must be loaded before this module:
     * a database module, when a database is used as configuration data
       source. Only SQL based databases are supported, as this module
       needs the capability to issue raw queries. Its not possible to use
       the dbtext or db_berkeley module at the moment.
     * The tm module, when you want to use the $T_reply_code
       pseudo-variable in the “cr_next_domain” function.

3. Parameters

   3.1. subscriber_table (string)
   3.2. subscriber_user_col (string)
   3.3. subscriber_domain_col (string)
   3.4. subscriber_carrier_col (string)
   3.5. config_source (string)
   3.6. config_file (string)
   3.7. default_tree (string)
   3.8. use_domain (int)
   3.9. fallback_default (int)
   3.10. fetch_rows (integer)
   3.11. db_load_description (integer)
   3.12. match_mode (integer)
   3.13. avoid_failed_destinations (integer)

3.1. subscriber_table (string)

   The name of the table containing the subscribers

   Default value is “subscriber”.

   Example 1.1. Set subscriber_table parameter
...
modparam("carrierroute", "subscriber_table", "subscriber")
...

3.2. subscriber_user_col (string)

   The name of the column in the subscriber table containing the
   usernames.

   Default value is “username”.

   Example 1.2. Set subscriber_user_col parameter
...
modparam("carrierroute", "subscriber_user_col", "username")
...

3.3. subscriber_domain_col (string)

   The name of the column in the subscriber table containing the domain of
   the subscriber.

   Default value is “domain”.

   Example 1.3. Set subscriber_domain_col parameter
...
modparam("carrierroute", "subscriber_domain_col", "domain")
...

3.4. subscriber_carrier_col (string)

   The name of the column in the subscriber table containing the carrier
   id of the subscriber.

   Default value is “cr_preferred_carrier”.

   Example 1.4. Set subscriber_carrier_col parameter
...
modparam("carrierroute", "subscriber_carrier_col", "cr_preferred_carrier")
...

3.5. config_source (string)

   Specifies whether the module loads its config data from a file or from
   a database. Possible values are file or db.

   Default value is “file”.

   Example 1.5. Set config_source parameter
...
modparam("carrierroute", "config_source", "file")
...

3.6. config_file (string)

   Specifies the path to the config file. The file has to be owned by the
   user and group used to run Kamailio.

   Default value is “/etc/kamailio/carrierroute.conf”.

   Example 1.6. Set config_file parameter
...
modparam("carrierroute", "config_file", "/etc/kamailio/carrierroute.conf")
...

3.7. default_tree (string)

   The name of the carrier tree used per default (if the current
   subscriber has no preferred tree)

   Default value is “default”.

   Example 1.7. Set default_tree parameter
...
modparam("carrierroute", "default_tree", "default")
...

3.8. use_domain (int)

   When using tree lookup per user, this parameter specifies whether to
   use the domain part for user matching or not. This parameter is tunable
   via the ser cfg framework.

   Default value is “0”.

   Example 1.8. Set use_domain parameter
...
modparam("carrierroute", "use_domain", 0)
...

3.9. fallback_default (int)

   This parameter defines the behaviour when using user-based tree lookup.
   If the user has a non-existing tree set and fallback_default is set to
   1, the default tree is used. Otherwise, cr_user_rewrite_uri returns an
   error. This parameter is tunable via the ser cfg framework.

   Default value is “1”.

   Example 1.9. Set fallback_default parameter
...
modparam("carrierroute", "fallback_default", 1)
...

3.10. fetch_rows (integer)

   The number of the rows to be fetched at once from database when loading
   the routing data. This value can be used to tune the load time at
   startup. For 1MB of private memory (default) it should be below 3750.
   The database driver must support the fetch_result() capability. This
   parameter is tunable via the ser cfg framework.

   Default value is “2000”.

   Example 1.10. Set fetch_rows parameter
...
modparam("carrierroute", "fetch_rows", 3000)
...

3.11. db_load_description (integer)

   Toggle on/off loading in memory the description column in the
   carrierroute/carrierfailureroute database tables. This reduces the
   shared memory used by the module.

   Default value is “1”.

   Example 1.11. Unset db_load_description parameter
...
modparam("carrierroute", "db_load_description", 0)
...

3.12. match_mode (integer)

   The number of individual characters that are used for matching. Valid
   values are 10 or 128. When you specify 10, only digits will be used for
   matching, this operation mode is equivalent to the old behaviour. When
   configured with 128, all standard ascii chars are available for
   matching. Please be aware that memory requirements for storing the
   routing tree in shared memory will also increase by a factor of 12.8.

   Default value is “10”.

   Example 1.12. Set match_mode parameter
...
modparam("carrierroute", "match_mode", 10)
...

3.13. avoid_failed_destinations (integer)

   Integer parameter to toggle on/off the possibility that in the
   failurerouting cases destinations that previously failed are avoided.
   Possible values are 0 (off), 1 (on). Also see cr_route section.

   Default value is “1”.

   Example 1.13. Set avoid_failed_destinations parameter
...
modparam("carrierroute", "avoid_failed_destinations", 0)
...

4. Functions

   4.1. cr_user_carrier(user, domain, dstavp)
   4.2. cr_route(carrier, domain, prefix_matching, rewrite_user,
          hash_source, descavp)

   4.3. cr_nofallback_route(carrier, domain, prefix_matching,
          rewrite_user, hash_source, descavp)

   4.4. cr_next_domain(carrier, domain, prefix_matching, host, reply_code,
          dstavp)

   Previous versions of carrierroute had some more function. All the old
   semantics can be achieved by using the few new functions like this:
cr_rewrite_uri(domain, hash_source)
-> cr_route("default", domain, "$rU", "$rU", hash_source)

cr_rewrite_by_to(domain, hash_source)
-> cr_route("default", domain, "$tU", "$rU", hash_source)

cr_rewrite_by_from(domain, hash_source)
-> cr_route("default", domain, "$fU", "$rU", hash_source)

cr_user_rewrite_uri(uri, domain)
-> cr_user_carrier(user, domain, "$avp(tree_avp)")
-> cr_route("$avp(tree_avp)", domain, "$rU", "$rU", "call_id")

cr_tree_rewrite_uri(tree, domain)
-> cr_route(tree, domain, "$rU", "$rU", "call_id")

4.1.  cr_user_carrier(user, domain, dstavp)

   This function loads the carrier and stores it in an AVP. It cannot be
   used in the config file mode, as it needs a mapping of the given user
   to a certain carrier. The is derived from a database entry belonging to
   the user parameter. This mapping must be available in the table that is
   specified in the “subscriber_table” variable. This data is not cached
   in memory, that means for every execution of this function a database
   query will be done.

   Meaning of the parameters is as follows:
     * user - Name of the user for the carrier tree lookup. Additional to
       a string any pseudo-variable could be used as input.
     * domain - Name of the routing domain to be used. Additional to a
       string any pseudo-variable could be used as input.
     * dstavp - Name of the AVP where to store the carrier id.

4.2.  cr_route(carrier, domain, prefix_matching, rewrite_user, hash_source,
descavp)

   This function searches for the longest match for the user given in
   prefix_matching at the given domain in the given carrier tree. The
   Request URI is rewritten using rewrite_user and the given hash source
   and algorithm. Returns -1 if there is no data found or an empty rewrite
   host on the longest match is found. On success also the description is
   stored in the given AVP (if omitted, nothing is stored in an AVP). This
   is useful if you need some additional informations that belongs to each
   gw, like the destination or the number of channels.

   Depending on the value of the avoid_failed_destinations module
   parameter, the function pays special attention to the failurerouting
   cases, so that any destination that has failed to provide a successful
   response will not be reused in a subsequent call of cr_route. This
   situation can appear when different route domains contain a set of
   common gateways.

   This function is only usable with rewrite_user and prefix_matching
   containing a valid string. This string needs to be numerical if the
   match_mode parameter is set to 10. It uses the standard CRC32 algorithm
   to calculate the hash values.

   If flags and masks values are specified in the routing rule, they will
   be compared by this function to the message flags. Specify a flag and
   mask value of “0” to match to all possible message flags (this is the
   default value). If flags and mask are not zero, and no match to the
   message flags is possible, no routing will be done. The calculation of
   the hash and the load-balancing is done after the flags matching.

   Meaning of the parameters is as follows:
     * carrier - The routing tree to be used. Additional to a string any
       pseudo-variable could be used as input.
     * domain - Name of the routing domain to be used. Additional to a
       string any pseudo-variable could be used as input.
     * prefix_matching - User name to be used for prefix matching in the
       routing tree. Additional to a string any pseudo-variable could be
       used as input.
     * rewrite_user - The user name to be used for applying the rewriting
       rule. Usually this is the user part of the request URI. Additional
       to a string any pseudo-variable could be used as input.
     * hash_source - The hash values of the destination set must be a
       contiguous range starting at 1, limited by the configuration
       parameter max_targets. Possible values for hash_source are:
       call_id, from_uri, from_user, to_uri, to_user and rand
     * decsavp - AVP where to store the description. This parameter is
       optional.

4.3.  cr_nofallback_route(carrier, domain, prefix_matching, rewrite_user,
hash_source, descavp)

   This function searches for the longest match for the user given in
   prefix_matching at the given domain in the given carrier tree. The
   Request URI is rewritten using rewrite_user and the given hash source
   and algorithm. Returns -1 if there is no data found or an empty rewrite
   host on the longest match is found. On success also the description is
   stored in the given AVP (if omitted, nothing is stored in an AVP). This
   is useful if you need some additional informations that belongs to each
   gw, like the destination or the number of channels. This function is
   only usable with rewrite_user and prefix_matching containing a valid
   string. This string needs to be numerical if the match_mode parameter
   is set to 10.

   It uses the standard CRC32 algorithm to calculate the hash values. In
   contrast to the normal cr_route function the backup rules of (now
   obsolete) cr_prime_route is used. This means not the configured
   probabilities will be used, only a fixed hash distribution. This makes
   sense to distribute incoming register requests e.g. to a bunch of
   registrar servers. If one of the hash targets is not available and
   backup rule is configured, the function will return -1.

   Meaning of the parameters is as follows:
     * carrier - The routing tree to be used. Additional to a string any
       pseudo-variable could be used as input.
     * domain - Name of the routing domain to be used. Additional to a
       string any pseudo-variable could be used as input.
     * prefix_matching - User name to be used for prefix matching in the
       routing tree. Additional to a string any pseudo-variable could be
       used as input.
     * rewrite_user - The user name to be used for applying the rewriting
       rule. Usually this is the user part of the request URI. Additional
       to a string any pseudo-variable could be used as input.
     * hash_source - The hash values of the destination set must be a
       contiguous range starting at 1, limited by the configuration
       parameter max_targets. Possible values for hash_source are:
       call_id, from_uri, from_user, to_uri and to_user.
     * descavp - Name of the AVP where to store the description. This
       parameter is optional.

4.4.  cr_next_domain(carrier, domain, prefix_matching, host, reply_code,
dstavp)

   This function searches for the longest match for the user given in
   prefix_matching at the given domain in the given carrier failure tree.
   It tries to find a next domain matching the given host, reply_code and
   the message flags. The matching is done in this order: host, reply_code
   and then flags. The more wildcards in reply_code and the more bits used
   in flags, the lower the priority. Returns -1 if there is no data found
   or an empty next_domain on the longest match is found. Otherwise the
   next domain is stored in the given AVP. This function is only usable
   with rewrite_user and prefix_matching containing a valid string. This
   string needs to be numerical if the match_mode parameter is set to 10.

   Meaning of the parameters is as follows:
     * carrier - The routing tree to be used. Additional to a string any
       pseudo-variable could be used as input.
     * domain - Name of the routing domain to be used. Additional to a
       string any pseudo-variable could be used as input.
     * prefix_matching - User name to be used for prefix matching in the
       routing tree. Additional to a string any pseudo-variable could be
       used as input.
     * host - The host name to be used for failure route rule matching.
       Usually this is the last tried routing destination stored in an avp
       by cr_route. Additional to a string any pseudo-variable could be
       used as input.
     * reply_code - The reply code to be used for failure route rule
       matching. Additional to a string any pseudo-variable could be used
       as input.
     * dstavp - Name of the AVP where to store the next routing domain.

5. RPC Commands

   5.1. cr.reload_routes
   5.2. cr.dump_routes
   5.3. cr.add_host
   5.4. cr.delete_host
   5.5. cr.activate_host
   5.6. cr.deactivate_host
   5.7. cr.replace_host

5.1.  cr.reload_routes

   This command reloads the routing data from the data source.

   Name: cr.reload_routes

   Parameters:
     * none

   Important: When new domains have been added, a restart of the server
   must be done, because the mapping of the ids used in the config script
   cannot be updated at runtime at the moment. So a reload could result in
   a wrong routing behaviour, because the ids used in the script could
   differ from the one used internally from the server. Modifying of
   already existing domains is no problem.

5.2.  cr.dump_routes

   This command prints the route rules on the command line.

   Name: cr.dump_routes

   Parameters:
     * none

5.3.  cr.add_host

   This command adds a new host to the route rules

   Name: cr.add_host

   Parameters:
     * One long string parameter that contains the arguments for this
       command

   Example:
     * kamcmd cr.add_host -- '-h test.domain.com:5060 -d proxy -p null -w
       0.1'

5.4.  cr.delete_host

   This command deletes a host from the route rules

   Name: cr.delete_host

   Parameters:
     * One long string parameter that contains the arguments for this
       command

   Example:
     * kamcmd cr.delete_host -- '-h test.domain.com:5060 -d proxy -p null'

5.5.  cr.activate_host

   This command activates a host from the route rules

   Name: cr.activate_host

   Parameters:
     * One long string parameter that contains the arguments for this
       command

   Example:
     * kamcmd cr.activate_host -- '-h test.domain.com:5060 -d proxy -p
       null'

5.6.  cr.deactivate_host

   This command deactivates a host from the route rules

   Name: cr.deactivate_host

   Parameters:
     * One long string parameter that contains the arguments for this
       command

   Example:
     * kamcmd cr.deactivate_host -- '-h test.domain.com:5060 -d proxy -p
       null'

5.7.  cr.replace_host

   This command replaces a host from the route rules

   Name: cr.replace_host

   Parameters:
     * One long string parameter that contains the arguments for this
       command

   Example:
     * kamcmd cr.replace_host -- '-h test1.domain.com:5060 -d proxy -t
       test2.domain.com:5060'

6. Configuration examples

   Example 1.14. Configuration example - Routing to default tree
...
route {
        # route calls based on hash over callid
        # choose route domain 0 of the default carrier

        if(!cr_route("default", "0", "$rU", "$rU", "call_id")){
                sl_send_reply("403", "Not allowed");
        } else {
                # In case of failure, re-route the request
                t_on_failure("1");
                # Relay the request to the gateway
                t_relay();
        }
}

failure_route[1] {
        revert_uri();
        # In case of failure, send it to an alternative route:
        if (t_check_status("408|5[0-9][0-9]")) {
        #choose route domain 1 of the default carrier
        if(!cr_route("default", "1", "$rU", "$rU", "call_id")){
                        t_reply("403", "Not allowed");
                } else {
                        t_on_failure("2");
                        t_relay();
                }
        }
}

failure_route[2] {
        # further processing
}

   Example 1.15. Configuration example - Routing to user tree
...
route[1] {
        cr_user_carrier("$fU", "$fd", "$avp(s:carrier)");

        # just an example domain
        $avp(s:domain)="start";
        if (!cr_route("$avp(s:carrier)", "$avp(s:domain)", "$rU", "$rU",
                        "call_id")) {
                xlog("L_ERR", "cr_route failed\n");
                exit;
        }
        # if you store also the port as part of the rewrite host,
        # otherwise you can just use $rd later
        $avp(s:host)= $rd+":"+$rp;
        t_on_failure("1");
                if (!t_relay()) {
                        sl_reply_error();
        };
}

failure_route[1] {
        revert_uri();
        if (!cr_next_domain("$avp(s:carrier)", "$avp(s:domain)", "$rU",
                        "$avp(s:host)", "$T_reply_code", "$avp(s:domain)")) {
                xlog("L_ERR", "cr_next_domain failed\n");
                exit;
        }
        if (!cr_route("$avp(s:carrier)", "$avp(s:domain)", "$rU", "$rU",
                        "call_id")) {
                xlog("L_ERR", "cr_route failed\n");
                exit;
        }
        $avp(s:host)= $rd+":"+$rp;
        t_on_failure("1");
        if (!t_relay()) {
                xlog("L_ERR", "t_relay failed\n");
                exit;
        };
}
...

   Example 1.16. Configuration example - module configuration

   The following config file specifies within the default carrier two
   domains, each with an prefix that contains two hosts. It is not
   possible to specify another carrier if you use the config file as data
   source.

   All traffic will be equally distributed between the hosts, both are
   active. The hash algorithm will working over the [1,2] set, messages
   hashed to one will go to the first host, the other to the second one.
   Don't use a hash index value of zero. If you omit the hash completely,
   the module gives them a autogenerated value, starting from one.

   Use the “NULL” prefix to specify an empty prefix in the config file.
   Please note that the prefix is matched against the request URI (or to
   URI), if they did not contain a valid (numerical) URI, no match is
   possible. So for load-balancing purposes e.g. for your registrars, you
   should use an empty prefix.
...
domain proxy {
   prefix 49 {
     max_targets = 2
      target proxy1.localdomain {
         prob = 0.500000
         hash_index = 1
         status = 1
         comment = "test target 1"
      }
      target proxy2.localdomain {
         prob = 0.500000
         hash_index = 2
         status = 1
         comment = "test target 2"
      }
   }
}

domain register {
   prefix NULL {
     max_targets = 2
      target register1.localdomain {
         prob = 0.500000
         hash_index = 1
         status = 1
         comment = "test target 1"
      }
      target register2.localdomain {
         prob = 0.500000
         hash_index = 2
         status = 1
         comment = "test target 2"
      }
   }
}
...

7. Installation and Running

   7.1. Database setup
   7.2. Database examples
   7.3. User specific routing

7.1. Database setup

   Before running Kamailio with carrierroute, you have to setup the
   database table where the module will store the routing data. For that,
   if the table was not created by the installation script or you choose
   to install everything by yourself you can use the
   carrierroute-create.sql SQL script in the database directories in the
   kamailio/scripts folder as template. Database and table name can be set
   with module parameters so they can be changed, but the name of the
   columns must be as they are in the SQL script. You can also find the
   complete database documentation on the project webpage,
   https://www.kamailio.org/docs/db-tables/kamailio-db-devel.html. The
   flags and mask columns have the same function as in the
   carrierfailureroute table. A zero value in the flags and mask column
   means that any message flags will match this rule.

   For a minimal configuration either use the config file given above, or
   insert some data into the tables of the module.

7.2. Database examples

   Example 1.17. Example database content - carrierroute table
...
+----+---------+--------+-------------+-------+------+---------------+
| id | carrier | domain | scan_prefix | flags | prob | rewrite_host  |
+----+---------+--------+-------------+-------+------+---------------+
| 1  |       1 |      1 | 49          |     0 |  0.5 | de-1.carrier1 |
| 2  |       1 |      1 | 49          |     0 |  0.5 | de-2.carrier1 |
| 3  |       1 |      1 | 49          |    16 |    1 | de-3.carrier1 |
| 4  |       1 |      1 |             |     0 |    1 | gw.carrier1-1 |
| 5  |       1 |      2 | 49          |     0 |    1 | gw.carrier1-1 |
| 6  |       1 |      3 |             |     0 |    1 | gw.carrier1-2 |
| 7  |       1 |      4 |             |     0 |    1 | gw.carrier1-3 |
| 8  |       2 |      1 | 49          |     0 |  0.5 | de-1.carrier2 |
| 9  |       2 |      1 | 49          |     0 |  0.5 | de-2.carrier2 |
| 10 |       2 |      1 |             |     0 |    1 | gw.carrier2   |
| 11 |       2 |      2 | 49          |     0 |    1 | gw.carrier2   |
| 12 |       3 |      8 | 49          |     0 |    1 | de-gw.default |
| 13 |       3 |      8 |             |     0 |    1 | gw.default    |
+----+---------+--------+-------------+-------+------+---------------+
...

   This table contains three routes to two gateways for the “49” prefix,
   and a default route for other prefixes over carrier 2 and carrier 1.
   The gateways for the default carrier will be used for functions that
   don't support the user specific carrier lookup. The routing rules for
   carrier 1 and carrier 2 for the “49” prefix contains a additional rule
   with the domain 2, that can be used for example as fallback if the
   gateways in domain 1 are not reachable. Two more fallback rules (domain
   3 and 4) for carrier 1 are also supplied to support the functionality
   of the carrierfailureroute table example that is provided in the next
   section.

   This table provides also a “carrier 1” routing rule for the “49”
   prefix, that is only chosen if some message flags are set. If this
   flags are not set, the other two rules are used. The “strip”, “mask”
   and “comment” columns are omitted for brevity.

   Example 1.18. Example database content - simple carrierfailureroute
   table
...
+----+---------+--------+---------------+------------+-------------+
| id | carrier | domain | host_name     | reply_code | next_domain |
+----+---------+--------+---------------+------------+-------------+
|  1 |       1 | 1      | gw.carrier1-2 | ...        | 3           |
|  2 |       1 | 1      | gw.carrier1-3 | ...        | 2           |
+----+---------+--------+---------------+------------+-------------+
...

   This table contains two failure routes for the “gw.carrier1-1” and “-2”
   gateways. For any (failure) reply code the respective next domain is
   chosen. After that no more failure routes are available, an error will
   be returned from the “cr_next_domain” function. Not all table columns
   are show here for brevity.

   For each failure route domain and carrier that is added to the
   carrierfailureroute table there must be at least one corresponding
   entry in the carrierroute table, otherwise the module will not load the
   routing data.

   Example 1.19. Example database content - more complex
   carrierfailureroute table
...
+----+---------+-----------+------------+--------+-----+-------------+
| id | domain  | host_name | reply_code | flags | mask | next_domain |
+----+---------+-----------+------------+-------+------+-------------+
|  1 |      99 |           | 408        |    16 |   16 |             |
|  2 |      99 | gw1       | 404        |     0 |    0 | 100         |
|  3 |      99 | gw2       | 50.        |     0 |    0 | 100         |
|  4 |      99 |           | 404        |  2048 | 2112 | 101         |
+----+---------+-----------+------------+-------+------+-------------+
...

   This table contains four failure routes that shows the usage of more
   advanced features. The first route matches to a 408, and to some flag
   for example that indicates that ringing has happened. If this flag is
   set, there will be no further forwarding, because next_domain is empty.
   In the second and third routes are certain gateway errors matched, if
   this errors have occurred, then the next domain will be chosen. Note
   that the reply_code must be 3 characters wide, and only the "."
   character is accepted as wildcard.The last route does forwarding
   according some flags, e.g. the customer came from a certain carrier,
   and has call-forwarding deactivated. In order to use the routing that
   is specified above, a matching carrierroute table must be provided,
   that holds domain entries for this routing rules. Not all table columns
   are show here for brevity.

   Example 1.20. Example database content - carrier_name table
...
+----+----------+
| id | carrier  |
+----+----------+
|  1 | carrier1 |
|  2 | carrier2 |
|  3 | default  |
+----+----------+
...

   This table contains the mapping of the carrier id to actual names.

   Example 1.21. Example database content - domain_name table
...
+----+----------+
| id | domain   |
+----+----------+
|  1 | domain1  |
|  2 | domain2  |
|  3 | domain3  |
+----+----------+
...

   This table contains the mapping of the domain id to actual names.

7.3. User specific routing

   For a functional routing the “cr_preferred_carrier” column must be
   added to the subscriber table (or to the table and column that you
   specified as module parameter) to choose the actual carrier for the
   users.

   Example 1.22. Necessary extensions for the user table

   Suggested changes:
...
ALTER TABLE subscriber ADD cr_preferred_carrier int(10) default NULL;
...

Chapter 2. Module parameter for database access.

   Table of Contents

   1. db_url (String)
   2. carrierroute_table (String)
   3. carrierroute_id_col (string)
   4. carrierroute_carrier_col (string)
   5. carrierroute_domain_col (string)
   6. carrierroute_scan_prefix_col (string)
   7. carrierroute_flags_col (string)
   8. carrierroute_mask_col (string)
   9. carrierroute_prob_col (string)
   10. carrierroute_strip_col (string)
   11. carrierroute_rewrite_host_col (string)
   12. carrierroute_rewrite_prefix_col (string)
   13. carrierroute_rewrite_suffix_col (string)
   14. carrierroute_description_col (string)
   15. carrierfailureroute_table (String)
   16. carrierfailureroute_id_col (string)
   17. carrierfailureroute_carrier_col (string)
   18. carrierfailureroute_domain_col (string)
   19. carrierfailureroute_scan_prefix_col (string)
   20. carrierfailureroute_host_name_col (string)
   21. carrierfailureroute_reply_code_col (string)
   22. carrierfailureroute_flags_col (string)
   23. carrierfailureroute_mask_col (string)
   24. carrierfailureroute_next_domain_col (string)
   25. carrierfailureroute_description_col (string)
   26. carrier_name_table (String)
   27. carrier_name_id_col (string)
   28. carrier_name_carrier_col (string)
   29. domain_name_table (String)
   30. domain_name_id_col (string)
   31. domain_name_domain_col (string)

1. db_url (String)

   URL to the database containing the data.

   Default value is “mysql://kamailioro:kamailioro@localhost/kamailio”.

   Example 2.1. Set db_url parameter
...
modparam("carrierroute", "db_url", "dbdriver://username:password@dbhost/dbname")
...

2. carrierroute_table (String)

   Name of the carrierroute table for the carrierroute module.

   Default value is “carrierroute”.

   Example 2.2. Set carrierroute_table parameter
...
modparam("carrierroute", "carrierroute_table", "carrierroute")
...

3. carrierroute_id_col (string)

   Name of the column contains the unique identifier of a route.

   Example 2.3. Set carrierroute_id_col parameter
...
modparam("carrierroute", "carrierroute_id_col", "id")
...

4. carrierroute_carrier_col (string)

   This column contains the carrier id.

   Example 2.4. Set carrierroute_carrier_col parameter
...
modparam("carrierroute", "carrierroute_carrier_col", "carrier")
...

5. carrierroute_domain_col (string)

   This column contains the routing domain id. You can define several
   routing domains to have different routing rules. Maybe you use domain 0
   for normal routing and domain 1 if domain 0 failed.

   Example 2.5. Set carrierroute_domain_col parameter
...
modparam("carrierroute", "carrierroute_domain_col", "domain")
...

6. carrierroute_scan_prefix_col (string)

   Name of column contains the scan prefixes. Scan prefixes define the
   matching portion of a phone number, e.g. when we have the scan prefixes
   49721 and 49, the called number is 49721913740, it matches 49721,
   because the longest match is taken. If no prefix matches, the number is
   not routed. To prevent this, an empty prefix value of could be added.

   Example 2.6. Set carrierroute_scan_prefix_col parameter
...
modparam("carrierroute", "carrierroute_scan_prefix_col", "scan_prefix")
...

7. carrierroute_flags_col (string)

   This column contains the flags used for rule matching.

   Example 2.7. Set carrierroute_flags_col parameter
...
modparam("carrierroute", "carrierroute_flags_col", "flags")
...

8. carrierroute_mask_col (string)

   This column contains the mask that is applied to the message flags
   before rule matching.

   Example 2.8. Set carrierroute_mask_col parameter
...
modparam("carrierroute", "carrierroute_mask_col", "mask")
...

9. carrierroute_prob_col (string)

   Name of column contains the probability. The probability value is used
   to distribute the traffic between several gateways. Let's say 70 % of
   the traffic shall be routed to gateway A, the other 30 % shall be
   routed to gateway B, we define a rule for gateway A with a prob value
   of 0.7 and a rule for gateway B with a prob value of 0.3. If all
   probabilities for a given prefix, tree and domain don't add to 100%,
   the prefix values will be adjusted according the given prob values.
   E.g. if three hosts with prob values of 0.5, 0.5 and 0.4 are defined,
   the resulting probabilities are 35.714, 35.714 and 28.571%. But its
   better to choose meaningful values in the first place because of
   clarity.

   Example 2.9. Set carrierroute_prob_col parameter
...
modparam("carrierroute", "carrierroute_prob_col", "prob")
...

10. carrierroute_strip_col (string)

   Name of the column contains the number of digits to be stripped of the
   userpart of an URI before prepending rewrite_prefix.

   Example 2.10. Set carrierroute_strip_col parameter
...
modparam("carrierroute", "carrierroute_strip_col", "strip")
...

11. carrierroute_rewrite_host_col (string)

   Name of column contains the rewrite prefixes. Here you can define a
   rewrite prefix for the localpart of the SIP URI. An empty field
   represents a blocklist entry, anything else is put as domain part into
   the Request URI of the SIP message.

   Example 2.11. Set carrierroute_rewrite_host_col parameter
...
modparam("carrierroute", "carrierroute_rewrite_host_col", "rewrite_host")
...

12. carrierroute_rewrite_prefix_col (string)

   Name of column contains the rewrite prefixes. Here you can define a
   rewrite prefix for the localpart of the SIP URI.

   Example 2.12. Set carrierroute_rewrite_prefix_col parameter
...
modparam("carrierroute", "carrierroute_rewrite_prefix_col", "rewrite_prefix")
...

13. carrierroute_rewrite_suffix_col (string)

   Name of column contains the rewrite suffixes. Here you can define a
   rewrite suffix for the localpart of the SIP URI.

   Example 2.13. Set carrierroute_rewrite_suffix_col parameter
...
modparam("carrierroute", "carrierroute_rewrite_suffix_col", "rewrite_suffix")
...

14. carrierroute_description_col (string)

   A comment for the route entry, useful for larger routing tables. The
   comment is also displayed by the rpc cmd "cr.dump_routes".

   Example 2.14. Set carrierroute_description_col parameter
...
modparam("carrierroute", "carrierroute_description_col", "description")
...

15. carrierfailureroute_table (String)

   Name of the carrierfailureroute table for the carrierroute module.

   Default value is “carrierfailureroute”.

   Example 2.15. Set carrierfailureroute_table parameter
...
modparam("carrierroute", "carrierfailureroute_table", "carrierfailureroute")
...

16. carrierfailureroute_id_col (string)

   This column contains the unique identifier of a failure route.

   Example 2.16. Set carrierfailureroute_id_col parameter
...
modparam("carrierroute", "carrierfailureroute_id_col", "id")
...

17. carrierfailureroute_carrier_col (string)

   This column contains the carrier id.

   Example 2.17. Set carrierfailureroute_carrier_col parameter
...
modparam("carrierroute", "carrierfailureroute_carrier_col", "carrier")
...

18. carrierfailureroute_domain_col (string)

   This column contains the routing domain id. You can define several
   routing domains to have different routing rules. Maybe you use domain 0
   for normal routing and domain 1 if domain 0 failed.

   Example 2.18. Set carrierfailureroute_domain_col parameter
...
modparam("carrierroute", "carrierfailureroute_domain_col", "domain")
...

19. carrierfailureroute_scan_prefix_col (string)

   Name of column contains the scan prefixes. Scan prefixes define the
   matching portion of a phone number, e.g. we have the scan prefixes
   49721 and 49, the called number is 49721913740, it matches 49721,
   because the longest match is taken. If no prefix matches, the number is
   not failure routed. To prevent this, an empty prefix value of could be
   added.

   Example 2.19. Set carrierfailureroute_scan_prefix_col parameter
...
modparam("carrierroute", "carrierfailureroute_scan_prefix_col", "scan_prefix")
...

20. carrierfailureroute_host_name_col (string)

   Name of the column containing the host name of the last routing
   destination, using for rules matching.

   Example 2.20. Set carrierfailureroute_host_name_col parameter
...
modparam("carrierroute", "carrierfailureroute_host_name_col", "host_name")
...

21. carrierfailureroute_reply_code_col (string)

   This column contains the reply code used for rule matching.

   Example 2.21. Set carrierfailureroute_reply_code_col parameter
...
modparam("carrierroute", "carrierfailureroute_reply_code_col", "reply_code")
...

22. carrierfailureroute_flags_col (string)

   This column contains the flags used for rule matching.

   Example 2.22. Set carrierfailureroute_flags_col parameter
...
modparam("carrierroute", "carrierfailureroute_flags_col", "flags")
...

23. carrierfailureroute_mask_col (string)

   This column contains the mask that is applied to the message flags
   before rule matching.

   Example 2.23. Set carrierfailureroute_mask_col parameter
...
modparam("carrierroute", "carrierfailureroute_mask_col", "mask")
...

24. carrierfailureroute_next_domain_col (string)

   This column contains the route domain id that should be used for the
   next routing attempt.

   Example 2.24. Set carrierfailureroute_next_domain_col parameter
...
modparam("carrierroute", "carrierfailureroute_next_domain_col", "next_domain")
...

25. carrierfailureroute_description_col (string)

   A comment for the route entry, useful for larger routing tables.

   Example 2.25. Set carrierfailureroute_description_col parameter
...
modparam("carrierroute", "carrierfailureroute_description_col", "description")
...

26. carrier_name_table (String)

   Name of the carrier_name table for the carrierroute module.

   Default value is “carrier_name”.

   Example 2.26. Set carrier_name_table parameter
...
modparam("carrierroute", "carrier_name_table", "carrier_name")
...

27. carrier_name_id_col (string)

   Name of the column containing the unique identifier of a carrier.

   Example 2.27. Set carrier_name_id_col parameter
...
modparam("carrierroute", "carrier_name_id_col", "id")
...

28. carrier_name_carrier_col (string)

   This column contains the carrier name.

   Example 2.28. Set carrier_name_carrier_col parameter
...
modparam("carrierroute", "carrier_name_carrier_col", "carrier")
...

29. domain_name_table (String)

   Name of the domain_name table for the carrierroute module.

   Default value is “domain_name”.

   Example 2.29. Set domain_name_table parameter
...
modparam("carrierroute", "domain_name_table", "domain_name")
...

30. domain_name_id_col (string)

   Name of the column containing the unique identifier of a domain.

   Example 2.30. Set domain_name_id_col parameter
...
modparam("carrierroute", "domain_name_id_col", "id")
...

31. domain_name_domain_col (string)

   This column contains the domain name.

   Example 2.31. Set domain_name_domain_col parameter
...
modparam("carrierroute", "domain_name_domain_col", "domain")
...
