[Home]

Summary:ASTERISK-26438: [patch] chan_sip: auto_force_rport: No NAT = No Symmetric Response.
Reporter:Alexander Traud (traud)Labels:
Date Opened:2016-10-05 04:32:22Date Closed:2016-10-06 17:40:47
Priority:MinorRegression?
Status:Closed/CompleteComponents:Channels/chan_sip/IPv6
Versions:11.23.1 13.11.2 14.0.2 Frequency of
Occurrence
Related
Issues:
is caused byASTERISK-08614 nat=no is not RFC 3261 compliant regarding sending responses
Environment:Attachments:( 0) A_aosp_via_tcp.patch
( 1) A_rport_present_nonat.patch
( 2) B_aosp_via_tcp.patch
( 3) B_rport_present_nonat.patch.patch
( 4) C_rport_present_nonat.patch
Description:*Steps to Reproduce*
# Asterisk with {{tcpenable=yes}}
# Asterisk with IPv6 enabled, like {{bindaddr=::}}
# VoIP/SIP client is in IPv6 enabled network but with firewall (for example the mobile operator Telekom Deutschland).
# VoIP/SIP client Google Nexus 5X, Android 7.0
# Nexus » Menu » Phone » Options » Settings » Calls » Calling accounts » (SIP settings) SIP accounts » Add » Options settings » Transport type: TCP
# Nexus » Menu » Phone » Options » Settings » Calls » Calling accounts » Receive incoming calls: Yes (The phone sends a SIP-REGISTER, visible via the app Wireshark and the command-line interface of Asterisk {{sip set debug on}}).
# Asterisk forwards a call and sends a SIP-INVITE to that Android phone.

*Expected Results*
The Android phone rings, because Asterisk sends a SIP-INVITE via the existing TCP connection – the TCP connection which was created by the SIP-REGISTER.

*Actual Results*
The Android phone does not ring. Although Asterisk is re-using the IP address of the SIP-REGISTER, Asterisk sends the SIP-INVITE to a different port. Because the remote network employs a firewall, that SIP-INVITE is rejected.

*Notes*

AOSP sends the parameter {{rport}} (RFC 3581) in UDP and TCP. AOSP does not send the parameter {{ob}} (RFC 5626) as recommend by RFC 6314 section 5.1.1.2.

_This does not happen, when the Android phone is configured for UDP._

The built-in VoIP/SIP client of the Android Open Source Project (AOSP) declares a different TCP port in its SIP-REGISTER Contact header. That port was not used for sending the SIP-REGISTER. This behavior exists since day one of that SIP client (Android 2.3) released in December 2010. In UDP, the port is not different between the SIP message and its UDP connection. TLS cannot be tested because this is not offered by the VoIP/SIP client of Android. In AOSP, this affects just TCP.

_This does not happen, when Asterisk is configured just for IPv4._

In IPv4, Asterisk considers this a NAT and ignores the Contact header in the SIP-REGISTER and goes for the IP and port of the TCP connection of that SIP-REGISTER right away. This is because of the setting {{nat=auto_force_rport}}, which is the default value. It is believed, similar happens for IPv4, when {{nat=no}} in sip.conf.

_This does not happen, when there is no firewall on the network of the phone._

When there is no firewall, Asterisk is able to start a TCP server in the phone via its SIP-INVITE to the TCP port of the Contact header in the SIP message. Consequently, the client is reachable on both TCP ports. This way, when the initial TCP connection got lost somehow, a VoIP server is able to leverage the TCP port of the SIP message as fallback address. Of course, this fails when there is a firewall (or NAT). Nevertheless, this second TCP port is an additional, last resort to start a connection anyway.

*Workaround*
{{nat=force_rport}} fixed the issue for me, because in that case the port of the TCP connection is used, not the port within of the Contact header of the SIP message. The state of {{comedia}} does not matter here although I use {{nat=force_rport,auto_comedia}}.
Comments:By: Alexander Traud (traud) 2016-10-05 05:16:28.734-0500

Added _five_ alternative patches to fix this issue, showing the difficulty which approach to choose – for an external contributor like me. Although each patch fixes the issue, no patch is related to this issue here or the correct solution either (see [RFC 6314|https://tools.ietf.org/html/rfc6314#section-5.1.1]):
* Officially, the parameter {{rport}} is limited to UDP.
* For TCP, the parameter {{ob}} should be used.

Instead, older SIP clients like the one of the Android Open Source Platform  send {{rport}} even via TCP/TLS and keep-alive the initial SIP-REGISTER connection for all subsequent SIP signaling. The server then re-uses that TCP connection. This is supported by Asterisk and as was discussed on the SIP-Implementors mailing-list [several|https://lists.cs.columbia.edu/pipermail/sip-implementors/2005-November/011215.html] [times|https://lists.cs.columbia.edu/pipermail/sip-implementors/2007-April/016175.html]. Therefore, my second approach to fix this, with three alternative patches – essentially a continuation of ASTERISK-20238.

Therefore, to catch all my SIP clients, I went for {{nat=force_rport,auto_comedia}}.