1. Nathelper Module

Maxim Sobolev

Sippy Software, Inc.
Revision History
Revision $Revision$ $Date$

1.1. Overview
1.2. Parameters
1.2.1. natping_interval (integer)
1.2.2. ping_nated_only (integer)
1.2.3. received_avp (integer)
1.3. Functions
1.3.1. fix_nated_contact()
1.3.2. fix_nated_sdp(mode)
1.3.3. force_rtp_proxy()
1.3.4. add_rcv_param()
1.3.5. fix_nated_register()
1.3.6. force_rtp_proxy(ip_address)
1.3.7. nat_uac_test(mode)
1.3.8. ping_contact(contact)
1.3.9. @nathelper.rewrite_contact[n]
1.3.10. rtpproxy_stream2uac(prompt_name, count), rtpproxy_stream2uas(prompt_name, count)
1.3.11. rtpproxy_stop_stream2uac(), rtpproxy_stop_stream2uas()

1.1. Overview

This is a module to help with NAT traversal. In particular, it helps symmetric UAs that don't advertise they are symmetric and are not able to determine their public address. fix_nated_contact rewrites Contact header field with request's source address:port pair. fix_nated_sdp adds the active direction indication to SDP (flag 0x01) and updates source IP address too (flag 0x02).

Known devices that get along over NATs with nathelper are ATAs (as clients) and Cisco Gateways (since 12.2(T)) as servers. See http://www.cisco.com/en/US/products/sw/iosswrel/ps1839/products_feature_guide09186a0080110bf9.html">

1.2. Parameters

Revision History
Revision $Revision$ $Date$

1.2.1. natping_interval (integer)

Period of time in seconds between sending short UDP packets to all currently registered UAs to keep their NAT bindings alive. Value of 0 disables this functionality.

Default value is 0.

Example 1. Set natping_interval parameter

...
modparam("nathelper", "natping_interval", 10)
...

1.2.2. ping_nated_only (integer)

If this variable is set then only contacts that have "behind_NAT" flag in user location database set set will get ping.

Default value is 0.

Example 2. Set ping_nated_only parameter

...
modparam("nathelper", "ping_nated_only", 1)
...

1.2.3. received_avp (integer)

The number of the Attribute-Value-Pair (AVP) used to store the URI containing the received IP, port, and protocol. The URI is created by fix_nated_register function of nathelper module and the attribute is then used by the registrar to store the received parameters. Do not forget to change the value of corresponding parameter in registrar module if you change the value of this parameter.

Default value is 42.

Example 3. Set received_avp parameter

...
modparam("nathelper", "received_avp", 43)
...

1.3. Functions

Revision History
Revision $Revision$ $Date$

1.3.1.  fix_nated_contact()

Rewrites Contact HF to contain request's source address:port.

Example 4. fix_nated_contact usage

...
if (search("User-Agent: Cisco ATA.*") {fix_nated_contact();};
...

1.3.2.  fix_nated_sdp(mode)

Rewrites Contact HF to contain request's source address:port.

Meaning of the parameters is as follows:

  • mode - 0x01 (add direction=active), 0x02 (rewrite media IP address with source address of the message).

Example 5. fix_nated_sdp usage

...
if (search("User-Agent: Cisco ATA.*") {fix_nated_sdp("3");};
...

1.3.3.  force_rtp_proxy()

Rewrites SDP body to ensure that media is passed through an RTP proxy.

Example 6. force_rtp_proxy usage

...
if (search("User-Agent: Cisco ATA.*")
{
    force_rtp_proxy();
};
...

1.3.4.  add_rcv_param()

Add received parameter to Contact header fields. The parameter will contain URI created from the source IP, port, and protocol of the packet containing the SIP message. The parameter can be then processed by another registrar, this is useful, for example, when replicating register messages using t_replicate function to another registrar.

Example 7. add_rcv_paramer usage

...
add_rcv_param();
...

1.3.5.  fix_nated_register()

The function creates a URI consisting of the source IP, port, and protocol and stores the URI in an Attribute-Value-Pair. The URI will be appended as "received" parameter to Contact in 200 OK and registrar will store it in the user location database.

Example 8. fix_nated_register usage

...
fix_nated_register();
...

1.3.6.  force_rtp_proxy(ip_address)

Rewrites SDP body with given IP address to ensure that media is passed through an RTP proxy.

Meaning of the parameters is as follows:

  • ip_address - new SDP IP address.

Example 9. force_rtp_proxy usage

...
if (search("User-Agent: Cisco ATA.*") {force_rtp_proxy("1.2.3.4");};
...

1.3.7.  nat_uac_test(mode)

Tries to guess if client's request originated behind a nat. The mode parameter determines what heuristics is used. If mode contains:

  • 01 - the Contact URI host contains a private IP address (from RFC1981).

  • 02 - the address in the topmost Via header differs from the source IP address of the request.

  • 04 - the address in the topmost Via contains a private IP address (RFC1918).

  • 08 - the SDP body of the request contains a private IP address (RFC1918).

  • 16 - the port in the topmost Via differs from the source port of the request.

  • 32 - the Contact URI port differs from the source port of the request (Warning: this is might be legal or even intended combination in non natted scenarios).

All of them might be bitwise combined (which is equal to the sum of the values from the list above). If one of the test matched the function returns true.

1.3.8.  ping_contact(contact)

Ping contact specified by parameter. It enables pinging independently on usrloc. It may be processed e.g. via timer module.

Example 10. ping_contact usage

...
$c = @get_a_contact;
ping_contact($c);
...

1.3.9.  @nathelper.rewrite_contact[n]

Get n-th Contact value with IP:Port rewritten to source ip:port. N is counted from 1. Only IP:port is rewritten, remaining part are left unchanged. Full nameaddr is supported.

Example 11. @nathelper.rewrite_contact usage

...
$c = @nathelper.rewrite_contact[1];
...
$c2 = @nathelper.rewrite_contact[1].nameaddr.uri;

1.3.10.  rtpproxy_stream2uac(prompt_name, count), rtpproxy_stream2uas(prompt_name, count)

Instruct the RTPproxy to stream prompt/announcement pre-encoded with the makeann command from the RTPproxy distribution. The uac/uas suffix selects who will hear the announcement relatively to the current transaction - UAC or UAS. For example invoking the rtpproxy_stream2uac in the request processing block on ACK transaction will play the prompt to the UA that has generated original INVITE and ACK while rtpproxy_stop_stream2uas on 183 in reply processing block will play the prompt to the UA that has generated 183.

Apart from generating announcements, another possible application of this function is implementing music on hold (MOH) functionality. When count is -1, the streaming will be in loop indefinitely until the appropriate rtpproxy_stop_stream2xxx is issued.

In order to work correctly, functions require that the session in the RTPproxy already exists. Also those functions don't alted SDP, so that they are not substitute for calling rtpproxy_offer, rtpproxy_answer or force_rtp_proxy.

Meaning of the parameters is as follows:

  • prompt_name - name of the prompt to stream. Should be either absolute pathname or pathname relative to the directory where RTPproxy runs.

  • count - number of times the prompt should be repeated. The value of -1 means that it will be streaming in loop indefinitely, until appropriate rtpproxy_stop_stream2xxx is issued.

Example 12. rtpproxy_stream2xxx usage

...
      if (method == "INVITE") {
          rtpproxy_offer();
          if (detect_hold()) {
              rtpproxy_stream2uas("/var/rtpproxy/prompts/music_on_hold", -1);
          } else {
              rtpproxy_stop_stream2uas();
          };
      };
...

1.3.11.  rtpproxy_stop_stream2uac(), rtpproxy_stop_stream2uas()

Stop streaming of announcement/prompt/MOH started previously by the respective rtpproxy_stream2xxx. The uac/uas suffix selects whose announcement relatively to tha current transaction should be stopped - UAC or UAS.