Here is my situation:
UAC1----\ /-------PSTN
\ SER----ASTERISK/
/ \
UAC2----/ \
\----- INTERNET
SER listening on 192.168.1.100 (towards the internal LAN -> UAC1 and
UAC2), and on 88.148.87.236 towards the internet ;
SER doing NAT between the internal and external networks;
SER serving as a registrar;
RTP Proxy installed on the SER machine,
and started with rtpproxy -l 192.168.1.100/88.148.87.236
problem is NATed UAC1 and UAC2 don't get any audio when calling to a
public endpoint, but can successfully call each other.
when the call is established, I am getting the following errors in the
onreply_route:
6(1742) ERROR: extract_body: message body has lenght zero
6(1742) ERROR: force_rtp_proxy2: can't extract body from the message
are there any parameters that should be handed to force_rtp_proxy()? i
noticed it has been called with II/EI/IE in the application layer
gateway example - alg.cfg marking Internal/External locations. in that
example. however both networks are RFC1918, i.e. no nathelper is
necessary.
below is my ser.cfg. please excuse the excessive logging, but i'm
trying to figure out how it all works...
#
# $Id: ser.cfg,v 1.21.4.1 2003/11/10 15:35:15 andrei Exp $
#
# simple quick-start config script
#
# ----------- global configuration parameters ------------------------
debug=3 # debug level (cmd line: -dddddddddd)
fork=yes
log_stderror=yes # (cmd line: -E)
alias=mertel.net
alias=88.148.87.236
alias=192.168.1.100
check_via=no # (cmd. line: -v)
syn_branch=yes
sip_warning=yes
dns=no # (cmd. line: -r)
rev_dns=no # (cmd. line: -R)
port=5060
children=4
fifo="/tmp/ser_fifo"
server_signature=yes
reply_to_via=no
# ------------------ module loading ----------------------------------
# Uncomment this if you want to use SQL database
loadmodule "/usr/local/lib/ser/modules/mysql.so"
loadmodule "/usr/local/lib/ser/modules/nathelper.so"
loadmodule "/usr/local/lib/ser/modules/textops.so"
loadmodule "/usr/local/lib/ser/modules/sl.so"
loadmodule "/usr/local/lib/ser/modules/tm.so"
loadmodule "/usr/local/lib/ser/modules/rr.so"
loadmodule "/usr/local/lib/ser/modules/maxfwd.so"
loadmodule "/usr/local/lib/ser/modules/usrloc.so"
loadmodule "/usr/local/lib/ser/modules/registrar.so"
loadmodule "/usr/local/lib/ser/modules/exec.so"
# Uncomment this if you want digest authentication
# mysql.so must be loaded !
loadmodule "/usr/local/lib/ser/modules/auth.so"
loadmodule "/usr/local/lib/ser/modules/auth_db.so"
loadmodule "/usr/local/lib/ser/modules/acc.so"
loadmodule "/usr/local/lib/ser/modules/uri.so"
# ----------------- setting module-specific parameters ---------------
modparam("tm", "fr_timer", 12)
modparam("tm", "fr_inv_timer", 24)
modparam("usrloc", "db_mode", 2)
modparam("auth_db", "calculate_ha1", yes)
modparam("auth_db", "password_column", "password")
modparam("rr", "enable_full_lr", 1)
modparam("acc", "db_flag", 2)
modparam("acc", "db_missed_flag", 3)
modparam("registrar", "nat_flag", 6)
modparam("nathelper", "natping_interval", 30)
modparam("nathelper", "ping_nated_only", 1)
# ------------------------- request routing logic -------------------
route {
log(1, "--------\n");
log(1, "LOG:Entering main route loop\n");
#initial sanity checks
if (!mf_process_maxfwd_header("10")) {
log(1, "LOG: Too many hops\n");
sl_send_reply("483", "Too many hops");
break;
};
if (msg:len > max_len) {
sl_send_reply("513", "Message too big");
};
# test if the client is nated
if(nat_uac_test("3")) {
log(1, "LOG:NAT detected\n");
if(method=="REGISTER" || ! search("^Record-Route:")) {
log(1, "LOG: Received REGISTER request from a NATed
client, calling fix_nated_contact()... \n");
if(!fix_nated_contact()) {
log(1, "LOG: fix_nated_contact() FAILED!\n");
} else {
log(1, "LOG: fix_nated_contact() successful.\n");
};
if(method=="INVITE") {
log(1, "LOG: Received INVITE request, calling
fix_nated_sdp()...\n");
if(!fix_nated_sdp("1")) {
log(1, "LOG: fix_nated_sdp() FAILED!\n");
} else {
log(1, "LOG: fix_nated_sdp() successful.\n");
};
};
log(1, "LOG: Calling force_rport()...\n");
if(!force_rport()) {
log(1, "LOG: force_rport() FAILED !\n");
} else {
log(1, "LOG: force_rport() successful.\n");
};
log(1, "LOG: calling setflag(6)...\n");
if(!setflag(6)) {
log(1, "LOG: setting flag 6 FAILED!\n");
} else {
log(1, "LOG: Flag 6 set successfully.\n");
};
append_hf("P-hint: fixed NAT contact for request\r\n");
}; # close if(method=="REGISTER");
}; #close if(nat_uac_test)
if (method=="REGISTER") log(1, "LOG: REGISTER msg received.\n");
if (method=="INVITE") log(1, "LOG: INVITE msg received.\n");
if (method=="ACK") log(1, "LOG: ACK msg received.\n");
if (method=="BYE") log(1, "LOG: INVITE msg received.\n");
if (method=="CANCEL") log(1, "LOG: CANCEL msg received.\n");
if (method=="SUBSCRIBE") log(1, "LOG: SUBSCRIBE msg
received.\n");
if (method=="NOTIFY") log(1, "LOG: NOTIFY msg received.\n");
if (method=="OPTIONS") log(1, "LOG: OPTIONS msg received.\n");
if (method=="INFO") log(1, "LOG: INFO msg received.\n");
if (method=="MESSAGE") log(1, "LOG: MESSAGE msg received.\n");
if (method=="REFER") log(1, "LOG: REFER msg received.\n");
if(!method=="REGISTER") {
log(1, "LOG: recording route...\n");
record_route();
};
#if processing a loose route()
if (loose_route()){
log(1, "Processing loose route.\n");
append_hf("P-hint: rr-enforced");
t_relay();
break;
};
# ROUTING TOWARDS ASTERISK
if ((uri=~"sip:033[0-9]{3,20}@.*") |
(uri=~"sip:02[0-9]{3,20}@.*") | (uri=~"sip:[56][0]{2}@.*") |
uri=~"sip:08314[0-9]{4}@" | uri=~"sip:12[34]@" |
uri=~"sip:32[0]{3}[1]@" ) {
log(1, "LOG: Destination is Asterisk - switching to route[3]\n");
route(3); # - handles routing to Asterisk GW
break;
};
if (!(uri==myself)) {
log(1, "LOG: Detected an outbound destination (uri!=myself) -
switching to route[2]\n");
append_hf("P-hint: outbound");
route(2); # - handles routing to outbound destinations, i.e. not local
break;
};
if(uri==myself) {
log(1, "LOG: uri==myself \n");
if(method=="REGISTER") {
log(1, "LOG: Analyzing REGISTER request\n");
if(!www_authorize("mertel.net", "subscriber")) {
log(1, "LOG: User not authorized - sending
www_challenge()...\n");
www_challenge("mertel.net","0"); #this reenters
route block
break;
};
if(!is_user("replicator") & !check_to()) {
log(1, "LOG: Unregistered user registration attempt\n");
sl_send_reply("403", "Only registered users are
allowed");
break;
};
log(1, "LOG: User is authorized, saving location...\n");
if(!save("location")) {
log(1, "LOG: !!!!! save location error on
registration !!!!!");
sl_reply_error();
} else {
log(1, "LOG: User location saved successfully.\n");
};
break;
}; # - closes if(method=="REGISTER")
#lookup("aliases");
# mostly offline or non-existent users
if(!lookup("location")) {
log(1, "LOG: Sending 404 not found ! \n");
sl_send_reply("404", "Not found");
break;
};
}; #closes if(uri==myself)
append_hf("P-hint: usrloc aplied");
route(2);
} /* end of initial routing logic */
route[2] {
log(1, "LOG: Entering route[2] now...\n");
# check for RFC1918 ip addresses
# -- NATHELPER --
if(uri=~"[@:](192\.168\. 10\. 172\.(1[6-9]|2[0-9]|3[0-1])\.)" &&
!search("^Route:")) {
sl_send_reply("479", "We do NOT forward to RFC 1918 IP
addresses\n");
break;
};
#check if the NAT Flag is set
if (isflagset(6)) {
log(1, "LOG: flag 6 set => One of the sides is NATed ->
force_rtp_proxy()\n");
if(!force_rtp_proxy()) {
log(1, "LOG: force_rtp_prpoxy FAILED!\n");
} else {
log(1, "LOG: force_rtp_proxy() succeeded!\n");
};
};
log(1, "LOG:setting up reply processing\n");
t_on_reply("2");
# outbound requests are allowed only for registered
mertel.net users
if (!(src_ip==88.148.87.236) & !(proxy_authorize("mertel.net",
"subscriber"))) {
# ACK and CANCEL have no security mechanisms so they are just noted
if (method=="ACK" | method=="BYE") {
log(1, "LOG: failed outbound authentication for ACK
granted\n");
} else if (method=="CANCEL") {
log(1, "LOG: failed outbound authentication for
CANCEL granted\n");
} else if ( src_ip==88.148.87.237 ) {
log(1, "LOG: Incoming FROM ASTERISK TO SIP\n");
} else {
proxy_challenge("mertel.net", "0");
break;
};
};
# to maintain credibility of our proxy, we check From in INVITEs
if (!src_ip==88.148.87.236 & method=="INVITE" & !check_from()) {
log(1, "LOG: Spoofed from attempt\n");
sl_send_reply("403", "Use From=id next time");
break;
};
log(1, "LOG: relaying message...\n");
if (!t_relay()) {
log(1, "LOG: t_relay error occured ! \n");
sl_reply_error();
};
}
onreply_route[2] {
log(1, "LOG: entered onreply_route[2] now... \n");
if(isflagset(6) && status =~"(183)|2[0-9][0-9]") {
log(1, "LOG: TRansaction was sent to a NATed client -->
fix_nated_contact() and force_rtp_proxy().\n");
if(!fix_nated_contact()) {
log(1, "LOG: fix_nated_contact() FAILED!\n");
} else {
log(1, "LOG: fix_nated_contact() succeded.\n");
};
if(!force_rtp_proxy()) {
log(1, "LOG: force_rtp_proxy() FAILED!\n");
} else {
log(1, "LOG: force_rtp_proxy() succeded.\n");
};
append_hf("P-hint: fixed NAT contact for response\r\n");
} else if (nat_uac_test("1")) {
log(1, "LOG: Uncaught NAT. => fix_nated_contact()\n");
if(!fix_nated_contact()) {
log(1, "LOG: fix_nated_contact() FAILED!\n");
} else {
log(1, "LOG: fix_nated_contact() succeded.\n");
};
};
if((status=~"100")) {
log(1, "LOG: received status 100\n");
};
if((status=~"180")) {
log(1, "LOG: received status 180\n");
};
if((status=~"202")) {
log(1, "LOG: received status 202\n");
};
}
#route[3] routes calls to the gateway
route[3] {
log(1, "LOG: Entered route[3] now...\n");
# all calls through the gateway must be record routed to assure
# acl acceptance on the gateway
#record_route();
# first the caller needs to be authenticated
if (!(src_ip==88.148.87.236 | method==ACK | method=="CANCEL" |
method=="BYE")) {
if ( ! src_ip==88.148.87.237 ) {
log(1, "LOG: Inbound call FROM ASTERISK !!!\n");
if (!proxy_authorize("mertel.net", "subscriber")) {
proxy_challenge( "mertel.net","0");
break;
} else if (method=="INVITE" & !check_from()) {
log(1, "LOG: Spoofed from attempt\n");
sl_send_reply("403", "Use From=id next
time");
break;
};
};
};
rewritehostport("88.148.87.237:5060");
append_hf("P-hint: GATEWAY\r\n");
log(1, "LOG: Relaying to Gateway\n");
if (!t_relay()) {
sl_reply_error();
break;
};
}