[asterisk-dev] STUN support in chan_sip revisited

Klaus Darilion klaus.mailinglists at pernau.at
Fri Aug 6 03:56:17 CDT 2010



Am 05.08.2010 20:20, schrieb David Vossel:
> Howdy,
>
> My initial assumptions for how and why we would want to use STUN in
> sip were rather naive.  I have attempted to outline what I believe is
> the current expected behavior and am asking for some additional
> feedback.
>
> --- Expected use of STUN in chan_sip.
>
> In chan_sip, a STUN server can be queried to obtain the external
> address/port of connectionless SIP traffic to the local Asterisk box
> behind a NAT.  The only reason querying a STUN server would be used
> rather than setting the external address statically in sip.conf is if
> the address and port mappings used by the NAT device are dynamic or
> unknown, and the only way to accurately receive the correct
> address/port mappings used by the NAT device is to send the STUN
> request out the same transport and port as the SIP traffic is being
> sent out.   This is because the addressed/port received by the STUN
> response must directly map to the external address/port we expect to
> receive external SIP responses/requests in on.  Once the external
> address/port is received from the STUN response, that address/port is
> used in SIP and SDP messages which indicates where we exist so other
> endpoints can communicate back with us.

Of course the external address/port which corresponds to the SIP socket 
is only used in SIP headers. The SDP should contain the external 
address/port which corresponds to the RTP/RTCP sockets.

Further, STUN should be used also to detect the type of the NAT device.

> Another useful effect of using STUN support is as a keepalive
> mechanism for the state entry on the NAT device.  By setting the
> 'externrefresh=180 ;where 180 is the configured number of seconds'
> option in sip.conf we should expect the STUN request to be set every
> 180 seconds in order to refresh the state entry on the NAT device.

The keep-alive is very important. Because if the NAT-mapping times out, 
incoming calls wont traverse the NAT anymore and also, further outgoing 
STUN/SIP requests will get assigned a new binding, probably with a new 
public port. Thus, the STUN keep-alive should be smaller than the NAT 
timeout to have a constant public address/port.

>
> --- Current STUN implementation problems/limitations
>
> 1.  When STUN is used, the response's port mapping is internally used
> for both the external address for TCP and UDP.  Since STUN queries
> are connectionless and use the configured UDP port, the STUN response
> is not accurate as an external address for TCP connections.

Indeed. Several SIP clients use a different approach for TCP: with the 
first SIP request sent to a certain target, the response indicates the 
public IP/port in the Via header. This one will be used for all further 
requests (mainly Contact header) within this TCP connection.

> 2.  When a STUN request is sent out, we block on the SIP UDP socket,
> throwing away any non-STUN related traffic until the STUN response is
> received.  This means that any SIP signaling received during a STUN
> query is just thrown away.  It also makes for some confusing error
> messages.
>
> 3. Using STUN queries as a keepalive mechanism does not work exactly
> like it is documented in sip.conf.  According to the documentation by
> setting the 'externalrefresh=x ; where x is number of seconds' option
> we  should expect an event to fire every 'x' number of seconds.  This
> is not an accurate assumption as there is no scheduled event that
> causes a STUN request.  We are only guaranteed that a new STUN
> request will be sent sometime after 'x' number of seconds after the
> ast_sip_ouraddrfor() function is invoked as a result of processing a
> new incoming or outgoing SIP request of some sort.
>
> 4. Asterisk's STUN implementation has no way of determining the
> correct external port mappings for media.  This means that while the
> SIP signaling may work correctly, the media may.  Because of this, I
> question why anyone would even choose to use Asterisk's STUN support
> at all.

There are some cases where it will work:
- NAT device is configured with static port forwarding of port 5060 and 
RTP port range, and the public IP address is dynamic
- NAT devices uses port-preservation (public port = local port)

> --- Conclusion.
>
> From what I have gathered, STUN support in Asterisk is useless in its
> current state.  Even if the current expected behavior worked I am

almost :-)

> unaware of how it would be useful.  If it is necessary to determine
> the external port for SIP traffic because of some NAT device, then it
> seems like we would need the correct external media port mappings as
> well.

yes, except the scenarios described above.

> --- What I need to know
>
> Is my analysis of the current expected behavior of STUN support in
> chan_sip accurate?

At least you found several issues. Maybe there are other issues as well :-)

> Assuming the expected behavior was not broken, what are some
> realistic use cases where this current behavior would be used?

It is broken.

> Forgetting how Asterisk does STUN support in chan_sip all together.
> How do you expect/want STUN support to work in relation to chan_sip?

As Simon said, SIP-outbound and ICE support would be nice. But to work 
with old servers too, old-style STUN support (using STUN to detect 
public addresses and put these addresses in the SIP messages) is needed to.

IMO, the STUN client should run in background all the time to detect the 
NAT type and to detect the public SIP address/port. It should do 
keep-alive and update the public address information if it changes.

If the STUN server is not reachable, or the NAT type does not allow NAT 
traversal by STUN (e.g. symmetric NAT), it should log warnings and use 
the local IP only. Maybe a proprietary header can be added to the SIP 
messages too, e.g. (X-NAT-Info: symmetric NAT, NAT traversal disabled)

This public address information should be used by chan_sip. When a RTP 
sessions is set up, can_sip should request the stun client to perform 
STUN lookup for the RTP and RTCP port. These lookups should not make 
multiple STUN request to detect the NAT type (we already know the NAT 
type) but instead should only use a single STUN request to get the 
public address. In case of symmetric NAT, these STUN requests can be 
skipped as they are worthless. If the STUN server is not available, the 
STUN requests should be skipped too, to avoid blocking.

Thanks for fixing STUN,
regards
Klaus

>
> Thanks for your help!
>
> David Vossel Digium, Inc. | Software Developer, Open Source Software
> 445 Jan Davis Drive NW - Huntsville, AL 35806 - USA Check us out at:
> www.digium.com&  www.asterisk.org The_Boy_Wonder in #asterisk-dev
>
>



More information about the asterisk-dev mailing list