123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629 |
- <?xml version="1.0" encoding="UTF-8"?>
- <!DOCTYPE section PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
- "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd"
- [ <!ENTITY % local.common.attrib
- "xmlns:xi CDATA #FIXED 'http://www.w3.org/2001/XInclude'">
- <!-- Include general documentation entities -->
- <!ENTITY % docentities SYSTEM "../../../docbook/entities.xml">
- %docentities;
- ]
- >
- <chapter>
- <title>Admin Guide</title>
- <section id="iptrtpproxy.overview">
- <title>Overview</title>
- <para>
- This module provides similar functionality as <emphasis>nathelper</emphasis> but
- communicates with <emphasis>netfilter</emphasis> kernel
- <emphasis>xt_RTPPROXY</emphasis> module using
- the <emphasis>libipt_RTPPROXY</emphasis> userspace library.
- All RTP streams are manipulated directly in kernel space, no data is copied from
- kernel to userspace and back, it reduces load and delay.
- See <ulink url="http://www.2p.cz/en/netfilter_rtp_proxy">
- http://www.2p.cz/en/netfilter_rtp_proxy</ulink> for more details.
- </para>
- <para>
- This &kamailio; module is written as a light-weight module, there is no
- dialog management as in <emphasis>Nathelper</emphasis>. The reason is that such an API
- should be provided by core or a specialized dialog manager module.
- Because such module is not in git, session information may be stored
- in extra attributes of the <emphasis>avp_db</emphasis> module and
- the session id itself in record route as cookie, see the <emphasis>rr</emphasis> module.
- </para>
- <para>
- It should be able to support all cases as re-invites when SIP client offers media change in SDP and
- when number of medias in offer/answer are different.
- </para>
- <para>
- <emphasis>Nathelper</emphasis> may be still used for testing if client is behind the NAT.
- </para>
- <para>
- There is also support for media authorization. Number of codec sets may be defined.
- When a message containing SDP offer/answer is being processed then current codecs
- and streams may be inspected, removed or signallized according a codec set.
- </para>
- </section>
- <section id="iptrtpproxy.known_limitations">
- <title>Known limitations</title>
- <itemizedlist>
- <listitem>
- <para>
- Only IPv4 addresses are supported.
- </para>
- </listitem>
- <listitem>
- <para>
- More media streams per session supported
- </para>
- </listitem>
- </itemizedlist>
- </section>
- <section id="iptrtpproxy.dep">
- <title>Dependencies</title>
-
- <para>
- The following libraries or applications must be installed before
- running &kamailio; with this module loaded:
- <itemizedlist>
- <listitem>
- <para>
- netfilter xt_RTPPROXY & libipt_RTPPROXY,
- see <ulink url="http://www.2p.cz/en/netfilter_rtp_proxy">http://www.2p.cz/en/netfilter_rtp_proxy</ulink>
- </para>
- </listitem>
- </itemizedlist>
- </para>
- <note><para>
- The modules Makefile must be edited and iptdir setup to the directory with
- the iptable sources (if different from ~/iptables). Alternatively
- compile the module using:
- <programlisting>
- make -C modules/iptrtpproxy iptdir=path_to_iptables_src
- </programlisting>
- </para></note>
- </section>
- <section id="iptrtpproxy.parameters" xmlns:xi="http://www.w3.org/2001/XInclude">
- <title>Parameters</title>
- <section id="config">
- <title><varname>config</varname> (string)</title>
- <para>
- References <emphasis>iptrtpproxy.cfg</emphasis>, see <emphasis>iptrtpproxy_helper</emphasis>. Default value
- is <emphasis>/etc/iptrtpproxy.cfg</emphasis>. If only codec authorization is to be used then
- <emphasis>/dev/null</emphasis> may be used.
- </para>
- </section>
- <section id="switchboard">
- <title><varname>switchboard</varname> (string)</title>
- <para>
- References <emphasis>xt_RTPPROXY</emphasis> switchboard for usage by ser module.
- </para>
- <para>
- The format is:
- </para>
- <programlisting>
- "name=" value * ( ";" name "=" value )
- name = "aggregation" | "sip-addr-"
- </programlisting>
- <para>
- The <emphasis>name</emphasis> is the switchboard name as declared in config and will be used by script functions and references switchboard.
- It's mandatory parameter. The special name <emphasis>*</emphasis> set values for all switchboards.
- </para>
- <para>
- The <emphasis>sip-addr</emphasis> is address used by <function>iptrtpproxy_ser_param(by_sip_ip)</function> to find a switchboard for particular
- connection. If not explicitly configured then RTP switchboard gate address are used for this feature.
- </para>
- <para>
- The <emphasis>aggregation</emphasis> enables to aggregate more switchboards in cluster and to widden bandwidth.
- Aggregation will take <emphasis>sip-addr</emphasis> from the first switchboard of its.
- </para>
- <example>
- <title>Declare <varname>switchboard</varname></title>
- <programlisting>
- ...
- modparam("iptrtpproxy", "config", "/etc/iptrtpproxy.cfg");
- modparam("iptrtpproxy", "switchboard", "name=my1;sip-addr-a=1.2.3.4;sip-addr-b=5.6.7.8");
- modparam("iptrtpproxy", "switchboard", "name=my2;sip-addr-a=2.3.4.5;sip-addr-b=3.4.5.6;aggregation=my23");
- modparam("iptrtpproxy", "switchboard", "name=my3;aggregation=my23");
- modparam("iptrtpproxy", "switchboard", "name=*;aggregation=my123");
- ...
- </programlisting>
- </example>
- </section>
- <section id="rpc_heartbeat_timeout">
- <title><varname>rpc_heartbeat_timeout</varname> (int)</title>
- <para>
- Timeout in seconds used for rerequest remote RTP proxy via RPC command after preceeding error.
- In other words if a RPC server is unresponsive at the moment then next attempt will be forced
- after this timeout. Default value is <emphasis>30</emphasis>.
- </para>
- </section>
- <section id="hostname">
- <title><varname>hostname</varname> (string)</title>
- <para>
- The hostname used by RPC to identify machine where Ser is running to communicate which RTP proxy
- via local interface. Default value is taken from system hostname.
- </para>
- </section>
- <section id="declare_codec">
- <title><varname>declare_codec</varname> (string)</title>
- <para>
- There are basic implicit codecs compiled in module, more codecs may be added by this parameter (one codec per modparam).
- </para>
- </section>
- <section id="codec_set">
- <title><varname>codec_set</varname> (string)</title>
- <para>
- Declares new codec set. Codecs are declared for each media type independently.
- </para>
- <para>
- The format is:
- </para>
- <programlisting>
- "name=" value * ( ";" name "=" value )
- name = "media_type" | "rights" | "codecs" | "max_streams" | ( "rtp" | "rtcp" ) "_" ( "bytes" | "packets" )
- media_types = "audio" | "video" | "application" | "text" | "message" | "data" | "control" | "?" | "*"
- </programlisting>
- <para>
- The <emphasis>name</emphasis> is the codec set name to be defined.
- </para>
- <para>
- The <emphasis>media_type</emphasis> belongs to type at <emphasis>m=</emphasis> SDP line. Question mark means
- "unknown media" type and asterisk "all media types".
- </para>
- <para>
- The <emphasis>max_streams</emphasis> defines how many streams (m= lines) is allowed per media type.
- </para>
- <para>
- The <emphasis>rights</emphasis> defines if particular codec is allowed <emphasis>0</emphasis>, disallowed, i.e. will be removed
- if bit AND operation with <function>remove_codec_mask</function> is non-zero or its presence will be signallized by <function>@iptrtpproxy.auth_rights</function> (any other value).
- </para>
- <para>
- The <emphasis>codecs</emphasis> comma separated list of codecs. Previous <emphasis>media_type&rights</emphasis> will be applied.
- </para>
- <para>
- The <emphasis>rtp/rtcp_bytes/packets</emphasis> limits bandwidth per <emphasis>media_type</emphasis> (0 is unlimited). It will override
- bandwidth limited by <function>iptrtpproxy_set_param("throttle_*")</function>.
- </para>
- <example>
- <title>Declare <varname>codec_set</varname></title>
- <programlisting>
- ...
- # enable all codecs, default state when codec is declared
- modparam("iptrtpproxy", "codec_set", "name=cs1;media_type=*;max_streams=9999;rights=0;codecs=*");
- # allow only 2 audio and 1 video stream
- modparam("iptrtpproxy", "codec_set", "name=cs2;media_type=*;max_streams=0;media_type=audio;max_streams=2;media_type=video;max_streams=1");
- # dtto, allow only a few audio and video codecs, GSM codec is allowed but signallized
- modparam("iptrtpproxy", "codec_set", "name=cs3;media_type=*;max_streams=0;rights=1;codecs=*;media_type=audio;max_streams=2;rights=0;codecs=PCMU,G729,G728,parityfec,telephone-events;rights=2;codecs=GSM;media_type=video;max_streams=1;rights=0;codecs=jpeg,parityfec");
- # limit max. bandwidth for video¨
- modparam("iptrtpproxy", "codec_set", "name=cs4;media_type=video;rtp_bytes=10000;rtcp_bytes=1000");
- ...
- </programlisting>
- </example>
- </section>
- </section>
- <section id="iptrtpproxy.funcs" xmlns:xi="http://www.w3.org/2001/XInclude">
- <title>Functions</title>
- <section id="iptrtpproxy_alloc">
- <title>
- <function>iptrtpproxy_alloc(gate_a_to_b [, existing_sess_ids])</function>
- </title>
- <para>
- Parses SDP content and allocates for each RTP media stream one RTP proxy session.
- SDP is updates to reflect allocated sessions. Switchboard/aggregation is set using
- <function>iptrtpproxy_set_param(by_sip_ip)</function> or <function>iptrtpproxy_set_param("switchboard/aggregation")</function>.
- </para>
- <para>
- Aggregation supports load balancing among more RTP proxies controlled by RPC.
- The module try to allocate at machines/switchboards in following order (priorities)
- not yet asked (or being heartbeated) machines, responsive machines, switchboards
- having percentualy more free slots, non responsive machines.
- </para>
- <para>
- Proxy may hide caller identity provided at <emphasis>o=</emphasis> line using
- <function>@iptrtpproxy.o_name/addr</function> and <function>iptrtpproxy_set_param(o_name/addr)</function>
- functions. But the script is responsible for rewritting to original values in
- a response or a callee initiated re-INVITE. Therefore original value need to be stored
- in-dialog.
- </para>
- <itemizedlist>
- <listitem>
- <para>
- if <emphasis>gate_a_to_b</emphasis> bit 0 is set
- then SDP regards to gate-a to gate-b direction.
- </para>
- </listitem>
- <listitem>
- <para>
- <emphasis>protected_session_ids</emphasis> list of existing sessions
- enables reusing already allocated sessions in re-INVITE without
- allocating new sessions for each stream in SDP regardless a IP/port
- is required. It's mostly undesirable, typically "hold-on" is
- done via re-INVITE without any change. There is drawback because
- callee cannot change IP:port in 200OK which is legal case in RFC3264.
- But because some non-RFC3264 compliant phones dislike proactively
- changed IP:port at RTP proxy it seems it's less evil.
- </para>
- </listitem>
- <listitem>
- <para>
- function returns true is a session was created, identifier is available
- via select <function>@iptrtpproxy.session_ids</function>.
- </para>
- </listitem>
- </itemizedlist>
- <example>
- <title><function>iptrtpproxy_alloc</function> usage</title>
- <programlisting>
- ...
- if (!iptrtpproxy_set_param("aggregation_by_sip_ip_a", "@received.ip")) {
- if (!iptrtpproxy_set_param("switchboard_by_sip_ip_a", "@received.ip")) {
- t_reply("500", "RTP proxy error");
- drop;
- }
- }
- eval_push("x:%@next_hop.src_ip");
- if (@eval.get[-1] == @received.ip) {
- if (@iptrtpproxy.aggregation_a) {
- iptrtpproxy_set_param("aggregation_b", "@iptrtpproxy.aggregation_a");
- }
- else {
- iptrtpproxy_set_param("switchboard_b", "@iptrtpproxy.switchboard_a");
- }
- }
- else {
- if (!iptrtpproxy_set_param("aggregation_by_sip_ip_b", "@eval.get[-1]")) {
- if (!iptrtpproxy_set_param("switchboard_by_sip_ip_b", "@eval.get[-1]")) {
- t_reply("500", "RTP proxy error");
- drop;
- }
- }
- }
- eval_remove(-1, 1);
-
- if (!iptrtpproxy_alloc("1")) {
- t_reply("500", "RTP proxy error");
- drop;
- }
- $sess_ids = @iptrtpproxy.session_ids;
- ...
- </programlisting>
- </example>
- </section>
- <section id="iptrtpproxy_update">
- <title>
- <function>iptrtpproxy_update(gate_a_to_b, session_ids)</function>
- </title>
- <para>
- Parses SDP content and updates sessions provided by <emphasis>session_ids</emphasis> and
- updates SDP. If succesfull then session_ids may be changed (in case e.g. media
- stream has port zero particular session is released), the
- result of <function>@iptrtpproxy.session_ids</function> should be stored for future in-dialog usage.
- </para>
- <para>
- The SDP contect is also affected by <function>iptrtpproxy_set_param(o_name/addr)</function>
- functions. If a stream is deactivated in SDP then Sessions may be deleted unless
- mentioned in <emphasis>protected_session_ids</emphasis>.
- </para>
- <itemizedlist>
- <listitem>
- <para>
- if <emphasis>gate_a_to_b</emphasis> bit 0 is set
- then SDP regards to gate-a to gate-b direction.
- </para>
- <para>
- if <emphasis>gate_a_to_b</emphasis> bit 1 is set
- then SDP is updated only, no RTP session are affected.
- Should be used when handling retransmission in onreply route,
- retransmission replies are not eaten be tm module!
- </para>
- </listitem>
- </itemizedlist>
- <example>
- <title><function>iptrtpproxy_update</function> usage</title>
- <programlisting>
- ...
- # load $sess_ids from dialog
- if (iptrtpproxy_update("0", $sess_ids)) {
- $sess_ids = @iptrtpproxy.session_ids;
- # save sess_ids in dialog
- }
- ...
- </programlisting>
- </example>
- </section>
- <section id="iptrtpproxy_adjust_timeout">
- <title>
- <function>iptrtpproxy_adjust_timeout(gate_a_to_b, session_ids)</function>
- </title>
- <para>
- Adjust timeout for particular gate. It's useful in "200 OK"
- decrease timeout to learning timeout if INVITE has set (long) <emphasis>ringing timeout</emphasis>.
- </para>
- <itemizedlist>
- <listitem>
- <para>
- if <emphasis>gate_a_to_b</emphasis> bit 0 is set
- then it regards to gate-a to gate-b direction.
- </para>
- </listitem>
- </itemizedlist>
- <example>
- <title><function>iptrtpproxy_adjust_timeout</function> usage</title>
- <programlisting>
- ...
- # load $sess_ids from dialog
- if (status=~"18[0-9]") {
- iptrtpproxy_set_param("learning_timeout", "60");
- }
- else {
- iptrtpproxy_set_param("learning_timeout", "5");
- }
- if (iptrtpproxy_adjust_timeout("0", $sess_ids)) {
- }
- ...
- </programlisting>
- </example>
- </section>
- <section id="iptrtpproxy_delete">
- <title>
- <function>iptrtpproxy_delete(session_ids)</function>
- </title>
- <para>
- Delete sessions identified by <emphasis>session_ids</emphasis>. May be used when dialog is being
- destroyed (BYE) or when INVITE failed in failure route. If <emphasis>protected_session_ids</emphasis>
- list is provided then this set is excluded from sessions to be deleted.
- </para>
- <example>
- <title><function>iptrtpproxy_delete</function> usage</title>
- <programlisting>
- ...
- # load $sess_ids from dialog
- iptrtpproxy_delete($sess_ids);
- ...
- </programlisting>
- </example>
- </section>
- <section id="iptrtpproxy_authorize_media">
- <title>
- <function>iptrtpproxy_authorize_media()</function>
- </title>
- <para>
- Authorizes SDP media according currect <emphasis>codec_set</emphasis>. If bit AND operation
- between rights in codec set and <function>remove_codec_mask</function> is non zero then
- such a codec are to be removed. The result may be obtained from
- <function>@iptrtpproxy.auth_rights</function> which returns max. right which has been applied when
- processing all codecs of enabled streams.
- </para>
- <para>
- The function MUST NOT be called after <function>iptrtpproxy_alloc/update</function>!
- But the function may be called several times to authorize using more codec sets.
- </para>
- <example>
- <title><function>iptrtpproxy_authorize_media</function> usage</title>
- <programlisting>
- ...
- if (@iptrtpproxy.active_media_num == "0") break;
- iptrtpproxy_set_param("codec_set", "cs2");
- iptrtpproxy_set_param("remove_codec_mask", "1");
- if (!iptrtpproxy_authorize_media()) {
- t_reply("415", "Cannot authorize media");
- drop;
- }
- iptrtpproxy_set_param("codec_set", "cs3");
- if (!iptrtpproxy_authorize_media()) {
- t_reply("415", "Cannot authorize media");
- drop;
- }
- if (@iptrtpproxy.active_media_num == "0") {
- t_reply("488", "Not acceptable here");
- drop;
- }
- if (@iptrtpproxy.auth_rights == "2") {
- append_hf_value("Contact: <sip:1.2.3.4>");
- t_reply("301", "Redirect to transcoder");
- drop;
- }
- ...
- </programlisting>
- </example>
- </section>
- <section id="iptrtpproxy_set_param">
- <title>
- <function>iptrtpproxy_set_param(param, value)</function>
- </title>
- <para>
- Set particular parameter needed mainly by <function>iptrtpproxy_alloc/update/adjust_timeout</function>.
- The paramter value is availble via <function>@iptrtpproxy.<param></function>.
- </para>
- <itemizedlist>
- <listitem>
- <para>
- Supported parameters: <emphasis>expiration_timeout</emphasis>, <emphasis>ttl</emphasis>, <emphasis>learning_timeout</emphasis>,
- <emphasis>always_learn</emphasis>,
- <emphasis>aggregation_a</emphasis>, <emphasis>aggregation_b</emphasis>,
- <emphasis>switchboard_a</emphasis>, <emphasis>switchboard_b</emphasis>,
- <emphasis>throttle_mark</emphasis>,
- <emphasis>throttle_rtp_max_bytes</emphasis>, <emphasis>throttle_rtp_max_packets</emphasis>,
- <emphasis>throttle_rtcp_max_bytes</emphasis>, <emphasis>throttle_rtcp_max_packets</emphasis>.
- </para>
- </listitem>
- </itemizedlist>
- </section>
- <section id="iptrtpproxy_set_param(by_sip_ip)">
- <title>
- <function>iptrtpproxy_set_param("(aggregation/switchboard)_by_sip_ip_(a/b)", sip_ip)</function>
- </title>
- <para>
- Find corresponding aggregation or switchboard and set
- <function>@iptrtpproxy.aggregation_a/b</function> or <function>@iptrtpproxy.switchboard_a/b</function>.
- Switchboards/aggregations are compared against <emphasis>sip-addr</emphasis>,
- it allow separate SIP and RTP traffic and RTP aggregation.
- </para>
- <itemizedlist>
- <listitem>
- <para>
- <emphasis>sip_ip</emphasis> IP to be compared, typically <function>@received.ip</function>
- or <function>@next_hop.src_ip</function>.
- </para>
- </listitem>
- <listitem>
- <para>
- function returns true if switchboard/aggregation was found
- </para>
- </listitem>
- </itemizedlist>
- </section>
- <section id="iptrtpproxy_set_param(protected_session_ids)">
- <title>
- <function>iptrtpproxy_set_param("protected_session_ids", sess_ids)</function>
- </title>
- <para>
- Used for reusing sessions in <function>iptrtpproxy_alloc</function>, <function>iptrtpproxy_update</function>
- and <function>iptrtpproxy_delete</function>.
- </para>
- </section>
- <section id="iptrtpproxy_set_param(o_name)">
- <title>
- <function>iptrtpproxy_set_param("o_name", value)</function>
- </title>
- <para>
- Username to be rewritten at <emphasis>o=</emphasis> line by <function>iptrtpproxy_alloc/update</function>
- to hide caller identity. If value is blank then username is left unchanged.
- </para>
- </section>
- <section id="iptrtpproxy_set_param(o_addr)">
- <title>
- <function>iptrtpproxy_set_param("o_addr", value)</function>
- </title>
- <para>
- Address to be rewritten at <emphasis>o=</emphasis> line by <function>iptrtpproxy_alloc/update</function>
- to hide caller identity. If value is blank then address is left unchanged.
- </para>
- </section>
- <section id="iptrtpproxy_set_param(codec_set)">
- <title>
- <function>iptrtpproxy_set_param("codec_set", value)</function>
- </title>
- <para>
- Codec set for <function>iptrtpproxy_authorize_media</function>. Current codec set
- may be obtained by <function>@iptrtpproxy.codec_set</function>.
- </para>
- </section>
- <section id="iptrtpproxy_set_param(remove_codec_mask)">
- <title>
- <function>iptrtpproxy_set_param("remove_codec_mask", value)</function>
- </title>
- <para>
- Mask used in <function>iptrtpproxy_authorize_media</function>. Current mask
- may be obtained by <function>@iptrtpproxy.remove_codec_mask</function>.
- </para>
- </section>
- </section>
- <section>
- <title>Selects</title>
- <section id="iptrtpproxy.session_ids">
- <title>
- <function>@iptrtpproxy.session_ids</function>
- </title>
- <para>
- Returns sessions allocated/updated in <function>iptrtpproxy_alloc/update</function>.
- </para>
- <para>
- The format is:
- </para>
- <programlisting>
- switchboard_name [ ":" [ session_id "/" created ] * ( "," session_id "/" created ) ] ]
- session_id = * ( [0-9] ) ; empty when no session allocated
- created = timestamp
- </programlisting>
- </section>
- <section id="iptrtpproxy.sdp_ip">
- <title>
- <function>@iptrtpproxy.sdp_ip</function>
- </title>
- <para>
- Return first rewritten IP provided at SDP <emphasis>c=</emphasis> line.
- </para>
- </section>
- <section id="iptrtpproxy.o_name">
- <title>
- <function>@iptrtpproxy.o_name</function>
- </title>
- <para>
- Return username from original <emphasis>o=</emphasis> line.
- </para>
- </section>
- <section id="iptrtpproxy.o_addr">
- <title>
- <function>@iptrtpproxy.o_addr</function>
- </title>
- <para>
- Return address from original <emphasis>o=</emphasis> line.
- </para>
- </section>
- <section id="iptrtpproxy.auth_rights">
- <title>
- <function>@iptrtpproxy.auth_rights</function>
- </title>
- <para>
- Result of <function>iptrtpproxy_authorize_media</function>.
- </para>
- </section>
- <section id="iptrtpproxy.active_media_num">
- <title>
- <function>@iptrtpproxy.active_media_num</function>
- </title>
- <para>
- Returns number of active media streams in SDP. <function>iptrtpproxy_authorize_media</function>
- may disable some streams, i.e. returned value may change after authorization.
- </para>
- </section>
- </section>
- </chapter>
|