# Id: ser.cfg # # # ----------- global configuration parameters ------------------------ # debug level debug=2 # this parameters can not be modified through web interface fork=yes log_stderror=no # listen port listen=127.0.0.1 listen= port = 5060 check_via=no dns=no rev_dns=no alias= # ----------------- setting script FLAGS ----------------------------- flags FLAG_ACC : 1, # include message in accouting FLAG_NAT_UAC : 2, # UA will be marked as behind NAT if this ���ag is set FLAG_NAT_UAS : 3, FLAG_FAILUREROUTE : 4; avpflags dialog_cookie; # handled by rr module # ------------------ module loading ---------------------------------- loadmodule "/usr/local/lib/ser/modules/enum.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/textops.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/ctl.so" loadmodule "/usr/local/lib/ser/modules/xmlrpc.so" loadmodule "/usr/local/lib/ser/modules/xlog.so" loadmodule "/usr/local/lib/ser/modules/fifo.so" loadmodule "/usr/local/lib/ser/modules/auth.so" loadmodule "/usr/local/lib/ser/modules/auth_radius.so" loadmodule "/usr/local/lib/ser/modules/exec.so" loadmodule "/usr/local/lib/ser/modules/gflags.so" loadmodule "/usr/local/lib/ser/modules/domain.so" loadmodule "/usr/local/lib/ser/modules/uri_db.so" loadmodule "/usr/local/lib/ser/modules/avp.so" loadmodule "/usr/local/lib/ser/modules/avpops.so" loadmodule "/usr/local/lib/ser/modules/avp_db.so" loadmodule "/usr/local/lib/ser/modules/avp_radius.so" loadmodule "/usr/local/lib/ser/modules/acc_radius.so" loadmodule "/usr/local/lib/ser/modules/nathelper.so" loadmodule "/usr/local/lib/ser/modules/eval.so" loadmodule "/usr/local/lib/ser/modules/lcr.so" loadmodule "/usr/local/lib/ser/modules/db_ops.so" # ----------------- setting module-specific parameters --------------- # specify the path to you database here modparam("avp_db", "db_url", "mysql://::3306/nsp") modparam("domain", "db_url", "mysql://::3306/nsp") modparam("gflags", "db_url", "mysql://::3306/nsp") modparam("usrloc", "db_url", "mysql://::3306/nsp") modparam("uri_db", "db_url", "mysql://::3306/nsp") modparam("lcr", "db_url", "mysql://::3306/nsp") modparam("db_ops", "db_url", "mysql://::3306/nsp") modparam("acc_radius","db_url","mysql://:3306/nsp") # -- usrloc params -- modparam("usrloc", "db_mode", 1) # -- tm params -- # orig 60 sec modparam("tm", "fr_timer", 60000) # orig 45 sec modparam("tm", "fr_inv_timer",120000) # -- auth params -- # -- rr params -- # add value to ;lr param to make some broken UAs happy modparam("rr", "enable_full_lr", 1) # limit the length of the AVP cookie to only necessary ones modparam("rr", "cookie_filter", "(account)") # you probably do not want that someone can simply read and change # the AVP cookie in your Routes, thus should really change this # secret value below modparam("rr", "cookie_secret", "MyRRAVPcookiesecret") # -- gflags params -- # load the global AVPs modparam("gflags", "load_global_attrs", 1) # -- domain params -- # load the domain AVPs modparam("domain", "load_domain_attrs", 1) # -- ctl params -- # listen on tcp, localhost modparam("ctl", "binrpc", "tcp:127.0.0.1:2046") modparam("ctl", "binrpc", "unixs:/tmp/ser_ctl") # listen on the "standard" fifo for backward compatibility modparam("ctl", "fifo", "fifo:/tmp/ser_fifo") # -- acc_db params -- modparam("acc_radius", "log_flag", "FLAG_ACC") modparam("acc_radius", "failed_transactions",yes) modparam("acc_radius", "report_cancels", yes) modparam("acc_radius", "report_ack", 0) modparam("acc_radius", "early_media", 0) modparam("acc_radius", "log_missed_flag", "acc.missed") # --nathelper params -- modparam("nathelper", "natping_interval",30) modparam("nathelper", "ping_nated_only", 1) modparam("nathelper", "rtpproxy_sock", "udp::22222=1 udp::22222=1 ") # --registrar params -- modparam("registrar", "default_expires", 600) # precedentemente a 180 - mod 23.12.08 Simone modparam("registrar", "min_expires", 300) # precedentemente a 180 - mod 23.12.08 Simone modparam("registrar", "max_expires", 3600) # precedentemente a 240 - mod 23.12.08 Simone modparam("registrar", "max_contacts", 10) modparam("registrar", "save_nat_flag", "FLAG_NAT_UAC") modparam("registrar", "load_nat_flag", "FLAG_NAT_UAS") # --radius params -- modparam("auth_radius","service_type",15) modparam("auth_radius", "radius_config","/usr/local/etc/radiusclient-ng/radiusclient.conf") modparam("acc_radius", "radius_config","/usr/local/etc/radiusclient-ng/radiusclient.conf") modparam("avp_radius", "radius_config","/usr/local/etc/radiusclient-ng/radiusclient.conf") # --lcr params -- #modparam("lcr","fr_inv_timer_avp","fr_inv_timer_avp") #modparam("lcr","rpid_avp","rpid") modparam("lcr","fr_inv_timer",90) modparam("lcr","fr_inv_timer_next",30) # --dbops -- modparam("db_ops", "declare_query", "select/user_attrs/value/uid,name///%$from,prepaid"); # ------------------------- request routing logic ------------------- # main routing logic route{ $domain_default=''; $voicemail=1; # as soon as it is save to distinguish HTTP from SIP # we can un-comment the next line route(RPC); # first do some initial sanity checks route(INIT); # check if the request is routed via Route header or # needs a Record-Route header route(RR); # check if the request come from a SIP-PSTN gateway route(GW_ACL); # # check if the request belongs to our proxy route(DOMAIN); # NAT detection comes here, this section sets flag FLAG_NAT_UAC route(NAT_DETECT); # handle REGISTER requests route(REGISTRAR); # from here on we want to know you is calling route(AUTHENTICATION); # check if we should be outbound proxy for a local user route(OUTBOUND); # check if the request is for a local user route(INBOUND); # check usrloc DB route(LOCATION); # here you coud for example try to an ENUM lookup before # the call gets routed to the PSTN # lets see if someone wants to call a PSTN number route(PSTN); # nothing matched, reject it finally sl_send_reply("404", "No route matched"); } failure_route[FAILURE_ROUTE] { xlog("L_INFO", "LXLOG FAILURE_ROUTE: Init\n"); # mark for the other routes that we are operating from here on from a # failure route #load_attrs("$tr", "$tr.uid"); setflag(FLAG_FAILUREROUTE); if (t_check_status("486|600")) { xlog("L_INFO", "LXLOG FAILURE_ROUTE: forward busy"); # if we received a busy and a busy target is set, forward it here # Note: again the forwarding target has to be a routeable URI if ($tr.forward_busy){ if($voicemail && $tr.forward_busy=="voicemail" ){ append_branch(); xlog("L_INFO", "LXLOG FAILURE_ROUTE: forward busy to voicemail"); route(VOICEMAIL); } else { xlog("L_INFO", "LXLOG FAILURE_ROUTE: forward busy to b2bua"); del_attr("$tr.uid"); attr2uri("$tr.forward_busy"); del_attr("$tr.forward_busy"); $tu.uid=$tu.uid_busy; del_attr("$tu.uid_busy"); append_branch(); rewritehostport(":5081"); t_relay_to_udp("","5081"); drop; } } } if (t_check_status("408|480")) { if ($tr.forward_no_answer) { if($voicemail && $tr.forward_no_answer=="voicemail"){ append_branch(); xlog("L_INFO", "LXLOG FAILURE_ROUTE: forward no_answret to voicemail"); route(VOICEMAIL); } else { xlog("L_INFO", "LXLOG FAILURE ROUTE: forward no answer to b2bua"); del_attr("$tr.uid"); attr2uri("$tr.forward_no_answer"); $tu.uid=$tu.uid_no_answer; del_attr("$tr.forward_no_answer"); del_attr("$tu.uid_no_answer"); append_branch(); rewritehostport(":5081"); t_relay_to_udp("","5081"); drop; } } } } failure_route["FAILURE_PSTN"] { xlog("L_INFO", "LXLOG FAILURE_PSTN: Init\n"); # ----------------------------------------------------------------- # Find Next Available Gateway # ----------------------------------------------------------------- if (method == "INVITE" && t_check_status("404|408|500|503")) { if(!next_gw()){ xlog("L_INFO", "LXLOG FAILURE_PSTN: Service not available, no more gateways found"); t_reply("503", "Service not available, no more gateways found"); break; } $failure_gw=1; t_on_failure("FAILURE_PSTN"); route(FORWARD); } } route [GW_ACL] { xlog("L_INFO", "LXLOG GW_ACL: Init\n"); if(from_gw()) { xlog("L_INFO","LXLOG GW_ACL: from_gw"); attr2uri("$domain_default","domain"); $from_gw=1; } else { $from_gw=0; } } route[VOICEMAIL] { xlog("L_INFO", "LXLOG VOICEMAIL: Init\n"); setflag(FLAG_ACC); rewritehostport(":5080"); t_relay_to_udp("","5080"); drop; } route[FORWARD] { xlog("L_INFO","LXLOG FORWARD: Init"); del_attr("$fu.anonymous"); del_attr("$fu.rpid"); load_attrs("$fu", "$f.uid"); if($fu.rpid){ xlog("L_INFO","LXLOG FORWARD calleer is an alias"); $asserted_id=$f.rpid; if($f.to_gw ){ if(!$fu.anonymous) { xlog("L_INFO","LXLOG FORWARD alias set gw"); xlset_attr("$rpidheader", " %$asserted_id ;party=calling;privacy=no;screen=yes"); replace_attr_hf("Remote-Party-ID", "$rpidheader"); } } else { if(!$fu.anonymous) { xlog("L_INFO","LXLOG FORWARD alias set voip"); #xlset_attr("$rpidheader", " %$asserted_id ;party=calling;privacy=no;screen=yes"); #replace_attr_hf("Remote-Party-ID", "$rpidheader"); append_hf("P-Asserted-Identity: \r\n"); } } } if($fu.anonymous=="1"){ xlog("L_INFO","LXLOG FORWARD anonymous set"); if($f.to_gw){ xlog("L_INFO","LXLOG FORWARD anonymous set gw"); $asserted_id=$f.authuid; $an='"Anonymous"'; xlset_attr("$rpidanon", " %$an ;party=calling;privacy=full;screen=yes"); replace_attr_hf("Remote-Party-ID", "$rpidanon"); } else { xlog("L_INFO","LXLOG FORWARD anonymous set voip"); $an='"Anonymous"'; # xlset_attr("$rpidanon", " %$an ;party=calling;id-type=subscriber;screen=yes;privacy=full"); # replace_attr_hf("Remote-Party-ID", "$rpidanon"); append_hf("P-Asserted-Identity: \r\n"); } } # if (!lookup_contacts("location")) { # xlog("L_INFO","LXLOG: FORWARD: !lookup_contacts"); # sl_reply("483", "Temporarily Unavailable"); # xlog("L_INFO","LXLOG: FORWARD: 483 - Callee temporarily unavailable"); # drop; # } if (isflagset("FLAG_NAT_UAS")){ xlog("L_INFO","LXLOG FORWARD: callee is behind NAT - setting t.nat = true"); $t.nat = true; } else { $t.nat = false; xlog("L_INFO","LXLOG FORWARD: callee is not behind NAT - setting t.nat = false"); } if(!$failure_gw){ route("NAT_MANGLE"); t_on_reply("NAT_MANGLE"); } # if record routed store following AVPs to Record Route header if ($record_route) { setavpflag("$f.nat", "dialog_cookie"); setavpflag("$t.nat", "dialog_cookie"); setavpflag("$rtpproxy", "dialog_cookie"); setavpflag("$con_realm", "dialog_cookie"); setavpflag("$rtp_proxy_node", "dialog_cookie"); setavpflag("$f.comedia", "dialog_cookie"); setavpflag("$t.comedia", "dialog_cookie"); xlog("L_INFO","LXLOG FORWARD: $record_route"); record_route(); } # if this is called from the failure route we need to open a new branch if (isflagset(FLAG_FAILUREROUTE)) { xlog("L_INFO","LXLOG FORWARD: failure flag is set"); append_branch(); } # if this is an INVITE we might try another # (forwarding or voicemail) target after receiving an error if (method=="INVITE" && !$to_gw){ xlog("L_INFO","LXLOG FORWARD: set_failure_route"); t_on_failure("FAILURE_ROUTE"); } # send it out now; use stateful forwarding as it works reliably # even for UDP2TCP if (!t_relay()) { xlog("L_INFO","LXLOG FORWARD: !t_relay"); sl_reply_error(); }; drop; } route[INIT] { xlog("L_INFO","LXLOG INIT: Init"); # initial sanity checks -- messages with # max_forwards==0, or excessively long requests if (method=="INVITE") { xlog("L_INFO","LXLOG INIT:INVITE!!!!!!!!"); # DENY T.38 static if(search("(a|A)=(t|T)38")){ xlog("L_ERR","LXLOG INIT: T38 not supported"); sl_send_reply("488","Not Acceptable Here"); drop; } } if (!mf_process_maxfwd_header("10")) { sl_send_reply("483","Too Many Hops"); xlog("L_INFO","LXLOG INIT: 483 Too Many Hops"); drop; }; if (msg:len >= max_len ) { sl_send_reply("513", "Message too big"); xlog("L_INFO","LXLOG INIT: 513 Message too big"); drop; }; # you could add some NAT detection here for example # or you cuold call here some of the check from the sanity module # lookup("aliases"); # lets account all initial INVITEs and the BYEs - e i CANCEL (Simone) 20091028 if ((method=="INVITE" && (!@to.tag || @to.tag=="")) || method=="BYE" || method=="CANCEL") { setflag(FLAG_ACC); xlog("L_INFO","LXLOG: INIT: setflag(FLAG_ACC)"); } } route[RPC] { xlog("L_INFO","LXLOG RPC: Init"); # allow XMLRPC from localhost if ((method=="POST" || method=="GET") && src_ip==127.0.0.1) { #if ((method=="POST" || method=="GET")) { if (msg:len >= 8192) { sl_send_reply("513", "Request too big"); drop; } # lets see if a module want to answer this dispatch_rpc(); drop; } } route[RR] { xlog("L_INFO","LXLOG RR: Init"); # subsequent messages withing a dialog should take the # path determined by record-routing # Commentato da indicazioni di NetResults, sostituito con la sottostante - 20090716 Simone ## if (loose_route() && method!=INVITE) { if ( (loose_route() && method!=INVITE) || method==ACK ) { # mark routing logic in request append_hf("P-hint: rr-enforced\r\n"); xlog("L_ERR","LXLOG RR: loose route"); # if the Route contained the accounting AVP cookie we # set the accounting flag for the acc_db module. # this is more for demonstration purpose as this could # also be solved without RR cookies. # Note: this means all in-dialog request will show up in the # accouting tables, so prepare your accounting software for this ;-) if (($account == "yes")&&(method!=PRACK)) { setflag(FLAG_ACC); xlog("L_INFO","LXLOG RR: setflag(FLAG_ACC)"); } # for broken devices which overwrite their Route's with each # (not present) RR from within dialog requests it is better # to repeat the RRing and if we call rr after loose_route # the AVP cookies are restored automatically :) record_route(); route(FORWARD); } else if (!method=="REGISTER") { xlog("L_INFO","LXLOG RR: !method==REGISTER "); # we 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 the inital INVITE got the ACC flag store this in # an RR AVP cookie. this is more for demonstration purpose if (isflagset(FLAG_ACC)) { $account = "yes"; setavpflag($account, "dialog_cookie"); xlog("L_INFO","LXLOG RR: setflag(FLAG_ACC) dialog_cookie"); } record_route(); } } route[DOMAIN] { xlog("L_INFO","LXLOG DOMAIN: Init"); if ($from_gw) { xlog("L_INFO","LXLOG DOMAIN: SIP message from gateway SIP-PSTN"); break; } # check if the caller is from a local domain lookup_domain("$fd", "@from.uri.host"); # check if the callee is at a local domain lookup_domain("$td", "@to.uri.host"); # we dont know the domain of the caller and also not # the domain of the callee -> somone uses our proxy as # a relay # commentato per FAX if (!$t.did && !$f.did) { xlog("L_INFO","LXLOG DOMAIN: 403 Relaying Forbidden"); sl_send_reply("403", "Relaying Forbidden"); drop; } } route[REGISTRAR] { xlog("L_INFO","LXLOG REGISTRAR: Init"); # if the request is a REGISTER lets take care of it if (method=="REGISTER") { # check if the REGISTER if for one of our local domains if (!$t.did) { xlog("L_INFO","LXLOG REGISTRAR: Register forwarding forbidden"); sl_send_reply("403", "Register forwarding forbidden"); drop; } # we want only authenticated users to be registered if (!radius_www_authorize("$fd.digest_realm")) { xlog("L_INFO","LXLOG REGISTRAR: !radius_www_authorize"); if ($? == -2) { xlog("L_INFO","LXLOG REGISTRAR: 500 Internal Server Error"); sl_send_reply("500", "Internal Server Error"); } else if ($? == -3) { xlog("L_INFO","LXLOG REGISTRAR: 400 Bad Request"); sl_send_reply("400", "Bad Request"); } else { if ($digest_challenge) { xlog("L_INFO","LXLOG REGISTRAR: append_to_reply digest_challenge"); append_to_reply("%$digest_challenge"); } sl_send_reply("401", "Unauthorized"); xlog("L_INFO","LXLOG REGISTRAR: 401 Unauthorized"); } drop; }; # check if the authenticated user is the same as the target user if (!lookup_user("$t.uid", "@to.uri")) { #TO BE CHECKED #sl_send_reply("404", "Unknown user in To"); #xlog("L_INFO","LXLOG REGISTRAR: 404 Unknown user in To %tu"); #drop; xlog("L_INFO","LXLOG REGISTRAR: Warning user in To %tu"); } if ($f.uid != $t.uid) { xlog("L_INFO","LXLOG REGISTRAR: 403 Authentication and To-Header mismatch"); sl_send_reply("403", "Authentication and To-Header mismatch"); drop; } # check if the authenticated user is the same as the request originator # you may uncomment it if you care, what uri is in From header # if (!lookup_user("$f.uid", "@from.uri")) { # sl_send_reply("404", "Unknown user in From"); # drop; # } # if ($f.uid != $t.uid) { # sl_send_reply("403", "Authentication and From-Header mismatch"); # drop; # } # everyhting is fine so lets store the binding save_contacts("location"); drop; }; } route[AUTHENTICATION] { xlog("L_INFO","LXLOG AUTHENTICATION: Init"); if ($from_gw) { xlog("L_INFO","LXLOG AUTHENTICATION: SIP message from gateway SIP-PSTN"); break; } if (src_ip=="") { xlog("L_INFO","LXLOG AUTHENTICATION: SIP message from asterisk b2bua"); break; } # per prepagato if (src_ip=="") { xlog("L_INFO","LXLOG AUTHENTICATION: SIP message from asterisk prepaid"); break; } $fromuser=@from.uri.user; $fromhost=@from.uri.host; $at="@"; xlset_attr("$from","%$fromuser%$at%$fromhost"); if (method=="INVITE" && @db.query[0]=='1'){ if (nat_uac_test("3")) { fix_nated_contact(); } xlog("L_INFO","LXLOG AUTHENTICATION: Utente PREPAID passato ad Asterisk"); t_relay_to_udp("","5090"); drop; } # fine prepagato # per interception if (method=="CANCEL" || method=="ACK") { # you are not allowed to challenge these methods xlog("L_INFO","LXLOG AUTHENTICATION: method==CANCEL || method==ACK"); break; } # requests from non-local to local domains should be permitted # remove this if you want a walled garden #if (! $f.did) { # xlog("L_INFO","LXLOG AUTHENTICATION: requests from non-local to local domains not permitted"); # break; # } # as gateways are usually not able to authenticate for their # requests you will have trust them base on some other information # like the source IP address. WARNING: if at all this is only safe # in a local network!!! #if (src_ip==a.b.c.d) { # break; # } if (!radius_proxy_authorize("$domain_default")) { xlog("L_INFO","LXLOG AUTHENTICATION: !proxy_authenticate"); if ($? == -2) { sl_send_reply("500", "Internal Server Error"); xlog("L_INFO","LXLOG AUTHENTICATION: 500 Internal Server Error"); } else if ($? == -3) { xlog("L_INFO","LXLOG AUTHENTICATION: 400 Bad Request"); sl_send_reply("400", "Bad Request"); } else { if ($digest_challenge) { append_to_reply("%$digest_challenge"); xlog("L_INFO","LXLOG AUTHENTICATION: append_to_reply %$digest_challenge"); } sl_send_reply("407", "Proxy Authentication Required"); xlog("L_INFO","LXLOG AUTHENTICATION: 407 Proxy Authentication Required"); } drop; } # check if the UID from the authentication meets the From header $authuid = $uid; if (!lookup_user("$f.uid", "@from.uri")) { #del_attr("$uid"); xlog("L_INFO","LXLOG AUTHENTICATION: check if the UID from the authentication meets the From header"); } if ($fr.uid != $fr.authuid) { sl_send_reply("403", "Fake Identity"); xlog("L_INFO","LXLOG AUTHENTICATION: 403 Fake Identity"); drop; } # load the user AVPs (preferences) of the caller, e.g. for RPID header load_attrs("$fu", "$f.uid"); } route[NAT_DETECT]{ xlog("L_INFO","LXLOG NAT_DETECT: Init"); # Skip spiralling requets if (src_ip == 127.0.0.1) return; # Skip requests that already passed a proxy if (is_present_hf("^Record-Route:")) { xlog("L_INFO","LXLOG NAT_DETECT: is_present_hf Record-Route"); return; } # 2010.09.10 - force nat VPN MPLS - Simone if ( (nat_uac_test("3")) || (src_ip == 7.17.0.0/12) ) { xlog("L_INFO","LXLOG NAT_DETECT: nat_uac_test(3): force_rport & setflag FLAG_NAT_UAC"); force_rport(); setflag("FLAG_NAT_UAC"); $f.nat = true; } else { $f.nat = false; xlog("L_INFO","LXLOG NAT_DETECT: nat_uac_test(3) false"); } return; } route[OUTBOUND] { xlog("L_INFO","LXLOG OUTBOUND: Init"); # if a local user calls to a foreign domain we play outbound proxy for him # comment this out if you want a walled garden if ($f.did && ! $t.did) { xlog("L_INFO","LXLOG OUTBOUND: calls to a foreign domain we play outbound proxy!"); append_hf("P-hint: outbound\r\n"); route(FORWARD); } } route[INBOUND] { xlog("L_INFO","LXLOG INBOUND: Init"); # lets see if know the callee if (lookup_user("$t.uid", "@ruri") || $from_gw) { xlog("L_INFO","LXLOG INBOUND: lets see if know the callee"); # load the preferences of the callee to have his timeout values loaded load_attrs("$tu", "$t.uid"); lookup_user("Request-URI"); #FIX per ruri_canocical con GW if ($from_gw==1) { xlog("L_INFO","LXLOG INBOUND: from gw"); del_attr("$tu.uid_blind"); del_attr("$tu.uid_no_answer"); del_attr("$tu.uid_busy"); del_attr("$tu.call_forward"); } if ($tu.ruri_canonical ) { xlog("L_INFO","LXLOG INBOUND: callee username is canonical"); del_attr("$tu.uid"); load_attrs("$tr","@ruri"); } else { # if the alias URI has different AVPs/preferences # you can load them into the URI track like this xlog("L_INFO","LXLOG INBOUND: callee username is an alias"); #caricare attributo alias per settare tu.uid per la location $ruriuser= @ruri.user; $rurihost=""; $at2="@"; xlset_attr("$ruri_no_sip","%$ruriuser%$at2%$rurihost"); xlog("L_INFO", "LXLOG %ruri_no_sip"); load_attrs("$tu", "$ruri_no_sip"); $tu.uid=$tu.alias; #caricare gli attributi nella uri_attrs dell'uri corrispondente alias xlset_attr("$ruri_sip", "sip:%$t.uid"); $tu.uid=$tu.alias; attr2uri("$ruri_sip"); load_attrs("$tr","$ruri_sip"); del_attr("$ruri_no_sip"); del_attr("$ruri_sip"); del_attr("$ruriuser"); del_attr("$rurihost"); del_attr("$at2"); } #if ($tu.call_forward == "blind" if( $tr.forward_blind ) { xlog("L_INFO", "LXLOG INBOUND: blind forward"); if ($voicemail && $tr.forward_blind=="voicemail"){ xlog("L_INFO","L_XLOG voicemail"); route(VOICEMAIL); } else { xlog("L_INFO", "LXLOG INBOUND: forward blind to b2bua"); del_attr("$tr.uid"); del_attr("$tu.call_forward"); attr2uri("$tr.forward_blind"); del_attr("$tr.forward_blind"); $tu.uid=$tu.uid_blind; del_attr("$tu.uid_blind"); rewritehostport(":5081"); t_relay_to_udp("","5081"); drop; } } } route(LOCATION); } route[LOCATION] { # native SIP destinations are handled using our USRLOC DB xlog("L_INFO","LXLOG LOCATION: Init"); if (lookup_user("$t.uid", "@ruri") || $from_gw) { if (lookup_contacts("location")) { xlog("L_INFO","LXLOG <%ru> request uri <%nh>"); append_hf("P-hint: usrloc applied\r\n"); xlog("L_INFO","LXLOG LOCATION: lookup_contacts(location)"); # we set the TM module timers according to the prefences # of the callee (avoid too long ringing of his phones) # Note1: timer values have to be in ms now! # Note2: this makes even more sense if you switch to a voicemail # in a FAILURE route if ($t.fr_inv_timer) { t_set_fr("$t.fr_inv_timer"); }; route(FORWARD); } #else if ($tu.call_forward == "not_registered" && $tr.forward_not_registered) { else if ($tr.forward_not_registered) { xlog("L_INFO", "LXLOG LOCATION: not_registered forward"); if($voicemail && $tr.forward_not_registered=="voicemail"){ xlog("L_INFO","LX_LOG voicemail not registered"); route(VOICEMAIL); } else { xlog("L_INFO", "LXLOG INBOUND CALL FORWARD TO PSTN"); del_attr("$tr.uid"); del_attr("$tu.call_forward"); attr2uri("$tr.forward_not_registered"); del_attr("$tr.forward_not_registered"); $tu.uid=$tu.uid_not_registered; del_attr("$tu.uid_not_registered"); rewritehostport(":5081"); t_relay_to_udp("","5081"); drop; }; } else { xlog("L_INFO","LXLOG LOCATION: 480 User temporarily not available"); sl_send_reply("480", "User temporarily not available"); drop; }; } } route[PSTN] { xlog("L_INFO","LXLOG PSTN: Init"); # Only if the AVP 'gw_ip' is set and the request URI contains # only a number we consider sending this to the PSTN GW. # Only users from a local domain are permitted to make calls. # Additionally you might want to check the acl AVP to verify # that the user is allowed to make such expensives calls. $pstn_flag="1"; if($pstn_flag) { #if ($pstn_flag && uri=~"sips?:\+?[0-9]{3,18}@.*") { # Test numeri consentiti # # # if (uri=~"^sip:6101[0-9]{3,12}@") { if (uri=~"^sip:6101[0-9]{1,20}@") { xlog("L_DBG","AK-LOG: segnalazione sip 6101xxxx"); # xlog("L_INFO","LXLOG PSTN: segnalazione sip 6101xxxx"); # route(LCR); # break; # subst_user('/^6101([0-9]+)/\1/'); subst_uri('/^sip:6101([0-9]+)@(.*)$/sip:\1@\2/ig'); } # # if (uri=~"^sip:0[0-9]{5,10}@" || uri=~"^sip:00[0-9]{9,14}@") { xlog("L_INFO","LXLOG PSTN: telefonia fissa nazionale e internazionale"); route(LCR); break; } # # Test 800 e 803 # if (uri=~"^sip:800[0-9]{6}@" || uri=~"^sip:803[0-9]{3}@") { xlog("L_INFO","LXLOG PSTN: numeri 800 e 803"); route(LCR); break; } # # Test 899, poi bloccati da PGW # if (uri=~"^sip:899[0-9]{6}@") { xlog("L_INFO","LXLOG PSTN: numeri 899"); route(LCR); break; } # # Test 848 e 15xx (1500, 1515, 1518, 1530) # if (uri=~"^sip:848[0-9]{6}@" || uri=~"^sip:15[0-9]{2}@") { xlog("L_INFO","LXLOG PSTN: numeri 848 e 15xxx"); route(LCR); break; } # # Test per numeri 840 e 841 # if (uri=~"^sip:840[0-9]{6}@" || uri=~"^sip:841[0-9]{6}@") { xlog("L_INFO","LXLOG PSTN: numeri 848 e 15xxx"); route(LCR); break; } # # Test # if (uri=~"^sip:3[0-9]{8,10}@") { xlog("L_INFO","LXLOG PSTN: cellulari"); route(LCR); break; } # # if (uri=~"^sip:116000@") { xlog("L_INFO","LXLOG PSTN: 116000 - Linea diretta minori scomparsi"); route(LCR); break; } # # Test e trattamento per numeri di emergenza # if (uri=~"^sip:11[0-9]{1}@") { exec_msg("cat > /tmp/11xTEXT.txt"); if (exec_dset("/bin/cat /tmp/11xTEXT.txt | /root/scripts/ser/redir11x ")) { route(LCR); break; } } sl_send_reply("404", "Not Authorized to call this number"); break; } } route[LCR] { if(!load_gws()){ xlog("L_INFO","LXLOG PSTN Internal server error, unable to load gateways "); sl_send_reply("500", "Internal server error, unable to load gateways"); break; } if(!next_gw()){ xlog("L_INFO","LXLOG PSTN Service not available, no gateways found"); sl_send_reply("503", "Service not available, no gateways found"); break; } else { xlog("L_INFO","LXLOG PSTN next gw "); if($fu.anonymous!= "1"){ xlog("L_INFO", "LXLOG PSTN not anoymous user Rpid change"); $rpid_user=@from.uri.user; $rpid_uri=@from.uri; xlset_attr("$rpid2"," %$rpid_user <%$rpid_uri;user=phone>;party=calling;screen=no;privacy=off"); replace_attr_hf("Remote-Party-ID", "$rpid2"); } t_on_failure("FAILURE_PSTN"); $to_gw=1; route(FORWARD); }; } # This block does whatever is necessary to make UAS behind NAT # reachable, that includes rewriting contact and forcing RTP # proxy if necessary. The logic in this block is base on # the value of FLAG_NAT_UAC and FLAG_NAT_UAS flags onreply_route[NAT_MANGLE] { xlog("L_INFO","LXLOG onreply_route NAT_MANGLE: Init"); # Rewrite Contact in 200 OK if UAS is behind NAT if ($t.nat || $tr.nat) { xlog("L_INFO","LXLOG onreply_route NAT_MANGLE: fixing NATed contact"); fix_nated_contact(); } # Apply RTP proxy if necessary, but only for INVITE transactions # and 183 or 2xx replie if (!$f.nat && (!$t.nat || !$tr.nat)) { xlog("L_INFO","LXLOG onreply_route NAT_MANGLE: !$f.nat && (!$t.nat || !$tr.nat)"); return; } # checks if both UAC and UAS are in the same connectivity realm if ($con_realm || $tr.con_realm) { xlog("L_INFO","LXLOG onreply_route NAT_MANGLE: $con_realm || $tr.con_realm"); return; } if (@cseq.method != "INVITE") { xlog("L_INFO","LXLOG onreply_route NAT_MANGLE: @cseq.method != INVITE"); return; } if ((status =~ "(183)|2[0-9][0-9]") && !search("^Content-Length: 0")) { xlog("L_INFO","LXLOG onreply_route NAT_MANGLE: status =~ (183)|2[0-9][0-9]"); if (!$rtpproxy && !$tr.rtpproxy) { xlog("L_INFO","LXLOG onreply_route NAT_MANGLE: UA supports symmettric RTP and passive role"); if ($t.nat || $tr.nat) { xlog("L_INFO","LXLOG onreply_route NAT_MANGLE: fix_nated_sdp"); fix_nated_sdp("8"); return; } else { xlog("L_INFO","LXLOG onreply_route NAT_MANGLE: not fix_nated_sdp"); return; } } force_rtp_proxy(); } return; } # This block does whatever is necessary to make UACs behind NAT # reachable, that includes rewriting contact and forcing RTP # proxy if necessary. The logic in this block is based on # the value of FLAG_NAT_UAC and FLAG_NAT_UAS flags # route[NAT_MANGLE] { xlog("L_INFO","LXLOG NAT_MANGLE: Init"); # Rewrite Contact if the UAC is behind NAT if ($f.nat) { if (method == "REGISTER") { xlog("L_INFO","LXLOG NAT_MANGLE: fix_nated_register"); fix_nated_register(); } else { fix_nated_contact(); xlog("L_INFO","LXLOG NAT_MANGLE: fix_nated_contact"); } } # AVP $rtp_proxy_node is stored in Record-Route HF and in URI CLASS # If this AVP attribute appears in this TO URI CLASS then it must be checked # by $tr.rtpproxy #if (($tr.rtpproxy || $fr.rtpproxy) && (method == "BYE" || method == "CANCEL")) { if ((method == "BYE" || method == "CANCEL")) { xlog("L_INFO","LXLOG NAT_MANGLE: BYE or CANCEL - unforcing RTP proxy"); unforce_rtp_proxy(); } else if (method == "INVITE") { xlog("L_INFO","LXLOG NAT_MANGLE: INVITE"); # If either UAC or UAS is behind NAT then go on # if (!$f.nat && (!$t.nat || !$tr.nat)) { xlog("L_INFO","LXLOG NAT_MANGLE: !$f.nat && (!$t.nat || !$tr.nat)"); return; } # Force record routing if either party is behind NAT $record_route = true; # Checks if both UAC and UAS are in the same # connectivity realm if ($con_realm || $tr.con_realm) { xlog("L_INFO","LXLOG NAT_MANGLE: Checks if both UAC and UAS are in the same realm"); return; } if ($f.connectivity_realm == $t.connectivity_realm) { xlog("L_INFO","LXLOG NAT_MANGLE: reguest message - is not in connectivity realm"); $con_realm = true; return; } # Checking if one UA is behind NAT and its peer # in public supports symmetric RTP and passive attribute if (($f.sym_pass || $fr.comedia) && ($t.nat || $tr.nat) && !$f.nat) { $f.comedia = $f.sym_pass; xlog("L_INFO","LXLOG NAT_MANGLE: Caller supports sym_pass and callee is behind NAT"); return; } if (($t.sym_pass || $tr.comedia) && $f.nat && (!$t.nat || !$tr.nat)) { $t.comedia = $t.sym_pass; fix_nated_sdp("8"); xlog("L_INFO","LXLOG NAT_MANGLE: Caller is behind NAT and callee supports sym_pass"); xlog("L_INFO","LXLOG NAT_MANGLE: Appending passive attr to INVITE for public UA"); return; } # This section is for re-INVITEs : If RTP proxy was forced during initiating # a new call then here is performed a check for flags $rtpproxy and $rtp_proxy_node. # This will use the same RTP proxy as was chosen while initiating the call. # Parameter L performs lookup which only rewrite SDP when # corresponding session is already existing in RTP proxy. # Parameter N followed by AVP attribute is stored index(integer) of a particular # RTP proxy defined at the beginning of this script in modparam if ($tr.rtpproxy || $rtpproxy) { xlog("L_INFO","LXLOG NAT_MANGLE: INVITE - rewriting IP and port in SDP - force_rtp_proxy"); force_rtp_proxy(); } # For initial call: sets the rtpproxy attribute to true and assign different AVP attribute # for RTP_proxy_node to make sure it is stored in Record-Route HF # $node comes from user_attrs table else { xlog("L_INFO","LXLOG NAT_MANGLE: For initial call: sets the rtpproxy attribute to true and assign different AVP for rtpproxy"); $rtpproxy = true; force_rtp_proxy(); } } return 1; }