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: http://openser.org/dokuwiki/doku.php?id=avp_examples
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: openser.org, iptel.org and onsip.org. 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@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@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 ###