I think I have this working. For anyone else trying to do similar thing (or placing
Kamailio behind FW/NAT), here is my cookbook.
We are trying to setup the following:
[UAS] <------>
(PubIP)[FireWall/One-to-OneNAT]<-------->(PrivIP)[Kamailio/RTPProxy](PrivIP)<---------->(PrivIP2)[UAC]
UAC/UAS cannot reach each other directly.
For simplicity I am running RTPProxy on same machines as Kamailio. But this can be
changed.
Versions/Patches/fixes you need if you are running 3.1.2 : (Trunk/3.2 has these):
a. Fixed forward.c for mhome to work properly (included in 3.1.4).
b. rr module from trunk to be able to use 2 strings for record_route_preset
c. Patched rtpproxy module to actually use the forced ip supplied to force_rtp_proxy.
Patch at the end of this message
d. rtpproxy version 1.2.1
What to do:
1. Setup FW/NAT rules to map public IP to PrivateIP and allow communications to/from
UAS
2. Setup RTPProxy in "bridged" mode (e.g -F -l 10.10.5.90/10.10.5.90 -s
udp:10.10.5.90:9005) listening on PrivateIP.
3. Setup the config file to:
a. Setup modparams to make the above rtpproxy available. Use set_rtp_proxy_set if you
have more than one instance.
b. Do the following where you are processing Outbound *initial* invite (i.e. check
totag) (Call from UAC to UAS)
set_advertised_address("YourPublicIP ");
if(!has_totag()) {
record_route_preset("YourPublicIP:5060;r2=on;nat=yes","YourPrivateIp:5060;r2=on;nat=yes");
}
force_rtp_proxy("ocfaei"," YourPublicIP ");
c. Do the following where you are processing Inbound invite (Call from UAS to UAC)
if(!has_totag()) { record_route_preset("YourPrivateIP:5060;r2=on;nat=yes",
"YourPublicIp:5060;r2=on;nat=yes"); }
force_rtp_proxy("ocfaei");
d. Do the following where you are processing replies (180/183/2XX)
For Inbound Calls
force_rtp_proxy("ocfa","YourPublicIP");
For Outbound Calls
force_rtp_proxy("ocfa");
e. Unforce RTPProxy on BYE or Failures.
Do not use record_route in the above scenario. If you have it now, remove it or make
sure it doesn't get called for this specific case.
Explanation:
In #b, you are fixing the Via headers to use public IP, setting Record-Route headers so
that ACK/RE-INVITE can find way back and are force fixing SDP with public IP for outbound
calls.
In #c, You are doing same thing except no need to fix Via and the route set is reversed.
No need to force fix SDP either since it is figured out automatically.
In #d, You are force fixing the SDP to use the public IP for inbound or usual for outbound
so that the audio stream from UAS can be relayed.
The r2=on parameter is required (as well as enabling double rr, which is default) so that
the proxy can deal with the route sets properly
Hope the above helps others.
SV.
Rtpproxy Path
2226,2233c2226
< LM_DBG("Str2 is %s\n", str2);
< if(str2) {
< newip.s = str2;
< LM_DBG("NewIp is %s\n", newip.s);
< }
< else {
< newip.s = (argc < 2) ? str2 : argv[1];
< }
---
newip.s = (argc < 2)
? str2 : argv[1];