[asterisk-dev] STUN support in chan_sip revisited

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



Am 05.08.2010 21:02, schrieb Simon Perreault:
> First, thank you very much for writing this. It is going to be
> tremendously useful.
>
> On 2010-08-05 14:20, David Vossel wrote:
>> 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.
>>
>> 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.
>>
>> --- 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.
>>
>> 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.
>
> A few more issues:
>
> 5. Ignoring TCP, the NAT device may assign a different address/port when
> we are talking to the STUN server than when we are talking to the remote
> SIP device. Using terminology defined in RFC 4787, such a NAT device
> would exhibit Address-Depend or Address and Port-Dependent mapping
> behaviour.

Is this what we usually just call "symmetric NAT"?

This can be detected by Asterisk by sending multiple STUN requests to 
the various IP addresses and ports offered by the STUN server. But how 
should Asterisk react in such a case? IMO it should log warnings and use 
the local IP address in requests.

Further it would be cool to get the STUN results on the console, e.g:
 > stun show status
STUN server: 1.2.3.4:5678
last STUN request: 23:00:59 2010-08-10
next STUN request: 23:01:14 2010-08-10
detected STUN type: Address-Depend or Address and Port-Dependent mapping
external SIP UDP address: 5.6.7.8:64344
external SIP address used for mapping: no

> 6. The address obtained from the STUN server (the Server-Reflexive
> Address) may not be usable for reaching us by the remote SIP device,
> depending on characteristics of the NAT device. Assuming
> Endpoint-Independent mapping behaviour (so that issue 5 does not apply),
> a NAT device with Address-Dependent or Address and Port-Dependent
> filtering behaviour would discard packets sent from the remote SIP
> device to the address learned using STUN.

Is this a practical scenario? How will the remote SIP device know the 
public IP address? Because the client sent a REGISTER (or any other SIP 
request) first, thus opening the pin-hole in the NAT for the reverse 
direction.

> 7. This usage is non-standard. It is Asterisk-specific, and it has
> issues. As an example, devices behind the same NAT device could not
> speak to each other if the NAT device does not support hairpinning.
> Correct STUN usage for SIP is documented in RFC 5626 while correct STUN
> usage for RTP/RTCP is documented in RFC 5245.

RFC 5626 describes how the client and the server can traverse the NAT in 
case of both support RFC 5626. If the Asterisk as client behind supports 
5626, but the server does not support it, then 5626 is useless for 
Asterisk and it still has to follow old-style STUN based NAT traversal 
with replacing of IP addresses in the SIP messages.

Thus, yes RFC 5626 would be nice, but it is useless if only the client 
supports it.

>> 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?
>
> :)
>
> My answer would be: a full implementation of RFC 5626 and RFC 5245.

and the old-style STUN based NAT traversal for cases where the server 
does not support RFC 5626 and 5245.

regards
Klaus



More information about the asterisk-dev mailing list