mirror of https://github.com/sipwise/kamailio.git
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
571 lines
19 KiB
571 lines
19 KiB
<?xml version="1.0" encoding="ISO-8859-1"?>
|
|
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.4//EN"
|
|
"http://www.oasis-open.org/docbook/xml/4.4/docbookx.dtd" [
|
|
<!-- Include general documentation entities -->
|
|
<!ENTITY % docentities SYSTEM "../../../docbook/entities.xml">
|
|
%docentities;
|
|
]>
|
|
<!-- Module User's Guide -->
|
|
<chapter>
|
|
<title>&adminguide;</title>
|
|
|
|
<section>
|
|
<title>Overview</title>
|
|
|
|
<para>The module contains record routing logic</para>
|
|
</section>
|
|
|
|
<section id="RR-dialog-id">
|
|
<title>Dialog support</title>
|
|
|
|
<para>&kamailio; is basically <emphasis>only</emphasis> a transaction
|
|
statefull proxy, without any dialog support build in. There are many
|
|
features/services which actually requires a dialog awareness, like storing
|
|
the information in the dialog creation stage, information which will be
|
|
used during the whole dialog existence.</para>
|
|
|
|
<para>The most urging example is NAT traversal, in dealing with the within
|
|
the dialog INVITEs (re-INVITEs). When processing the initial INVITE, the
|
|
proxy detects if the caller or callee is behind some NAT and fixes the
|
|
signalling and media parts - since not all the detection mechanism are
|
|
available for within the dialog requests (like usrloc), to be able to fix
|
|
correspondingly the sequential requests, the proxy must remember that the
|
|
original request was NAT processed. There are many other cases where
|
|
dialog awareness fixes or helps.</para>
|
|
|
|
<para>The solution is to store additional dialog-related information in
|
|
the routing set (Record-Route/Route headers), headers which show up in all
|
|
sequential requests. So any information added to the Record-Route header
|
|
will be found (with no direction dependencies) in Route header
|
|
(corresponding to the proxy address).</para>
|
|
|
|
<para>As storage container, the parameters of the Record-Route / Route
|
|
header will be used - Record-Route parameters mirroring are reinforced by
|
|
RFC 3261 (see 12.1.1 UAS behavior).</para>
|
|
|
|
<para>For this purpose, the modules offers the following functions:</para>
|
|
|
|
<itemizedlist>
|
|
<listitem>
|
|
<para>add_rr_param() - see <xref linkend="add-rr-param-id"/></para>
|
|
</listitem>
|
|
|
|
<listitem>
|
|
<para>check_route_param() - see <xref
|
|
linkend="check-route-param-id"/></para>
|
|
</listitem>
|
|
</itemizedlist>
|
|
|
|
<example>
|
|
<title>Dialog support in RR module</title>
|
|
|
|
<programlisting format="linespecific">
|
|
|
|
UAC &kamailio; PROXY UAS
|
|
|
|
---- INVITE ------> record_route() ----- INVITE ---->
|
|
add_rr_param(";foo=true")
|
|
|
|
--- reINVITE -----> loose_route() ---- reINVITE --->
|
|
check_route_param(";foo=true")
|
|
|
|
<-- reINVITE ------ loose_route() <--- reINVITE ----
|
|
check_route_param(";foo=true")
|
|
|
|
<------ BYE ------- loose_route() <----- BYE -------
|
|
check_route_param(";foo=true")
|
|
|
|
</programlisting>
|
|
</example>
|
|
</section>
|
|
|
|
<section>
|
|
<title>Dependencies</title>
|
|
|
|
<section>
|
|
<title>&kamailio; Modules</title>
|
|
|
|
<para>The following modules must be loaded before this module:
|
|
<itemizedlist>
|
|
<listitem>
|
|
<para>(optional) The "outbound" module is needed for outbound
|
|
routing as per RFC 5626.</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>
|
|
<title><varname>enable_full_lr</varname> (integer)</title>
|
|
|
|
<para>If set to 1 then <quote>;lr=on</quote> instead of just
|
|
<quote>;lr</quote> will be used. This is to overcome problems with
|
|
broken &ua;s which strip <quote>;lr</quote> parameter when generating
|
|
Route header fields from Record-Route (<quote>;lr=on</quote> seems to
|
|
help).</para>
|
|
|
|
<para><emphasis> Default value is 0 (no). </emphasis></para>
|
|
|
|
<example>
|
|
<title>Set <varname>enable_full_lr</varname> parameter</title>
|
|
|
|
<programlisting format="linespecific">
|
|
...
|
|
modparam("rr", "enable_full_lr", 1)
|
|
...
|
|
</programlisting>
|
|
</example>
|
|
</section>
|
|
|
|
<section id="append-fromtag-id">
|
|
<title><varname>append_fromtag</varname> (integer)</title>
|
|
|
|
<para>If turned on, request's from-tag is appended to record-route;
|
|
that's useful for understanding whether subsequent requests (such as
|
|
BYE) come from caller (route's from-tag==BYE's from-tag) or callee
|
|
(route's from-tag==BYE's to-tag)</para>
|
|
|
|
<para><emphasis> Default value is 1 (yes). </emphasis></para>
|
|
|
|
<example>
|
|
<title>Set <varname>append_fromtag</varname> parameter</title>
|
|
|
|
<programlisting format="linespecific">
|
|
...
|
|
modparam("rr", "append_fromtag", 0)
|
|
...
|
|
</programlisting>
|
|
</example>
|
|
</section>
|
|
|
|
<section>
|
|
<title><varname>enable_double_rr</varname> (integer)</title>
|
|
|
|
<para>There are some situations when the server needs to insert two
|
|
Record-Route header fields instead of one. For example when using two
|
|
disconnected networks or doing cross-protocol forwarding from
|
|
UDP->TCP. This parameter enables inserting of 2 Record-Routes. The
|
|
server will later remove both of them.</para>
|
|
|
|
<para>Double record-routing does not occur when outbound is used for a
|
|
request.</para>
|
|
|
|
<para><emphasis> Default value is 1 (yes). </emphasis></para>
|
|
|
|
<example>
|
|
<title>Set <varname>enable_double_rr</varname> parameter</title>
|
|
|
|
<programlisting format="linespecific">
|
|
...
|
|
modparam("rr", "enable_double_rr", 0)
|
|
...
|
|
</programlisting>
|
|
</example>
|
|
</section>
|
|
|
|
<section>
|
|
<title><varname>add_username</varname> (integer)</title>
|
|
|
|
<para>If set to a non 0 value (which means yes), the username part will
|
|
be also added in the Record-Route URI.</para>
|
|
|
|
<para>This option cannot be set when the <quote>outbound</quote> module
|
|
is loaded before this module as outbound uses the username part of
|
|
Record-Route URIs to store flow-tokens.</para>
|
|
|
|
<para><emphasis> Default value is 0 (no). </emphasis></para>
|
|
|
|
<example>
|
|
<title>Set <varname>add_username</varname> parameter</title>
|
|
|
|
<programlisting format="linespecific">
|
|
...
|
|
modparam("rr", "add_username", 1)
|
|
...
|
|
</programlisting>
|
|
</example>
|
|
</section>
|
|
|
|
<section>
|
|
<title><varname>enable_socket_mismatch_warning</varname>
|
|
(integer)</title>
|
|
|
|
<para>When a preset record-route header is forced in &kamailio; config
|
|
and the host from the record-route header is not the same as the host
|
|
server, a warning will be printed out in the logs. The
|
|
'enable_socket_mismatch_warning' parameter enables or disables the
|
|
warning. When &kamailio; is behind a NATed firewall, we don't want this
|
|
warning to be printed for every bridged call.</para>
|
|
|
|
<para><emphasis> Default value is 1 (yes). </emphasis></para>
|
|
|
|
<example>
|
|
<title><varname>enable_socket_mismatch_warning</varname> usage</title>
|
|
|
|
<programlisting format="linespecific">
|
|
...
|
|
modparam("rr", "enable_socket_mismatch_warning", 0)
|
|
...
|
|
</programlisting>
|
|
</example>
|
|
</section>
|
|
|
|
<section>
|
|
<title><varname>custom_user_avp</varname> (avp string)</title>
|
|
|
|
<para>When enable_username is enabled, a call to record_route will add
|
|
the username of the RequestURI to the Record-Route URI. This parameter
|
|
allows you to setup an AVP with which you can customise the username to
|
|
be added in the Record-Route URI.</para>
|
|
|
|
<para><emphasis> Default value: if not set, the std add_username
|
|
behaviour is used - i.e. Request URI username. </emphasis></para>
|
|
|
|
<example>
|
|
<title><varname>custom_user_avp</varname> usage</title>
|
|
|
|
<programlisting format="linespecific">
|
|
...
|
|
modparam("rr", "custom_user_avp", "$avp(RR_CUSTOMER_USER_AVP)")
|
|
|
|
#usage in cfg file
|
|
$avp(RR_CUSTOM_USER_AVP)="mo";
|
|
record_route();
|
|
|
|
...
|
|
</programlisting>
|
|
</example>
|
|
</section>
|
|
</section>
|
|
|
|
<section>
|
|
<title>Functions</title>
|
|
|
|
<section id="loose-route-id">
|
|
<title><function moreinfo="none">loose_route()</function></title>
|
|
|
|
<para>The function performs routing of SIP requests which contain a
|
|
route set. The name is a little bit confusing, as this function also
|
|
routes requests which are in the <quote>strict router</quote>
|
|
format.</para>
|
|
|
|
<para>This function is usually used to route in-dialog requests (like
|
|
ACK, BYE, reINVITE). Nevertheless also out-of-dialog requests can have a
|
|
<quote>pre-loaded route set</quote> and my be routed with loose_route.
|
|
It also takes care of translating between strict-routers and
|
|
loose-router.</para>
|
|
|
|
<para>The loose_route function analyzes the Route: headers in the
|
|
requests. If there is no Route: header, the function returns FALSE and
|
|
routing should be done with normal lookup functions. If a Route: header
|
|
is found, the function returns 1 and behaves as described in section
|
|
16.12 of RFC 3261. There is only one exception: If the request is
|
|
out-of-dialog (no to-tag) and there is only one Route: header indicating
|
|
the local proxy, then the Route: header is removed and the function
|
|
returns FALSE.</para>
|
|
|
|
<para>When the <quote>outbound</quote> module was loaded before this
|
|
module and the Route: header contains a username part this function will
|
|
attempt to use the username part as a flow-token for routing.</para>
|
|
|
|
<para>Make sure your loose_routing function can't be used by attackers
|
|
to bypass proxy authorization.</para>
|
|
|
|
<para>The loose_routing topic is very complex. See the RFC3261 for more
|
|
details (grep for <quote>route set</quote> is a good starting point in
|
|
this comprehensive RFC).</para>
|
|
|
|
<para>Return codes:</para>
|
|
|
|
<itemizedlist>
|
|
<listitem>
|
|
<para><emphasis>1</emphasis> - route calculation has been
|
|
successful</para>
|
|
</listitem>
|
|
|
|
<listitem>
|
|
<para><emphasis>-1</emphasis> - route calculation has been
|
|
unsuccessful</para>
|
|
</listitem>
|
|
|
|
<listitem>
|
|
<para><emphasis>-2</emphasis> - outbound flow-token shows evidence
|
|
of tampering</para>
|
|
</listitem>
|
|
</itemizedlist>
|
|
|
|
<para>This function can be used from REQUEST_ROUTE.</para>
|
|
|
|
<example>
|
|
<title><function>loose_route</function> usage</title>
|
|
|
|
<programlisting format="linespecific">
|
|
...
|
|
loose_route();
|
|
...
|
|
</programlisting>
|
|
</example>
|
|
</section>
|
|
|
|
<section id="record-route-id">
|
|
<title><function moreinfo="none">record_route()</function> and <function
|
|
moreinfo="none">record_route(string)</function></title>
|
|
|
|
<para>The function adds a new Record-Route header field. The header
|
|
field will be inserted in the message before any other Record-Route
|
|
header fields.</para>
|
|
|
|
<para>If any string is passed as parameter, it will be appended as URI
|
|
parameter to the Record-Route header. The string must follow the
|
|
<quote>;name=value</quote> scheme and it may contain
|
|
pseudo-variables.</para>
|
|
|
|
<para>When the <quote>outbound</quote> module was loaded before this
|
|
module this function will determine whether outbound is required for the
|
|
request and generate and add a flow-token as the username part of the
|
|
Record-Route-URI.</para>
|
|
|
|
<para>This function can be used from REQUEST_ROUTE, BRANCH_ROUTE and
|
|
FAILURE_ROUTE.</para>
|
|
|
|
<example>
|
|
<title><function>record_route</function> usage</title>
|
|
|
|
<programlisting format="linespecific">
|
|
...
|
|
record_route();
|
|
...
|
|
</programlisting>
|
|
</example>
|
|
</section>
|
|
|
|
<section>
|
|
<title><function moreinfo="none">record_route_preset(string
|
|
[,string2])</function></title>
|
|
|
|
<para>This function will put the string into Record-Route, don't use
|
|
unless you know what you are doing.</para>
|
|
|
|
<para>Meaning of the parameters is as follows:</para>
|
|
|
|
<itemizedlist>
|
|
<listitem>
|
|
<para><emphasis>string</emphasis> - String to be inserted into the
|
|
first header field; it may contain pseudo-variables.</para>
|
|
</listitem>
|
|
|
|
<listitem>
|
|
<para><emphasis>string2</emphasis> - String to be inserted into the
|
|
second header field; it may contain pseudo-variables.</para>
|
|
</listitem>
|
|
</itemizedlist>
|
|
|
|
<para>Note: If 'string2' is present, then the 'string' param is pointing
|
|
to the outbound interface and the 'string2' param is pointing to the
|
|
inbound interface.</para>
|
|
|
|
<para>When the <quote>outbound</quote> module was loaded before this
|
|
module this function will determine whether outbound is required for the
|
|
request and generate and add a flow-token as the username part of the
|
|
Record-Route-URI.</para>
|
|
|
|
<para>This function can be used from REQUEST_ROUTE, BRANCH_ROUTE and
|
|
FAILURE_ROUTE.</para>
|
|
|
|
<example>
|
|
<title><function>record_route_preset</function> usage</title>
|
|
|
|
<programlisting format="linespecific">
|
|
...
|
|
record_route_preset("1.2.3.4:5090");
|
|
...
|
|
</programlisting>
|
|
</example>
|
|
</section>
|
|
|
|
<section id="record-route-adv-addr-id">
|
|
<title><function
|
|
moreinfo="none">record_route_advertised_address(address)</function></title>
|
|
|
|
<para>The function adds a new Record-Route header field using the
|
|
address given. The header field will be inserted in the message before
|
|
any other Record-Route header fields.</para>
|
|
|
|
<para>When the <quote>outbound</quote> module was loaded before this
|
|
module this function will determine whether outbound is required for the
|
|
request and generate and add a flow-token as the username part of the
|
|
Record-Route-URI.</para>
|
|
|
|
<para>Meaning of the parameter is as follows:</para>
|
|
|
|
<itemizedlist>
|
|
<listitem>
|
|
<para><emphasis>address</emphasis> - Advertised address to use in
|
|
the header; it may contain pseudo-variables.</para>
|
|
</listitem>
|
|
</itemizedlist>
|
|
|
|
<para>If double record-routing is enabled two Record-Route headers will
|
|
be inserted with the same given address with different transports if the
|
|
transport changes.</para>
|
|
|
|
<para>This function can be used from REQUEST_ROUTE, BRANCH_ROUTE and
|
|
FAILURE_ROUTE.</para>
|
|
|
|
<example>
|
|
<title><function>record_route_advertised_address</function>
|
|
usage</title>
|
|
|
|
<programlisting format="linespecific">
|
|
...
|
|
record_route_advertised_address("1.2.3.4:5080");
|
|
...
|
|
</programlisting>
|
|
</example>
|
|
</section>
|
|
|
|
<section id="add-rr-param-id">
|
|
<title><function moreinfo="none">add_rr_param(param)</function></title>
|
|
|
|
<para>Adds a parameter to the Record-Route URI (param must be in
|
|
<quote>;name=value</quote> format. The function may be called also
|
|
before or after the record_route() or record_route_advertised_address()
|
|
calls (see <xref linkend="record-route-id"/> or <xref
|
|
linkend="record-route-adv-addr-id"/>)).</para>
|
|
|
|
<para>Meaning of the parameters is as follows:</para>
|
|
|
|
<itemizedlist>
|
|
<listitem>
|
|
<para><emphasis>param</emphasis> - String containing the URI
|
|
parameter to be added. It must follow the <quote>;name=value</quote>
|
|
scheme; it may contain pseudo-variables.</para>
|
|
</listitem>
|
|
</itemizedlist>
|
|
|
|
<para>This function can be used from REQUEST_ROUTE, BRANCH_ROUTE and
|
|
FAILURE_ROUTE.</para>
|
|
|
|
<example>
|
|
<title><function>add_rr_param</function> usage</title>
|
|
|
|
<programlisting format="linespecific">
|
|
...
|
|
add_rr_param(";nat=yes");
|
|
...
|
|
</programlisting>
|
|
</example>
|
|
</section>
|
|
|
|
<section id="check-route-param-id">
|
|
<title><function
|
|
moreinfo="none">check_route_param(re)</function></title>
|
|
|
|
<para>The function checks if the URI parameters of the local Route
|
|
header (corresponding to the local server) matches the given regular
|
|
expression. It must be call after loose_route() (see <xref
|
|
linkend="loose-route-id"/>).</para>
|
|
|
|
<para>Meaning of the parameters is as follows:</para>
|
|
|
|
<itemizedlist>
|
|
<listitem>
|
|
<para><emphasis>re</emphasis> - regular expression to check against
|
|
the Route URI parameters.</para>
|
|
</listitem>
|
|
</itemizedlist>
|
|
|
|
<para>This function can be used from REQUEST_ROUTE.</para>
|
|
|
|
<example>
|
|
<title><function>check_route_param</function> usage</title>
|
|
|
|
<programlisting format="linespecific">
|
|
...
|
|
if (check_route_param("nat=yes")) {
|
|
setflag(6);
|
|
}
|
|
...
|
|
</programlisting>
|
|
</example>
|
|
</section>
|
|
|
|
<section>
|
|
<title><function moreinfo="none">is_direction(dir)</function></title>
|
|
|
|
<para>The function checks the flow direction of in-dialog requests. This
|
|
function uses the <quote>ftag</quote> prameter from the Route header,
|
|
therefore the append_fromtag (see <xref linkend="append-fromtag-id"/>
|
|
module parameter must be enabled. Also this must be called only after
|
|
loose_route() (see <xref linkend="loose-route-id"/>).</para>
|
|
|
|
<para>The function returns true if the <quote>dir</quote> is the same
|
|
with the request's flow direction.</para>
|
|
|
|
<para>The <quote>downstream</quote> direction means that the request is
|
|
in the same direction as the initial request that created the
|
|
dialog.</para>
|
|
|
|
<para>Meaning of the parameters is as follows:</para>
|
|
|
|
<itemizedlist>
|
|
<listitem>
|
|
<para><emphasis>dir</emphasis> - string containing the direction to
|
|
be checked. It may be <quote>upstream</quote> (from callee to
|
|
caller) or <quote>downstream</quote> (caller to callee).</para>
|
|
</listitem>
|
|
</itemizedlist>
|
|
|
|
<para>This function can be used from REQUEST_ROUTE.</para>
|
|
|
|
<example>
|
|
<title><function>is_direction</function> usage</title>
|
|
|
|
<programlisting format="linespecific">
|
|
...
|
|
if (is_direction("downstream")) {
|
|
xdbg("in-dialog request from caller to callee (downstream) ($rm)\n");
|
|
} else {
|
|
xdbg("in-dialog request from callee to caller (upstream) ($rm)\n");
|
|
}
|
|
...
|
|
</programlisting>
|
|
</example>
|
|
</section>
|
|
</section>
|
|
|
|
<section>
|
|
<title>Exported Pseudo Variables</title>
|
|
|
|
<section>
|
|
<title><function moreinfo="none">$route_uri</function></title>
|
|
|
|
<para>Returns the URI of the top route-header.</para>
|
|
|
|
<example>
|
|
<title>$route_uri</title>
|
|
|
|
<programlisting format="linespecific">
|
|
...
|
|
xdbg("Route-URI is: $route_uri\n");
|
|
...
|
|
</programlisting>
|
|
</example>
|
|
</section>
|
|
</section>
|
|
</chapter>
|