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

<chapter>
	
	<title>&adminguide;</title>
	
	<section id="overview" xreflabel="Overview">
	<title>Overview</title>
	<para>
		This is a module which provides topology hiding capabilities.
		The module can work on top of the dialog module, or as a standalone module ( thus alowing topology hiding for all
		types of requests )
	</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>TM - Transaction Module</emphasis>.
			</para>
			</listitem>
			<listitem>
			<para>
				<emphasis>Dialog Module</emphasis>, if <quote>force_dialog</quote>
				module parameter is enabled, or a dialog is created from the
				configuration script.
			</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_th_callid_passwd" xreflabel="th_callid_passwd">
		<title><varname>th_callid_passwd</varname> (string)</title>
		<para>
			The string password that will be used for encoding/decoding the callid in case of topology_hiding with callid mangling.
		</para>
		<para>
		<emphasis>
			Default value is <quote>"OpenSIPS"</quote>
		</emphasis>
		</para>
		<example>
		<title>Set <varname>th_callid_passwd</varname> parameter</title>
		<programlisting format="linespecific">
...
modparam("topology_hiding", "th_callid_passwd", "my_topo_hiding_secret")
...
</programlisting>
		</example>
	</section>

	<section id="param_th_callid_prefix" xreflabel="th_callid_prefix">
		<title><varname>th_callid_prefix</varname> (string)</title>
		<para>
			The prefix that will be used for detecting callids which have been encoded by the dialog topology hiding. Make sure to change this value in case your SIP path contains multiple OpenSIPS boxes with topology hiding.
		</para>
		<para>
		<emphasis>
			Default value is <quote>"DLGCH_"</quote>
		</emphasis>
		</para>
		<example>
		<title>Set <varname>th_callid_prefix</varname> parameter</title>
		<programlisting format="linespecific">
...
modparam("topology_hiding", "th_callid_prefix", "MYCALLIDPREFIX_")
...
</programlisting>
		</example>
	</section>

	<section id="param_th_passed_contact_uri_params" xreflabel="th_passed_contact_uri_params">
		<title><varname>th_passed_contact_uri_params</varname> (string)</title>
		<para>
			List of semicolon-separated Contact URI parameters that will be passed from one side to the other for topology hiding calls. To be used when end-to-end functionality uses such Contact URI parameters. 
		</para>
		<para>
		<emphasis>
			Default value is <quote>empty</quote> - do not pass any parameters
		</emphasis>
		</para>
		<example>
		<title>Set <varname>th_passed_contact_uri_params</varname> parameter</title>
		<programlisting format="linespecific">
...
modparam("topology_hiding", "th_passed_contact_uri_params", "paramname1;myparam;custom_param")
...
</programlisting>
		</example>
	</section>

	<section id="param_th_passed_contact_params" xreflabel="th_passed_contact_params">
		<title><varname>th_passed_contact_params</varname> (string)</title>
		<para>
			List of semicolon-separated Contact header parameters that will be passed from one side to the other for topology hiding calls. To be used when end-to-end functionality uses such Contact header parameters. 
		</para>
		<para>
		<emphasis>
			Default value is <quote>empty</quote> - do not pass any parameters
		</emphasis>
		</para>
		<example>
		<title>Set <varname>th_passed_contact_params</varname> parameter</title>
		<programlisting format="linespecific">
...
modparam("topology_hiding", "th_passed_contact_params", "paramname1;myparam;custom_param")
...
</programlisting>
		</example>
	</section>

	<section id="param_force_dialog" xreflabel="force_dialog">
		<title><varname>force_dialog</varname> (int)</title>
		<para>
			If set to 1, the module will internally create the dialog ( if not already created ). This will only work for INVITE based dialogs, and the dialog module must be loaded.
		</para>
		<para>
		<emphasis>
			Default value is <quote>0</quote>
		</emphasis>
		</para>
		<example>
		<title>Set <varname>force_dialog</varname> parameter</title>
		<programlisting format="linespecific">
...
modparam("topology_hiding", "force_dialog", 1)
...
</programlisting>
		</example>
	</section>

	<section id="param_th_contact_encode_passwd" xreflabel="th_contact_encode_passwd">
		<title><varname>th_contact_encode_passwd</varname> (string)</title>
		<para>
			When not relying on the dialog module ( due to script writer preference or simply when doing topo hiding for non INVITE dialogs ), the module will store the needed information in a Contact URI param. The parameter configures the string password that will be used for encoding/decoding that specific param .
		</para>
		<para>
		<emphasis>
			Default value is <quote>"ToPoCtPaSS"</quote>
		</emphasis>
		</para>
		<example>
		<title>Set <varname>th_contact_encode_passwd</varname> parameter</title>
		<programlisting format="linespecific">
...
modparam("topology_hiding", "th_contact_encode_passwd", "my_topoh_passwd")
...
</programlisting>
		</example>
	</section>

	<section id="param_th_contact_encode_param" xreflabel="th_contact_encode_param">
		<title><varname>th_contact_encode_param</varname> (string)</title>
		<para>
			When not relying on the dialog module ( due to script writer preference or simply when doing topo hiding for non INVITE dialogs ), the module will store the needed information in a Contact URI param. The parameter configures the respective parameter name.
		</para>
		<para>
		<emphasis>
			Default value is <quote>"thinfo"</quote>
		</emphasis>
		</para>
		<example>
		<title>Set <varname>th_contact_encode_param</varname> parameter</title>
		<programlisting format="linespecific">
...
modparam("topology_hiding", "th_contact_encode_param", "customparam")
...
</programlisting>
		</example>
	</section>

	<section id="param_th_contact_encode_scheme" xreflabel="th_contact_encode_scheme">
		<title><varname>th_contact_encode_scheme</varname> (string)</title>
		<para>
			When not relying on the dialog module ( due to script writer preference or simply when doing topo hiding for non INVITE dialogs ), the module will store the needed information in a Contact URI param. This parameter configures the encoding scheme to be used for the data stored in
			the Contact URI param. Possible values are:
			<itemizedlist>
				<listitem><para><emphasis>base64</emphasis></para></listitem>
				<listitem><para><emphasis>base32</emphasis></para></listitem>
			</itemizedlist>
		</para>
		<para>
		<emphasis>
			Default value is <quote>"base64"</quote>
		</emphasis>
		</para>
		<example>
		<title>Set <varname>th_contact_encode_scheme</varname> parameter</title>
		<programlisting format="linespecific">
...
modparam("topology_hiding", "th_contact_encode_scheme", "base32")
...
</programlisting>
		</example>
	</section>

	</section>
	<section id="exported_functions" xreflabel="exported_functions">
	<title>Exported Functions</title>
	<section id="func_topology_hiding" xreflabel="topology_hiding()">
		<title>
		<function moreinfo="none">topology_hiding()</function>
		</title>
		<para>
			By calling this function on an initial request, the modules will
			hide the topology, meaning that it will strip and restore all the Via,
			Record-Route and Route headers and it will replace the contact with the
			IP address of the interface where the request was received.
		</para>
		<para>
			You must note however, that the detection of the future in-dialog requests(BYE, reInvite, etc.)
			for these dialogs on which topology hiding is applied, is not done automatically.
			Without topology hiding and only normal dialog, the detection was
			done when loose_route was called. But now, for this dialogs where topology
			hiding is applied, the in dialog requests reaching OpenSIPS won't have any Route headers
			and the RURI will point to OpenSIPS machine.
			So, to be able to match the in-dialog requests to the corresponding dialog, a script
			function must be called. It's name is <emphasis>topology_hiding_match</emphasis> and you can read
			it's description above.
			The in-dialog topology requests are requests with a to tag,
			RURI pointing to opensips and with a method specific to a
			Invite dialog. For this kind of requests you should call
			topology_hiding_match() function. If the request is successfully matched and fixed as according to the topology hiding logic,the function returns success.
		</para>
		<para>
			Optionally,the function also receives a string parameter, which holds string flags.
			Current options for the string flags are :
			<itemizedlist>
				<listitem>
					<para><emphasis>U</emphasis> - Propagate the Username in the Contact header URI
					</para>
				</listitem>
				<listitem>
					<para><emphasis>D</emphasis> - Dialog ID (DID) is pushed into Contact username, rather than URI param. This option makes sense only when using topology hiding with dialog support.
					</para>
				</listitem>
				<listitem>
					<para><emphasis>a</emphasis> - Preserve the advertised Contact header advertised to the caller throughout the entire dialog.
					</para>
				</listitem>
				<listitem>
					<para><emphasis>A</emphasis> - Preserve the advertised Contact header advertised to the callee throughout the entire dialog.
					</para>
				</listitem>
				<listitem>
					<para><emphasis>D</emphasis> - Dialog ID (DID) is pushed into Contact username, rather than URI param. This option makes sense only when using topology hiding with dialog support.
					</para>
				</listitem>
				<listitem>
					<para><emphasis>C</emphasis> - Encode the callid header
					</para>
					<para>
					There are many cases where propagating the callid towards the callee side is not a good idea, since sometimes the callid contains the IP of the actual caller side, thus revealing part of the network topology.
					</para>
					<para>
					When using the "C" flag, the callid will be automatically encoded / decoded, transparent for the script writer - inside OpenSIPS (script,MI functions, etc ) all the variables related to the callid will represent the callid value for the caller side. If the callid for the callee side is needed, refer to the $TH_callee_callid pvar.
					</para>
					<para>
						<emphasis>Note:</emphasis> Changing the callid of the call using the "C" flag is only
						available when doing topology_hiding with <emphasis>dialog support</emphasis>. Using this
						flag without dialog support will not change the callid at all!.
					</para>
				</listitem>
			</itemizedlist>
		</para>
		<example>
		<title><function>topology_hiding</function> usage</title>
		<programlisting format="linespecific">
...
if(!has_totag() &amp;&amp; is_method("INVITE")) {
	topology_hiding();
}
...
...
if(!has_totag() &amp;&amp; is_method("INVITE")) {
	topology_hiding("U");
}
...
</programlisting>
		</example>
		<example>
		<title><function>Calling topology_hiding_match() function for topology hiding sequential requests</function></title>
		<programlisting format="linespecific">
...
if (has_totag())
        if(topology_hiding_match())
        {
                xlog("Found a request $rm belonging to an existing topology hiding dialog\n");
                route(relay);
                exit;
        }
}
...
</programlisting>
		</example>
	</section>

	<section id="func_topology_hiding_match" xreflabel="topology_hiding_match()">
		<title>
		<function moreinfo="none">topology_hiding_match([dlg_match_mode])</function>
		</title>
		<para>
		This function is to be used to match and fix a sequential request
		belong to an existing topology hiding dialog.
		</para>
		<para>
		With regards to dialog matching (including the optional parameter),
		this function behaves identically to match_dialog(). Please see the
		dialog module documentation for further details regarding dialog
		matching options.
		</para>
		<para>
		The function returns true if a topology hiding dialog exists for the request and the request has been successfully fixed.
		</para>
		<para>
		This function can be used from REQUEST_ROUTE.
		</para>
		<example>
		<title><function>topology_hiding_match_dialog()</function> usage</title>
		<programlisting format="linespecific">
...
    if (has_totag()) {
        if (!topology_hiding_match() ) {
            xlog(" cannot match request to a dialog \n");
	    send_reply(404,"Not found");
        } else
		route(RELAY);
    }
...
</programlisting>
		</example>
	</section>

	</section>

	<section id="exported_pseudo_variables">
	<title>Exported Pseudo-Variables</title>
		<section id="pv_TH_callee_callid" xreflabel="$TH_callee_callid">
			<title><varname>$TH_callee_callid</varname></title>
			<para>
				Read only variable that will contain the callid as it is propagated towards the callee side, in case topology_hiding("C") is called.
			</para>
			<para>
			NULL will be returned if there is no topology hiding dialog for the request or if topology_hiding with callid encoding was not used for the current dialog.
			</para>
		</section>
	</section>

</chapter>

