[asterisk-users] Asterisk both behind a NAT and outside at the same time

Brad Templeton brad+aster at templetons.com
Tue Oct 31 17:10:58 MST 2006


On Tue, Oct 31, 2006 at 04:51:44PM -0500, C F wrote:
> >The correct behaviour, as I see it is:
> >
> >    a) Native bridge when connecting two external channels -- everybody is 
> >    on the real internet
> 
> It might not work if one of them is NATed. Therefore the correct way
> to do this is to use canreinvite=no

Of course, if the external peer or user is natted, you would want to
turn on nat and canreinvite=no for such channels.   However, I do not
wish to set canreinvite=no for an external peer like another asterisk
box with an external IP, or a SIP termination provider.

More than do not wish -- this is the most important case.

> 
> >    b) Native bridge when connecting two internal channels -- everybody is 
> >    on the 192.168.* network
> 
> canreinvite=yes will take care of this.

Of course, but the point is that the internal channels (local SIP phones)
are involved in connections to both local phones, and to external peers.
> 
> >    c) Route RTP through Asterisk when connecting internal and external
> 
> Again by adding canreinvite=no to externals you have this.

But this defeats the entire purpose.  Here are two situations where you would
most definitely not want to have canreinvite=no

a) Call comes in via SIP origination, and you direct it back out to a PSTN
phone via your SIP termination.   You want the RTP to go directly from
the originating point to the termination point, not to hairpin through
your asterisk box, which would just add latency and eat bandwidth.

b) Click to call APP I have where I connect two PSTN endpoints.  Again,
it's necessary not to hairpin the RTP.

c) Double all this with some advanced providers who, once they figure
where the call is actually being terminated, do their own native bridging
and direct your RTP to the actual PSTN entry point.  There it's possible
to get the RTP to go by the shortest (and lowest latency) path it can.

But not if you hairpin it.
> 
> >    d) When a channel is to a device behind a remote NAT, the usual rules 
> >    apply
> >       (either use STUN or other smart NAT, or route RTP through Asterisk)
> 
> How will asterisk know? The correct *setting* (not behavior) is
> canreinvite=no for the external devices.

I would have to differ.  That's the right setting for external user devices
behind NAT. Do you believe it's correct for devices not behind NAT?

Asterisk can tell if a device is behind NAT if the device has been made
in the last few years, because such devices support a variety of techniques
to inform the server they call that they are behind NAT, and even what
their external IP is if need be.

However, reinvite is not safe with a symmetric nat unless there is really good
cooperation.  So I understand turning off reinvite for any external device
behind NAT.

(Of course a clever box can notice that it sees two devices that have
NAT addresses on the same subnet and both are using the same external
IP.  In that case, it can tell them to send their RTP directly to one
another which is very much the best thing to do.  This allows things
like a branch office using a head office Asterisk server and calls
within the branch staying on the LAN.

This is what the ICE protocol is supposed to solve, of course.)

> 
> Why are you so against having the RTP go thru asterisk?

For external connections?  There are a ton of reasons, some outlined above.
An asterisk box with proper use of native bridging can handle a virtually
unlimited number of calls.    Put the RTP through it and it can handle only
a modest number, and reduces the quality of those calls significantly.

Having internal calls go through the asterisk box is not as much of a problem,
but I have noticed latencies because of it even on my internal LAN, though I
have not pieced together exactly why, it's almost certainly because of the
RTP bridging.   Which I always get when I call IAX to SIP of course.  It's
not because of load. 

Anyway, my main question is, has anybody figured out how to make Asterisk
do the right thing here.  I am surprised if my configuration is that
unusual.  Having both an internal and external network is pretty common
at a lot of places.   And a server that's on both is, I think, quite common,
so I had not expected this to be a difficult thing to figure out how to do.


More information about the asterisk-users mailing list