<?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 "../../../../doc/docbook/entities.xml">
%docentities;

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

<chapter>

	<title>&adminguide;</title>


	<section>
		<title>Overview</title>
		<para>
		The <acronym>UAC</acronym> (User Agent Client) module provides some basic UAC
		functionalities like sending SIP requests, registering with a remote service,
		From: header manipulation (anonymization) and client authentication.
		</para>
		<para>
		The UAC module also supports sending a SIP request from the
		configuration file. See variable $uac_req(name) and the function
		uac_req_send().
		</para>
		<para>
		In addition, the module supports database-driven SIP registration functionality. See
		the uac_reg_lookup() function and dedicated section for remote
		registration configuration.
		</para>
		<para>
		Known limitations in this version:
		</para>
		<itemizedlist>
			<listitem>
			<para>
				Authentication does not support qop auth-int, just qop auth;
			</para>
			</listitem>
			<listitem>
			<para>
				CSeq is not increased automatically by uac_auth() during authentication
				- the follow up request may be rejected. CSeq can be increased when
				authenticating INVITE requests - dialog module has to be used, with
				CSeq tracking feature enabled (see the readme of dialog module).
			</para>
			</listitem>
			<listitem>
			<para>
				The <quote>uac_replace_*</quote> functions can only be run once on the same
				SIP request. Try to save needed changes in a pseudovariable and
				apply them once.
			</para>
			<para>
				There is also a limitation regarding the use of the
				<quote>msg_apply_changes()</quote> function together with the
				<quote>uac_replace_*</quote> functions for messages that are
				loose-routed (e.g. Re-INVITE requests). In this case you need
				to call the <quote>loose_route()</quote> function after the
				replace and msg_apply_changes. Otherwise Kamailio can create
				replies with wrong From/To headers (e.g. for the 100 - Trying
				reply in the Re-INVITE example).
			</para>
			</listitem>
		</itemizedlist>
	</section>

	<section>
		<title>Dependencies</title>
		<section>
			<title>&kamailio; Modules</title>
			<para>
			The following modules must be loaded before this module:
			<itemizedlist>
			<listitem>
			<para>
				<emphasis>TM - Transaction Module</emphasis>
			</para>
			</listitem>
			<listitem>
			<para>
				<emphasis>RR - Record-Route Module</emphasis>, but only if
				restore mode for From: URI is set to <quote>auto</quote>.
			</para>
			</listitem>
			<listitem>
			<para>
				<emphasis>Dialog Module</emphasis>, but only if
				restore mode for From: URI is set to <quote>auto</quote> and
				you want uac_replace_from or uac_replace_to to store the values
				of the URIs as dialog variables.
			</para>
			</listitem>
			</itemizedlist>
			</para>
		</section>
		<section>
			<title>External Libraries or Applications</title>
			<para>
				The following libraries or applications must be installed
				before running &kamailio; with this module loaded:
				<itemizedlist>
				<listitem>
				<para>
					<emphasis>None</emphasis>
				</para>
				</listitem>
				</itemizedlist>
			</para>
		</section>
	</section>

	<section>
		<title>Parameters</title>
		<section id="uac.p.rr_from_store_param">
			<title><varname>rr_from_store_param</varname> (string)</title>
			<para>
			Name of Record-Route header parameter that will be used to store
			an encoded version of the original FROM URI.
			</para>
			<para>
				<emphasis>
					This parameter is optional, it's default value being
					<quote>vsf</quote>.
				</emphasis>
			</para>
			<example>
				<title>Set <varname>rr_from_store_param</varname> parameter</title>
				<programlisting format="linespecific">
...
modparam("uac","rr_from_store_param","my_param")
...
				</programlisting>
			</example>
		</section>
		<section id="uac.p.rr_to_store_param">
			<title><varname>rr_to_store_param</varname> (string)</title>
			<para>
			Name of Record-Route header parameter that will be used to store
			(encoded) the original TO URI.
			</para>
			<para>
				<emphasis>
					This parameter is optional, it's default value being
					<quote>vst</quote>.
				</emphasis>
			</para>
			<example>
				<title>Set <varname>rr_to_store_param</varname> parameter</title>
				<programlisting format="linespecific">
...
modparam("uac","rr_to_store_param","my_param")
...
				</programlisting>
			</example>
		</section>
		<section id="uac.p.restore_mode">
			<title><varname>restore_mode</varname> (string)</title>
			<para>
			There are 3 modes of restoring the original FROM URI and the original TO URI:
			<itemizedlist>
			<listitem>
				<para>
				<quote>none</quote> - no information about original URI is
				stored; restoration is not possible.
				</para>
			</listitem>
			<listitem>
				<para>
				<quote>manual</quote> - all following replies will be restored,
				but not also the sequential requests - this must be manually
				updated based on original URI.
				</para>
			</listitem>
			<listitem>
				<para>
				<quote>auto</quote> - all sequential requests and replies will
				be automatically updated based on stored original URI. For this
				option you have to set <quote>modparam("rr", "append_fromtag", 1)</quote>.
				</para>
			</listitem>
			</itemizedlist>
			</para>
			<para>
				<emphasis>
					This parameter is optional, it's default value being
					<quote>auto</quote>.
				</emphasis>
			</para>
			<example>
				<title>Set <varname>restore_mode</varname> parameter
				</title>
				<programlisting format="linespecific">
...
modparam("uac","restore_mode","auto")
...
				</programlisting>
			</example>
		</section>
		<section id="uac.p.restore_dlg">
			<title><varname>restore_dlg</varname> (int)</title>
			<para>
			If set to 1, the module uses dialog variables to store initial and
			new values for From/To headers. The Dialog module has to be loaded and
			all calls that involve changes to From/To headers must be tracked.
			</para>
			<para>
				<emphasis>
					Default value of this parameter is 0.
				</emphasis>
			</para>
			<example>
				<title>Set <varname>restore_dlg</varname> parameter</title>
				<programlisting format="linespecific">
...
modparam("uac", "restore_dlg", 1)
...
				</programlisting>
			</example>
		</section>
		<section id="uac.p.restore_passwd">
			<title><varname>restore_passwd</varname> (string)</title>
			<para>
			String password to be used to encrypt the RR storing parameters. If
			empty, no encryption will be used.
			</para>
			<para>
				<emphasis>
					Default value of this parameter is empty.
				</emphasis>
			</para>
			<example>
				<title>Set <varname>restore_passwd</varname> parameter</title>
				<programlisting format="linespecific">
...
modparam("uac","restore_passwd","my_secret_passwd")
...
				</programlisting>
			</example>
		</section>
		<section id="uac.p.restore_from_avp">
			<title><varname>restore_from_avp</varname> (string)</title>
			<para>
			If defined and restore_mode is manual or auto, the avp is used to save
			the original from uri in order to be able to restore it in replies.
			That makes sense, if the original-uri can not be extracted from the original
			request, e.g. if msg_apply_changes() was used after calling uac_replace_from()
			or uac_replace_to().
			</para>
			<para>
				If you create a dialog ( with dlg_manage() ) before calling uac_replace_from(),
			this avp will not be needed. The values of the uris will be stored as dialog variables.
			</para>
			<para><emphasis>
					Default value of this parameter is empty.
				</emphasis>
			</para>
			<example>
				<title>Set <varname>restore_from_avp</varname> parameter</title>
				<programlisting format="linespecific">
...
modparam("uac","restore_from_avp","$avp(original_uri_from)")
...
				</programlisting>
			</example>
		</section>
		<section id="uac.p.restore_to_avp">
			<title><varname>restore_to_avp</varname> (string)</title>
			<para>
			If defined and restore_mode is manual or auto, the avp is used to save
			the original To URI in order to be able to restore it in replies.
			That makes sense if the original-uri can not be extracted from the original
			request, e.g. if msg_apply_changes() was used after calling uac_replace_to()
			</para>
			<para>
				If you create a dialog ( with dlg_manage() ) before calling or uac_replace_to(),
				this avp will not be needed. The values of the uris will be stored as dialog variables.
			</para>
			<para><emphasis>
					Default value of this parameter is empty.
				</emphasis>
			</para>
			<example>
				<title>Set <varname>restore_to_avp</varname> parameter</title>
				<programlisting format="linespecific">
...
modparam("uac","restore_to_avp","$avp(original_uri_to)")
...
				</programlisting>
			</example>
		</section>
		<section id="uac.p.credential">
			<title><varname>credential</varname> (string)</title>
			<para>
			Contains a multiple definition of credentials used to perform
			authentication.
			</para>
			<para>
				<emphasis>
					This parameter is required if UAC authentication is used.
				</emphasis>
			</para>
			<example>
				<title>Set <varname>credential</varname> parameter</title>
				<programlisting format="linespecific">
...
modparam("uac","credential","username:domain:password")
...
				</programlisting>
			</example>
		</section>
		<section id="uac.p.auth_realm_avp">
			<title><varname>auth_realm_avp</varname> (string)</title>
			<para>
			The definition of a PV that might contain the realm to be used
			to perform authentication.
			</para>
			<para>
			When the PV value is an empty string or NULL when uac_auth() is called,
			the realm is taken from the reply and only username matching is done.
			This can be used if the realm upstream will be using is not known in advance.
			</para>
			<para><emphasis>
				If you define it, you also need to define
				<quote>auth_username_avp</quote>
				(<xref linkend="uac.p.auth_username_avp"/>) and
				<quote>auth_password_avp</quote>
				(<xref linkend="uac.p.auth_password_avp"/>).
			</emphasis></para>
			<example>
				<title>Set <varname>auth_realm_avp</varname> parameter</title>
				<programlisting format="linespecific">
...
modparam("uac","auth_realm_avp","$avp(arealm)")
...
				</programlisting>
			</example>
		</section>
		<section id="uac.p.auth_username_avp">
			<title><varname>auth_username_avp</varname> (string)</title>
			<para>
			The definition of an AVP that might contain the username to be used
			to perform authentication.
			</para>
			<para><emphasis>
				If you define it, you also need to define
				<quote>auth_realm_avp</quote>
				(<xref linkend="uac.p.auth_realm_avp"/>) and
				<quote>auth_password_avp</quote>
				(<xref linkend="uac.p.auth_password_avp"/>).
			</emphasis></para>
			<example>
				<title>Set <varname>auth_username_avp</varname> parameter</title>
				<programlisting format="linespecific">
...
modparam("uac","auth_username_avp","$avp(auser)")
...
				</programlisting>
			</example>
		</section>
		<section id="uac.p.auth_password_avp">
			<title><varname>auth_password_avp</varname> (string)</title>
			<para>
			The definition of an AVP that might contain the password to be used
			to perform authentication.
			</para>
			<para><emphasis>
				If you define it, you also need to define
				<quote>auth_realm_avp</quote>
				(<xref linkend="uac.p.auth_realm_avp"/>) and
				<quote>auth_username_avp</quote>
				(<xref linkend="uac.p.auth_username_avp"/>).
			</emphasis></para>
			<example>
				<title>Set <varname>auth_password_avp</varname> parameter</title>
				<programlisting format="linespecific">
...
modparam("uac","auth_password_avp","$avp(apasswd)")
...
				</programlisting>
			</example>
		</section>
		<section id="uac.p.reg_db_url">
			<title><varname>reg_db_url</varname> (string)</title>
			<para>
			DB URL to fetch account profiles for registration. This parameter
			must be set in order to enable remote registrations feature.
			</para>
			<para>The default value is "" (no value).</para>
			<example>
				<title>Set <varname>reg_db_url</varname> parameter</title>
				<programlisting format="linespecific">
...
modparam("uac", "reg_db_url",
    "&defaultdb;")
...
				</programlisting>
			</example>
		</section>

		<section id="uac.p.reg_timer_interval">
			<title><varname>reg_timer_interval</varname> (int)</title>
			<para>
			Timer interval (in seconds) at which registrations are managed, e.g. renewed as needed.
			</para>
			<para>
				<emphasis>
				The default value is 90 seconds.
				</emphasis>
			</para>

			<example>
				<title>Set <varname>reg_timer_interval</varname> parameter</title>
				<programlisting format="linespecific">
...
modparam("uac", "reg_timer_interval", 60)
...
				</programlisting>
			</example>
		</section>

		<section id="uac.p.reg_retry_interval">
			<title><varname>reg_retry_interval</varname> (int)</title>
			<para>
			Failed registration attempts will be retried after this interval
			(in seconds). The interval is not exact, retries may be
			attempted as much as reg_timer_interval secs earlier.
			If set to 0, failed registrations will be disabled permanently.
			</para>
			<para>The default value is 0 sec (disabled)</para>
			<example>
				<title>Set <varname>reg_retry_interval</varname> parameter</title>
				<programlisting format="linespecific">
...
modparam("uac", "reg_retry_interval", 300)
...
				</programlisting>
			</example>
		</section>

		<section id="uac.p.reg_random_delay">
			<title><varname>reg_random_delay</varname> (int)</title>
			<para>
			Set a random reg_delay for each registration that has
			reg_delay set to 0 in the database.
			If set to 0, randomization will be disabled.
			</para>
			<para>The default value is 0 sec (disabled)</para>
			<example>
				<title>Set <varname>reg_random_delay</varname> parameter</title>
				<programlisting format="linespecific">
...
modparam("uac", "reg_random_delay", 300)
...
				</programlisting>
			</example>
		</section>

		<section id="uac.p.reg_hash_size">
			<title><varname>reg_hash_size</varname> (int)</title>
			<para>
			 The number of entries of the hash table used by uac_reg to store the
			 registration records is 2^hash_size. For hash_size=4, the number of
			 slots of the hash table is 16.
			</para>
			<para>
				<emphasis>Default value is <quote>4</quote> (16 slots).</emphasis>
			</para>
			<example>
				<title>Set <varname>reg_hash_size</varname> parameter</title>
				<programlisting format="linespecific">
...
modparam("uac", "reg_hash_size", 10)
...
				</programlisting>
			</example>
		</section>

		<section id="uac.p.reg_db_table">
			<title><varname>reg_db_table</varname> (string)</title>
			<para>
			DB table name to fetch user profiles for registration.
			</para>
			<para>
				<emphasis>
					This parameter is optional, it's default value being
					<quote>uacreg</quote>.
				</emphasis>
			</para>
			<example>
				<title>Set <varname>reg_db_table</varname> parameter</title>
				<programlisting format="linespecific">
...
modparam("uac", "reg_db_table", "uacreg")
...
				</programlisting>
			</example>
		</section>

		<section id="uac.p.reg_contact_addr">
			<title><varname>reg_contact_addr</varname> (string)</title>
			<para>
			Address to be used to build contact address. Must be at least
			host part, can have port and parameters. Must not include 'sip:'.
			The username part of the Contact: URI will be the L_UUID field in the database.
			</para>
			<para>
			A contact_addr value in the uacreg table will
			override the parameter for this particular entry.
			</para>
			<example>
				<title>Set <varname>reg_contact_addr</varname> parameter</title>
				<programlisting format="linespecific">
...
modparam("uac", "reg_contact_addr", "192.168.1.2:5080")
...
				</programlisting>
			</example>
		</section>

		<section id="uac.p.reg_keep_callid">
			<title><varname>reg_keep_callid</varname> (int)</title>
			<para>
			If set to 0 (default), a new Call-Id will be generated for each
			registration attempt.
			If set to non-zero, the same Call-Id will be used for
			re-registrations, as recommended by RFC3261 section 10.2.4.
			A new Call-Id will be generated when a previous registration
			had failed.
			</para>
			<example>
				<title>Set <varname>reg_keep_callid</varname> parameter</title>
				<programlisting format="linespecific">
...
modparam("uac", "reg_keep_callid", 1)
...
				</programlisting>
			</example>
		</section>


		<section id="uac.p.reg_active">
			<title><varname>reg_active</varname> (int)</title>
			<para>
				If set to 0, no remote regisrations are done. In other words,
				it can control at once if the module should do remote registratios
				or not. It can be changed at runtime via rpc command
				'uac.reg_active 0|1'.
			</para>
			<para>The default value is 1 (active).</para>
			<example>
				<title>Set <varname>reg_active</varname> parameter</title>
				<programlisting format="linespecific">
...
modparam("uac", "reg_active", 0)
...
				</programlisting>
			</example>
		</section>

		<section id="uac.p.reg_gc_interval">
			<title><varname>reg_gc_interval</varname> (int)</title>
			<para>
			Timer interval (in seconds) at which remote registrations are cleaned
			up in case of failure or removed. When setting it take in consideration
			the maximum value for retransmission timeout, this param should be greater
			than it. This value also impacts how often the reload for remote
			registrations table can be executed -- the RPC command will fail if
			executed in less than reg_gc_interval value since the last reload.
			</para>
			<para>
				<emphasis>
				The default value is 150 seconds.
				</emphasis>
			</para>

			<example>
				<title>Set <varname>reg_gc_interval</varname> parameter</title>
				<programlisting format="linespecific">
...
modparam("uac", "reg_gc_interval", 60)
...
				</programlisting>
			</example>
		</section>
		<section id="uac.p.reg_use_domain">
			<title><varname>reg_use_domain</varname> (int)</title>
			<para>
				If set to 1, domain part of URIs is used by functions doing
				lookup on user name.
			</para>
			<para>
				<emphasis>Default value is <quote>0</quote>.</emphasis>
			</para>
			<example>
				<title>Set <varname>reg_use_domain</varname> parameter</title>
				<programlisting format="linespecific">
...
modparam("uac", "reg_use_domain", 1)
...
				</programlisting>
			</example>
		</section>
	<section id="uac.p.default_socket">
		<title><varname>default_socket</varname> (str)</title>
		<para>
			Default socket to be used for generating registration requests and sending
			requests with the function uac_req_send(). Useful e.g. when several public
			interfaces are available.
		</para>
		<para>
			A send socket in the $uac_reg variable used together with the uac_req_send()
			function will override this parameter. A socket value in the uacreg table will
			also override the parameter for this particular entry.
		</para>
		<para>
		<emphasis>
			By default no default socket is defined, the send socket is choosen from the
			<quote>tm</quote> module when the requests is sent out.
		</emphasis>
		</para>
		<para>If you want to force a certain TCP port (e.g. 5060), you will need to set
			the <emphasis>tcp_reuse_port=yes</emphasis> core parameter as well.
		</para>
		<example>
		<title>Set the <quote>default_socket</quote> parameter</title>
 <programlisting format="linespecific">
 ...
 modparam("uac", "default_socket", "udp:192.168.0.125:5060")
 ...
 </programlisting>
		</example>
	</section>

	<section id="uac.p.event_callback">
		<title><varname>event_callback</varname> (str)</title>
		<para>
			The name of the function in the kemi configuration file (embedded
			scripting language such as Lua, Python, ...) to be executed instead
			of event_route[uac:reply] block.
		</para>
		<para>
			The function receives a string parameter with the name of the event,
			the value can be: 'uac:reply'.
		</para>
		<para>
		<emphasis>
			Default value is 'empty' (no function is executed for events).
		</emphasis>
		</para>
		<example>
		<title>Set <varname>event_callback</varname> parameter</title>
 <programlisting format="linespecific">
 ...
modparam("uac", "event_callback", "ksr_uac_event")

function ksr_uac_event(evname)
	KSR.info("===== uac module triggered event: " .. evname .. "\n");
	return 1;
end
 ...
 </programlisting>
		</example>
	</section>
	</section>

	<section>
		<title>Functions</title>
		<section id="uac.f.uac_replace_from">
			<title>
				<function moreinfo="none">uac_replace_from(display, uri)</function>
			</title>
			<para>
			Replace in FROM header the <emphasis>display</emphasis> name and
			the <emphasis>URI</emphasis> part.
			</para>
			<para>
			<emphasis>display</emphasis> and <emphasis>URI</emphasis> parameters
			can include pseudo-variables.
			</para>
			<para>
			This function can be used from REQUEST_ROUTE and from BRANCH_ROUTE.
			</para>
			<para>NOTE: Previous versions of this function added double quotes automatically to
			display variable. That is no longer the case, if you expect that behavior, you will
			have to add the quotes by yourself.
			</para>
			<para>
			If you set restore_mode to AUTO, the URI will be modified automatically in
			all subsequent requests and replies in that dialog.
			</para>
			<para>
				There are two ways in which the AUTO mode can be achieved.
			</para>
			<para>
				One uses the rr module and appends to the Record-Route header a parameter
				containing some strings from which the original and new URI can be computed.
				The problem with this mode is that it relies on the fact the parties will
				send the Route exactly as it was received. In case there is a change, the
				resulting URIs will not be correct.
			</para>
			<para>
				The other one uses the dialog module to store the original and new URI.
				If you already use dialog module in your configuration, this is the advisable mode.
				All you need to do to use this is to call dlg_manage() before calling uac_replace_from().
				It works by storing the URIs as dialog variables and registering callbacks in dialog
				module for in dialog requests.
			</para>
			<example>
				<title><function>uac_replace_from</function> usage</title>
				<programlisting format="linespecific">
...
# replace both display and uri
uac_replace_from("$avp(s:display)","$avp(s:uri)");
# replace only display and do not touch uri
uac_replace_from("batman","");   # display is replaced with: batman
uac_replace_from("\"batman\"","");  # display is replaced with: "batman"
# remove display and replace uri
uac_replace_from("","sip:robin@gotham.org");
# remove display and do not touch uri
uac_replace_from("","");
...
				</programlisting>
			</example>
		</section>
		<section id="uac.f.uac_replace_from_uri">
			<title>
				<function moreinfo="none">uac_replace_from(uri)</function>
			</title>
			<para>
				Replace in FROM header the <emphasis>URI</emphasis> part
				without altering the display name.
			</para>
			<para>
			<emphasis>URI</emphasis> parameter can include pseudo-variables.
			</para>
			<para>
			This function can be used from REQUEST_ROUTE and from BRANCH_ROUTE.
			</para>
			<example>
				<title><function>uac_replace_from</function> usage</title>
				<programlisting format="linespecific">
...
uac_replace_from("sip:batman@gotham.org");
...
				</programlisting>
			</example>
		</section>
		<section id="uac.f.uac_restore_from">
			<title>
				<function moreinfo="none">uac_restore_from()</function>
			</title>
			<para>
			This function will check if the FROM URI was modified and will
			use the information stored in header parameter to restore
			the original FROM URI value.
			</para>
			<para>
			This function can be used from REQUEST_ROUTE.
			</para>
			<example>
				<title><function>uac_restore_from</function> usage</title>
				<programlisting format="linespecific">
...
uac_restore_from();
...
				</programlisting>
			</example>
		</section>
		<section id="uac.f.uac_replace_to">
		<title>
				<function moreinfo="none">uac_replace_to(display, uri)</function>
			</title>
			<para>
			Replace in TO header the <emphasis>display</emphasis> name and
			the <emphasis>URI</emphasis> part.
			</para>
			<para>
			<emphasis>display</emphasis> and <emphasis>URI</emphasis> parameters
			can include pseudo-variables.
			</para>
			<para>
			This function can be used from REQUEST_ROUTE and from BRANCH_ROUTE.
			</para>
			<para>NOTE: Previous versions of this function added double quotes automatically to
			display variable. That is no longer the case, if you expect that behavior, you will
			have to add the quotes by yourself.
			</para>
			<example>
				<title><function>uac_replace_to</function> usage</title>
				<programlisting format="linespecific">
...
# replace both display and uri
uac_replace_to("$avp(display)","$avp(uri)");
# replace only display and do not touch uri
uac_replace_to("batman","");   # display is replaced with: batman
uac_replace_to("\"batman\"","");  # display is replaced with: "batman"
# remove display and replace uri
uac_replace_to("","sip:robin@gotham.org");
# remove display and do not touch uri
uac_replace_to("","");
...
				</programlisting>
			</example>
		</section>
		<section id="uac.f.uac_replace_to_uri">
			<title>
				<function moreinfo="none">uac_replace_to(uri)</function>
			</title>
			<para>
				Replace in TO header the <emphasis>URI</emphasis> part
				without altering the display name.
			</para>
			<para>
			<emphasis>URI</emphasis> parameter can include pseudo-variables.
			</para>
			<para>
			This function can be used from REQUEST_ROUTE and from BRANCH_ROUTE.
			</para>
			<para>
			If you set restore_mode to AUTO, the URI will be modified automatically in
			all subsequent requests and replies in that dialog.
			</para>
			<para>
				There are two ways in which the AUTO mode can be achieved.
			</para>
			<para>
				One uses the rr module and appends to the Record-Route header a parameter
				containing some strings from which the original and new URI can be computed.
				The problem with this mode is that it relies on the fact the parties will
				send the Route exactly as it was received. In case there is a change, the
				resulting URIs will not be correct.
			</para>
			<para>
				The other one uses the dialog module to store the original and new URI.
				If you already use dialog module in your configuration, this is the advisable mode.
				All you need to do to use this is to call dlg_manage() before calling uac_replace_to().
				It works by storing the URIs as dialog variables and registering callbacks in dialog
				module for in dialog requests.
			</para>

			<example>
				<title><function>uac_replace_to</function> usage</title>
				<programlisting format="linespecific">
...
uac_replace_to("sip:batman@gotham.org");
...
				</programlisting>
			</example>
		</section>
		<section id="uac.f.uac_restore_to()">
			<title>
				<function moreinfo="none">uac_restore_to()</function>
			</title>
			<para>
			This function will check if the TO URI was modified and will
			use the information stored in header parameter to restore
			the original TO URI value.
			</para>
			<para>
			This function can be used from REQUEST_ROUTE.
			</para>
			<example>
				<title><function>uac_restore_to</function> usage</title>
				<programlisting format="linespecific">
...
uac_restore_to();
...
				</programlisting>
			</example>
		</section>
		<section id="uac.f.uac_auth">
			<title>
				<function moreinfo="none">uac_auth([mode])</function>
			</title>
			<para>
			This function can be called only from failure route and will
			build the authentication response header and insert it into the
			request without sending anything.
			</para>
			<para>
			If mode is set to 1, then the password has to be provided in HA1 format.
			The parameter can be a static integer or a variable holding an integer value.
			</para>
			<para>
			This function can be used from FAILURE_ROUTE and BRANCH_FAILURE_ROUTE event route.
			</para>
			<example>
				<title><function>uac_auth</function> usage</title>
				<programlisting format="linespecific">
...
modparam("uac","auth_username_avp","$avp(auser)")
modparam("uac","auth_password_avp","$avp(apass)")
modparam("uac","auth_realm_avp","$avp(arealm)")

request_route {
   ...
   if(is_method("INVITE")) {
      t_on_failure("TRUNKAUTH");
   }
   ...
}

failure_route[TRUNKAUTH] {

    if (t_is_canceled()) {
        exit;
    }
    if(t_check_status("401|407")) {
        $avp(auser) = "test";
        $avp(apass) = "test";
        # $avp(apass) = "36d0a02793542b4961e8348347236dbf";
        # if (uac_auth("1")) {
        if (uac_auth()) {
            t_relay();
        }
        exit;
    }
}
...
				</programlisting>
			</example>
		</section>
		<section id="uac.f.uac_auth_mode">
			<title>
				<function moreinfo="none">uac_auth_mode(vmode)</function>
			</title>
			<para>
			This function can be called only from failure route and will
			build the authentication response header and insert it into the
			request without sending anything.
			</para>
			<para>
			If mode is set to 1, then the password has to be provided in HA1 format.
			The parameter can be a static integer or a variable holding an integer value.
			</para>
			<para>
			This function can be used from FAILURE_ROUTE and BRANCH_FAILURE_ROUTE event route.
			</para>
			<example>
				<title><function>uac_auth_mode</function> usage</title>
				<programlisting format="linespecific">
...
modparam("uac","auth_username_avp","$avp(auser)")
modparam("uac","auth_password_avp","$avp(apass)")
modparam("uac","auth_realm_avp","$avp(arealm)")

request_route {
   ...
   if(is_method("INVITE")) {
      t_on_failure("TRUNKAUTH");
   }
   ...
}

failure_route[TRUNKAUTH] {

    if (t_is_canceled()) {
        exit;
    }
    if(t_check_status("401|407")) {
        $avp(auser) = "test";
        $avp(apass) = "test";
        # $avp(apass) = "36d0a02793542b4961e8348347236dbf";
        if (uac_auth_mode("1")) {
            t_relay();
        }
        exit;
    }
}
...
				</programlisting>
			</example>
		</section>
		<section id="uac.f.uac_req_send">
			<title>
				<function moreinfo="none">uac_req_send()</function>
			</title>
			<para>
			This function sends a SIP message from the configuration file.
			The message is built out of $uac_req(...) pseudo-variable.
			</para>
			<para>
			This function can be used from REQUEST_ROUTE, FAILURE_ROUTE,
			BRANCH_ROUTE, ONREPLY_ROUTE, LOCAL_ROUTE.
			</para>
			<example>
				<title><function>uac_req_send</function> usage</title>
				<programlisting format="linespecific">
...
$uac_req(method)="OPTIONS";
$uac_req(ruri)="sip:kamailio.org";
$uac_req(furi)="sip:kamailio.org";
$uac_req(turi)="sip:kamailio.org";
$uac_req(callid)=$(mb{s.md5});
uac_req_send();
...
				</programlisting>
			</example>
		</section>
		<section id="uac.f.uac_reg_lookup">
			<title>
				<function moreinfo="none">uac_reg_lookup(uuid, dst)</function>
			</title>
			<para>
			This function sets the PV dst to SIP URI that correspond to uuid
			in uac registrations table. uuid and dst must be pseudo-variables.
			</para>
			<para>
			This function can be used from ANY_ROUTE.
			</para>
			<example>
				<title><function>uac_reg_lookup</function> usage</title>
				<programlisting format="linespecific">
...

if(uac_reg_lookup("$rU", "$ru"))
{
    lookup("location");
}
...
				</programlisting>
			</example>
		</section>
		<section id="uac.f.uac_reg_lookup_uri">
			<title>
				<function moreinfo="none">uac_reg_lookup_uri(uri, dst)</function>
			</title>
			<para>
			This function sets the PV dst to SIP URI that correspond to the URI user
			in uac registrations table. The uri can contain pseudo-variables and
			dst must be the name of a pseudo-variable.
			</para>
			<para>
			This function can be used from ANY_ROUTE.
			</para>
			<example>
				<title><function>uac_reg_lookup_uri</function> usage</title>
				<programlisting format="linespecific">
...

if(uac_reg_lookup("$var(uri)", "$ru"))
{
    lookup("location");
}
...
				</programlisting>
			</example>
		</section>
		<section id="uac.f.uac_reg_status">
			<title>
				<function moreinfo="none">uac_reg_status(uuid)</function>
			</title>
			<para>
			This function returns the current registration status for the uuid.
			</para>
			<para>
			Return values:
			<itemizedlist>
			<listitem>
				<para>
				1 - a valid registration exists.
				</para>
			</listitem>
			<listitem>
				<para>
				-1 - uuid does not exist or an error occurred while executing
				the function.
				</para>
			</listitem>
			<listitem>
				<para>
				-2 - a registration attempt is ongoing (and currently there is
				no valid registration).
				</para>
			</listitem>
			<listitem>
				<para>
				-3 - registration is disabled.
				</para>
			</listitem>
			<listitem>
				<para>
				-99 - no valid registration, waiting for new registration attempt.
				</para>
			</listitem>
			</itemizedlist>
			</para>
			<para>
			This function can be used from ANY_ROUTE.
			</para>
			<example>
				<title><function>uac_reg_status</function> usage</title>
				<programlisting format="linespecific">
...
$var(status) = uac_reg_status("$rU");
...
				</programlisting>
			</example>
		</section>
		<section id="uac.f.uac_reg_request_to">
			<title>
				<function moreinfo="none">uac_reg_request_to(user, mode)</function>
			</title>
			<para>
			This function can be used to send an authenticated request to a remote user in
			the uac registrations table. It sets the request-uri, dst-uri and auth_*_avp
			variables to the values that correspond to the supplied user.
			</para>
			<para>
			The mode is a bitwise set of flags controlling how the matching of
			the record is done and what field is used to set auth_password_avp:
			<itemizedlist>
			<listitem>
				<para>
				indicates whether the user should match the local uuid (bit value=0),
				or the username (bit value=1, int value=1).
				</para>
			</listitem>
			<listitem>
				<para>
				indicates whether the auth_password value is used to set auth_password_avp
				(bit value=0), or the auth_ha1 value (bit value=1, int value=2).
				</para>
			</listitem>
			</itemizedlist>
			</para>
			<para>
			The auth_*_avp module parameters must be set to valid pv&apos;s.
			</para>
			<para>
			This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, BRANCH_ROUTE.
			</para>
			<example>
				<title><function>uac_reg_request_to</function> usage</title>
				<programlisting format="linespecific">
...

if(uac_reg_request_to("$fU", 0))
{
	xlog("L_NOTICE", "Found remote user [$rU] on [$rd] via [$du]");
	t_on_failure("REMOTE_AUTH");

	t_relay()
}
...
failure_route[REMOTE_AUTH] {
	if ($T_reply_code == 401 or $T_reply_code == 407) {
		xlog("L_NOTICE", "Remote asked for authentication");
		uac_auth();
	}
}
...
				</programlisting>
			</example>
		</section>
		<section id="uac.f.uac_reg_enable">
			<title>
				<function moreinfo="none">uac_reg_enable(attr, val)</function>
			</title>
		<para>
			Enable a remote registration record based on a filter specified by
			attribute and value. The attribute can be: l_uuid, l_username,
			r_username or auth_username. The value is what should be matched
			against the value of the attribute in the remote registration record.
		</para>
		<para>
			The SIP processing is done on the next timer routine.
		</para>
		<example>
		<title><function>uac_reg_enable</function> usage</title>
			<programlisting format="linespecific">
...
   uac_reg_enable("l_uuid", "account123");
...
			</programlisting>
		</example>
		</section>

		<section id="uac.f.uac_reg_disable">
			<title>
				<function moreinfo="none">uac_reg_disable(attr, val)</function>
			</title>
		<para>
			Disable a remote registration record based on a filter specified by
			attribute and value. The attribute can be: l_uuid, l_username,
			r_username or auth_username. The value is what should be matched
			against the value of the attribute in the remote registration record.
		</para>
		<para>
			The SIP processing is done on the next timer routine.
		</para>
		<example>
		<title><function>uac_reg_disable</function> usage</title>
			<programlisting format="linespecific">
...
   uac_reg_disable("l_uuid", "account123");
...
			</programlisting>
		</example>
		</section>

		<section id="uac.f.uac_reg_refresh">
			<title>
				<function moreinfo="none">uac_reg_refresh(luuid)</function>
			</title>
		<para>
			Refresh the uac remote registration record based on local uuid. If
			the record was already loaded, new values are taken from database,
			otherwise a new record is created.
		</para>
		<example>
		<title><function>uac_reg_refresh</function> usage</title>
			<programlisting format="linespecific">
...
   uac_reg_refresh("account123");
...
			</programlisting>
		</example>
		</section>
	</section>
	<section>
		<title>Pseudo Variables</title>
		<itemizedlist>
			<listitem><para>
				<emphasis>$uac_req(key)</emphasis>
			</para></listitem>
		</itemizedlist>
		<para>
		Exported pseudo-variables are documented at &kamwikilink;.
		</para>
	</section>

	<section>
		<title>Event Routes</title>
		<section id="uac.ert.uac_reply">
			<title>
				<function moreinfo="none">event_route[uac:reply]</function>
			</title>
		<para>
		The associated $uac_req(evroute) can have either of the following values:
		<itemizedlist>
			<listitem><para>
				<emphasis>1</emphasis> : event route executed for the <emphasis>final reply</emphasis> of the branch for the
			request sent with uac_req_send(). If the request is challenged for authentication
			with 401/407, then the event_route is executed twice, first for
			401/407 and second for final reply of the transaction.
			</para></listitem>
			<listitem><para>
				<emphasis>2</emphasis> : event route executed for <emphasis>failure</emphasis> of the branch for the
			request sent with uac_req_send(). event route will execute also for timeout.
			In order for this to work, please also enable TM module "enable_uac_fr" modparam.
			</para></listitem>
		</itemizedlist>
		</para>
		<example>
		<title><function>event_route[uac:reply]</function> usage</title>
			<programlisting format="linespecific">
...
$uac_req(method)="OPTIONS";
$uac_req(ruri)="sip:kamailio.org";
$uac_req(furi)="sip:kamailio.org";
$uac_req(turi)="sip:kamailio.org";
$uac_req(callid)=$(mb{s.md5});
$uac_req(evroute)=1;
uac_req_send();
...
event_route[uac:reply] {
    xlog("received reply code is: $uac_req(evcode)\n");
}
...
			</programlisting>
		</example>
		</section>
	</section>

	<section>
		<title>Counters</title>
		<itemizedlist>
			<listitem><para>
				<emphasis>regtotal</emphasis>: Total number of registrations
			</para></listitem>
			<listitem><para>
				<emphasis>regactive</emphasis>: Total number of active registrations (successfully registered with service)
			</para></listitem>
			<listitem><para>
				<emphasis>regdisabled</emphasis>: Total number of disabled registrations (no longer active)
			</para></listitem>
		</itemizedlist>
	</section>
	<section>
		<title>RPC Commands</title>
		<section id="uac.r.uac.reg_dump">
			<title>
				<function moreinfo="none">uac.reg_dump</function>
			</title>
		<para>
		Dump the content of remote registration table from memory.
		</para>
		<example>
		<title><function>uac.reg_dump</function> usage</title>
			<programlisting format="linespecific">
...
   kamcmd uac.reg_dump
...
			</programlisting>
		</example>

		</section>
		<section id="uac.r.uac.reg_info">
			<title>
				<function moreinfo="none">uac.reg_info</function>
			</title>
		<para>
			Return the details of a remote registration record based on
			a filter. The command has two parameter: attribute and value.
			The attribute can be: l_uuid, l_username, r_username or auth_username.
			The value is what should be matched against the value of the attribute
			in the remote registration record.
		</para>
		<para>
			The state of the registration is reflected in the flags field:
			<itemizedlist>
			<listitem><para>
			1 (2^0) - registration profile is disabled
			</para></listitem>
			<listitem><para>
			2 (2^1) - registration in progress
			</para></listitem>
			<listitem><para>
			4 (2^2) - registration succeeded
			</para></listitem>
			<listitem><para>
			8 (2^3) - registration in progres with authentication
			</para></listitem>
			<listitem><para>
			16 (2^4) - registration initialized (after loading from database,
			the registration process was initialized)
			</para></listitem>
		</itemizedlist>
		</para>
		<example>
		<title><function>uac.reg_info</function> usage</title>
			<programlisting format="linespecific">
...
   kamcmd uac.reg_info l_uuid account123
   kamcmd uac.reg_info l_uuid s:12345678
...
			</programlisting>
		</example>
		</section>

		<section id="uac.r.uac.reg_enable">
			<title>
				<function moreinfo="none">uac.reg_enable</function>
			</title>
		<para>
			Enable a remote registration record based on
			a filter. The command has two parameter: attribute and value.
			The attribute can be: l_uuid, l_username, r_username or auth_username.
			The value is what should be matched against the value of the attribute
			in the remote registration record.
		</para>
		<example>
		<title><function>uac.reg_enable</function> usage</title>
			<programlisting format="linespecific">
...
   kamcmd uac.reg_enable l_uuid account123
   kamcmd uac.reg_enable l_uuid s:12345678
...
			</programlisting>
		</example>
		</section>

		<section id="uac.r.uac.reg_disable">
			<title>
				<function moreinfo="none">uac.reg_disable</function>
			</title>
		<para>
			Disable a remote registration record based on
			a filter. The command has two parameter: attribute and value.
			The attribute can be: l_uuid, l_username, r_username or auth_username.
			The value is what should be matched against the value of the attribute
			in the remote registration record.
		</para>
		<example>
		<title><function>uac.reg_disable</function> usage</title>
			<programlisting format="linespecific">
...
   kamcmd uac.reg_disable l_uuid account123
   kamcmd uac.reg_disable l_uuid s:12345678
...
			</programlisting>
		</example>
		</section>

		<section id="uac.r.uac.reg_unregister">
			<title>
				<function moreinfo="none">uac.reg_unregister</function>
			</title>
		<para>
			Send REGISTER with expires 0 for matching record, disabling it.
			The command has two parameter: attribute and value.
			The attribute can be: l_uuid, l_username, r_username or auth_username.
			The value is what should be matched against the value of the attribute
			in the remote registration record.
		</para>
		<example>
		<title><function>uac.reg_unregister</function> usage</title>
			<programlisting format="linespecific">
...
   kamcmd uac.reg_unregister l_uuid account123
   kamcmd uac.reg_unregister l_uuid s:12345678
...
			</programlisting>
		</example>
		</section>

		<section id="uac.r.uac.reg_reload">
			<title>
				<function moreinfo="none">uac.reg_reload</function>
			</title>
		<para>
			Reload the records from database for remote registrations. There is
			a limit of how often the reload command can be executed, by default
			is 150 seconds between reloads -- see the reg_gc_interval parameter
			for more details.
		</para>
		<example>
		<title><function>uac.reg_reload</function> usage</title>
			<programlisting format="linespecific">
...
   kamcmd uac.reg_reload
...
			</programlisting>
		</example>
		</section>

		<section id="uac.r.uac.reg_refresh">
			<title>
				<function moreinfo="none">uac.reg_refresh</function>
			</title>
		<para>
			Load one record by l_uuid from database for remote registrations.
			If the record exists in memory, it will be replaced with the new
			values loaded from database.
		</para>
		<example>
		<title><function>uac.reg_refresh</function> usage</title>
			<programlisting format="linespecific">
...
   kamcmd uac.reg_refresh account123
   kamcmd uac.reg_refresh s:12345678
...
			</programlisting>
		</example>
		</section>

		<section id="uac.r.uac.reg_active">
			<title>
				<function moreinfo="none">uac.reg_active</function>
			</title>
		<para>
			Control if the module should do remote registrations or not. Setting
			to 1 enables remote registrations for all records and 0 disables
			doing them.
		</para>
		<example>
		<title><function>uac.reg_active</function> usage</title>
			<programlisting format="linespecific">
...
   kamctl rpc uac.reg_active 0
   kamctl rpc uac.reg_active 1
...
			</programlisting>
		</example>
		</section>

		<section id="uac.r.uac.reg_add">
			<title>
				<function moreinfo="none">uac.reg_add</function>
			</title>
		<para>
		Add a new UAC remote registration record. If one with the same
		unique id is found, it is deleted.
		</para>
		<para>
		The parameters are:
		<itemizedlist>
			<listitem><para>l_uuid</para></listitem>
			<listitem><para>l_username</para></listitem>
			<listitem><para>l_domain</para></listitem>
			<listitem><para>r_username</para></listitem>
			<listitem><para>r_domain</para></listitem>
			<listitem><para>realm</para></listitem>
			<listitem><para>auth_username</para></listitem>
			<listitem><para>auth_password</para></listitem>
			<listitem><para>auth_ha1</para></listitem>
			<listitem><para>auth_proxy</para></listitem>
			<listitem><para>expires</para></listitem>
			<listitem><para>flags</para></listitem>
			<listitem><para>reg_delay</para></listitem>
			<listitem><para>socket</para></listitem>
			<listitem><para>contact_addr</para></listitem>
		</itemizedlist>
		</para>
		<para>
			Use a dot (.) if no value should be set for realm, auth_password, auth_ha1, socket
			or contact_addr.
		</para>

		<example>
		<title><function>uac.reg_add</function> usage</title>
			<programlisting format="linespecific">
...
   kamcmd uac.reg_add ...
...
			</programlisting>
		</example>
		</section>

		<section id="uac.r.uac.reg_remove">
			<title>
				<function moreinfo="none">uac.reg_remove</function>
			</title>
		<para>
		Remove a UAC remote registration record by l_uuid.
		</para>

		<example>
		<title><function>uac.reg_remove</function> usage</title>
			<programlisting format="linespecific">
...
   kamcmd uac.reg_remove my_l_uuid
...
			</programlisting>
		</example>
		</section>
	</section>

	<section>
		<title>Remote Registration</title>
		<para>
		The module can register contact addresses to remote REGISTRAR servers.
		You have to add records to uacreg table. The table stores following
		attributes:
		</para>

		<itemizedlist>
			<listitem><para>
			<emphasis>l_uuid</emphasis> - local unique user id, e.g.,:
			12345678
			</para></listitem>
		</itemizedlist>
		<itemizedlist>
			<listitem><para>
			<emphasis>l_username</emphasis> - local user name, e.g.,: test
			</para></listitem>
		</itemizedlist>
		<itemizedlist>
			<listitem><para>
			<emphasis>l_domain</emphasis> - local domain, e.g.,:
			mysipserver.com
			</para></listitem>
		</itemizedlist>
		<itemizedlist>
			<listitem><para>
			<emphasis>r_username</emphasis> - remote username, e.g.,:
			test123
			</para></listitem>
		</itemizedlist>
		<itemizedlist>
			<listitem><para>
			<emphasis>r_domain</emphasis> - remote domain, e.g.,:
			sipprovider.com
			</para></listitem>
		</itemizedlist>
		<itemizedlist>
			<listitem><para>
			<emphasis>realm</emphasis> - remote realm, e.g.,:
			sipprovider.com
			</para></listitem>
		</itemizedlist>
		<itemizedlist>
			<listitem><para>
			<emphasis>auth_username</emphasis> - authentication username,
			e.g.,: test123
			</para></listitem>
		</itemizedlist>
		<itemizedlist>
			<listitem><para>
			<emphasis>auth_password</emphasis> - authentication password in
			clear text, e.g.,: xxxxxx
			</para></listitem>
		</itemizedlist>
		<itemizedlist>
			<listitem><para>
			<emphasis>auth_ha1</emphasis> - hashed (HA1) authentication password,
			it has priority over auth_password.
			</para></listitem>
		</itemizedlist>
		<itemizedlist>
			<listitem><para>
			<emphasis>auth_proxy</emphasis> - SIP address of authentication
			proxy, e.g.,: sip:sipprovider.com
			</para></listitem>
		</itemizedlist>
		<itemizedlist>
			<listitem><para>
			<emphasis>expires</emphasis> - expiration time for registration,
			in seconds, e.g.,: 360
			</para></listitem>
		</itemizedlist>
		<itemizedlist>
			<listitem><para>
			<emphasis>flags</emphasis> - the state of the registration, see <xref linkend="uac.r.uac.reg_info"/>
			</para></listitem>
		</itemizedlist>
		<itemizedlist>
			<listitem><para>
			<emphasis>reg_delay</emphasis> - delay initial registration with at least reg_delay seconds, e.g.,: 3
			</para></listitem>
		</itemizedlist>
		<itemizedlist>
			<listitem><para>
			<emphasis>contact_addr</emphasis> - contact address to be used for this record
			instead of reg_contact_addr module parameter, e.g.:, 192.168.0.125:5060. It can
			be set to '' (empty string) to skip setting it and then reg_contact_addr modparam is used.
			</para></listitem>
		</itemizedlist>
		<itemizedlist>
			<listitem><para>
			<emphasis>socket</emphasis> - Used socket for sending out registration requests,
			e.g.:, udp:192.168.0.125:5060
			</para></listitem>
		</itemizedlist>

		<para>
		The module takes care of sending REGISTER and refresh registrations
		before they expire.
		</para>
		<para>
		When calls come in, you have to run uac_reg_lookup() that will detect
		if the call is coming from a remote SIP provider and can change the
		R-URI to local username@domain. Afterwards you can run location lookup.
		</para>

		<example>
		<title><function>lookup remote registrations</function> usage</title>
			<programlisting format="linespecific">
...
    if(uac_reg_lookup("$rU", "$ru")) {
        xlog("request from a remote SIP provider [$ou => $ru]\n");
    }
    lookup("location");
...
			</programlisting>
		</example>
	</section>
</chapter>

