Thanks for sharing the link @BrianWest-SW, really good explanation. I watched the video and summarized everything you said below in case it’s useful for anyone that comes across this. It all makes perfect sense how this works now, so thanks!
Unfortunately, none of the 3 NAT modes described work to send RTP to the WAN IP directly from the outset. I’ll try to join office hours next time they come up. Thanks so much for all the help!
NAT Mode 1
<param name="ext-rtp-ip" value="190.102.98.2"/>
<param name="ext-sip-ip" value="190.102.98.2"/>
When we first started, FreeSWITCH had NAT mode 1 which just had ext-rtp-ip and ext-sip-ip. These two settings would allow you to always tell a lie in the SIP packets and the RTP. We would bind to the local IPs on the box and we would use two particular elements in the SDP and in the SIP packets. You would always be able to speak with your clients that reside outside of the NAT that the FreeSWITCH server is sitting behind.
NAT Mode 2 (Uses NAT-PMP/uPNP to discover your public IP)
<param name="ext-rtp-ip" value="auto-nat"/>
<param name="ext-sip-ip" value="auto-nat"/>
<param name="local-network-acl" value="localnet.auto"/>
With NAT mode 1, this posed a problem: if you wanted to use one profile to talk to entities that live behind the NAT with you at the same time, you couldn’t use a single profile with that particular configuration. You would have to create a separate Sofia profile to be able to speak with those elements behind the NAT with FreeSWITCH and elements outside. This posed a little bit of a problem if you had a client that would reside on the network and roam off the network onto say LTE or otherwise the outside of your network.
The second way you can configure your NAT mode is by setting ext-rtp-ip and ext-sip-ip to auto-nat. What this does is it activates the discovery process in the beginning. A lot of you guys probably run on static IPs when you start FreeSWITCH with -nonat to not waste the 3-5s startup delay.
If you’re on a consumer grade connection or consumer-grade router, you probably have NAT-PnP or NAT-UPnP. One technique that is critical for this function properly is the local-network-acl. This is set up by default with allow lines that will dictate what networks are behind NAT with you.
What this will do is allow the NAT subsystem in Sofia to look at where the request came from. NOT what is in the SDP and NOT what is in the packet, but where did this request ACTUALLY come from - the real IP address. So, it will compare the where it came from against this ACL. If there’s a match, it WILL NOT use the ext-rtp-ip and ext-sip-ip if it matches the ACL.
If it matches the ACL, it will use those external settings. So you can determine if something’s behind NAT with you or outside of NAT with you.
NAT Mode 3
<param name="ext-rtp-ip" value="autonat:190.102.98.2"/>
<param name="ext-sip-ip" value="autonat:190.102.98.2"/>
<param name="local-network-acl" value="localnet.auto"/>
More of a static configuration – I know my public IP, I know I’m going to talk to things behind NAT and things on the public internet. Allows you to prefix your external SIP and RTP IPs with autonat: (no dash). What this does it activates the local-network-acl and hard-sets your IPs to those values if you always know those values. If they change, this will not function anymore; you will have inconsistent calls where they end after 30 seconds if your IP address changed.
This will use the local-network-acl to determine what is local to the system vs. what is not so it can dynamically figure out “should I use the internal RTP IP and the SIP IP or should I use the external RTP IP or external SIP IP.
This whole thing is a little bit confusing because a lot of people will assume that setting the local-network-acl and just setting and IP in the ext-rtp-ip and ext-sip-ip will make this behavior happen. Unfortunately, it won’t. You have to prefix it with autonat: that’s very critical.
The reason we need to do that is to maintain the old behavior where you hard-set the ext-rtp-ip and ext-sip-ip as in Mode 1. We didn’t want to break anybody in the field by changing that behavior.
aggressive-nat-detection
Values: true, false
You probably should not use this – it’s there for legacy reasons. If you’re having to do this, you’ve got some situations where you’re just at your last end and this is the only thing that will work. I don’t think it’s even recommended anymore.
apply-nat-acl
Values: acl_name
Should I do NAT processing on this packet? Maybe set to “nat.auto”. Only benefit of not setting this is for CPU performance gain, which nowadays is negligible.
enable-compact-headers
Values: true, false
If you guys have been paying attention to WebRTC and how bit those SDPs are – there’s a reason they use TCP. They are too big to fit in a UDP frame because of the MTU so they use TCP. This option will try to make the packet a bit smaller to try and fit it within the MTU whenever possible.
-nonat (startup flag)
To turn it off use “-nonat” to start FreeSWITCH. If you still prefer to have NAT detection but want to avoid the port mapping using UPnP/NAT-PMP you can use “-nonatmap”.