[asterisk-dev] Symmetric RTP behaviour and 'nat' peer option.

Alex Balashov abalashov at evaristesys.com
Wed Apr 22 00:25:54 CDT 2009


I'm just wondering why the behaviour I would expect out of nat=yes vs. 
nat=no seems to be inverted.

I expect nat=no to result in strict adherence to the dictates of SIP and 
SDP protocol mechanics, and nat=yes to pull out various tricks like 
using received IPs and ports for SIP and RTP.  Instead, it seems to be 
the other way around.

Venefax wrote:

> The subject is affecting the whole planet. It would be great if somebody
> would explain how it works. I have awful problems with NATted clients.
> 
> 
> -----Original Message-----
> From: asterisk-dev-bounces at lists.digium.com
> [mailto:asterisk-dev-bounces at lists.digium.com] On Behalf Of Alex Balashov
> Sent: Tuesday, April 21, 2009 8:52 PM
> To: Asterisk Developers Mailing List
> Subject: Re: [asterisk-dev] Symmetric RTP behaviour and 'nat' peer option.
> 
> My interpretation seems to be supported by main/rtp.c:ast_rtp_read():
> 
>          /* Send to whoever send to us if NAT is turned on */
>          if (rtp->nat) {
>                  if ((rtp->them.sin_addr.s_addr != sin.sin_addr.s_addr) ||
>                      (rtp->them.sin_port != sin.sin_port)) {
>                          rtp->them = sin;
>                          if (rtp->rtcp) {
>                                  memcpy(&rtp->rtcp->them, &sin, 
> sizeof(rtp->rtcp->them));
>                                  rtp->rtcp->them.sin_port = 
> htons(ntohs(rtp->them.sin_port)+1);
>                          }
>                          rtp->rxseqno = 0;
>                          ast_set_flag(rtp, FLAG_NAT_ACTIVE);
>                          if (option_debug || rtpdebug)
>                                  ast_log(LOG_DEBUG, "RTP NAT: Got audio 
> from other end. Now sending to address %s:%d\n", 
> ast_inet_ntoa(rtp->them.sin_addr), ntohs(rtp->them.sin_port));
>                  }
>          }
> 
> Yet, with nat=no, I would expect that NAT would not be "turned on."
> 
> I would expect the behaviour under nat=no to follow strict protocol 
> mechanics and ignore any received Layer 3 / Layer 4 characteristics, yet 
> that is clearly not the case.
> 
> Perhaps I am missing something about how Packet2Packet bridging works?
> 
> Thanks!
> 
> Alex Balashov wrote:
> 
>> Greetings,
>>
>> I am running Asterisk 1.4.21.2 and seeing some counterintuitive 
>> behaviour with regard to RTP and far-end NAT traversal and could use a 
>> little perspective.
>>
>> The topology looks like this:
>>
>>   endpoint <--NAT GW--> NAT traversal fixup proxy <--> Asterisk
>>
>> The NAT traversal fixup proxy uses the usual far-end traversal 
>> techniques - mangling the Contact header to the received IP, forcing the 
>> use of the received port for replies, and SDP received IP endpoint 
>> mangling.
>>
>> There is a SIP peer built out to the proxy from Asterisk.
>>
>> Anyway, when I initiate a call from the phone to a PSTN gateway through 
>> this chain (Asterisk bridges the call to a PSTN gateway via SIP), I am 
>> seeing the following behaviour.  Here is the scenario:
>>
>>   1) Endpoint sends INVITE to proxy;
>>
>>   2) Proxy does NAT traversal fixups including substitution of received
>>      IP in the m= line of the SDP payload.
>>
>>   3) Proxy statefully forwards call to Asterisk.
>>
>>   4) When the endpoint starts sending RTP toward Asterisk after the
>>      call is established, the source port of the RTP packets is
>>      different from the destination port announced in the endpoint's
>>      initial INVITE's SDP payload.  This is typical of SIP NAT gateways
>>      without SIP-aware ALGs.
>>
>> And here is what I am experiencing:
>>
>> 1) With nat=no on the peer, Asterisk sends RTP toward the endpoint at 
>> the destination port specified in the SDP payload of its INVITE *until* 
>> it receives its first RTP packet from the endpoint.  The first RTP 
>> packet has a different source port than what was advertised in the 
>> endpoint's SDP offer, and from that moment, Asterisk starts sending RTP 
>> to the source port of that first media packet *instead* of what is in 
>> the SDP.
>>
>> 2) With nat=yes, Asterisk ignores the source ports of incoming RTP from 
>> the endpoint and continues sending media to the destination port 
>> specified in the received SDP.
>>
>> ...
>>
>> This seems counterintuitive to me.  I had always thought that nat=yes is 
>> what enables symmetric RTP, but it seems that the opposite is true in 
>> this implementation;  with nat=yes, the received source port of 
>> subsequent RTP is ignored and the SDP is used, while with nat=no, 
>> attention is paid to the actual received source port.
>>
>> What am I missing?
>>
>> Thanks!
>>
> 
> 


-- 
Alex Balashov
Evariste Systems
Web    : http://www.evaristesys.com/
Tel    : (+1) (678) 954-0670
Direct : (+1) (678) 954-0671
Mobile : (+1) (678) 237-1775



More information about the asterisk-dev mailing list