Summary:ASTERISK-21373: In proxy NAT traversal situation the far end requires Asterisk to send RTP first
Reporter:Marcello Lupo (hunters14473)Labels:
Date Opened:2013-04-02 10:04:24Date Closed:2013-04-30 18:55:40
Versions:11.2.1 Frequency of
Environment:Linux with compiled from sources asteriskAttachments:( 0) log_fax_outgoing.zip
( 1) send-cng-on-address-set.diff
Description:Good Afternoon,
I'm contacting you because i worked a lot with opensips and rtpproxy developers trying solve issues with Asterisk behind NAT registered to sip proxy (opensips or Kamailio) using an rtpproxy to traverse NAT.
We decided in the end that is not something that can be solved at rtpproxy/SIP proxy level.
It is an unresolvable issue with outgoing fax calls from Asterisk to the outside world using T38.
In short the problem is that when the fax call begins it start with voice codec and all is OK.
When the remote fax answer the other party ask for a reinvite to switch in T38 protocol.
Asterisk answer to this re INVITE with a 200 OK changing the RTP port for T38. The rtpproxy managing the call take as good the RTP port declared from Asterisk in the 200 OK and start to send rtp to this port  (that is still closed from outside). Rtpproxy will take valid this port till it will receive some packets from the real port that the Asterisk is using (out of the NAT).
Since Asterisk do not send out any packet from the T38 port till it receive the RTP IN the fax call fail.
I'm asking you if is possible to let asterisk send some packets (even fake ones or the real CNG fax tone) from the declared SDP port to the outside world. This will open the NAT hole that rtpproxy need to permit to all this situation to work correctly. This will avoid to have NAT mapping and so on in the customers router/firewall.

Here a deep analisys of the issue:

Sip Proxy Opensips 1.6.4 with Rtpproxy 1.2.1
UAS (PSTNGW)  Audiocode Mediant 3000
UAC (CPE) is Asterisk 11.2.1
UAC behind symmetric NAT and place an outgoing fax call.
UAC use INVITE with only voice codec and reINVITE in T38 changing the rtp port for t38.

Call flow initial INVITE:

INVITE from CPE —————> Proxy ———> PSTNGW
200 OK from PSTNGW —————> Proxy ——-> CPE

Call flow of re INVITE

re-INVITE from PSTNGW —————> Proxy ——-> CPE
OK from CPE —————> Proxy ——-> PSTNGW

INVITE from CPE and 200 OK from PSTNGW: the session start correctly with audio codec and packets are correctly relayed from rtpproxy.

re INVITTE from PSTNGW and 200 OK from CPE: the call seems to be ok but the fax is not working. The reason is that on reINVITE 200 OK from CPE the CPE put a different port in the SDP and the rtpproxy update immediately the rtp stream that is currently going to the port of the voice codec and start immediately to send it to the port declared in the SDP from the CPE. The RTP do not go in to Asterisk because it still have not sent any packets from T38 port port (and it can be different port as well because it is behind NAT, not all routers/firewall make a symmetric nat from inside ports to outside ports).
Rtpproxy in thi sphase is still in learning mode so it will send RTP to the declared SDP port till it receive at least one packet from the CPE. At this poing it will update the session and move the RTP (fax answering tone) to the correct port.

In the zip file attached you can find a text file with this info:

Call flow is in this way:

Proxy IP
Rtpproxy IP

CPE start call on port 13462
GW start call on port 6350

after reinvite

GW switch to port 6352
CPE switch to port 4291 (closed in NAT so no way to work)

You can fount the re INVITE at line 6180 and the 200 OK and ack form line 6300.

I wait your comments.
Thank you
Best regards
Comments:By: Rusty Newton (rnewton) 2013-04-19 15:08:10.236-0500

I'm asking you if is possible to let asterisk send some packets (even fake ones or the real CNG fax tone) from the declared SDP port to the outside world. This will open the NAT hole that rtpproxy need to permit to all this situation to work correctly. This will avoid to have NAT mapping and so on in the customers router/firewall.

From your description of the situation, it sounds like what you are requesting would certainly be an improvement..

This looks like a [feature request/improvement|https://wiki.asterisk.org/wiki/display/AST/Asterisk+Issue+Guidelines#AsteriskIssueGuidelines-Howtorequestafeature]. Can you provide a patch for the behavior?

If you feel this is a bug, can you point to an RFC or other spec that would suggest Asterisk's current behavior should be different?

By: Marcello Lupo (hunters14473) 2013-04-25 10:22:21.167-0500

I'm not an RFC expert but may be something useful can be found here:

From RFC 4734
Section 2.6.  T.30 Events
It says that the CNG tone is sent from the calling terminal.
Asterisk do not send anything out. In effect this was what i was asking for. To let asterisk send the CNG tone. It is part of the fax protocol and asterisk do not send it out.

I tested a lot of other equipments (Avaya and Audiocode) that use different port for RTP and T38 and all of them send out that tone and avoid the issue.
Thank you

By: Rusty Newton (rnewton) 2013-04-30 18:47:16.219-0500

1. If the far end just wants to receive any audio then a possible fix would be to insert a call to Progress() and then Playback(silence/1) into the dialplan at the appropriate place. This would open up early media and send out some RTP.

2. I'm attaching send-cng-on-address-set.diff which was designed for an issue in an older version of Asterisk (that reporter stopped responding and the patch was never tested) that sounds pretty much the same. You'll have to modify the patch for your own version of Asterisk and try it out. For Asterisk 11 a brief look using the line above the addition in the patch, I found the "rtp->rxseqno = 0;" in two places in res_rtp_asterisk. You might try placing the addition below the "rtp->rxseqno = 0;" line at line 3930?  (disclaimer that I'm not a dev, just a power user that pokes my nose around and if any dev wants to step in and help out, go for it!)

By: Rusty Newton (rnewton) 2013-04-30 18:55:27.995-0500

Please report back and let us know what you find. For now I'm going to close this out as Workaround Available. If you or someone else are able to develop and test a working patch then we'll get a dev to review it for possible inclusion. You can always bring this issue up on the asterisk-dev mailing list or #asterisk-dev chat room if you make progress on a patch or want to see if others are interested in helping. Feel free to ping a bug marshal in the #asterisk-bugs chat room to re-open this issue or discuss further if needed.