<?xml version="1.0" encoding='ISO-8859-1'?>
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.4//EN"
"http://www.oasis-open.org/docbook/xml/4.4/docbookx.dtd" [

<!-- Include general documentation entities -->
<!ENTITY % docentities SYSTEM "../../../docbook/entities.xml">
%docentities;

]>
<!-- Module User's Guide -->

<chapter>
	
	<title>&adminguide;</title>
	
	<section>
	<title>Overview</title>
	<para>
	The Least Cost Routing (LCR) module implements capability to
	serially forward a request to one or more gateways so that the
	order in which the gateways is tried is based on admin defined
	"least cost" rules.
	</para>
	<para>
	The LCR module supports many independent LCR instances (gateways and
	least cost rules).  Each such instance has its own <emphasis>LCR
	instance identifier</emphasis>.  Identifiers of normal LCR instances
	are positive integers. Gateways may belong to special LCR instance
	with identifier 0 meaning that such gateways belong to all normal
	LCR instances.
	</para>
	<para>
	For the purpose of facilitating least cost routing of requests,
	each gateway of an LCR instance is associated with one or more 
	&lt;prefix, from uri pattern, request uri pattern, priority, weight&gt;
	tuples.  A gateway matches a request if user part of the Request-URI
	matches a "prefix", the caller's URI matches a "From-URI" pattern and
	the callee's URI matches a "Request-URI" pattern in a tuple that is
	associated with the gateway.
	</para>
	<para>
	When the function <emphasis>load_gws()</emphasis> is called,
	matching gateways (that are not currently designated as defunct)
	are ordered for forwarding purposes as follows:
	</para>
	<para>
	<itemizedlist>
            <listitem>
                <para>(1) according to longest Request-URI user part match
                </para>
            </listitem>
            <listitem>
                <para>(2) according to tuple's priority
                </para>
            </listitem>
            <listitem>
                <para>(3) according to tuple's randomized weight
                </para>
            </listitem>
        </itemizedlist>
	</para>
	<para>
	A tuple can be marked as a "stopper" tuple.  If a "stopper"
	tuple matches, then matching stops at it and all other tuples
	with shorter prefixes are not considered.
	</para>
	<para>
	Prefix is a string of characters or NULL.  From-URI
	pattern and Request-URI pattern are regular expressions (see 'man 
	pcresyntax' for syntax), an empty string, or NULL.  An empty or
	NULL From-URI pattern, Request-URI pattern or prefix matches anything.
	Smaller priority value means higher priority (highest priority
	value being 0 and lowest being 255).
	</para>
	<para>
	Weight is an integer value from 1 to 254.  Weight implementation is
	fast, but unfair favoring larger weight values at the expense smaller
	ones.  For example, if two gateways have weights 1 and 2, probability
	that the gateway with weight 1 is tried first is 1/4, not 1/3.
	Two scripts are provided in lcr/utils directory that can be used to
	check the probabilities resulting from a given set of weight values.
	Same can be done with command 'kamctl eval_weights'.
	</para>
	<para>
        The function <emphasis>next_gw()</emphasis> can then be used to
	select one gateway at a 
	time for forwarding.  Upon each call, unless "dont_strip_or_tag_flag"
	flag is set, user part of the original Request-URI is first  
	stripped by the number of characters as specified by the
	gateway's strip count and then prefixed by 
	the gateway's prefix.  Upon each call, if a gateway's hostname is
	NULL, Request-URI will be  
	rewritten based on gateway's URI scheme, IP address, port,
	parameters, and transport protocol.  If hostname is not NULL and
	IP address is NULL, Request-URI will be rewritten based on the
	gateway's URI scheme, 
	hostname, port, parameters and transport protocol.  If both
	hostname and IP address are not NULL, Request-URI will be
	rewritten based on gateway's URI scheme, 
	hostname, and parameters, and destination URI is set 
	based on gateway's URI scheme, IP address, port, and transport
	protocol.
	</para>
        <para>
        Valid URI scheme values are NULL = sip, 1 = sip and 2
	= sips.  Currently valid transport protocol values are NULL and 0 =
	none, 1 = udp, 2 = tcp, 3 = tls, and 4 = sctp.
	</para>
	<para>
	As a side effect of gateway selection, selected gateway's tag and flags
	(that may contain information about the gateway and its capabilities)
	are stored to tag_avp and flags_avp, respectively, if the corresponding
	module parameter has been defined.
	</para>
	</section>

	<section>
	<title>Dependencies</title>
	<section>
	<title>&siprouter; modules</title>
	<para>
		The following modules must be loaded before this module:
		<itemizedlist>
		<listitem>
		<para>
			<emphasis>A database module like mysql, postgres or 
			dbtext</emphasis>.
		</para>
		</listitem>
		</itemizedlist>
	</para>
	</section>
	<section>
	<title>External libraries or applications</title>
	<para>
		The following libraries or applications must be installed before
		running &siprouter; with this module:
			<itemizedlist>
			<listitem>
			<para>
				<emphasis>libpcre</emphasis>
			</para>
			</listitem>
			</itemizedlist>
	</para>
	</section>
	</section>

	<section>
	<title>Parameters</title>
	<section>
		<title><varname>db_url</varname> (string)</title>
		<para>
		&url; of the database table to be used.
		</para>
		<para>
		<emphasis>
			Default value is 
			<quote>&defaultrodb;</quote>.
		</emphasis>
		</para>
		<example>
		<title>Setting <varname>db_url</varname> module parameter</title>
		<programlisting format="linespecific">
...
modparam("lcr","db_url","&exampledb;")
...
</programlisting>
		</example>
	</section>

	<section>
		<title><varname>lcr_gw_table</varname> (string)</title>
		<para>
		Name of the table holding gateways definitions.
		</para>
		<para>
		<emphasis>
			Default value is <quote>lcr_gw</quote>.
		</emphasis>
		</para>
		<example>
		<title>Setting <varname>gw_table</varname> module parameter</title>
		<programlisting format="linespecific">
...
modparam("lcr", "lcr_gw_table","gw")
...
</programlisting>
		</example>
	</section>

	<section>
		<title><varname>id_column</varname> (string)</title>
		<para>
		Name of the auto-increment, primary key column.  Common
		to all lcr module tables.
		</para>
		<para>
		<emphasis>
			Default value is <quote>id</quote>.
		</emphasis>
		</para>
		<example>
		<title>Setting <varname>id_column</varname> module
		parameter</title> 
		<programlisting format="linespecific">
...
modparam("lcr", "id_column", "row_id")
...
</programlisting>
		</example>
	</section>

	<section>
		<title><varname>lcr_id_column</varname> (string)</title>
		<para>
		Name of the column holding the identifier of an LCR
		instance.  Common to all lcr module tables.  In lcr_rule and
		lcr_rule_target tables, value of the column is
		integer from 1 to lcr_count.  In lcr_gw table, value of the
		column is from 0 to lcr_count.
		</para>
		<para>
		<emphasis>
			Default value is <quote>lcr_id</quote>.
		</emphasis>
		</para>
		<example>
		<title>Setting <varname>lcr_id_column</varname> module
		parameter</title> 
		<programlisting format="linespecific">
...
modparam("lcr", "lcr_id_column", "lcr_identifier")
...
</programlisting>
		</example>
	</section>

	<section>
		<title><varname>gw_name_column</varname> (string)</title>
		<para>
		Name of the column holding gateway's name for
		documentation purpose.
		</para>
		<para>
		<emphasis>
			Default value is <quote>gw_name</quote>.
		</emphasis>
		</para>
		<example>
		<title>Setting <varname>gw_name_column</varname> module parameter</title>
		<programlisting format="linespecific">
...
modparam("lcr", "gw_name_column", "name")
...
</programlisting>
		</example>
	</section>

	<section>
		<title><varname>ip_addr_column</varname> (string)</title>
		<para>
		Name of the column holding the IPv4 or IPv6 address of
		the gateway.
		</para>
		<para>
		<emphasis>
			Default value is <quote>ip_addr</quote>.
		</emphasis>
		</para>
		<example>
		<title>Setting <varname>ip_addr_column</varname> module
		parameter</title> 
		<programlisting format="linespecific">
...
modparam("lcr", "ip_addr_column", "ip")
...
</programlisting>
		</example>
	</section>

	<section>
		<title><varname>hostname_column</varname> (string)</title>
		<para>
		Name of the column holding gateway's hostname that is
		used in Request-URI hostpart, when request is sent to the
		gateway.
		</para>
		<para>
		<emphasis>
			Default value is <quote>hostname</quote>.
		</emphasis>
		</para>
		<example>
		<title>Setting <varname>hostname_column</varname> module parameter</title>
		<programlisting format="linespecific">
...
modparam("lcr", "hostname_column", "host")
...
</programlisting>
		</example>
	</section>

	<section>
		<title><varname>port_column</varname> (string)</title>
		<para>
		Name of the column holding the port number of the gateway.
		</para>
		<para>
		<emphasis>
			Default value is <quote>port</quote>.
		</emphasis>
		</para>
		<example>
		<title>Setting <varname>port_column</varname> module parameter</title>
		<programlisting format="linespecific">
...
modparam("lcr", "port_column", "port")
...
</programlisting>
		</example>
	</section>

	<section>
		<title><varname>params_column</varname> (string)</title>
		<para>
		Name of the column holding gateway's parameters that is
		used in Request-URI, when request is sent to the
		gateway.
		</para>
		<para>
		<emphasis>
			Default value is <quote>params</quote>.
		</emphasis>
		</para>
		<example>
		<title>Setting <varname>params_column</varname> module parameter</title>
		<programlisting format="linespecific">
...
modparam("lcr", "params_column", "parameters")
...
</programlisting>
		</example>
	</section>

	<section>
		<title><varname>uri_scheme_column</varname> (string)</title>
		<para>
		Name of the column holding the uri scheme of the gateway.
		</para>
		<para>
		<emphasis>
			Default value is <quote>uri_scheme</quote>.
		</emphasis>
		</para>
		<example>
		<title>Setting <varname>uri_scheme_column</varname> module 
		parameter</title>
		<programlisting format="linespecific">
...
modparam("lcr", "uri_scheme_column", "uri_scheme")
...
</programlisting>
		</example>
	</section>

	<section>
		<title><varname>transport_column</varname> (string)</title>
		<para>
		Name of the column holding the transport protocol to be
		used for the gateway.
		</para>
		<para>
		<emphasis>
			Default value is <quote>transport</quote>.
		</emphasis>
		</para>
		<example>
		<title>Setting <varname>transport_column</varname> module 
		parameter</title>
		<programlisting format="linespecific">
...
modparam("lcr", "transport_column", "trans")
...
</programlisting>
		</example>
	</section>

	<section>
		<title><varname>strip_column</varname> (string)</title>
		<para>
		Name of the column holding the number of characters
		to be stripped from the front of Request-URI user part
		before inserting tag.
		</para>
		<para>
		<emphasis>
			Default value is <quote>strip</quote>.
		</emphasis>
		</para>
		<example>
		<title>Setting <varname>strip_column</varname> module 
		parameter</title>
		<programlisting format="linespecific">
...
modparam("lcr", "strip_column", "strip_count")
...
</programlisting>
		</example>
	</section>

	<section>
		<title><varname>tag_column</varname> (string)</title>
		<para>
		Name of the column holding gateway specific tag string
		that is added to Request URI userpart after stripping.
		</para>
		<para>
		<emphasis>
			Default value is <quote>tag</quote>.
		</emphasis>
		</para>
		<example>
		<title>Setting <varname>tag_column</varname> module parameter</title>
		<programlisting format="linespecific">
...
modparam("lcr", "tag_column", "gw_tag")
...
</programlisting>
		</example>
	</section>

	<section>
		<title><varname>flags_column</varname> (string)</title>
		<para>
		Name of the column holding gateway specific flag values.
		</para>
		<para>
		<emphasis>
			Default value is <quote>flags</quote>.
		</emphasis>
		</para>
		<example>
		<title>Setting <varname>flags_column</varname> module parameter</title>
		<programlisting format="linespecific">
...
modparam("lcr", "flags_column", "gw_flags")
...
</programlisting>
		</example>
	</section>

	<section>
		<title><varname>defunct_column</varname> (string)</title>
		<para>
		Name of the column holding UNIX timestamp telling the
		time until which the gw is considered as defunct.
		If timestamp value is 4294967295 (= max UNIX timestamp value)
		or greater, gw is considered currently unused and is not
		loaded into memory at all.
		</para>
		<para>
		<emphasis>
			Default value is <quote>defunct</quote>.
		</emphasis>
		</para>
		<example>
		<title>Setting <varname>defunct_column</varname> module parameter</title>
		<programlisting format="linespecific">
...
modparam("lcr", "defunct_column", "defunct_until")
...
</programlisting>
		</example>
	</section>

	<section>
		<title><varname>lcr_rule_table</varname> (string)</title>
		<para>
		Name of the table holding the LCR rules.
		</para>
		<para>
		<emphasis>
			Default value is <quote>lcr_rule</quote>.
		</emphasis>
		</para>
		<example>
		<title>Setting <varname>lcr_rule_table</varname> module parameter</title>
		<programlisting format="linespecific">
...
modparam("lcr", "lcr_rule_table", "rules")
...
</programlisting>
		</example>
	</section>

	<section>
		<title><varname>prefix_column</varname> (string)</title>
		<para>
		Name of the column holding prefix of Request-URI user
		part and prefix of gateway.
		</para>
		<para>
		<emphasis>
			Default value is <quote>prefix</quote>.
		</emphasis>
		</para>
		<example>
		<title>Setting <varname>prefix_column</varname> module
		parameter</title> 
		<programlisting format="linespecific">
...
modparam("lcr", "prefix_column", "number_prefix")
...
</programlisting>
		</example>
	</section>

	<section>
		<title><varname>from_uri_column</varname> (string)</title>
		<para>
		Name of the column holding the From (caller's) URI.
		</para>
		<para>
		<emphasis>
			Default value is <quote>from_uri</quote>.
		</emphasis>
		</para>
		<example>
		<title>Setting <varname>from_uri_column</varname> module parameter</title>
		<programlisting format="linespecific">
...
modparam("lcr", "from_uri_column", "caller_uri")
...
</programlisting>
		</example>
	</section>

	<section>
		<title><varname>request_uri_column</varname> (string)</title>
		<para>
		Name of the column holding the regular expression to match
		against the complete request URI (including the "sip:" prefix).
		</para>
		<para>
		<emphasis>
			Default value is <quote>request_uri</quote>.
		</emphasis>
		</para>
		<example>
		<title>Setting <varname>request_uri_column</varname> module parameter</title>
		<programlisting format="linespecific">
...
modparam("lcr", "request_uri_column", "callee_uri")
...
</programlisting>
		</example>
	</section>

	<section>
		<title><varname>stopper_column</varname> (string)</title>
		<para>
		Name of the column holding rule's stopper attribute.
		</para>
		<para>
		<emphasis>
			Default value is <quote>stopper</quote>.
		</emphasis>
		</para>
		<example>
		<title>Setting <varname>stopper_column</varname> module
		parameter 
			</title>
		<programlisting format="linespecific">
...
modparam("lcr", "stopper_column", "stop")
...
</programlisting>
		</example>
	</section>

	<section>
		<title><varname>enabled_column</varname> (string)</title>
		<para>
		Name of the column telling is the rule is currently
		enabled or disabled.
		</para>
		<para>
		<emphasis>
			Default value is <quote>enabled</quote>.
		</emphasis>
		</para>
		<example>
		<title>Setting <varname>enabled_column</varname> module
		parameter
		</title>
		<programlisting format="linespecific">
...
modparam("lcr", "enabled_column", "in_use")
...
</programlisting>
		</example>
	</section>

	<section>
		<title><varname>lcr_rule_target_table</varname> (string)</title>
		<para>
		Name of the table holding information about the LCR rule
		targets (gateways).
		</para>
		<para>
		<emphasis>
			Default value is <quote>lcr_rule_target</quote>.
		</emphasis>
		</para>
		<example>
		<title>Setting <varname>lcr_rule_target_table</varname>
		module parameter</title> 
		<programlisting format="linespecific">
...
modparam("lcr", "lcr_rule_target_table", "rules")
...
</programlisting>
		</example>
	</section>

	<section>
		<title><varname>rule_id_column</varname> (string)</title>
		<para>
		Name of lcr_rule_target_table column containing an id of
		lcr_rule table.
		</para>
		<para>
		<emphasis>
			Default value is <quote>rule_id</quote>.
		</emphasis>
		</para>
		<example>
		<title>Setting <varname>rule_id_column</varname> module
		parameter 
			</title>
		<programlisting format="linespecific">
...
modparam("lcr", "rule_id_column", "rule")
...
</programlisting>
		</example>
	</section>

	<section>
		<title><varname>gw_id_column</varname> (string)</title>
		<para>
		Name of lcr_rule_target_table column containing an id of
		lcr_gw table.
		</para>
		<para>
		<emphasis>
			Default value is <quote>gw_id</quote>.
		</emphasis>
		</para>
		<example>
		<title>Setting <varname>gw_id_column</varname> module
		parameter 
			</title>
		<programlisting format="linespecific">
...
modparam("lcr", "gw_id_column", "gw")
...
</programlisting>
		</example>
	</section>

	<section>
		<title><varname>priority_column</varname> (string)</title>
		<para>
		Name of the column holding the priority of the rule
		target.
		</para>
		<para>
		<emphasis>
			Default value is <quote>priority</quote>.
		</emphasis>
		</para>
		<example>
		<title>Setting <varname>priority_column</varname> module
		parameter</title>
		<programlisting format="linespecific">
...
modparam("lcr", "priority_column", "priority")
...
</programlisting>
		</example>
	</section>

	<section>
		<title><varname>weight_column</varname> (string)</title>
		<para>
		Name of the column holding weight of rule target.
		</para>
		<para>
		<emphasis>
			Default value is <quote>weight</quote>.
		</emphasis>
		</para>
		<example>
		<title>Setting <varname>weight_column</varname> module
		parameter</title> 
		<programlisting format="linespecific">
...
modparam("lcr","weight_column", "target_weight")
...
</programlisting>
		</example>
	</section>

	<section>
		<title><varname>lcr_count</varname> (integer)</title>
		<para>
		Maximun value of lcr_id.
		</para>
		<para>
		<emphasis>
			Default value is 1.
		</emphasis>
		</para>
		<example>
		<title>
		Setting <varname>lcr_count</varname> module
		parameter
		</title>
		<programlisting format="linespecific">
...
modparam("lcr", "lcr_count", 10)
...
</programlisting>
                </example>
	</section>

	<section>
		<title><varname>gw_uri_avp</varname> (AVP string)</title>
		<para>
		Internal AVP that load_gws() function uses to store
		information of matching gateways.
		</para>
		<para>
		<emphasis>
			There is NO default value, thus this variable must
			be defined in &siprouterconfig;.
		</emphasis>
		</para>
		<example>
		<title>Setting <varname>gw_uri_avp</varname> module
		parameter</title> 
		<programlisting format="linespecific">
...
modparam("lcr", "gw_uri_avp", "$avp(i:709)")
...
</programlisting>
		</example>
	</section>

	<section>
		<title><varname>ruri_user_avp</varname> (AVP string)</title>
		<para>
   		Internal AVP that next_gw function uses to store
		Request-URI user for subsequent next_gw calls.
		</para>
		<para>
		<emphasis>
			There is NO default value, thus this variable must
			be defined in &siprouterconfig;.
		</emphasis>
		</para>
		<example>
		<title>Setting <varname>ruri_user_avp</varname> module parameter</title>
		<programlisting format="linespecific">
...
modparam("lcr", "ruri_user_avp", "$avp(i:500)")
...
</programlisting>
		</example>
	</section>

	<section>
		<title><varname>tag_avp</varname> (AVP string)</title>
		<para>
		If defined, an AVP where successful next_gw and from_gw
		functions store gateway's tag.
		</para>
		<para>
		<emphasis>
			There is NO default value, i.e, if not defined,
			gateway's tag is not stored anywhere.
		</emphasis>
		</para>
		<example>
		<title>Setting <varname>tag_avp</varname> module parameter</title>
		<programlisting format="linespecific">
...
modparam("lcr", "tag_avp", "$avp(lcr_tag)")
...
</programlisting>
		</example>
	</section>

	<section>
		<title><varname>flags_avp</varname> (AVP string)</title>
		<para>
		If defined, an AVP where successful next_gw and from_gw
		functions store gateway's flags.
		</para>
		<para>
		<emphasis>
			There is NO default value, i.e, if not defined,
			gateway's flags are not stored anywhere.
		</emphasis>
		</para>
		<example>
		<title>Setting <varname>flags_avp</varname> module parameter</title>
		<programlisting format="linespecific">
...
modparam("lcr", "flags_avp", "$avp(i:712)")
...
</programlisting>
		</example>
	</section>

	<section>
		<title><varname>defunct_capability</varname> (integer)</title>
		<para>
		Tells if defunct capability of (non-responsive) gateways is
		supported.  Non-zero value turns on defunct capability.
		</para>
		<para>
		<emphasis>
			Default value is 0.
		</emphasis>
		</para>
		<example>
		<title>
		Setting <varname>defunct_capability</varname> module
		parameter
		</title>
		<programlisting format="linespecific">
...
modparam("lcr", "defunct_capability", 1)
...
</programlisting>
                </example>
	</section>

	<section>
		<title><varname>lcr_id_avp</varname> (AVP string)</title>
		<para>
		Internal AVP that load_gws() function uses to store
		LCR instance identifier of loaded gateways.  Only needed if
		gateway defunct capability has been activated.
		</para>
		<para>
		<emphasis>
			There is NO default value.
		</emphasis>
		</para>
		<example>
		<title>Setting <varname>lcr_id_avp</varname> module
		parameter</title> 
		<programlisting format="linespecific">
...
modparam("lcr", "lcr_id_avp", "$avp(s:lcr_id_avp)")
...
</programlisting>
		</example>
	</section>

	<section>
		<title><varname>defunct_gw_avp</varname> (AVP string)</title>
		<para>
		Internal AVP that next_gw() function uses to store
		internal index of the  
		selected gateway for later use by defunct_gw() function.
		Only needed if 
		gateway defunct capability has been activated.
		</para>
		<para>
		<emphasis>
			There is NO default value.
		</emphasis>
		</para>
		<example>
		<title>Setting <varname>defunct_gw_avp</varname> module
		parameter</title> 
		<programlisting format="linespecific">
...
modparam("lcr", "defunct_gw_avp", "$avp(s:defunct_gw_avp)")
...
</programlisting>
		</example>
	</section>

	<section>
		<title><varname>lcr_rule_hash_size</varname> (integer)</title>
		<para>
		Defines the size of hash table used to store LCR rules.
		Hashing is done based on rule's prefix.  Larger value means
		less collisions with other prefixes.  Hash size value
		should be a power of 2.
		</para>
		<para>
		<emphasis>
			Default value is 128.
		</emphasis>
		</para>
		<example>
		<title>
		Setting <varname>lcr_rule_hash_size</varname> module
		parameter
		</title>
		<programlisting format="linespecific">
...
modparam("lcr", "lcr_rule_hash_size", 1024)
...
</programlisting>
                </example>
	</section>

	<section>
		<title><varname>lcr_gw_count</varname> (integer)</title>
		<para>
		Defines the maximum number of gateways in lcr_gw table.
		</para>
		<para>
		<emphasis>
			Default value is 128.
		</emphasis>
		</para>
		<example>
		<title>
		Setting <varname>lcr_gw_count</varname> module parameter
		</title>
		<programlisting format="linespecific">
...
modparam("lcr", "lcr_gw_count", 1024)
...
</programlisting>
                </example>
	</section>

	<section>
		<title><varname>dont_strip_or_tag_flag</varname> (integer)</title>
		<para>
		Defines the flag number used to tell if stripping and
		tagging is done for the selected gateway.
		</para>
		<para>
		<emphasis>
			Default value is -1 meaning that the flag is not
		defined.
		</emphasis>
		</para>
		<example>
		<title>
		Setting <varname>dont_strip_or_tag_flag</varname> module
		parameter
		</title>
		<programlisting format="linespecific">
...
modparam("lcr", "dont_strip_or_tag_flag", 10)
...
</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 data from lcr_rule table. This value can be
		used to tune 
		the load time at startup.  For 1MB of private memory (default)
		it should be below 3750. In order for this parameter to
		have effect, the database driver must support fetch_result()
		capability.
		</para>
		<para>
		<emphasis>
			Default value is <quote>1024</quote>.
		</emphasis>
		</para>
		<example>
		<title>Set <varname>fetch_rows</varname> parameter</title>
		<programlisting format="linespecific">
...
modparam("lcr", "fetch_rows", 3000)
...
</programlisting>
		</example>
	</section>

	</section>

	<section>
	<title>Functions</title>
	<section>
		<title>
		<function moreinfo="none">load_gws(lcr_id[, uri_user[, caller_uri]])
		</function> 
		</title>
		<para>
		Loads attributes of matching gateways to gw_uri_avp
		(see Overview section).  Argument lcr_id specifies the used
	        LCR instance.  It can be a positive integer or a pseudo
		variable containing an integer value.
		If uri_user is given, it is used, instead of Request-URI user
		part, to look for matching gateways.  Caller's URI may be given
		by caller_uri argument. If caller_uri argument is
		omitted, it defaults to empty string. Both uri_user and
		caller_uri argument may be a string or a pseudo variable
		containing a sting value.  
		</para>
		<para>
		Returns 1 if at least one matching gateway was found, 2
		if no matching gateways was found, and -1 on error.
		</para>
		<para>
		Execution time of load_gws() function is O(N) * O(M),
		where N is number of different prefix lengths and M
		is number of collisions for matching prefix(es) in lcr
		rules hash table of the LCR instance.
		</para>
		<para>
		This function can be used from REQUEST_ROUTE.
		</para>
		<example>
		<title><function>load_gws</function> usage</title>
		<programlisting format="linespecific">
...
if (!load_gws(1, $rU, $var(caller_uri))) {
	sl_send_reply("500", "Server Internal Error - Cannot load gateways");
	exit;
};
...
</programlisting>
		</example>
	</section>

	<section>
		<title>
		<function moreinfo="none">next_gw()</function>
		</title>	
		<para>
		Upon first call, fetches attribute values stored in first
		gw_uri_avp, destroys that AVP, and rewrites
		Request-URI and possibly also destination URI as
		described in the Overview section. Saves user part of
		Request-URI into 
		ruri_user_avp for use in subsequent next_gw() calls.
		</para>
		<para>
		Upon subsequent calls, does the same as in above, but
		takes user part of Request-URI from ruri_user_avp.
		</para>
		<para>
		As a side effect, stores gateway's tag and flags to
		tag_avp and flags_avp, respectively, if the corresponding
		module parameter has been defined.
		</para>
		<para>
		Returns 1 on success and -1 if there were no gateways
		left or if an error occurred (see syslog).
		</para>
		<para>
		Must be preceded by successful load_gws() call.
		</para>
		<para>
		This function can be used from REQUEST_ROUTE, FAILURE_ROUTE.
		</para>
		<example>
		<title><function>next_gw</function> usage from a route block</title>
		<programlisting format="linespecific">
...
if (!next_gw()) {
	sl_send_reply("503", "Service not available - No gateways");
	exit;
};
...
</programlisting>
		</example>
		<example>
		<title><function>next_gw</function> usage from a failure
		route block 
			</title>
		<programlisting format="linespecific">
...
if (!next_gw()) {
	t_reply("503", "Service not available - No more gateways");
	exit;
};
...
</programlisting>
		</example>
	</section>

	<section>
		<title>
		<function moreinfo="none">defunct_gw(period)</function>
		</title>	
		<para>
		Defuncts gateway denoted by lcr_id_avp and defunct_gw_avp
		(which were set by previuos next_gw() call)
		for a period of seconds given as argument.  Argument 
		must be a positive integer constant or a pseudo variable
		with positive integer value.  Value of defunct column in
		database is not updated.
		</para>
		<para>
		Returns 1 on success and -1 in case of error (see syslog).
		</para>
		<para>
		This function can be used from REQUEST_ROUTE, FAILURE_ROUTE.
		</para>
		<example>
		<title><function>defunct_gw</function> usage</title>
		<programlisting format="linespecific">
...
defunct_gw(60);
...
</programlisting>
		</example>
	</section>

	<section>
		<title>
		<function moreinfo="none">from_gw(lcr_id[, ip_addr, proto])</function>
		</title>
		<para>
		Checks if request comes from IP address and transport protocol
		specified for a gateway in LCR instance lcr_id.
		Fails if the LCR instance includes 
		one or more gateways without IP address.
		IP address and transport protocol to be checked are either
		taken from source IP address of the request or
		(if present) from ip_addr and proto arguments.
		</para>
		<para>
		lcr_id can be an integer constant or a pseudo variable
		holding an integer value.  ip_addr can be a string or a pseudo
		variable holding a string value.  proto can be an integer
		constant (0 = ANY, 1 = UDP, 2 = TCP,
		3 = TLS, 4 = SCTP) or a pseudo variable holding such an
		integer value.
		</para>
		<para>
		If request comes from a gateway, gateway's tag and flags are
		stored as a side effect to
		tag_avp and flags_avp, respectively, if the corresponding
		module parameter has been defined.
		</para>
		<para>
		Returns 1 on success and -1 on failure or on error.
		</para>
		<para>
		Execution time of from_gw() function is O(log N),
		where N is number of gateways in the LCR instance.
		</para>
		<para>
		This function can be used from REQUEST_ROUTE, FAILURE_ROUTE,
		ONREPLY_ROUTE.
		</para>
		<example>
		<title><function>from_gw</function> usage</title>
		<programlisting format="linespecific">
...
if (from_gw(1, $avp(s:real_source_addr), 2) {
	...
};
...
</programlisting>
		</example>
		</section>

	<section>
		<title>
		<function moreinfo="none">from_any_gw([ip_addr, proto])</function>
		</title>
		<para>
		Checks if request comes from IP address and transport 
		protocol specified for any gateway.  Only LCR instances,
		where all gateways
		have IP address, are included in the test.
		IP address and transport protocol to be checked are either
		taken from source IP address and transport protocol 
		of the request or
		(if present) from ip_addr and proto arguments.  See from_gw()
		function for more info about the arguments.
		</para>
		<para>
		If any gateway has the IP address and transport protocol,
		function returns LCR
		identifier of the gateway.  Returns -1 on error or if
		the request does not come from a gateway. 
		</para>
		<para>
		If request comes from a gateway, gateway's tag and flags are
		stored as a side effect to
		tag_avp and flags_avp, respectively, if the corresponding
		module parameter has been defined.
		</para>
		<para>
		Execution time of from_gw() function is M * O(log N),
		where M is number of LCR instances and N is average number of
		gateways in LCR instances.
		</para>
		<para>
		This function can be used from REQUEST_ROUTE, FAILURE_ROUTE,
		ONREPLY_ROUTE.
		</para>
		<example>
		<title><function>from_gw</function> usage</title>
		<programlisting format="linespecific">
...
$var(lcr_id) = from_any_gw("192.168.1.1", 3);
...
</programlisting>
		</example>
		</section>

		<section>
		<title>
		<function moreinfo="none">to_gw(lcr_id[, ip_addr, proto])</function>
		</title>
		<para>
		Checks if in-dialog request goes to IP address and transport
		protocol specified for a gateway in LCR instance lcr_id.
		Fails if LCR
		instance includes one or more gateways without IP
		address.  IP address and transport protocol to be
		checked are either taken from Request-URI or (if
		present) from ip_addr and proto arguments.  See from_gw()
		for more info regarding the arguments.
		</para>
		<para>
		Returns 1 on success and -1 on failure and error.
		</para>
		<para>
		Execution time of to_gw() function is O(log N),
		where N is number of gateways in the LCR instance.
		</para>
		<para>
		This function can be used from REQUEST_ROUTE, FAILURE_ROUTE.
		</para>
		<example>
		<title><function>to_gw</function> usage</title>
		<programlisting format = "linespecific">
...
if (to_gw("1")) {
	...
	exit;
};
...
</programlisting>
		</example>
	</section>

	<section>
		<title>
		<function moreinfo="none">to_any_gw([ip_addr, proto])</function>
		</title>
		<para>
		Checks if in-dialog request goes to IP address and transport
		protocol of any gateway.
		Only LCR instances, where all gateways 
		have IP address, are included in the test. IP
		address and transport protocol to be checked are
		either taken from Request-URI or (if present)
		from ip_addr and proto arguments.   See from_gw()
		for more info regarding the arguments.
		</para>
		<para>
		Execution time of to_any_gw() function is M * O(log N),
		where M is number of LCR instances and N is average
		number of gateways in LCR instances.
		</para>
		<para>
		If any gateway has the IP address, returns LCR identifier
		of the gateway.  Returns -1 if request does
		not go to a gateway and on error.
		</para>
		<para>
		This function can be used from REQUEST_ROUTE, FAILURE_ROUTE.
		</para>
		<example>
		<title><function>to_gw</function> usage</title>
		<programlisting format = "linespecific">
...
if (to_any_gw("192.55.66.2", 1)) {
	...
	exit;
};
...
</programlisting>
		</example>
	</section>

	</section>

	<section>
	<title>Exported RPC Commands</title>
		<section>
		<title><function>lcr.reload</function></title>
		<para>
			Causes lcr module to re-read the contents of
			LCR tables into memory.
		</para>
		<para>
		Name: <emphasis>lcr.reload</emphasis>
		</para>
		<para>Parameters: <emphasis>none</emphasis></para>
		<example>
		<title><function>lcr.reload</function> RPC example</title>
		<programlisting  format="linespecific">
		$ &sercmd; lcr.reload
		</programlisting>
		</example>
		</section>
		
		<section>
		<title><function>lcr.dump_gws</function></title>
		<para>
			Causes lcr module to dump the contents of its
			in-memory gw table.
		</para>
		<para>Parameters: <emphasis>none</emphasis></para>
		<example>
		<title><function>lcr.dump_gws</function> RPC example</title>
		<programlisting  format="linespecific">
		$ &sercmd; lcr.dump_gws
		</programlisting>
		</example>
		</section>
		
		<section>
		<title><function>lcr.dump_rules</function></title>
		<para>
			Causes lcr module to dump the contents of its
			in-memory lcr_rule and lcr_rule_target tables.
		</para>
		<para>Parameters: <emphasis>none</emphasis></para>
 		<example>
		<title><function>lcr.dump_rules</function> RPC example</title>
        <programlisting  format="linespecific">
		$ &sercmd; lcr.dump_rules
		</programlisting>
		</example>
		</section>

		<section>
		<title><function>lcr.defunct_gw</function></title>
		<para>
			Defuncts gateway loaded into memory for a period of
			time (seconds) without a need to store gateway's
			defunct	value into database and reload the tables.
		</para>
		<para>
		Name: <emphasis>lcr.defunct_gw</emphasis>
		</para>
		<para>Parameters: <emphasis>lcr_id gw_id period</emphasis></para>
		<example>
		<title><function>lcr.defunct_gw</function> RPC example</title>
		<programlisting  format="linespecific">
		$ &sercmd; lcr.defunct_gw 1 4 120
		</programlisting>
		</example>
		</section>
	</section>
	<section>
	<title>Known Limitations</title>
	<para>
		In-memory LCR rules and gw tables are switched
		by two consecutive machine instructions. If lcr reload
		process is interrupted after the first one, in-memory
		gateway table does not match in-memory rule table until
		execution of lcr reload process is resumed.
	</para>
	</section>
</chapter>
