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

<chapter>
	
	<title>&adminguide;</title>
	
	<section id="overview" xreflabel="Overview">
	<title>Overview</title>
	<para>
	The Load-Balancer module comes to provide traffic routing based on load. 
	Shortly, when &osips; routes calls to a set of destinations, it is able 
	to keep the load status (as number of ongoing calls) of each destination 
	and to choose to route to the less loaded destination (at that moment). 
	&osips; is aware of the capacity of each destination - it is preconfigured 
	with the maximum load accepted by the destinations. To be more precise, 
	when routing, &osips; will consider the less loaded destination not the 
	destination with the smallest number of ongoing calls, but the destination 
	with the largest available slot.
	</para>
	<para>
	Also the module has the capability to do failover (to try a new destination
	if the selected one does not respond), to keep state of the destinations 
	(to remember the failed destination and avoid using them agai) and to 
	check the health of the destination (by doing probing of the destination 
	and auto re-enabling).
	</para>
	</section>

	<section>
	<title>How it works</title>
		<para>
		Please refer to the Load-Balancer tutorial from the &osips; website:
		<ulink url='https://opensips.org/Documentation/Tutorials-LoadBalancing-1-9'>https://opensips.org/Documentation/Tutorials-LoadBalancing-1-9</ulink>.
		</para>
	</section>

	<section>
	<title>Probing and Disabling destinations</title>
	<para>
	The module has the capability to monitor the status of the destinations by
	doing SIP probing (sending SIP requests like OPTIONS).
	</para>
	<para>
	For each destination, you can configure what kind of probing should be 
	done (probe_mode column):
	</para>
	<itemizedlist>
	<listitem>
		<para><emphasis>(0)</emphasis> - no probing at all;</para>
	</listitem>
	<listitem>
		<para><emphasis>(1)</emphasis> - probing only when the destination is
		in disabled mode (disabling via MI command will competely stop the 
		probing also). The destination will be automatically re-enabled
		when the probing will succeed next time;</para>
	</listitem>
	<listitem>
		<para><emphasis>(2)</emphasis> - probing all the time. If disabled, 
		the destination will be automatically re-enabled when the probing 
		will succeed next time;
		</para>
	</listitem>
	</itemizedlist>
	<para>
	A destination can become disabled in two ways:
	<itemizedlist>
	<listitem>
		<emphasis>script detection</emphasis> - by calling from script the
		lb_disabled() function after try the destination. In this case, if
		probing mode for the destination is (1) or (2), the destination will
		be automatically re-enabled when the probing will succeed.
	</listitem>
	<listitem>
		<emphasis>MI command</emphasis> - by calling the lb_status MI
		command for disabling (on demand) the destination. If so, the probing
		and re-enabling of this destination will be completly disabled until
		you re-enable it again via MI command - this is designed to allow 
		controlled and complete disabling of some destination during 
		maintenance.
	</listitem>
	</itemizedlist>
	</para>
	</section>

	<section id="dependencies" xreflabel="Dependencies">
	<title>Dependencies</title>
	<section>
		<title>&osips; Modules</title>
		<para>
		The following modules must be loaded before this module:
			<itemizedlist>
			<listitem>
			<para>
				<emphasis>Dialog</emphasis> - Dialog module
			</para>
			<para>
				<emphasis>freeswitch</emphasis>. - only if 
				"fetch_freeswitch_stats" is enabled.
			</para>
			</listitem>
			<listitem>
			<para>
				<emphasis>dialog</emphasis> - TM module (only if probing is
				enabled)
			</para>
			</listitem>
			<listitem>
			<para>
				<emphasis>clusterer</emphasis> - only if "cluster_id"
				option is enabled.
			</para>
			</listitem>
			<listitem>
			<para>
				<emphasis>database</emphasis> - one of the DB modules
			</para>
			</listitem>
			</itemizedlist>
		</para>
	</section>


	<section>
		<title>External Libraries or Applications</title>
		<para>
		The following libraries or applications must be installed before 
		running &osips; with this module loaded:
			<itemizedlist>
			<listitem>
			<para>
				<emphasis>None</emphasis>.
			</para>
			</listitem>
			</itemizedlist>
		</para>
	</section>
	</section>


	<section id="exported_parameters" xreflabel="Exported Parameters">
	<title>Exported Parameters</title>

	<section id="param_db_url" xreflabel="db_url">
		<title><varname>db_url</varname> (string)</title>
		<para>
		The URL pointing to the database where the load-balancing rules 
		are stored.
		</para>
		<para>
		<emphasis>
			Default value is <quote>&defaultdb;</quote>.
		</emphasis>
		</para>
		<example>
		<title>Set <varname>db_url</varname> parameter</title>
		<programlisting format="linespecific">
...
modparam("load_balancer", "db_url", "&exampledb;")
...
</programlisting>
		</example>
	</section>

	<section id="param_db_table" xreflabel="db_table">
		<title><varname>db_table</varname> (string)</title>
		<para>
		The name of the DB table containing the load-balancing rules.
		</para>
		<para>
		<emphasis>
			Default value is <quote>load_balancer</quote>.
		</emphasis>
		</para>
		<example>
		<title>Set <varname>db_table</varname> parameter</title>
		<programlisting format="linespecific">
...
modparam("load_balancer", "db_table", "lb")
...
</programlisting>
		</example>
	</section>

	<section id="param_probing_interval" xreflabel="probing_interval">
		<title><varname>probing_interval</varname> (integer)</title>
		<para>
		How often (in seconds) the probing of a destination should be done. If
		set to 0, the probing will be disabled as functionality (for all 
		destinations)
		</para>
		<para>
		<emphasis>
			Default value is <quote>30</quote>.
		</emphasis>
		</para>
		<example>
		<title>Set <varname>probing_interval</varname> parameter</title>
		<programlisting format="linespecific">
...
modparam("load_balancer", "probing_interval", 60)
...
</programlisting>
		</example>
	</section>

	<section id="param_probing_method" xreflabel="probing_method">
		<title><varname>probing_method</varname> (string)</title>
		<para>
		The SIP method to be used for the probing requests.
		</para>
		<para>
		<emphasis>
			Default value is <quote>"OPTIONS"</quote>.
		</emphasis>
		</para>
		<example>
		<title>Set <varname>probing_method</varname> parameter</title>
		<programlisting format="linespecific">
...
modparam("load_balancer", "probing_method", "INFO")
...
</programlisting>
		</example>
	</section>

	<section id="param_probing_from" xreflabel="probing_from">
		<title><varname>probing_from</varname> (string)</title>
		<para>
		The FROM SIP URI to be advertised in the SIP probing requests.
		</para>
		<para>
		<emphasis>
			Default value is <quote>"sip:prober@localhost"</quote>.
		</emphasis>
		</para>
		<example>
		<title>Set <varname>probing_from</varname> parameter</title>
		<programlisting format="linespecific">
...
modparam("load_balancer", "probing_from", "sip:pinger@192.168.2.10")
...
</programlisting>
		</example>
	</section>

	<section id="param_probing_reply_codes" xreflabel="probing_reply_codes">
		<title><varname>probing_reply_codes</varname> (string)</title>
		<para>
		A comma separted list of SIP reply codes. The codes defined here 
		will be considered as valid reply codes for probing messages,
		apart for 200.
		</para>
		<para>
		<emphasis>
			Default value is <quote>NULL</quote>.
		</emphasis>
		</para>
		<example>
		<title>Set <varname>probing_reply_codes</varname> parameter</title>
		<programlisting format="linespecific">
...
modparam("load_balancer", "probing_reply_codes", "501, 403")
...
</programlisting>
		</example>
	</section>

	<section id="param_probing_verbose" xreflabel="probing_verbose">
		<title><varname>probing_verbose</varname> (number)</title>
		<para>
		A boolean option to enable extra logging related to the 
		enabling or disabling of the destinations based on probing
		replies and MI commands.
		</para>
		<para>
		A 0 value means disabled, anything else means enabled.
		</para>
		<para>
		The extra logging will be done on INFO level.
		</para>
		<para>
		<emphasis>
			Default value is <quote>0</quote> (disabled).
		</emphasis>
		</para>
		<example>
		<title>Set <varname>probing_verbose</varname> parameter</title>
		<programlisting format="linespecific">
...
modparam("load_balancer", "probing_verbose", 1)
...
</programlisting>
		</example>
	</section>


	<section id="param_lb_define_blacklist" xreflabel="lb_define_blacklist">
		<title><varname>lb_define_blacklist</varname> (string)</title>
		<para>
		Defines a blacklist based on a lb group. This list will contain the IPs
		(no port, all protocols) of the destinations matching the given group.
		</para>
		<para>
		Multiple instances of this param are allowed.
		</para>
		<para>
		<emphasis>
			Default value is <quote>NULL</quote>.
		</emphasis>
		</para>
		<example>
		<title>Set the <varname>lb_define_blacklist</varname> parameter</title>
		<programlisting format="linespecific">
...
modparam("load_balancer", "lb_define_blacklist", "list= 1,4,3")
modparam("load_balancer", "lb_define_blacklist", "blist2= 2,10,6")
...
</programlisting>
		</example>
	</section>

	<section id="param_fetch_freeswitch_stats" xreflabel="fetch_freeswitch_stats">
		<title><varname>fetch_freeswitch_stats</varname> (integer)</title>
		<para>
		If enabled, the maximum value of a resource may also consist of
		FreeSWITCH Event Socket Layer URLs, e.g. <emphasis>"channels=fs://:password@freeswitch.example.com"</emphasis>
		or <emphasis>"channels=fs://user:password@127.0.0.1:8021"</emphasis>. The default ESL port is 8021.
		</para>
		<para>
		OpenSIPS will establish a connection with the given socket and
		periodically update the internal maximum value of the given resource
		using statistics pushed by the FreeSWITCH box.
		</para>
		<para>
		The max value of a resource is updated every <emphasis>event_heartbeat_interval</emphasis>
		seconds (see the "freeswitch" OpenSIPS module for more details
		regarding this setting), as the stats arrive from FreeSWITCH.
	</para>
	<para>
		Given the following format for FreeSWITCH heartbeat messages:
		<programlisting format="linespecific">
{
  ...
  "FreeSWITCH-Hostname": "pbx2",
  "FreeSWITCH-IPv4": "172.17.0.3",
  "Idle-CPU": "78.400000",
  "Max-Sessions": "1000",
  "Session-Count": "0",
  ...
}
</programlisting>
		, the load balancer uses the following formula in order to periodically
		update its "max_load" values for each FreeSWITCH box (FreeSWITCH data
		is highlighted in bold):
		</para>
		<para>
			<emphasis>max_load = (<emphasis role='bold'>Idle-CPU</emphasis> / 100)
				* (<emphasis role='bold'>Max-Sessions</emphasis> -
				(<emphasis role='bold'>Session-Count</emphasis> -
				current_load))</emphasis>
		</para>
		<para>
		<emphasis>
			Default value is <quote>0</quote> (disabled).
		</emphasis>
		</para>
		<example>
		<title>Set the <varname>fetch_freeswitch_load</varname> parameter</title>
		<programlisting format="linespecific">
...
modparam("load_balancer", "fetch_freeswitch_stats", 1)
...
</programlisting>
		</example>
	</section>

	<section id="param_initial_freeswitch_load" xreflabel="initial_freeswitch_load">
		<title><varname>initial_freeswitch_load</varname> (integer)</title>
		<para>
		This parameter is only relevant for some seconds after module startup/reload,
		when no statistics from newly loaded FreeSWITCH ESL sockets have arrived, yet the
		routing of calls must remain unaffected. Any FreeSWITCH-enabled resource will
		inherit this value for the entire interval mentioned above (up to 20 seconds!).
		</para>
		<para>
		<emphasis>
			Default value is <quote>1000</quote>.
		</emphasis>
		</para>
		<example>
		<title>Set the <varname>initial_freeswitch_load</varname> parameter</title>
		<programlisting format="linespecific">
...
modparam("load_balancer", "initial_freeswitch_load", 200)
...
</programlisting>
		</example>
	</section>

	<section id="param_cluster_id" xreflabel="cluster_id">
		<title><varname>cluster_id</varname> (integer)</title>
		<para>
		The ID of the cluster the module is part of. The clustering support is 
		used in load-balancer module for two purposes: for sharing the status 
		of the destinations and for controlling the pinging to destinations.
		</para>
		<para>
		If clustering enbled, the module will automatically share changes
		over the status of the destinations with the other 
		OpenSIPS instances that are part of a cluster. Whenever such a status 
		changes (following an MI command, a probing result, a script command),
		the module will replicate this status change to all the nodes in this 
		given cluster.
		</para>
		<para>
		The clustering with sharing tag support may be used to control which 
		node in the cluster will perform the pinging/probing to 
		destinations. See the
		<xref linkend="param_cluster_sharing_tag"/> option.
		</para>

			&clusterer_sync_cap_para;

		<para>
		For more info on how to define and populate a cluster (with OpenSIPS 
		nodes) see the "clusterer" module.
		</para>
		<para>
		<emphasis>
			Default value is <quote>0 (none)</quote>.
		</emphasis>
		</para>
		<example>
		<title>Set <varname>cluster_id</varname> parameter</title>
		<programlisting format="linespecific">
...
# replicate destination status with all OpenSIPS in cluster ID 9
modparam("load_balancer", "cluster_id", 9)
...
</programlisting>
		</example>
	</section>

	<section id="param_cluster_sharing_tag" xreflabel="cluster_sharing_tag">
		<title><varname>cluster_sharing_tag</varname> (string)</title>
		<para>
		The name of the sharing tag (as defined per clusterer modules) to 
		control which node is responsible for perform the self-triggered
		actions in the module. Such actions may be the destination probing or 
		sharing the changes in the destination status.
		If defined, only the node with active status of this tag will 
		perform the actions (pinging and sharing status).
		</para>
		<para>
		The <xref linkend="param_cluster_id"/> must be defined for this option
		to work.
		</para>
		<para>
		This is an optional parameter. If not set, all the nodes in the cluster
		will individually do the probing and share the status changes.
		</para>
		<para>
		<emphasis>
			Default value is <quote>empty (none)</quote>.
		</emphasis>
		</para>
		<example>
		<title>Set <varname>cluster_sharing_tag</varname> parameter</title>
		<programlisting format="linespecific">
...
# only the node with the active "vip" sharing tag will perform pinging
# and broadcast the status changes
modparam("load_balancer", "cluster_id", 9)
modparam("load_balancer", "cluster_sharing_tag", "vip")
...
</programlisting>
		</example>
	</section>

	</section>


	<section id="exported_functions" xreflabel="exported_functions">
	<title>Exported Functions</title>
	<section id="func_lb_start" xreflabel="lb_start()">
		<title>
		<function moreinfo="none">lb_start(grp,resources[,flags],[attrs])</function>
		</title>
		<para>
		The function starts a new load-balancing session over the available
		destinations. This translates into finding the less loaded destination
		that can provide the requested resources and belong to a requested
		group.
		</para>
		<para>Meaning of the parameters is as follows:</para>
		<itemizedlist>
		<listitem>
			<para><emphasis>grp</emphasis> (int) - group id for the destinations;
			the destination may be grouped in several groups you can you for 
			differnet scenarios.
			</para>
		</listitem>
		<listitem>
			<para><emphasis>resources</emphasis> (string) - a 
			semi-colon separated list of resources required by the current
			call.
			</para>
		</listitem>
		<listitem>
			<para><emphasis>flags</emphasis> (string, optional) - various flags
			to controll the LB algorithm ( or computing the available load on
			the system):
			</para>
			<itemizedlist>
			<listitem>
				<para><emphasis>n</emphasis> - Negative availability  - use
				destinations with negative availability (exceeded capacity);
				do not ignore resources with negative availability, and thus 
				able to select for load balancing destinations with exceeded 
				capacity. This might be needed in scenarios where we want to 
				limit generic calls volume and always pass 
				important/high-priority calls.
				</para>
			</listitem>
			<listitem>
				<para><emphasis>r</emphasis> - Relative value - the relative
				available load (how many percentages are free) is used in
				computing the load of each pear/resource; Without this flag,
				the Absolute value is assumed - the effective
				available load ( maximum_load - current_load) is used in
				computing the load of each pear/resource.
				</para>
			</listitem>
			<listitem>
				<para><emphasis>s</emphasis> - Pick a random destination if
				multiple destinations with the same load are found, instead
				of always picking first matched destination.
				This could help to offload an excessive load from the first
				destination and distribute load in situations when failed
				calls always routed to first destination, since they almost
				does not affect load counters of destinations.
				</para>
			</listitem>
			</itemizedlist>
		</listitem>
		<listitem>
			<para><emphasis>attrs</emphasis> (var, optional) - a writable variable 
			to be populated with the attributes of the selected destination.
			</para>
		</listitem>
		</itemizedlist>
		<para>
		The function may return:
		</para>
		<itemizedlist>
		<listitem>
			<para><emphasis>1 (true)</emphasis> - if a new destination URI is 
			set, pointing to the selected destination. NOTE that the RURI will
			not be changed by this function.</para>
		</listitem>
		<listitem>
			<para><emphasis>-1 (false)</emphasis> - generic internal error
			(memory allocation, parsing)</para>
		</listitem>
		<listitem>
			<para><emphasis>-2 (false)</emphasis> - no capacity available 
			(detinations are up and available, but they do not have any 
			availabe channels)</para>
		</listitem>
		<listitem>
			<para><emphasis>-3 (false)</emphasis> - no destinations available 
			(the requested resources did not match any active destination)
			</para>
		</listitem>
		<listitem>
			<para><emphasis>-4 (false)</emphasis> - bad resources 
			(requested resources do not exist)
			</para>
		</listitem>
		</itemizedlist>
		<para>
		This function can be used from REQUEST_ROUTE, BRANCH_ROUTE and
		FAILURE_ROUTE.
		</para>
		<example>
		<title><function>lb_start</function> usage</title>
		<programlisting format="linespecific">
...
if (lb_start(1,"trascoding;conference")) {
	# dst URI points to the new destination
	xlog("sending call to $du\n");
	t_relay();
	exit;
}
...
</programlisting>
		</example>
	</section>

	<section id="func_lb_next" xreflabel="lb_next()">
		<title>
		<function moreinfo="none">lb_next([attrs])</function>
		</title>
		<para>
		Function to be used to pull the next available (and less loaded)
		destination. You need to have an ongoing LB session (started with
		lb_start()).
		</para>
		<para>
		This function is mainly used for implementing failover for the LB
		destinations.
		</para>
		<para>Meaning of the parameters is as follows:</para>
		<itemizedlist>
		<listitem>
			<para><emphasis>attrs</emphasis> (var, optional) - a writable variable 
			to be populated with the attributes of the selected destination.
			</para>
		</listitem>
		</itemizedlist>
		<para>
		The function may return:
		</para>
		<itemizedlist>
		<listitem>
			<para><emphasis>1 (true)</emphasis> - if a new destination URI is 
			set, pointing to the selected destination. NOTE that the RURI will
			not be changed by this function.</para>
		</listitem>
		<listitem>
			<para><emphasis>-1 (false)</emphasis> - generic internal error
			(memory allocation, parsing)</para>
		</listitem>
		<listitem>
			<para><emphasis>-2 (false)</emphasis> - no capacity available 
			(detinations are up and available, but they do not have any 
			availabe channels)</para>
		</listitem>
		<listitem>
			<para><emphasis>-3 (false)</emphasis> - no more destinations 
			available (the requested resources did not match any active 
			destination)
			</para>
		</listitem>
		</itemizedlist>
		<para>
		This function can be used from REQUEST_ROUTE and FAILURE_ROUTE.
		</para>
		<example>
		<title><function>lb_next()</function> usage</title>
		<programlisting format="linespecific">
...
if (t_check_status("(408)|(5[0-9][0-9])")) {
	/* check next available LB destination */
	if ( lb_next() ) {
		t_on_failure("1");
		xlog("-----------new dst is $du\n");
		t_relay();
		exit;
	}
}

...
</programlisting>
		</example>
	</section>


	<section id="func_lb_start_or_next" xreflabel="lb_start_or_next()">
		<title>
		<function moreinfo="none">lb_start_or_next(grp,resources[,flags],[attrs])</function>
		</title>
		<para>
		This is just a wrapper function to simplify scripting. If there is no
		ongoing LB session, it acts as lb_start(); If there is an ongoing LB 
		session, it acts as lb_next().
		</para>
	</section>


	<section id="func_load_balance" xreflabel="load_balance()">
		<title>
		<function moreinfo="none">load_balance(grp,resources[,flags],[attrs])</function>
		</title>
		<para>
		Old name of the lb_start_or_next() function.
		</para>
		<para>
		Take care, this will become obsolete.
		</para>
	</section>


	<section id="func_lb_reset" xreflabel="lb_reset()">
		<title>
		<function moreinfo="none">lb_reset()</function>
		</title>
		<para>
		Function to stop and flush a current LB session. To be used in 
		failure route, if you want to stop the current LB session (not to try
		any other destinations from this session) and to start a completly new
		one.
		</para>
		<para>
		This function can be used from REQUEST_ROUTE and FAILURE_ROUTE.
		</para>
		<example>
		<title><function>lb_next()</function> usage</title>
		<programlisting format="linespecific">
...
if (t_check_status("(5[0-9][0-9])")) {
	/* check next available LB destination */
	if ( lb_next() ) {
		t_on_failure("1");
		xlog("-----------new dst is $du\n");
		t_relay();
		exit;
	}
} else if (t_check_status("(408)")) {
	lb_reset();
	if (lb_start(1,"conference")) {
		t_relay();
		exit;
	}
}
...
</programlisting>
		</example>
	</section>

	<section id="func_lb_is_started" xreflabel="lb_is_started()">
		<title>
		<function moreinfo="none">lb_is_started()</function>
		</title>
		<para>
		Function to check if there is any ongoing LB session. Returns true if
		so.
		</para>
		<para>
		This function can be used in any type of route.
		</para>
	</section>


	<section id="func_lb_disable_dst" xreflabel="lb_disable_dst()">
		<title>
		<function moreinfo="none">lb_disable_dst()</function>
		</title>
		<para>
		Marks as disabled the last destination that was used for the current
		call. The disabling done via this function will prevent the 
		destination to be used for usage from now on. The probing mechanism
		can re-enable this peer (see the probing section in the beginning)
		</para>
		<para>
		This function can be used from REQUEST_ROUTE and FAILURE_ROUTE.
		</para>
		<example>
		<title><function>lb_disable_dst()</function> usage</title>
		<programlisting format="linespecific">
...
if (t_check_status("(408)|(5[0-9][0-9])")) {
	lb_disable_dst();
	if ( lb_next() ) {
		t_on_failure("1");
		xlog("-----------new dst is $du\n");
		t_relay();
	} else {
		t_reply(500,"Error");
	}
}

...
</programlisting>
		</example>
	</section>


	<section id="func_lb_is_destination" xreflabel="lb_is_destination()">
		<title>
		<function moreinfo="none">lb_is_destination(ip,port,[group],[active],[attrs]])</function>
		</title>
		<para>
		Checks if the given IP and PORT belongs to a destination configured in
		the load-balancer's list. Returns true if found and active (see the
		"active" parameter).
		</para>
		<para>
		This function can be used from REQUEST_ROUTE, FAILURE_ROUTE,
		ONREPLY_ROUTE, BRANCH_ROUTE and LOCAL_ROUTE.
		</para>
		<para>Meaning of the parameters is as follows:</para>
		<itemizedlist>
		<listitem>
			<para><emphasis>ip</emphasis> (string) - IP to be checked
			</para>
		</listitem>
		<listitem>
			<para><emphasis>port</emphasis> (int) - PORT to be checked. 
			A value 0 means "any" - will match any port.
			</para>
		</listitem>
		<listitem>
			<para><emphasis>group</emphasis> (int, optional) - in what LB group
			the destination should be looked for; If not specified, the search
			will be in all groups.
			</para>
		</listitem>
		<listitem>
			<para><emphasis>active</emphasis>  (int, optional)- if "1", the search will be
			performed only over "active" (not disabled) destinations. If 
			missing, the search will consider any kind of destinations.
			</para>
		</listitem>
		<listitem>
			<para><emphasis>attrs</emphasis> (var, optional) - a writable variable 
			to be populated with the attributes of the identified destination.
			</para>
		</listitem>

		</itemizedlist>

		<example>
		<title><function>lb_is_destination</function> usage</title>
		<programlisting format="linespecific">
...
if (lb_is_destination($si,$sp) ) {
	# request from a LB destination
}
...
</programlisting>
		</example>
	</section>

	<section id="func_lb_count_call" xreflabel="lb_count_call()">
		<title>
		<function moreinfo="none">lb_count_call(ip,port,grp,resources[,undo])</function>
		</title>
		<para>
		The function counts the current call as load for a given destination 
		with some given resources. Note that this call is not going through
		the load-balancing logic (there are not routing decision taken for the
		call); it is simply counted by LB as ongoing call for a destination;
		</para>
		<para>Meaning of the parameters is as follows:</para>
		<itemizedlist>
		<listitem>
			<para><emphasis>ip</emphasis> (string) - IP to identify the destination
			the call has to be counted for.
			</para>
		</listitem>
		<listitem>
			<para><emphasis>port</emphasis> (int) - PORT to identify the destination
			the call has to be counted for.
			</para>
		</listitem>
		<listitem>
			<para><emphasis>grp</emphasis> (int) - group id for the destinations; if
			no knows, "-1" will mean all groups.
			</para>
		</listitem>
		<listitem>
			<para><emphasis>resources</emphasis> - (string) a semi-colon separated
			list of resources required by the current call.
			</para>
		</listitem>
		<listitem>
			<para><emphasis>undo</emphasis> - (int, optional) if set to a non zero
			value, it will force the function to un-count -
			actually it will undo the counting of this call as load in the 
			current LB session; this might be needed if we count call for
			particular resources and then need to un-count it.
			</para>
		</listitem>
		</itemizedlist>
		<para>
		Function returns true if the call was properly taken into consideration
		for estimating the load on the destination.
		</para>
		<para>
		This function can be used from REQUEST_ROUTE, BRANCH_ROUTE and
		FAILURE_ROUTE.
		</para>
		<example>
		<title><function>lb_count_call</function> usage</title>
		<programlisting format="linespecific">
...
# count as load also the calls orgininated by lb destinations
if (lb_is_destination($si,$sp) ) {
	# inbound call from destination
	lb_count_call($si,$sp,-1,"conference");
} else {
	# outbound call to destinations
	if ( !load_balance(1,"conference") ) {
		send_reply(503,"unavailable");
		exit();
	}
	# dst URI points to the new destination
	xlog("sending call to $du\n");
	t_relay();
	exit;
}
...
</programlisting>
		</example>
	</section>


	</section>

	<section id="exported_mi_functions" xreflabel="Exported MI Functions">
	<title>Exported MI Functions</title>

		<section id="mi_lb_reload" xreflabel="lb_reload">
		<title><function moreinfo="none">lb_reload</function></title>
		<para>
		Trigers the reload of the load balancing data from the DB.
		</para>
		<para>
		MI FIFO Command Format:
		</para>
		<programlisting  format="linespecific">
		opensips-cli -x mi lb_reload
		</programlisting>
		</section>

		<section id="mi_lb_resize" xreflabel="lb_resize">
		<title><function moreinfo="none">lb_resize</function></title>
		<para>
		Changes the capacity for a resource of a destination.
		</para>
		<para>Parameters:</para>
		<itemizedlist>
			<listitem><para>
				<emphasis>destination_id</emphasis> - the ID (as per DB) of the destination.
			</para></listitem>
			<listitem><para>
				<emphasis>res_name</emphasis> - name of the resource you want to resize.
			</para></listitem>
			<listitem><para>
				<emphasis>new_capacity</emphasis> - new resource capacity.
			</para></listitem>
		</itemizedlist>
		<para>
		MI FIFO Command Format:
		</para>
		<programlisting  format="linespecific">
		opensips-cli -x mi lb_resize 11 voicemail 56
		</programlisting>
		</section>

		<section id="mi_lb_list" xreflabel="lb_list">
		<title><function moreinfo="none">lb_list</function></title>
		<para>
		Lists all the destinations and the maximum and current load for each 
		resource of the destination.
		</para>
		<example>
		<title><function>lb_list</function> usage</title>
		<programlisting format="linespecific">
$ opensips-cli -x mi lb_list
Destination:: sip:127.0.0.1:5100 id=1 enabled=yes auto-re=on
        Resource:: pstn max=3 load=0
        Resource:: transc max=5 load=1
        Resource:: vm max=5 load=2
Destination:: sip:127.0.0.1:5200 id=2 enabled=no auto-re=on
        Resource:: pstn max=6 load=0
        Resource:: trans max=57 load=0
        Resource:: vm max=5 load=0
</programlisting>
		</example>
		</section>

		<section id="mi_lb_status" xreflabel="lb_status">
		<title><function moreinfo="none">lb_status</function></title>
		<para>
		Gets or sets the status (enabled or disabled) of a destination.
		</para>
		<para>Parameters:</para>
		<itemizedlist>
			<listitem><para>
				<emphasis>destination_id</emphasis> - the ID (as per DB) of the destination.
			</para></listitem>
			<listitem><para>
				<emphasis>new_status</emphasis> (optional) - If no new status is given, the
				function will return the current status. If a new status is given 
				(0 - disable, 1 - enable), this status will be forced for the 
				destination.
			</para></listitem>
		</itemizedlist>
		<example>
		<title><function>lb_status</function> usage</title>
		<programlisting format="linespecific">
$ opensips-cli -x mi lb_status 2
enable:: no
$ opensips-cli -x mi lb_status 2 1
$ opensips-cli -x mi lb_status 2
enable:: yes
</programlisting>
		</example>
	</section>
	</section>


	<section id="exported_events" xreflabel="Exported Events">
	<title>Exported Events</title>
	<section id="event_E_LOAD_BALANCER_STATUS" xreflabel="E_LOAD_BALANCER_STATUS">
		<title>
		<function moreinfo="none">E_LOAD_BALANCER_STATUS</function>
		</title>
		<para>
			This event is raised when the module changes the state of a destination,
			either through MI or probing.
		</para>
		<para>Parameters:</para>
		<itemizedlist>
			<listitem><para>
				<emphasis>group</emphasis> - the group of the destination.
			</para></listitem>
			<listitem><para>
				<emphasis>uri</emphasis> - the URI of the destination.
			</para></listitem>
			<listitem><para>
				<emphasis>status</emphasis> - <emphasis>disabled</emphasis> if
				the destination was disabled or <emphasis>enabled</emphasis> if 
				the destination is being used.
			</para></listitem>
		</itemizedlist>
	</section>
	</section>


</chapter>

