Hi Rafael,
You would use the "example code snippet" when you want to decide whether
or not to use rtpproxy or mediaproxy based on the fact that both the
caller and the callee are behind the same NAT device. Please review the
mailing lists as this topic has been discussed many times.
I added some additional comments in regard to the setting of flags 2 and
3 in the posted example at:
Generally, I have found that if OpenSER fails to start with an error
indicating that the function can't be found, it's time to find the
correct module to add.
In response to your last question "etc." I suggest that you review the
three web sites:
. The last one has
some really great material that explains alot.
Regards,
Norm
Rafael R. GV wrote:
Hi
I am using nathelper/rtpproxy in ser , please see my ser.cfg attached
and tell me where do I have to use this code snippet? where did you
set flags 2 and 3?, what other modules I need?, etc.
thank you
Rafael
Lima-Peru
On 12/7/05, *Norman Brandinger* <norm(a)goes.com <mailto:norm@goes.com>>
wrote:
Thanks go out to Klaus and Tavis.
I took the results of this thread and placed it in the docuwiki
for the
rest of the user community to use (at least, the rest of the user
community that reads the docuwiki :)
http://openser.org/dokuwiki/doku.php?id=avp_examples
If I made any typos, please feel free to correct them.
Regards,
Norm
_______________________________________________
Users mailing list
Users(a)openser.org <mailto:Users@openser.org>
http://openser.org/cgi-bin/mailman/listinfo/users
<http://openser.org/cgi-bin/mailman/listinfo/users>
------------------------------------------------------------------------
#
# If you don't want to enforce RTP proxy for some destinations
# then simply use t_relay() instead of route(1)
#
# Modificado para MYSQL_ACC support
# Handling of Unavailable user and Voicemail redirection (404|408|486)
#
# Log Missed Calls (403|404|408|415|484|486|487).
#
# Group checking and PSTN credentials.
#
# 18/07/2005 Prepaid & B2bua support added
# 11/11/2005 LDI a 192.168.2.132 with a2billing
#
# Pendientes !! - Administrar Multi-Dominio para otros Códigos de Area.
# - Completar Logica para tratamiento de llamadas entre
# un mismo NAT usando avpops.
#
# ----------- global configuration parameters ------------------------
#/* Uncomment these lines to enter debugging mode
debug=2
fork=yes
log_stderror=yes
#*/
listen=192.168.2.130
listen=127.0.0.1
port=5060
# hostname matching an alias will satisfy the condition uri==myself".
alias=mydomain.com.pe
alias=127.0.0.1
check_via=no # (cmd. line: -v)
dns=no # (cmd. line: -r)
rev_dns=no # (cmd. line: -R)
children=4
fifo="/tmp/ser_fifo"
fifo_mode=0666 # Fifo permissions can be changes from here.
# sip_warning - Should replies include extensive warnings?
# By default yes, it is good for trouble-shooting.
sip_warning=yes
# ------------------ module loading ----------------------------------
loadmodule "/usr/local/lib/ser/modules/domain.so"
loadmodule "/usr/local/lib/ser/modules/avpops.so"
loadmodule "/usr/local/lib/ser/modules/mysql.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/group.so"
loadmodule "/usr/local/lib/ser/modules/uri.so"
loadmodule "/usr/local/lib/ser/modules/uri_db.so"
loadmodule "/usr/local/lib/ser/modules/acc.so"
loadmodule "/usr/local/lib/ser/modules/textops.so"
# digest authentication
loadmodule "/usr/local/lib/ser/modules/auth.so"
loadmodule "/usr/local/lib/ser/modules/auth_db.so"
# !! Nathelper
loadmodule "/usr/local/lib/ser/modules/nathelper.so"
# ----------------- setting module-specific parameters ---------------
modparam("usrloc", "db_mode", 2)
# minimize write back window - default is 60 seconds
modparam("usrloc", "timer_interval", 10)
# database location
modparam("usrloc", "db_url",
"mysql://ser:heslo@localhost/ser")
modparam("usrloc", "use_domain", 1)
modparam("auth_db", "use_domain", 1)
modparam("domain", "db_mode", 1)
modparam("domain", "domain_table", "domain")
modparam("domain", "domain_col", "domain")
# ------------- Mysql Accounting parameters
modparam("acc", "log_flag", 1)
modparam("acc", "log_level", 2)
modparam("acc", "db_flag", 1)
modparam("acc", "db_missed_flag", 3)
modparam("acc", "log_missed_flag", 3)
modparam("acc", "db_url",
"mysql://seradmin:heslo@localhost/ser")
modparam("acc", "report_ack", 0) # 1 reporta dos starts en acc (para
INVITE y ACK)
modparam("acc", "failed_transactions", 1) # *all* non-200
transactions marked for acc will be logged too.
modparam("acc", "log_fmt", "miocfsputdr")
modparam("tm", "fr_timer", 20 )
modparam("tm", "fr_inv_timer", 40 ) # Timer which hits if no final
reply for an INVITE
modparam("tm", "wt_timer", 20 )
# add value to ;lr param to make some broken UAs happy
modparam("rr", "enable_full_lr", 1)
modparam("group", "db_url",
"mysql://seradmin:heslo@localhost/ser")
modparam("uri_db", "db_url",
"mysql://seradmin:heslo@localhost/ser")
# ------------- registration parameters
modparam("registrar", "nat_flag", 6)
modparam("registrar", "min_expires", 60)
modparam("registrar", "max_expires", 86400)
modparam("registrar", "default_expires", 3600)
modparam("registrar", "desc_time_order", 1)
modparam("registrar", "append_branches", 1)
modparam("registrar", "use_domain", 1)
# !! Nathelper
# modparam("registrar", "nat_flag", 6)
modparam("nathelper", "natping_interval", 30) # Ping interval 30 s
modparam("nathelper", "ping_nated_only", 1) # Ping only clients
behind NAT
# -------------------------- request routing logic --------------------------
route {
log(1, "-------------------------------------------\n");
log(1, "entering main loop\n");
# initial sanity checks -- messages with
# max_forwards==0, or excessively long requests
if (!mf_process_maxfwd_header("10")) {
sl_send_reply("483","Too Many Hops");
break;
};
if ( msg:len >= max_len ) {
sl_send_reply("513", "Message too big");
break;
};
# !! Nathelper
# Special handling for NATed clients; first, NAT test is
# executed: it looks for via!=received and RFC1918 addresses
# in Contact (may fail if line-folding is used); also,
# the received test should, if completed, should check all
# vias for rpesence of received
if (nat_uac_test("19")) {
# Allow RR-ed requests, as these may indicate that
# a NAT-enabled proxy takes care of it; unless it is
# a REGISTER
if (method == "REGISTER" || !
search("^Record-Route:")) {
log("LOG: Someone trying to register from private IP,
rewriting\n");
# This will work only for user agents that support symmetric
# communication. We tested quite many of them and majority is
# smart enough to be symmetric. In some phones it takes a
configuration
# option. With Cisco 7960, it is called NAT_Enable=Yes, with kphone
it is
# called "symmetric media" and "symmetric
signalling".
fix_nated_contact(); # Rewrite contact with source IP of signalling
if (method == "INVITE") {
fix_nated_sdp("1"); # Add direction=active to SDP
};
force_rport(); # Add rport parameter to topmost Via
setflag(6); # Mark as NATed
};
};
# set flag for Radius Accounting:
if (!method=="OPTIONS") setflag(3); # SET MISSED_CALLS FLAG FOR ACC
if (method=="INVITE") {
log(1, "INVITE MESSAGE RECEIVED - START ACC\n");
setflag(1); /* set for accounting (the same value as in log_flag!) */
};
if (method=="BYE") {
log (1, "BYE - STOP ACCOUNTING\n");
setflag(1);
};
if (method=="CANCEL") {
log (1, "CANCEL - STOP ACCOUNTING\n");
setflag(1);
};
# record-route all messages -- to make sure that
# subsequent messages will go through our proxy; that's
# particularly good if upstream and downstream entities
# use different transport protocol
if (!method=="REGISTER") record_route();
# subsequent messages withing a dialog should take the
# path determined by record-routing
# Excluding packets from b2bua (port 5070)
if (loose_route() ) {
log(1," Mark routing logic in request --> rr-enforced \n");
append_hf("P-hint: rr-enforced\r\n");
# t_relay();
route(1); # Nathelper!!
break;
};
if (!uri==myself ) {
log(1," Mark routing logic in request --> outbound\r \n");
append_hf("P-hint: outbound\r\n");
# t_relay();
route(1); # Nathelper!!
break;
};
if (uri==myself) {
if (method == "REGISTER") {
log(1, "ANALYZING REGISTER REQUEST\n");
# to use digest authentication
if (is_user_in("Request-URI", "desactivado"))
{
sl_send_reply("402", "Su cuenta fue
desactivada");
break;
};
if (!www_authorize("mydomain.com.pe",
"subscriber")) {
log(1," ----- Fails to Register \n");
www_challenge("mydomain.com.pe",
"0");
break;
};
# only signed users are allowed
if (!check_to()) {
log(1, "LOG: Hijack!!!--> unsigned user
registration attempt\n");
sl_send_reply("403", "hijack attempt!!!!
Only signed users are allowed");
break;
};
log(1," Registered!!! \n");
if (!save("location")) {
sl_reply_error();
};
break;
};
#For *B2bua: First check the source of the call
#**********************************************
# If the call comes from the gateways, no authentication is required.
if (src_ip==192.168.2.145 || src_ip==192.168.2.132 || src_ip==192.168.2.131) {
log(1,"Call from pstn|*, no authentication is required. \n");
# If the call comes from B2BUA, no authentication is required,
# The first leg of the call has already been authenticated.
} else if (src_ip==192.168.2.130 && src_port==5070) {
log(1,"Call from B2BUA, no authentication is required. \n");
} else {
# We check user credentials
if ((method == "INVITE" || method== "CANCEL" ||
method== "BYE" || method== "ACK") && (!src_ip==192.168.2.130
&& !src_port==5070)){
log(1, "ANALYZING INVITE||CANCEL REQUESTs\n");
if (!proxy_authorize("mydomain.com.pe",
"subscriber")) {
# log(1," ----- Fails to ...proxy_authorize
\n");
proxy_challenge("mydomain.com.pe",
"0");
break;
} else {
if (method == "INVITE" && !check_from()) {
sl_send_reply("403", "Only registered
users are allowed");
log(1," ----> Only registered users are allowed
\n");
break;
};
};
# Not all the users are PREPAID, so we check the database
# to see if the call will be routed through B2BUA.
# If every call is to be routed through B2BUA the "is_user_in"
# conditional is not required.
# Do not use b2bua for local calls
if (is_user_in("From", "prepaidb") &&
uri=~"^sip:00") {
log(1," ----> Usuario PREPAGO!!! enviando a
b2bua... \n");
rewritehostport("192.168.2.130:5070");
t_relay_to_udp("192.168.2.130",
"5070");
break;
};
};# End of if (method == "INVITE" |...
};
/* *********** Dial out to Local and PSTN logic ********* */
# Forward +9n digit requests to gateway Cisco-AS5350 (Celulares):
if(uri=~"^sip:9" ){
log(1," digit expression match - Celulares \n");
if (!is_user_in("from", "movlim")) {
sl_send_reply("403", "No permission for mobile
calls");
acc_db_request("403 Forbidden",
"missed_calls");
break;
};
rewritehostport("192.168.2.145:5060");
route(1);
break;
};
/* ******************************************************************** */
lookup("aliases");
# does the user wish redirection on no availability? (i.e., is he
# in the voicemail group?) -- determine it now and store it in
# flag 4, before we rewrite the flag using UsrLoc
if (is_user_in("Request-URI", "voicemail")) {
log(1, "requested user is in voicemail group \n");
setflag(4);
};
# native SIP destinations are handled using our USRLOC DB:
# LOOKUP (location)!!!!
if (!lookup("location")) {
log(1,"unable to locate user X ... sending to route(4)!
\n");
# handle user which was not found
route(4);
break;
};
### Test if UAS are in the same NAT:
# get the host part of the final uri (IP part) and store it in AVP ID 13
avp_write("$ruri/domain", "i:13");
if (avp_check("i:13","eq/$src_ip/i")) {
log(1, "source IP is the same as destination IP\n");
route(3);
break;
};
avp_delete("i:13/g");
}; # End of "if(uri==myself)"
append_hf("P-hint: usrloc applied\r\n");
route(1);
# if user is on-line and is in Voicemail group, enable redirection
if (method == "INVITE" && isflagset(4)) {
log(1, "invite for voicemail user->initiate
failureroute[1]\n");
t_on_failure("1");
};
}
### ##### ####### ########## - ROUTES - ############### #################
##################
route[1]
{
# if client or server know to be behind a NAT, enable relay
if (isflagset(6)) {
log(1, "Route1: force rtp proxy!!!\n");
force_rtp_proxy();
};
# NAT processing of replies; apply to all transactions (for example,
# re-INVITEs from public to private UA are hard to identify as
# NATed at the moment of request processing); look at replies
t_on_reply("1");
# send it out now; use stateful forwarding as it works reliably
# even for UDP2TCP
if (!t_relay()) {
sl_reply_error();
};
log(1, "Route[1]: Send it out now!!!\n");
break;
}
# !! Nathelper
onreply_route[1] {
# NATed transaction ?
# Not all 2xx messages have a content body so here we
# make sure our Content-Length > 0 to avoid a parse error
if (isflagset(6) && status =~ "(183)|2[0-9][0-9]") {
fix_nated_contact();
if (!search("^Content-Length:\ 0")) {
force_rtp_proxy();
};
# otherwise, is it a transaction behind a NAT and we did not
# know at time of request processing ? (RFC1918 contacts)
} else if (nat_uac_test("1")) {
fix_nated_contact();
};
}
# -------------- SIP-to-PSTN call routed ---------------------
route[2]{
log(1,"route[2]:SIP-to-GW call routed \n");
if(!t_relay()){
sl_reply_error();
};
log(1, "Route[2]: Send it out now!!!\n");
}
# -------------- Same NAT Call Routing (no force rtpproxy) ----
route[3]{
log(1," route[3]: UAs are in the same nat, NO force_rtp_proxy ");
# What do I have to do here?
if(!t_relay()){
sl_reply_error();
};
log(1, "Route[3]: Send it out now!!!\n");
}
# --------------- Handling of Unavailable user ----------------
route[4] {
# non-Voip -- just send "off-line"
if (!(method=="INVITE" || method=="ACK" ||
method=="CANCEL" || method=="BYE" || method=="OPTIONS")) {
sl_send_reply("404", "Not Found");
acc_db_request("404 Not Found", "missed_calls");
log(1, "acc 404 Not Found 1 \n");
break;
};
if (!isflagset(4) && !method=="OPTIONS" &&
!method=="ACK" && !method=="BYE") {
sl_send_reply("404", "Not Found and no voicemail turned on
!! ");
acc_db_request("404 Not Found", "missed_calls");
log(1, " acc 404 Not Found and no voicemail \n");
break;
};
# forward to voicemail adding prefix to simplify asterisk
"extension.conf"
prefix("vm");
acc_db_request("404 Not Found -> Vm", "missed_calls");
rewritehostport("192.168.2.131:5070");
t_relay_to_udp("192.168.2.131", "5070");
}
# if forwarding downstream did not succeed, try voicemail running at Asterisk
failure_route[1]{
if (t_check_status("408")){
# revert_uri (); back to the original URI, makes me loose all
lookup/rewrite stuff
prefix("vm");
rewritehostport ("192.168.2.131:5070");
acc_db_request("408 Timeout -> Vm",
"missed_calls");
append_branch();
t_relay();
break;
} else if (t_check_status("486")){
# revert_uri (); back to the original URI, makes me loose all
lookup/rewrite stuff
prefix("vm");
rewritehostport ("192.168.2.131:5070");
acc_db_request("486 Busy -> Vm",
"missed_calls");
append_branch();
t_relay();
break;
}
}
### The End ###