Thursday, March 26, 2009

Problems with UDP streams and STUN

I recently came across a problem with longer lasting UDP sessions that use STUN for NAT traversal. More specifically when using a Microsoft LiveMeeting session to share real time video.

The client PC initiates a connection to the Microsoft servers and starts sending UDP data to which the Microsoft servers respond. The response packets contain other users' video or if you are in the conference by yourself your own video. NAT traffic through the firewall looks something like this in a packet capture:

  • Before reaching the firewall
  • Client Source IP, UDP Source Port, STUN Destination Port (e.g. 192.168.1.100, Source Port 43000, Destination Port 3478)
  • After passing through the firewall
  • NAT Source IP, UDP translated Source Port, STUN Destination Port (e.g. 100.100.100.1, Source Port 56565, Destination Port 3478)

In this example the firewall translates the source IP and source port in a PAT or many-to-one NAT situation.
After about 7 minutes the firewall all of a sudden changes the translated Source Port, for example 56565 becomes 61616. The original source port on the client however has not changed. Therefore the destination server on the far end no longer sees the correct UDP source port and after several seconds ends the connection due to lack of UDP data. This behaviour has been confirmed in FortiOS 3.0 MR7. In further testing I found that FortiOS 4.0 does not exhibit this behaviour.

The temporary workaround is to use static NAT where possible. Static NAT uses a one-to-one relationship between the original and translated source port and IP addresses. Therefore no translation is done on any ports, only the source IP, and the connection stays alive.

** Update from Fortinet **

Fortinet has identified two bugs which have been fixed in FortiOS 4.0. The bugs are "Port changed in SIP header" and "SDP contact not modified correctly". There are currently no plans to resolve this in 3.0 MR7.

1 comment:

Anonymous said...

My Fortigate with Fortios 3.0 MR7 P9 changed the outside nat source ports for udp sessions with idle time >3 minutes, which killed stun, of course. I discovered an expire count down field in "dia sys session list" indicating the Fortigate creates a new session every 180s. After some investigation I found the following option where you can change this behaviour:
conf system global
set udp-idle-timer 3600

This solved it for me.