rr: docs - note about use of record_route() for requests within dialog
[kamailio] / src / modules / rr / doc / rr_admin.xml
1 <?xml version="1.0" encoding="ISO-8859-1"?>
2 <!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.4//EN"
3 "http://www.oasis-open.org/docbook/xml/4.4/docbookx.dtd" [
4 <!-- Include general documentation entities -->
5 <!ENTITY % docentities SYSTEM "../../../../doc/docbook/entities.xml">
6 %docentities;
7 ]>
8 <!-- Module User's Guide -->
9 <chapter>
10   <title>&adminguide;</title>
11
12   <section>
13     <title>Overview</title>
14
15     <para>The module contains record routing logic</para>
16   </section>
17
18   <section id="RR-dialog-id">
19     <title>Dialog support</title>
20
21     <para>&kamailio; is basically <emphasis>only</emphasis> a transaction
22     stateful proxy, without any dialog support build in. There are many
23     features/services which actually requires a dialog awareness, like storing
24     the information in the dialog creation stage, information which will be
25     used during the whole dialog existence.</para>
26
27     <para>The most urging example is NAT traversal, in dealing with the within
28     the dialog INVITEs (re-INVITEs). When processing the initial INVITE, the
29     proxy detects if the caller or callee is behind some NAT and fixes the
30     signalling and media parts - since not all the detection mechanism are
31     available for within the dialog requests (like usrloc), to be able to fix
32     correspondingly the sequential requests, the proxy must remember that the
33     original request was NAT processed. There are many other cases where
34     dialog awareness fixes or helps.</para>
35
36     <para>The solution is to store additional dialog-related information in
37     the routing set (Record-Route/Route headers), headers which show up in all
38     sequential requests. So any information added to the Record-Route header
39     will be found (with no direction dependencies) in Route header
40     (corresponding to the proxy address).</para>
41
42     <para>As storage container, the parameters of the Record-Route / Route
43     header will be used - Record-Route parameters mirroring are reinforced by
44     RFC 3261 (see 12.1.1 UAS behavior).</para>
45
46     <para>For this purpose, the modules offers the following functions:</para>
47
48     <itemizedlist>
49       <listitem>
50         <para>add_rr_param() - see <xref linkend="add-rr-param-id"/></para>
51       </listitem>
52
53       <listitem>
54         <para>check_route_param() - see <xref
55         linkend="check-route-param-id"/></para>
56       </listitem>
57     </itemizedlist>
58
59     <example>
60       <title>Dialog support in RR module</title>
61
62       <programlisting format="linespecific">
63 ...
64 UAC                       &kamailio; PROXY                          UAS
65
66 ---- INVITE ------&gt;       record_route()          ----- INVITE ----&gt;
67                      add_rr_param(";foo=true")
68
69 --- reINVITE -----&gt;        loose_route()          ---- reINVITE ---&gt;
70                     check_route_param(";foo=true")
71
72 &lt;-- reINVITE ------        loose_route()          &lt;--- reINVITE ----
73                     check_route_param(";foo=true")
74
75 &lt;------ BYE -------        loose_route()          &lt;----- BYE -------
76                     check_route_param(";foo=true")
77 ...
78 </programlisting>
79     </example>
80   </section>
81
82   <section>
83     <title>Dependencies</title>
84
85     <section>
86       <title>&kamailio; Modules</title>
87
88       <para>The following modules must be loaded before this module:
89       <itemizedlist>
90           <listitem>
91             <para>(optional) The "outbound" module is needed for outbound
92             routing as per RFC 5626.</para>
93           </listitem>
94         </itemizedlist></para>
95     </section>
96
97     <section>
98       <title>External Libraries or Applications</title>
99
100       <para>The following libraries or applications must be installed before
101       running &kamailio; with this module loaded: <itemizedlist>
102           <listitem>
103             <para><emphasis>None</emphasis>.</para>
104           </listitem>
105         </itemizedlist></para>
106     </section>
107   </section>
108
109   <section>
110     <title>Parameters</title>
111
112     <section id="rr.p.enable_full_lr">
113       <title><varname>enable_full_lr</varname> (integer)</title>
114
115       <para>If set to 1 then <quote>;lr=on</quote> instead of just
116       <quote>;lr</quote> will be used. This is to overcome problems with
117       broken &ua;s which strip <quote>;lr</quote> parameter when generating
118       Route header fields from Record-Route (<quote>;lr=on</quote> seems to
119       help).</para>
120
121       <para><emphasis> Default value is 0 (no). </emphasis></para>
122
123       <example>
124         <title>Set <varname>enable_full_lr</varname> parameter</title>
125
126         <programlisting format="linespecific">
127 ...
128 modparam("rr", "enable_full_lr", 1)
129 ...
130 </programlisting>
131       </example>
132     </section>
133
134     <section id="rr.p.append_fromtag_id">
135       <title><varname>append_fromtag</varname> (integer)</title>
136
137       <para>If turned on, request's from-tag is appended to record-route;
138       that's useful for understanding whether subsequent requests (such as
139       BYE) come from caller (route's from-tag==BYE's from-tag) or callee
140       (route's from-tag==BYE's to-tag)</para>
141
142       <para><emphasis> Default value is 1 (yes). </emphasis></para>
143
144       <example>
145         <title>Set <varname>append_fromtag</varname> parameter</title>
146
147         <programlisting format="linespecific">
148 ...
149 modparam("rr", "append_fromtag", 0)
150 ...
151 </programlisting>
152       </example>
153     </section>
154
155     <section id="rr.p.enable_double_rr">
156       <title><varname>enable_double_rr</varname> (integer)</title>
157
158       <para>There are some situations when the server needs to insert two
159       Record-Route header fields instead of one. For example when using two
160       disconnected networks or doing cross-protocol forwarding from
161       UDP-&gt;TCP. This parameter enables inserting of 2 Record-Routes. The
162       server will later remove both of them.</para>
163
164       <para>Double record-routing does not occur when outbound is used for a
165       request.</para>
166
167       <para><emphasis> Default value is 1 (yes). </emphasis></para>
168
169       <example>
170         <title>Set <varname>enable_double_rr</varname> parameter</title>
171
172         <programlisting format="linespecific">
173 ...
174 modparam("rr", "enable_double_rr", 0)
175 ...
176 </programlisting>
177       </example>
178       <para>Some useragents (e. g. Linphone) incorrectly use UDP transport for
179       subsequent requests in dialog, despite being configured to use another
180       SIP transport protocol. This can be worked around by setting Record-Route
181       header with explicit transport attribute. But enable_double_rr enabled in
182       default mode omits transport attribute from being added to header if it
183       detects that both sender and receiver use same protocol (e. g. TCP or
184       TLS), and this results in UDP being used by such broken clients. Set
185       enable_double_rr to value 2 to always have two RR headers with transport
186       attributes explicitly set.</para>
187
188       <example>
189         <title>Set <varname>enable_double_rr</varname> to 2 to always have two explicit RR headers</title>
190
191         <programlisting format="linespecific">
192 ...
193 modparam("rr", "enable_double_rr", 2)
194 ...
195 </programlisting>
196       </example>
197     </section>
198
199     <section id="rr.p.add_username">
200       <title><varname>add_username</varname> (integer)</title>
201
202       <para>If set to a non 0 value (which means yes), the username part will
203       be also added in the Record-Route URI.</para>
204
205       <para>This option cannot be set when the <quote>outbound</quote> module
206       is loaded before this module as outbound uses the username part of
207       Record-Route URIs to store flow-tokens.</para>
208
209       <para><emphasis> Default value is 0 (no). </emphasis></para>
210
211       <example>
212         <title>Set <varname>add_username</varname> parameter</title>
213
214         <programlisting format="linespecific">
215 ...
216 modparam("rr", "add_username", 1)
217 ...
218 </programlisting>
219       </example>
220     </section>
221
222     <section id="rr.p.enable_socket_warning">
223       <title><varname>enable_socket_mismatch_warning</varname>
224       (integer)</title>
225
226       <para>When a preset record-route header is forced in &kamailio; config
227       and the host from the record-route header is not the same as the host
228       server, a warning will be printed out in the logs. The
229       'enable_socket_mismatch_warning' parameter enables or disables the
230       warning. When &kamailio; is behind a NATed firewall, we don't want this
231       warning to be printed for every bridged call.</para>
232
233       <para><emphasis> Default value is 1 (yes). </emphasis></para>
234
235       <example>
236         <title><varname>enable_socket_mismatch_warning</varname> usage</title>
237
238         <programlisting format="linespecific">
239 ...
240 modparam("rr", "enable_socket_mismatch_warning", 0)
241 ...
242 </programlisting>
243       </example>
244     </section>
245
246     <section id="rr.p.custom_user_avp">
247       <title><varname>custom_user_avp</varname> (avp string)</title>
248
249       <para>When enable_username is enabled, a call to record_route will add
250       the username of the RequestURI to the Record-Route URI. This parameter
251       allows you to setup an AVP with which you can customise the username to
252       be added in the Record-Route URI.</para>
253
254       <para><emphasis> Default value: if not set, the std add_username
255       behaviour is used - i.e. Request URI username. </emphasis></para>
256
257       <example>
258         <title><varname>custom_user_avp</varname> usage</title>
259
260         <programlisting format="linespecific">
261 ...
262 modparam("rr", "custom_user_avp", "$avp(RR_CUSTOMER_USER_AVP)")
263
264 #usage in cfg file
265 $avp(RR_CUSTOM_USER_AVP)="mo";
266 record_route();
267 ...
268 </programlisting>
269       </example>
270     </section>
271     <section id="rr.p.force_send_socket">
272       <title><varname>force_send_socket</varname> (int)</title>
273
274           <para>
275                   If set to 1, local socket is forced even for single Record-Route,
276                   otherwise is done on double Record-Route (should that be enabled).
277           </para>
278
279           <para>
280                   When use of <quote>outbound</quote> is enabled, the socket is not
281                   forced.
282           </para>
283
284       <para><emphasis>Default value is 0.</emphasis></para>
285
286       <example>
287         <title>Set <varname>force_send_socket</varname> parameter</title>
288
289         <programlisting format="linespecific">
290 ...
291 modparam("rr", "force_send_socket", 1)
292 ...
293 </programlisting>
294       </example>
295     </section>
296     <section id="rr.p.ignore_sips">
297       <title><varname>ignore_sips</varname> (int)</title>
298
299           <para>
300                   If set to 1, the Record-Route header are build with 'sip' schema
301                   always, ignoring the presence of 'sips' schema in request URI.
302           </para>
303
304       <para><emphasis>Default value is 0 (use 'sips' if present in R-URI).</emphasis></para>
305
306       <example>
307         <title>Set <varname>ignore_sips</varname> parameter</title>
308
309         <programlisting format="linespecific">
310 ...
311 modparam("rr", "ignore_sips", 1)
312 ...
313 </programlisting>
314       </example>
315     </section>
316   </section>
317
318   <section>
319     <title>Functions</title>
320
321     <section id="rr.f.loose_route">
322       <title><function moreinfo="none">loose_route()</function></title>
323
324       <para>The function performs routing of SIP requests which contain a
325       route set. The name is a little bit confusing, as this function also
326       routes requests which are in the <quote>strict router</quote>
327       format.</para>
328
329       <para>This function is usually used to route in-dialog requests (like
330       ACK, BYE, reINVITE). Nevertheless also out-of-dialog requests can have a
331       <quote>pre-loaded route set</quote> and my be routed with loose_route.
332       It also takes care of translating between strict-routers and
333       loose-router.</para>
334
335       <para>The loose_route function analyzes the Route: headers in the
336       requests. If there is no Route: header, the function returns FALSE and
337       routing should be done with normal lookup functions. If a Route: header
338       is found, the function returns 1 and behaves as described in section
339       16.12 of RFC 3261. There is only one exception: If the request is
340       out-of-dialog (no to-tag) and there is only one Route: header indicating
341       the local proxy, then the Route: header is removed and the function
342       returns FALSE.</para>
343
344       <para>When the <quote>outbound</quote> module was loaded before this
345       module and the Route: header contains a username part this function will
346       attempt to use the username part as a flow-token for routing.  If route
347       calculation based on flow-token succeeds, function returns TRUE even
348       if there is only one Route: header indicating the local proxy.</para>
349
350       <para>Make sure your loose_routing function can't be used by attackers
351       to bypass proxy authorization.</para>
352
353       <para>The loose_routing topic is very complex. See the RFC3261 for more
354       details (grep for <quote>route set</quote> is a good starting point in
355       this comprehensive RFC).</para>
356
357       <para>Return codes:</para>
358
359       <itemizedlist>
360         <listitem>
361           <para><emphasis>1</emphasis> - route calculation has been
362           successful</para>
363         </listitem>
364
365         <listitem>
366           <para><emphasis>2</emphasis> - route calculation based on
367           flow-token has been successful</para>
368         </listitem>
369
370         <listitem>
371           <para><emphasis>-1</emphasis> - route calculation has been
372           unsuccessful</para>
373         </listitem>
374
375         <listitem>
376           <para><emphasis>-2</emphasis> - outbound flow-token shows evidence
377           of tampering</para>
378         </listitem>
379
380         <listitem>
381           <para><emphasis>-3</emphasis> - next hop is taken from
382           a preloaded route set</para>
383         </listitem>
384       </itemizedlist>
385
386       <para>This function can be used from REQUEST_ROUTE.</para>
387
388       <example>
389         <title><function>loose_route</function> usage</title>
390
391         <programlisting format="linespecific">
392 ...
393 loose_route();
394 ...
395 </programlisting>
396       </example>
397     </section>
398
399     <section id="rr.f.record_route">
400       <title><function moreinfo="none">record_route([sparams])</function></title>
401
402       <para>The function adds a new Record-Route header field. The header
403       field will be inserted in the message before any other Record-Route
404       header fields.</para>
405
406       <para>If any string is passed as parameter, it will be appended as URI
407       parameter to the Record-Route header. The string must follow the
408       <quote>;name=value</quote> scheme and it may contain
409       pseudo-variables.</para>
410
411       <para>When the <quote>outbound</quote> module was loaded before this
412       module this function will determine whether outbound is required for the
413       request and generate and add a flow-token as the username part of the
414       Record-Route-URI.</para>
415
416       <para>Note: if append From-tag is enabled and the function is used for requests
417       within dialog, it must be executed after loose_route() in order to detect
418       properly the direction.</para>
419
420       <para>This function can be used from REQUEST_ROUTE, BRANCH_ROUTE and
421       FAILURE_ROUTE.</para>
422
423       <example>
424         <title><function>record_route</function> usage</title>
425
426         <programlisting format="linespecific">
427 ...
428 record_route();
429 ...
430 </programlisting>
431       </example>
432     </section>
433
434     <section id="rr.f.remove_record_route">
435                 <title><function moreinfo="none">remove_record_route()</function></title>
436
437                 <para>The function removes the internal lumps added by
438                         record_route() functions.
439                 </para>
440
441                 <para>
442                         Can be used to revert adding Record-Route header(s).
443                 </para>
444                 <para>
445                         This function can be used from REQUEST_ROUTE and FAILURE_ROUTE.
446                 </para>
447
448       <example>
449         <title><function>remove_record_route</function> usage</title>
450
451         <programlisting format="linespecific">
452 ...
453 remove_record_route();
454 ...
455 </programlisting>
456       </example>
457     </section>
458
459     <section id="rr.f.record_route_preset">
460       <title><function moreinfo="none">record_route_preset(string
461       [,string2])</function></title>
462
463       <para>This function will put the string into Record-Route, don't use
464       unless you know what you are doing.</para>
465
466       <para>Meaning of the parameters is as follows:</para>
467
468       <itemizedlist>
469         <listitem>
470           <para><emphasis>string</emphasis> - String to be inserted into the
471           first header field; it may contain pseudo-variables.</para>
472         </listitem>
473
474         <listitem>
475           <para><emphasis>string2</emphasis> - String to be inserted into the
476           second header field; it may contain pseudo-variables.</para>
477         </listitem>
478       </itemizedlist>
479
480       <para>Note: If 'string2' is present, then the 'string' param is pointing
481       to the outbound interface and the 'string2' param is pointing to the
482       inbound interface.</para>
483
484       <para>When the <quote>outbound</quote> module was loaded before this
485       module this function will determine whether outbound is required for the
486       request and generate and add a flow-token as the username part of the
487       Record-Route-URI.</para>
488
489       <para>This function can be used from REQUEST_ROUTE, BRANCH_ROUTE and
490       FAILURE_ROUTE.</para>
491
492       <example>
493         <title><function>record_route_preset</function> usage</title>
494
495         <programlisting format="linespecific">
496 ...
497 record_route_preset("1.2.3.4:5090");
498 ...
499 </programlisting>
500       </example>
501     </section>
502
503     <section id="rr.f.record_route_adv_addr">
504       <title><function
505       moreinfo="none">record_route_advertised_address(address)</function></title>
506
507       <para>The function adds a new Record-Route header field using the
508       address given. The header field will be inserted in the message before
509       any other Record-Route header fields.</para>
510
511       <para>When the <quote>outbound</quote> module was loaded before this
512       module this function will determine whether outbound is required for the
513       request and generate and add a flow-token as the username part of the
514       Record-Route-URI.</para>
515
516       <para>Meaning of the parameter is as follows:</para>
517
518       <itemizedlist>
519         <listitem>
520           <para><emphasis>address</emphasis> - Advertised address to use in
521           the header; it may contain pseudo-variables.</para>
522         </listitem>
523       </itemizedlist>
524
525       <para>If double record-routing is enabled two Record-Route headers will
526       be inserted with the same given address with different transports if the
527       transport changes.</para>
528
529       <para>This function can be used from REQUEST_ROUTE, BRANCH_ROUTE and
530       FAILURE_ROUTE.</para>
531
532       <example>
533         <title><function>record_route_advertised_address</function>
534         usage</title>
535
536         <programlisting format="linespecific">
537 ...
538 record_route_advertised_address("1.2.3.4:5080");
539 ...
540 </programlisting>
541       </example>
542     </section>
543
544     <section  id="rr.f.add_rr_param">
545       <title><function moreinfo="none">add_rr_param(param)</function></title>
546
547       <para>Adds a parameter to the Record-Route URI (param must be in
548       <quote>;name=value</quote> format. The function may be called also
549       before or after the record_route() or record_route_advertised_address()
550       calls (see <xref linkend="record-route-id"/> or <xref
551       linkend="record-route-adv-addr-id"/>)).</para>
552
553       <para>Meaning of the parameters is as follows:</para>
554
555       <itemizedlist>
556         <listitem>
557           <para><emphasis>param</emphasis> - String containing the URI
558           parameter to be added. It must follow the <quote>;name=value</quote>
559           scheme; it may contain pseudo-variables.</para>
560         </listitem>
561       </itemizedlist>
562
563       <para>This function can be used from REQUEST_ROUTE, BRANCH_ROUTE and
564       FAILURE_ROUTE.</para>
565
566       <example>
567         <title><function>add_rr_param</function> usage</title>
568
569         <programlisting format="linespecific">
570 ...
571 add_rr_param(";nat=yes");
572 ...
573 </programlisting>
574       </example>
575     </section>
576
577     <section id="rr.f.check_route_param">
578       <title><function
579       moreinfo="none">check_route_param(re)</function></title>
580
581       <para>The function checks if the URI parameters of the local Route
582       header (corresponding to the local server) matches the given regular
583       expression. It must be call after loose_route() (see <xref
584       linkend="loose-route-id"/>).</para>
585
586       <para>Meaning of the parameters is as follows:</para>
587
588       <itemizedlist>
589         <listitem>
590           <para><emphasis>re</emphasis> - regular expression to check against
591           the Route URI parameters.</para>
592         </listitem>
593       </itemizedlist>
594
595       <para>This function can be used from REQUEST_ROUTE.</para>
596
597       <example>
598         <title><function>check_route_param</function> usage</title>
599
600         <programlisting format="linespecific">
601 ...
602 if (check_route_param("nat=yes")) {
603     setflag(6);
604 }
605 ...
606 </programlisting>
607       </example>
608     </section>
609
610     <section id="rr.f.is_direction">
611       <title><function moreinfo="none">is_direction(dir)</function></title>
612
613       <para>The function checks the flow direction of in-dialog requests. This
614       function uses the <quote>ftag</quote> parameter from the Route header,
615       therefore the append_fromtag (see <xref linkend="append-fromtag-id"/>
616       module parameter must be enabled. Also this must be called only after
617       loose_route() (see <xref linkend="loose-route-id"/>).</para>
618
619       <para>The function returns true if the <quote>dir</quote> is the same
620       with the request's flow direction.</para>
621
622       <para>The <quote>downstream</quote> direction means that the request is
623       in the same direction as the initial request that created the
624       dialog.</para>
625
626       <para>Meaning of the parameters is as follows:</para>
627
628       <itemizedlist>
629         <listitem>
630           <para><emphasis>dir</emphasis> - string containing the direction to
631           be checked. It may be <quote>upstream</quote> (from callee to
632           caller) or <quote>downstream</quote> (caller to callee).</para>
633         </listitem>
634       </itemizedlist>
635
636       <para>This function can be used from REQUEST_ROUTE.</para>
637
638       <example>
639         <title><function>is_direction</function> usage</title>
640
641         <programlisting format="linespecific">
642 ...
643 if (is_direction("downstream")) {
644     xdbg("in-dialog request from caller to callee (downstream) ($rm)\n");
645 } else {
646     xdbg("in-dialog request from callee to caller (upstream) ($rm)\n");
647 }
648 ...
649 </programlisting>
650       </example>
651     </section>
652   </section>
653
654   <section>
655     <title>Exported Pseudo Variables</title>
656
657     <section>
658       <title><function moreinfo="none">$route_uri</function></title>
659
660       <para>Returns the URI of the top route-header.</para>
661
662       <example>
663         <title>$route_uri</title>
664
665         <programlisting format="linespecific">
666 ...
667     xdbg("Route-URI is: $route_uri\n");
668 ...
669                 </programlisting>
670       </example>
671     </section>
672   </section>
673 </chapter>