<?xml version="1.0" encoding='UTF-8'?>
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.4//EN"
  "http://www.oasis-open.org/docbook/xml/4.4/docbookx.dtd" [
  <!ENTITY % local.common.attrib "xmlns:xi CDATA #FIXED 'http://www.w3.org/2001/XInclude'">
  <!ENTITY % docentities SYSTEM "../../../../doc/docbook/entities.xml">
  %docentities;
]>

<chapter>
  <title>&adminguide;</title>
  <section>
    <title>Overview</title>
    <para>A module which provides routing, balancing and blocklisting capabilities.</para>
    <para>
        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 use 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.
    </para>
    <para>
        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.
    </para>
    <para>
        This module 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.
    </para>
    <para>
        Routing tables can be reloaded and edited (in config file mode) with the RPC
        interface, the config file is updated according to the changes. This is not
        implemented for the db interface, because it is easier to do the changes
        directly on the db. But the reload and dump functions work of course here
        as well.
    </para>
    <para>
        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 a later sections. For user based routing or LCR you should use the database mode.
    </para>
    <para>
        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 using learner search to find the needed
        data structures. So from a performance point of view it is better to pass only IDs in
        the routing functions.
    </para>
    <para>
        Basically this module could be used as a replacement for the lcr and the
        dispatcher module, if you have certain flexibility, integration and/or performance
        requirements that can not be satisfied with these modules. But for smaller
        installations it probably make more sense to use the lcr and dispatcher module.
    </para>
    <para>
        Starting with version 3.1 , if you want to use this module in failure routes,
        it is not needed to call<quote>append_branch()</quote> after rewriting the request URI
        in order to relay the message to the new target. It also supports the usage of database
        drived failure routing decisions using the carrierfailureroute table.
    </para>
  </section>
  <section>
    <title>Dependencies</title>
    <section>
      <title>&kamailio; Modules</title>
      <para>
        The following module must be loaded before this module:
        <itemizedlist>
          <listitem>
            <para>
              <emphasis>a database module</emphasis>,
              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. It is not possible to use the dbtext or db_berkeley module at the moment.
            </para>
          </listitem>
          <listitem>
            <para>
              The <emphasis>tm module</emphasis>,
              when you want to use the $T_reply_code pseudo-variable in the <quote>cr_next_domain</quote>
              function.
            </para>
          </listitem>
        </itemizedlist>
      </para>
    </section>
  </section>
  <section>
    <title>Parameters</title>
    <section>
      <title><varname>subscriber_table</varname> (string)</title>
      <para>
        The name of the table containing the subscribers
      </para>
      <para>
        <emphasis>
          Default value is <quote>subscriber</quote>.
        </emphasis>
      </para>
      <example>
        <title>Set <varname>subscriber_table</varname> parameter</title>
        <programlisting format="linespecific">
...
modparam("carrierroute", "subscriber_table", "subscriber")
...
        </programlisting>
      </example>
    </section>
    <section>
      <title><varname>subscriber_user_col</varname> (string)</title>
      <para>
        The name of the column in the subscriber table containing the usernames.
      </para>
      <para>
        <emphasis>
          Default value is <quote>username</quote>.
        </emphasis>
      </para>
      <example>
        <title>Set <varname>subscriber_user_col</varname> parameter</title>
        <programlisting format="linespecific">
...
modparam("carrierroute", "subscriber_user_col", "username")
...
        </programlisting>
      </example>
    </section>
    <section>
      <title><varname>subscriber_domain_col</varname> (string)</title>
      <para>
        The name of the column in the subscriber table containing the domain of
        the subscriber.
      </para>
      <para>
        <emphasis>
          Default value is <quote>domain</quote>.
        </emphasis>
      </para>
      <example>
        <title>Set <varname>subscriber_domain_col</varname> parameter</title>
        <programlisting format="linespecific">
...
modparam("carrierroute", "subscriber_domain_col", "domain")
...
        </programlisting>
      </example>
    </section>
    <section>
      <title><varname>subscriber_carrier_col</varname> (string)</title>
      <para>
        The name of the column in the subscriber table containing the carrier id
        of the subscriber.
      </para>
      <para>
        <emphasis>
          Default value is <quote>cr_preferred_carrier</quote>.
        </emphasis>
      </para>
      <example>
        <title>Set <varname>subscriber_carrier_col</varname> parameter</title>
        <programlisting format="linespecific">
...
modparam("carrierroute", "subscriber_carrier_col", "cr_preferred_carrier")
...
        </programlisting>
      </example>
    </section>
    <section>
      <title><varname>config_source</varname> (string)</title>
      <para>
        Specifies whether the module loads its config data from a file or from a
        database. Possible values are <quote>file</quote> and <quote>db</quote>.
      </para>
      <para>
        <emphasis>
          Default value is <quote>file</quote>.
        </emphasis>
      </para>
      <example>
        <title>Set <varname>config_source</varname> parameter</title>
        <programlisting format="linespecific">
...
modparam("carrierroute", "config_source", "file")
...
        </programlisting>
      </example>
    </section>
    <section>
      <title><varname>config_file</varname> (string)</title>
      <para>
        Specifies the path to the config file. The file has to be owned by
        the user and group used to run &kamailio;.
      </para>
      <para>
        <emphasis>
          Default value is <quote>/etc/kamailio/carrierroute.conf</quote>.
        </emphasis>
      </para>
      <example>
        <title>Set <varname>config_file</varname> parameter</title>
        <programlisting format="linespecific">
...
modparam("carrierroute", "config_file", "/etc/kamailio/carrierroute.conf")
...
        </programlisting>
      </example>
    </section>
    <section>
      <title><varname>default_tree</varname> (string)</title>
      <para>
        The name of the carrier tree used per default (if the current
        subscriber has no preferred tree)
      </para>
      <para>
        <emphasis>
          Default value is <quote>default</quote>.
        </emphasis>
      </para>
      <example>
        <title>Set <varname>default_tree</varname> parameter</title>
        <programlisting format="linespecific">
...
modparam("carrierroute", "default_tree", "default")
...
        </programlisting>
      </example>
    </section>
    <section>
      <title><varname>use_domain</varname> (int)</title>
      <para>
        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.
      </para>
      <para>
        <emphasis>
          Default value is <quote>0</quote>.
        </emphasis>
      </para>
      <example>
        <title>Set <varname>use_domain</varname> parameter</title>
        <programlisting format="linespecific">
...
modparam("carrierroute", "use_domain", 0)
...
        </programlisting>
      </example>
    </section>
    <section>
      <title><varname>fallback_default</varname> (int)</title>
      <para>
        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.
      </para>
      <para>
        <emphasis>
          Default value is <quote>1</quote>.
        </emphasis>
      </para>
      <example>
        <title>Set <varname>fallback_default</varname> parameter</title>
        <programlisting format="linespecific">
...
modparam("carrierroute", "fallback_default", 1)
...
        </programlisting>
      </example>
    </section>
    <section>
      <title><varname>fetch_rows</varname> (integer)</title>
      <para>
        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.
      </para>
      <para>
        <emphasis>
          Default value is <quote>2000</quote>.
        </emphasis>
      </para>
      <example>
        <title>Set <varname>fetch_rows</varname> parameter</title>
        <programlisting format="linespecific">
...
modparam("carrierroute", "fetch_rows", 3000)
...
        </programlisting>
      </example>
    </section>
    <section>
      <title><varname>db_load_description</varname> (integer)</title>
      <para>
        Toggle on/off loading in memory the description column in the
        carrierroute/carrierfailureroute database tables. This reduces the
        shared memory used by the module.
      </para>
      <para>
        <emphasis>
          Default value is <quote>1</quote>.
        </emphasis>
      </para>
      <example>
        <title>Unset <varname>db_load_description</varname> parameter</title>
        <programlisting format="linespecific">
...
modparam("carrierroute", "db_load_description", 0)
...
        </programlisting>
      </example>
    </section>
    <section>
      <title><varname>match_mode</varname> (integer)</title>
      <para>
        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.
      </para>
      <para>
        <emphasis>
          Default value is <quote>10</quote>.
        </emphasis>
      </para>
      <example>
        <title>Set <varname>match_mode</varname> parameter</title>
        <programlisting format="linespecific">
...
modparam("carrierroute", "match_mode", 10)
...
        </programlisting>
      </example>
    </section>
    <section>
      <title><varname>avoid_failed_destinations</varname> (integer)</title>
      <para>
        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.
      </para>
      <para>
        <emphasis>
          Default value is <quote>1</quote>.
        </emphasis>
      </para>
      <example>
        <title>Set <varname>avoid_failed_destinations</varname> parameter</title>
        <programlisting format="linespecific">
...
modparam("carrierroute", "avoid_failed_destinations", 0)
...
        </programlisting>
      </example>
    </section>
  </section>
  <section>
    <title>Functions</title>
    <para>
      Previous versions of carrierroute had some more function. All the
      old semantics can be achieved by using the few new functions
      like this:
    </para>
    <programlisting format="linespecific">
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")

    </programlisting>
    <section>
      <title>
        <function moreinfo="none">cr_user_carrier(user, domain, dstvar)</function>
      </title>
      <para>
        This function loads the carrier and stores it in a config variable.
        It cannot be used in the config file mode, as it needs a mapping of the
        given user to a certain carrier. The is drived from a database entry
        belonging to the user parameter. This mapping must be available in the
        table that is specified in the <quote>subscriber_table</quote> variable.
        This data is not cached in memory, that means for every execution of this
        function a database query will be done.
      </para>
      <para>Meaning of the parameters is as follows:</para>
      <itemizedlist>
        <listitem>
          <para>
            <emphasis>user</emphasis> - Name of the user for the carrier tree lookup.
            Additional to a string any pseudo-variable could be used as input.
          </para>
        </listitem>
        <listitem>
          <para>
            <emphasis>domain</emphasis> - Name of the routing domain to be used.
            Additional to a string any pseudo-variable could be used as input.
          </para>
        </listitem>
        <listitem>
          <para>
            <emphasis>dstvar</emphasis> - Name of the writable config variable
            (e.g., an AVP) where to store the carrier id.
          </para>
        </listitem>
      </itemizedlist>
    </section>
    <section>
      <title>
        <function moreinfo="none">cr_route(carrier, domain, prefix_matching, rewrite_user, hash_source, descavp)</function>
      </title>
      <para>
        This function searches for the longest match for the user given
        in prefix_matching with 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,
        it also stores the carrier description in the given AVP (if present).
        This is useful if you need some additional informations that belongs
        to each gw, like the destination uri, force socket or any arbitrary info.
      </para>
      <para>
        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 this function. This situation can appear
        when different route domains contain a set of common gateways.
      </para>
      <para>
        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.
      </para>
      <para>
        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
        <quote>0</quote> 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.
      </para>
      <para>
        Meaning of the parameters is as follows:
      </para>
      <itemizedlist>
        <listitem>
          <para>
            <emphasis>carrier</emphasis> - The routing tree to be used. It must be
            string containing either carrier id (nummeric) or carrier name (arbitrary string).
            It also accepts any pseudo-variable as input.
          </para>
        </listitem>
        <listitem>
          <para>
            <emphasis>domain</emphasis> - Name of the routing domain to be used. it must be
            string containing either domain id (nummeric) or domain name (arbitrary string).
            It also accepts any pseudo-variable as input.
          </para>
        </listitem>
        <listitem>
          <para>
            <emphasis>prefix_matching</emphasis> - User name to be used for prefix matching
            in the routing tree.
            It also accepts any pseudo-variable as input
          </para>
        </listitem>
        <listitem>
          <para>
            <emphasis>rewrite_user</emphasis> - The user name to be used for applying the
            rewriting rule. Usually this is the user part of the request URI.
            It also accepts any pseudo-variable as input
          </para>
        </listitem>
        <listitem>
          <para>
            <emphasis>hash_source</emphasis> - The hash values of the destination set, it must
            be a contiguous range starting at 1, limited by the configuration parameter
            <quote>max_targets</quote>. Possible values for hash_source are: <quote>call_id</quote>,
            <quote>from_uri</quote>, <quote>from_user</quote>, <quote>to_uri</quote>,
            <quote>to_user</quote> and <quote>rand</quote>.
          </para>
        </listitem>
        <listitem>
          <para>
            <emphasis>decsavp</emphasis> - AVP where to store the description.
            This parameter is optional.
          </para>
        </listitem>
      </itemizedlist>
    </section>
    <section>
      <title>
        <function moreinfo="none">cr_nofallback_route(carrier, domain, prefix_matching, rewrite_user, hash_source, descavp)</function>
      </title>
      <para>
        This function searches for the longest match for the user given
        in prefix_matching with 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
        it also stores the carrier description in the given AVP (if present).
        This is useful if you need some additional informations that belongs
        to each gw, like the destination uri, force socket or any arbitrary info.
      </para>
      <para>
        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.
      </para>
      <para>
        It uses the standard CRC32 algorithm to calculate the hash values. In contrast
        to the normal <emphasis>cr_route</emphasis> function, the backup rules of
        (now obsolete) cr_prime_route is used. This means none of the configured
        probabilities will be used, only a fixed hash distribution is used. 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.
      </para>
      <para>Meaning of the parameters is as follows:</para>
      <itemizedlist>
        <listitem>
          <para>
            <emphasis>carrier</emphasis> - The routing tree to be used. It must be
            string containing either carrier id (nummeric) or carrier name (arbitrary string).
            It also accepts any pseudo-variable as input.
          </para>
        </listitem>
        <listitem>
          <para>
            <emphasis>domain</emphasis> - Name of the routing domain to be used. it must be
            string containing either domain id (nummeric) or domain name (arbitrary string).
            It also accepts any pseudo-variable as input
          </para>
        </listitem>
        <listitem>
          <para>
            <emphasis>prefix_matching</emphasis> - User name to be used for prefix matching
            in the routing tree.
            It also accepts any pseudo-variable as input
          </para>
        </listitem>
        <listitem>
          <para>
            <emphasis>rewrite_user</emphasis> - The user name to be used for applying the
            rewriting rule. Usually this is the user part of the request URI.
            It also accepts any pseudo-variable as input
          </para>
        </listitem>
        <listitem>
          <para>
            <emphasis>hash_source</emphasis> - The hash values of the destination set, it must
            be a contiguous range starting at 1, limited by the configuration parameter
            <quote>max_targets</quote>. Possible values for hash_source are: <quote>call_id</quote>,
            <quote>from_uri</quote>, <quote>from_user</quote>, <quote>to_uri</quote>,
            <quote>to_user</quote> and <quote>rand</quote>.
          </para>
        </listitem>
        <listitem>
          <para>
            <emphasis>decsavp</emphasis> - AVP where to store the description.
            This parameter is optional.
          </para>
        </listitem>
      </itemizedlist>
    </section>
    <section>
      <title>
        <function moreinfo="none">cr_next_domain(carrier, domain, prefix_matching, host, reply_code, dstavp)</function>
      </title>
      <para>
        This function searches for the longest match for the user given
        in prefix_matching with 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: <quote>host</quote> then <quote>reply_code</quote> and
        then <quote>flags</quote>. The more wildcards in reply_code
        and the more bits used in flags, the lower the priority will be.
        Returns -1, if there is no data found or if the next_domain on the
        longest match is empty. Otherwise the next domain is stored in the
        given variable.
      </para>
      <para>
        This function is only usable if rewrite_user and prefix_matching
        contains a valid string. This string must be numerical if the
        match_mode parameter is set to 10.
      </para>
      <para>Meaning of the parameters is as follows:</para>
      <itemizedlist>
        <listitem>
          <para>
            <emphasis>carrier</emphasis> - The routing tree to be used. It must be
            string containing either carrier id (nummeric) or carrier name (arbitrary string).
            It also accepts any pseudo-variable as input.
          </para>
        </listitem>
        <listitem>
          <para>
            <emphasis>domain</emphasis> - Name of the routing domain to be used. it must be
            string containing either domain id (nummeric) or domain name (arbitrary string).
            It also accepts any pseudo-variable as input.
          </para>
        </listitem>
        <listitem>
          <para><emphasis>prefix_matching</emphasis> - User name to be used for prefix matching
            in the routing tree.
            It also accepts any pseudo-variable as input.
          </para>
        </listitem>
        <listitem>
          <para><emphasis>host</emphasis> - 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.
            It also accepts any pseudo-variable as input
          </para>
        </listitem>
        <listitem>
          <para><emphasis>reply_code</emphasis> - The reply code to be used for failure route rule
            matching.
            It also accepts any pseudo-variable as input
          </para>
        </listitem>
        <listitem>
          <para>
            <emphasis>dstavp</emphasis> - Name of the AVP where to store the next
            routing domain.
          </para>
        </listitem>
      </itemizedlist>
    </section>
  </section>
  <xi:include href="rpc.xml"/>
  <section>
    <title>Configuration examples</title>
    <example>
      <title>Configuration example - Routing to default tree</title>
      <programlisting format="linespecific">
...
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
}

      </programlisting>
    </example>
    <example>
      <title>Configuration example - Routing to user tree</title>
      <programlisting format="linespecific">
...
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;
    };
}
...
      </programlisting>
    </example>
    <example>
      <title>Configuration example - module configuration</title>
      <para>
        The following config file specifies within the default carrier two
        domains, each with a prefix that contains two hosts. It is not possible
        to specify another carrier if you use the config file as data source.
      </para>
      <para>
        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 an autogenerated value, starting from one.
      </para>
      <para>
        Use the <quote>NULL</quote> 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.
      </para>
      <programlisting format="linespecific">
...
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"
      }
   }
}
...
      </programlisting>
    </example>
  </section>
  <section>
    <title>Installation and Running</title>
    <section>
      <title>Database setup</title>
      <para>
        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
        <acronym>SQL</acronym> 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 <acronym>SQL</acronym> script.
        You can also find the complete database documentation on the
        project webpage, &kamailiodbdocs;.
        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.
      </para>
      <para>
        For a minimal configuration either use the config file given above, or
        insert some data into the tables of the module.
      </para>
    </section>
    <section>
      <title>Database examples</title>
      <example>
        <title>Example database content - carrierroute table</title>
        <programlisting format="linespecific">
...
+----+---------+--------+-------------+-------+------+---------------+
| 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    |
+----+---------+--------+-------------+-------+------+---------------+
...
        </programlisting>
      </example>
      <para>
        This table contains three routes to two gateways for the <quote>49</quote> 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 <quote>49</quote> prefix contains an 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.
      </para>
      <para>
        This table provides also a <quote>carrier 1</quote> routing rule for the
        <quote>49</quote> prefix, that is only chosen if some message flags are set.
        If this flags are not set, the other two rules are used. The <quote>strip</quote>,
        <quote>mask</quote> and <quote>comment</quote> columns are omitted for brevity.
      </para>
      <example>
        <title>Example database content - simple carrierfailureroute table</title>
        <programlisting format="linespecific">
...
+----+---------+--------+---------------+------------+-------------+
| id | carrier | domain | host_name     | reply_code | next_domain |
+----+---------+--------+---------------+------------+-------------+
|  1 |       1 | 1      | gw.carrier1-2 | ...        | 3           |
|  2 |       1 | 1      | gw.carrier1-3 | ...        | 2           |
+----+---------+--------+---------------+------------+-------------+
...
        </programlisting>
      </example>
      <para>
        This table contains two failure routes for the <quote>gw.carrier1-1</quote> and
        <quote>-2</quote> 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 <quote>cr_next_domain</quote> function. Not all table
        columns are shown here for brevity.
      </para>
      <para>
        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.
      </para>
      <example>
        <title>Example database content - more complex carrierfailureroute table</title>
        <programlisting format="linespecific">
...
+----+---------+-----------+------------+--------+-----+-------------+
| 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         |
+----+---------+-----------+------------+-------+------+-------------+
...
</programlisting>
	</example>
		<para>
			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 shown here for
			brevity.
		</para>

	<example>
		<title>Example database content - carrier_name table</title>
		<programlisting format="linespecific">
...
+----+----------+
| id | carrier  |
+----+----------+
|  1 | carrier1 |
|  2 | carrier2 |
|  3 | default  |
+----+----------+
...
        </programlisting>
      </example>
      <para>
        This table contains the mapping of the carrier id to actual names.
      </para>
      <example>
        <title>Example database content - domain_name table</title>
        <programlisting format="linespecific">
...
+----+----------+
| id | domain   |
+----+----------+
|  1 | domain1  |
|  2 | domain2  |
|  3 | domain3  |
+----+----------+
...
        </programlisting>
      </example>
      <para>
        This table contains the mapping of the domain id to actual names.
      </para>
    </section>
    <section>
      <title>User specific routing</title>
      <para>
        For a functional routing the <quote>cr_preferred_carrier</quote> 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.
      </para>
      <example>
        <title>Necessary extensions for the user table</title>
        <para>Suggested changes:</para>
        <programlisting format="linespecific">
...
ALTER TABLE subscriber ADD cr_preferred_carrier int(10) default NULL;
...
        </programlisting>
      </example>
    </section>
  </section>
</chapter>
