Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #
- # $Id: opensips.cfg 7027 2010-07-15 13:48:29Z razvancrainea $
- #
- # OpenSIPS basic configuration script
- # by Anca Vamanu <anca@voice-system.ro>
- #
- # Please refer to the Core CookBook at:
- # http://www.opensips.org/index.php?n=Resources.DocsCookbooks
- # for a explanation of possible statements, functions and parameters.
- #
- ####### Global Parameters #########
- log_stderror=no
- log_facility=LOG_LOCAL0
- fork=yes
- children=4
- /* uncomment the following lines to enable debugging */
- #debug=6
- debug=3
- /* uncomment the next line to disable the auto discovery of local aliases
- based on revers DNS on IPs (default on) */
- auto_aliases=no
- # change the listen-opensips and advertised-opensips values in the defines.m4 file
- listen=udp:REAL_IP:REAL_PORT
- listen=tcp:REAL_IP:REAL_PORT
- advertised_address=VIRTUAL_IP
- advertised_port=VIRTUAL_PORT
- server_header="Server: SoftSwitch_G9"
- user_agent_header="User-Agent: SoftSwitch_G9"
- ####### Modules Section ########
- #set module path
- mpath="//lib/opensips/modules/"
- /* uncomment next line for MySQL DB support */
- loadmodule "db_mysql.so"
- loadmodule "signaling.so"
- loadmodule "sl.so"
- loadmodule "tm.so"
- loadmodule "rr.so"
- loadmodule "maxfwd.so"
- loadmodule "usrloc.so"
- loadmodule "registrar.so"
- loadmodule "textops.so"
- loadmodule "mi_fifo.so"
- loadmodule "uri.so"
- loadmodule "auth.so"
- loadmodule "auth_db.so"
- loadmodule "domain.so"
- loadmodule "avpops.so"
- loadmodule "dialog.so"
- loadmodule "alias_db.so"
- loadmodule "drouting.so"
- loadmodule "uac.so"
- loadmodule "nat_traversal.so"
- loadmodule "nathelper.so"
- loadmodule "siptrace.so"
- loadmodule "sst.so"
- # loadmodule "perl.so"
- # ----------------- setting module-specific parameters ---------------
- # ----- perl params -----
- # modparam("perl", "filename", "/etc/opensips/scripts/perlfunctions.pl")
- # modparam("perl", "modpath", "/lib/opensips/perl/")
- # ----- sst params -----
- modparam("sst", "min_se", 300) # 1800
- modparam("sst", "timeout_avp", "$avp(s:timeout_sst)")
- modparam("sst", "sst_flag", 13)
- modparam("sst", "reject_to_small", 1)
- # ----- dialog params ------
- modparam("dialog", "profiles_with_value", "accountcalls")
- modparam("dialog", "dlg_match_mode", 1)
- modparam("dialog", "default_timeout", 10800)
- modparam("dialog", "timeout_avp", "$avp(s:timeout_sst)")
- modparam("dialog", "dlg_flag", 12)
- modparam("dialog", "bye_on_timeout_flag", 15)
- # ----- siptrace params -----
- modparam("siptrace", "trace_on", 1)
- modparam("siptrace", "trace_flag", 22)
- modparam("siptrace", "db_url", "mysql://opensips:opensipsrw@localhost/opensips")
- # ----- nathelper params -----
- #This will do a SIP ping to the devices via SIP OPTIONS messages.
- #The value of the response (negative or positive) doesn't matter, although it does matter if you get the response.
- modparam("nathelper", "natping_interval", 60)
- modparam("nathelper", "ping_nated_only", 0)
- modparam("nathelper", "sipping_bflag", 7)
- modparam("nathelper", "sipping_from", "<sip:NAME@VIRTUAL_DOMAIN>")
- modparam("nathelper", "sipping_method", "OPTIONS")
- modparam("nathelper", "received_avp", "$avp(s:rcv)")
- # ----- registrar params
- modparam("registrar", "received_avp", "$avp(s:rcv)")
- # ----- tm params -----
- modparam("tm", "fr_inv_timer_avp", "$avp(s:custom_fr_inv_timer)")
- modparam("tm", "pass_provisional_replies", 1)
- # ----- drouting params ------
- modparam("drouting", "db_url", "mysql://opensips:opensipsrw@localhost/opensips")
- modparam("drouting", "use_domain", 0)
- modparam("drouting", "probing_interval", 60)
- modparam("drouting", "probing_from", "sip:NAME@REAL_IP")
- modparam("drouting", "probing_method", "OPTIONS")
- modparam("drouting", "probing_reply_codes", "501, 403, 404")
- # ----- avpops params ------
- modparam("avpops", "db_url", "mysql://opensips:opensipsrw@localhost/opensips")
- # ----- mi_fifo params -----
- modparam("mi_fifo", "fifo_name", "/tmp/opensips_fifo")
- modparam("mi_fifo", "fifo_mode", 0666)
- # ----- rr params -----
- # add value to ;lr param to cope with most of the UAs
- modparam("rr", "enable_full_lr", 1)
- # do not append from tag to the RR (no need for this script)
- modparam("rr", "append_fromtag", 1)
- # ----- usrloc params -----
- modparam("usrloc", "desc_time_order", 1)
- modparam("usrloc", "db_mode", 3)
- modparam("usrloc", "nat_bflag", 7)
- modparam("usrloc", "db_url", "mysql://opensips:opensipsrw@localhost/opensips")
- # ----- uri params -----
- modparam("uri", "use_uri_table", 0)
- # ----- auth_db params -----
- /* uncomment the following lines if you want to enable the DB based authentication */
- modparam("auth_db", "calculate_ha1", yes)
- modparam("auth_db", "password_column", "password")
- modparam("auth_db", "db_url", "mysql://opensips:opensipsrw@localhost/opensips")
- modparam("auth_db", "load_credentials", "")
- # ----- auth params -----
- modparam("auth", "rpid_avp", "$avp(s:rpid)")
- # ----- alias_db params -----
- /* uncomment the following lines if you want to enable the DB based aliases */
- modparam("alias_db", "db_url", "mysql://opensips:opensipsrw@localhost/opensips")
- # ----- domain params -----
- /* uncomment the following lines to enable multi-domain detection
- support */
- modparam("domain", "db_url","mysql://opensips:opensipsrw@localhost/opensips")
- modparam("domain", "db_mode", 0) # Use non-caching
- ####### Routing Logic ########
- # main request routing logic
- route{
- if (!mf_process_maxfwd_header("10")) {
- sl_send_reply("483","Too Many Hops");
- exit;
- }
- if (client_nat_test("3")) {
- if(search("Content-Type: application/sdp"))
- fix_nated_sdp("10");
- }
- force_rport();
- if ( is_present_hf("Remote-Party-ID") && is_from_gw("1") )
- {
- $avp(s:rpidpriv) = $(hdr(Remote-Party-ID){s.select,1,>}{param.value,privacy});
- if( $avp(s:rpidpriv) != NULL && ( $avp(s:rpidpriv) == "full" || $avp(s:rpidpriv) == "uri" ) ) {
- setflag(11); # Privacy flag
- xlog("Found Remote-Party-ID. And it is a private call with privacy level of $avp(s:rpidpriv) ");
- }
- remove_hf("Remote-Party-ID");
- }
- if (has_totag()) {
- # sequential request within a dialog should
- # take the path determined by record-routing
- if (loose_route()) {
- if (is_method("BYE")) {
- setflag(3); # ... even if the transaction fails
- } else if (is_method("INVITE")) {
- # even if in most of the cases is useless, do RR for
- # re-INVITEs also, as some buggy clients do change route set
- # during the dialog.
- record_route_preset("VIRTUAL_IP:VIRTUAL_PORT");
- if(is_from_gw("1"))
- {
- /* Remove GW_PREFIX from Contact if you are getting a reply from the GW, i.e. the client just placed an outbound call */
- if($ct != NULL)
- {
- $var(ct_username) = $(ct.fields(uri){uri.user});
- if($(var(ct_username){s.substr,0,4}) == "GW_PREFIX")
- {
- remove_hf("Contact");
- append_hf("Contact: <sip:$(var(ct_username){s.substr,4,0})@$(ct.fields(uri){uri.domain}):$(ct.fields(uri){uri.port})> \r\n", "Allow-Events");
- }
- }
- }
- else
- {
- if (client_nat_test("3"))
- fix_nated_contact();
- #Outgoing Re-Invite on a Received anonymous call, fetch the saved Unknown username and update the RURI
- if( $ruri.user == "Unknown" )
- {
- fetch_dlg_value("unk_to_username","$avp(s:to_ruri_username)");
- $ruri.user = $avp(s:to_ruri_username);
- }
- $avp(s:tmp) = goes_to_gw("1","p");
- setflag(22);
- sip_trace();
- if (sstCheckMin("1")) {
- xlog("L_ERR", "422 Session Timer Too Small reply sent.\n");
- exit;
- }
- }
- # If it is a Re-Invite just remove the Require:timer from the headers
- route(21);
- }
- # route it out to whatever destination was set by loose_route()
- # in $du (destination URI).
- route(1);
- } else {
- if ( is_method("ACK") ) {
- if ( t_check_trans() ) {
- # non loose-route, but stateful ACK; must be an ACK after
- # a 487 or e.g. 404 from upstream server
- t_relay();
- exit;
- } else {
- # ACK without matching transaction ->
- # ignore and discard
- exit;
- }
- }
- sl_send_reply("404","Not here");
- }
- exit;
- }
- # initial requests
- # OPTIONS processing
- if (is_method("OPTIONS"))
- {
- t_reply("404", "Not Found");
- exit;
- }
- # CANCEL processing
- if (is_method("CANCEL"))
- {
- setflag(22);
- sip_trace();
- if (t_check_trans())
- t_relay();
- exit;
- }
- t_check_trans();
- $var(is_nat_treated) = 0;
- # authenticate if you're not registering but sending a request
- if (!(method=="REGISTER") && !is_from_gw("1"))
- {
- remove_hf("P-Preferred-Identity");
- remove_hf("P-Asserted-Identity");
- remove_hf("Remote-Party-Id");
- remove_hf("Privacy");
- if(is_method("INVITE"))
- {
- setflag(22);
- sip_trace();
- if (sstCheckMin("1")) {
- xlog("L_ERR", "422 Session Timer Too Small reply sent.\n");
- exit;
- }
- }
- if( !proxy_authorize("","subscriber") )
- {
- $var(auth_code) = $retcode;
- switch($var(auth_code))
- {
- case "-5": $var(auth_error) = "generic error"; break;
- case "-4": $var(auth_error) = "no credentials"; break;
- case "-3": $var(auth_error) = "stale nonce"; break;
- case "-2": $var(auth_error) = "invalid password"; break;
- case "-1": $var(auth_error) = "invalid user"; break;
- default: $var(auth_error) = "$var(auth_code)";
- }
- if(is_method("INVITE") && $var(auth_code) != -4 && $var(auth_code) != -3 && $var(auth_code) != -2)
- {
- avp_db_query("INSERT INTO G9_ProxyLogs (CallingStationID, CalledStationID, call_id, type, source, error_code, description, datetime_created) VALUES ('$(fU{s.escape.common})','$(tU{s.escape.common})','$(ci{s.escape.common})','outbound','$si:$sp','407 - Proxy Authorization Required','NAME: Auth error - $var(auth_error) for user $au',NOW())");
- }
- if($var(auth_code) != -2)
- {
- xlog("L_NOTICE","Auth error for $fU@$fd from $si cause _ $var(auth_error) _ call");
- proxy_challenge("", "0");
- exit;
- }
- }
- avp_db_query("SELECT dba.alias_username, dba.username, dba.pmp_username, sub.domain, sub.password FROM dbaliases dba, subscriber sub WHERE sub.username = '$au' AND sub.username = dba.username AND (dba.pmp_username = '$(fU{s.escape.common})' OR dba.alias_username = '$(fU{s.escape.common})') ", "$avp(s:alias_username);$avp(s:username);$avp(s:pmp_username);$avp(s:domain);$avp(s:password)");
- #xlog("SELECT dba.alias_username, dba.username, dba.pmp_username, sub.domain, sub.password FROM dbaliases dba, subscriber sub WHERE sub.username = '$au' AND sub.username = dba.username AND (dba.pmp_username = '$(fU{s.escape.common})' OR dba.alias_username = '$(fU{s.escape.common})') ");
- if( $avp(s:alias_username) != NULL && $avp(s:alias_username) != '' )
- {
- #verify if the user has a blank password in the BD
- if($var(auth_code) == -2)
- if( $avp(s:password) == NULL || $avp(s:password) == '') /* 'sempassword' */
- xlog("L_NOTICE", "Client $fU (with $au) has no password defined, will skip password auth");
- else
- {
- xlog("L_NOTICE","Auth error for $fU@$fd from $si cause _ invalid password _ call");
- avp_db_query("INSERT INTO G9_ProxyLogs (CallingStationID, CalledStationID, call_id, type, source, error_code, description, datetime_created) VALUES ('$(fU{s.escape.common})','$(tU{s.escape.common})','$(ci{s.escape.common})','outbound','$si:$sp','407 - Proxy Authorization Required','NAME: Auth error - $var(auth_error) for user $au',NOW())");
- proxy_challenge("", "0");
- exit;
- }
- #authenticate with the user's domain if it exists
- if($avp(s:domain) != NULL && $avp(s:domain) != '' && $si != $avp(s:domain))
- {
- xlog("L_NOTICE","Auth error for $fU@$fd from $si cause _ invalid ip address _ call");
- if(is_method("INVITE") && $var(auth_code) != -4 && $var(auth_code) != -3)
- {
- avp_db_query("INSERT INTO G9_ProxyLogs (CallingStationID, CalledStationID, call_id, type, source, error_code, description, datetime_created) VALUES ('$(fU{s.escape.common})','$(tU{s.escape.common})','$(ci{s.escape.common})','outbound','$si:$sp','407 - Proxy Authorization Required','NAME: Auth error - invalid ip address for user $au@$si, expecting $avp(s:domain)',NOW())");
- }
- proxy_challenge("","0");
- exit;
- }
- if($avp(s:username) == $au)
- {
- if( $fn == "\"Anonymous\"" )
- {
- # Remote-Party-Id construct for outbound call
- $avp(s:rpid) = "<sip:" + $au + "@" + $ar + ">;privacy=full";
- append_rpid_hf();
- # P-Asserted-Identity construct for outbound call
- append_hf("P-Asserted-Identity: sip:$au@$ar \r\n", "Contact");
- append_hf("Privacy: id \r\n", "Contact");
- }
- else
- append_hf("Privacy: none \r\n", "Contact");
- if($avp(s:pmp_username) == $fU && $avp(s:pmp_username) != $avp(s:alias_username))
- {
- uac_replace_from("$avp(s:alias_username)","sip:$avp(s:alias_username)@$fd");
- $avp(s:ct) = $ct;
- if (client_nat_test("3"))
- {
- avp_subst("$avp(s:ct)", "/(.*)@(.*)/$avp(s:alias_username)@$si:$sp>/");
- $var(is_nat_treated) = 1;
- }
- else
- avp_subst("$avp(s:ct)", "/(.*)@(.*)/$avp(s:alias_username)@\2/");
- remove_hf("Contact");
- append_hf("Contact: <sip:$avp(s:ct) \r\n");
- }
- }
- else
- {
- uac_replace_from("$au","sip:$au@$ar");
- }
- }
- else
- {
- uac_replace_from("$au","sip:$au@$ar");
- }
- if (client_nat_test("3")) {
- if($var(is_nat_treated) == 0)
- fix_nated_contact();
- }
- consume_credentials();
- # caller authenticated
- }
- # preloaded route checking
- if (loose_route())
- {
- xlog("L_ERR", "Attempt to route with preloaded Route's [$fu/$tu/$ru/$ci]");
- if (!is_method("ACK"))
- sl_send_reply("403","Preload Route denied");
- exit;
- }
- # record routing
- if (!is_method("REGISTER|MESSAGE"))
- record_route_preset("VIRTUAL_IP:VIRTUAL_PORT");
- # INVITEs - differentiate between outbound and inbound calls
- if (is_method("INVITE"))
- {
- if (!is_from_gw("1"))
- {
- $avp(s:is_inbound) = 0;
- # On outbound-calls leave the timeout of SIP-negotiation at 120 sec
- $avp(s:custom_fr_inv_timer) = 120;
- # Outbound-route for call-limit control
- route(39);
- # Call our dynamic route.
- route(4);
- }
- else
- {
- $avp(s:is_inbound) = 1;
- # On inbound-calls leave the timeout of SIP-negotiation at 45 sec. Defines how much time it will take for the end of the call, it leads to redirection of the call to Voicemail
- $avp(s:custom_fr_inv_timer) = 45;
- # if it was recognized that this inbound-call has to have an unknown number has the originator of the call (privacy=full on Remote-Party-ID header) do some headers manipulation
- if(isflagset(11))
- {
- create_dialog();
- store_dlg_value( "unk_to_username", "$(ct.fields(uri){uri.user})" );
- xlog("Inbound call with request for Unknown username. We save the number for future Re-Invite as unk_to_username = $(ct.fields(uri){uri.user})");
- remove_hf("Contact");
- append_hf("Contact: <sip:Unknown@$(ct.fields(uri){uri.domain}):$(ct.fields(uri){uri.port})> \r\n", "Allow-Events");
- uac_replace_from("Unknown","sip:Unknown@$fd");
- }
- /*
- # [Ticket: 9681]
- else
- # if there is no Display-name in the From header, just add the username in the URI to it
- if ($fn == NULL || $fn == "")
- {
- uac_replace_from("$fU","");
- }
- */
- }
- }
- if (!is_uri_host_local())
- {
- if(!is_from_gw("1") && !goes_to_gw("1") && is_method("REGISTER"))
- {
- setflag(22);
- sip_trace();
- xlog("L_NOTICE","Auth error for $fU@$fd from $si cause _ unknown domain _ register");
- avp_db_query("INSERT INTO G9_ProxyLogs (CallingStationID, call_id, type, source, error_code, description, datetime_created) VALUES ('$(fU{s.escape.common})','$(ci{s.escape.common})','register','$si:$sp','404 - Not Found (unknown domain)','NAME: Auth error - unknown domain $rd',NOW())");
- t_reply("404", "Not Found (unknown domain)");
- exit;
- }
- append_hf("P-hint: outbound\r\n");
- route(1);
- }
- if (is_method("PUBLISH"))
- {
- sl_send_reply("503", "Service Unavailable");
- exit;
- }
- if (is_method("REGISTER"))
- {
- fix_nated_register();
- if (client_nat_test("3")) {
- setbflag(7);
- }
- setflag(22);
- sip_trace();
- if(!www_authorize("","subscriber"))
- {
- $var(auth_code) = $retcode;
- switch($var(auth_code))
- {
- case "-5": $var(auth_error) = "generic error"; break;
- case "-4": $var(auth_error) = "no credentials"; break;
- case "-3": $var(auth_error) = "stale nonce"; break;
- case "-2": $var(auth_error) = "invalid password"; break;
- case "-1": $var(auth_error) = "invalid user"; break;
- default: $var(auth_error) = "$var(auth_code)";
- }
- if($var(auth_code) != -4 && $var(auth_code) != -3 && $var(auth_code) != -2)
- avp_db_query("INSERT INTO G9_ProxyLogs (CallingStationID, call_id, type, source, error_code, description, datetime_created) VALUES ('$(fU{s.escape.common})','$(ci{s.escape.common})','register','$si:$sp','401 - Unauthorized','NAME: Auth error - $var(auth_error) for user $au',NOW())");
- if($var(auth_code) != -2)
- {
- xlog("L_NOTICE","Auth error for $fU@$fd from $si cause _ $var(auth_error) _ register");
- www_challenge("", "0");
- exit;
- }
- }
- #authenticate with the user's domain
- avp_db_query("SELECT domain, password, BO_login, BO_name FROM subscriber WHERE username='$(fU{s.escape.common})'", "$avp(s:domain);$avp(s:password);$avp(s:login);$avp(s:name)");
- #verify if the user has a blank password in the BD
- if($var(auth_code) == -2 )
- if( $avp(s:password) == NULL || $avp(s:password) == '') /* 'sempassword' */
- xlog("L_NOTICE", "User $fU has no password defined, will skip password auth");
- else
- {
- xlog("L_NOTICE","Auth error for $fU@$fd from $si cause _ invalid password _ register");
- avp_db_query("INSERT INTO G9_ProxyLogs (CallingStationID, call_id, type, source, error_code, description, datetime_created) VALUES ('$(fU{s.escape.common})','$(ci{s.escape.common})','register','$si:$sp','401 - Unauthorized','NAME: Auth error - $var(auth_error) for user $au',NOW())");
- www_challenge("", "0");
- exit;
- }
- if($avp(s:domain) != NULL && $avp(s:domain) != '' && $si != $avp(s:domain))
- {
- xlog("L_NOTICE","Auth error for $fU@$fd from $si cause _ invalid ip address _ register");
- avp_db_query("INSERT INTO G9_ProxyLogs (CallingStationID, call_id, type, source, error_code, description, datetime_created) VALUES ('$(fU{s.escape.common})','$(ci{s.escape.common})','register','$si:$sp','401 - Unauthorized','NAME: Auth error - invalid ip address for user $au@$si, expecting $avp(s:domain)',NOW())");
- www_challenge("","0");
- exit;
- }
- if (!db_check_to())
- {
- sl_send_reply("403", "Forbidden auth ID");
- exit;
- }
- if (!save("location"))
- sl_reply_error();
- else
- # Add to the BO login and name of the user to the entry on the location table
- avp_db_query("UPDATE location SET login='$avp(s:login)', name='$avp(s:name)' WHERE username = '$au'");
- exit;
- }
- if ($rU==NULL) {
- # request with no Username in RURI
- sl_send_reply("484","Address Incomplete");
- exit;
- }
- if($avp(s:is_inbound) == 1)
- {
- alias_db_lookup("dbaliases", "d");
- }
- # do lookup with method filtering
- if (!lookup("location","mb")) {
- switch ($retcode) {
- case -1:
- setflag(22);
- sip_trace();
- if(is_method("REGISTER"))
- {
- avp_db_query("INSERT INTO G9_ProxyLogs (CallingStationID, call_id, type, source, error_code, description, datetime_created) VALUES ('$(fU{s.escape.common})','$(ci{s.escape.common})','register','$si:$sp','401 - Unauthorized','NAME: Possible break-through attack attempt that went too far',NOW())");
- }else if(is_method("INVITE"))
- {
- xlog("Call to $rU not delivered, user not registered");
- avp_db_query("INSERT INTO G9_ProxyLogs (CallingStationID, CalledStationID, call_id, type, source, error_code, description, datetime_created) VALUES ('$(fU{s.escape.common})','$(tU{s.escape.common})','$(ci{s.escape.common})','inbound','$si:$sp','480 - Temporarily Not Available','NAME: Call to $(rU{s.escape.common}) not delivered, user not registered',NOW())");
- }
- xlog("Lookup on location with return value of -1 : Placed call on a user that is not available or an attack that went to far - analyse this if you were not expecting this.");
- avp_db_query("SELECT dba.vmail FROM dbaliases dba WHERE dba.alias_username = '$(tU{s.escape.common})' ", "$avp(s:is_voicemail)");
- if( $avp(s:is_voicemail) == 1)
- {
- # ASTERISK HOOK - BEGIN
- # callee is not registered, so different to Voicemail
- # First add the VM recording prefix to the RURI
- prefix("VMR_U_");
- # forward the call to Asterisk (replace below with real IP and port)
- rewritehostport("VOICEMAIL_IP:VOICEMAIL_PORT");
- route(1);
- # ASTERISK HOOK - END
- exit;
- }
- case -3:
- t_newtran();
- t_reply("404", "Not Found");
- exit;
- case -2:
- sl_send_reply("405", "Method Not Allowed");
- exit;
- }
- }
- if($avp(s:is_inbound) == 1)
- {
- #inbound-route for call-limit control
- route(40);
- avp_db_query("SELECT pmp_username FROM dbaliases WHERE alias_username='$tU'", "$avp(s:pmp_username)");
- if($avp(s:pmp_username) != NULL && $avp(s:pmp_username) != "")
- {
- $ruri.user = $avp(s:pmp_username);
- uac_replace_to("$avp(s:pmp_username)","sip:$avp(s:pmp_username)@$ruri.domain");
- }
- }
- route(1);
- }
- route[1] {
- # for INVITEs enable some additional helper routes
- if (is_method("INVITE")) {
- t_on_branch("2");
- t_on_reply("2");
- t_on_failure("1");
- }
- /* Insert SIP message into sip_trace table, avoiding duplicated entries from other parts of the script */
- if( (!is_method("SUBSCRIBE") && !is_method("INVITE")) || (is_method("INVITE") && is_from_gw("1")) )
- {
- setflag(22);
- sip_trace();
- }
- /* Just prefix with the one defined in the drouting tables on an outgoing BYE or ACK to the GW */
- if(is_method("ACK") || is_method("BYE") || is_method("PRACK") || is_method("CANCEL"))
- {
- #Bye to an Unknown user
- if( $ruri.user == "Unknown" )
- {
- fetch_dlg_value("unk_to_username","$avp(s:to_ruri_username)");
- $ruri.user = $avp(s:to_ruri_username);
- }
- $avp(s:tmp) = goes_to_gw("1","p");
- }
- if (!t_relay()) {
- sl_reply_error();
- };
- exit;
- }
- route[4] {
- if(!isflagset(10))
- {
- setflag(10);
- # Fetch from DB the group_id that is associated with the username so that is possible to choose the related route
- avp_db_query("SELECT groupid FROM dr_groups WHERE username = '$avp(s:alias_username)'", "$avp(s:group_id)");
- # If no group_id is found use the default one
- if (!$avp(s:group_id))
- $avp(s:group_id) = 0;
- # Do routing by choosing the rule associated with the group_id
- if ( !do_routing("$avp(s:group_id)", "0") ) {
- send_reply("503", "No Rules matching the URI");
- exit;
- }
- }
- }
- branch_route[2] {
- xlog("New branch at $ru\n");
- if( ( is_method("INVITE") || is_method("REGISTER") ) && $du != NULL)
- {
- # if RURI-domain is equal to the destination-domain and their ports are different substitute RURI-port with the destination-port
- if( $(du{uri.host}) == $rd && $(du{uri.port}) != $rp )
- $rp = $(du{uri.port});
- }
- }
- local_route{
- if( !is_method("OPTIONS") )
- {
- setflag(22);
- sip_trace();
- }
- }
- onreply_route[2] {
- if(is_from_gw("1"))
- {
- /* Remove GW_PREFIX from Contact if you are getting a reply from the GW, i.e. the client just placed an outbound call */
- if($ct != NULL)
- {
- $var(ct_username) = $(ct.fields(uri){uri.user});
- if($(var(ct_username){s.substr,0,4}) == "GW_PREFIX")
- {
- remove_hf("Contact");
- append_hf("Contact: <sip:$(var(ct_username){s.substr,4,0})@$(ct.fields(uri){uri.domain}):$(ct.fields(uri){uri.port})> \r\n", "Allow-Events");
- }
- }
- }else{
- if (client_nat_test("3"))
- {
- if(search("Content-Type: application/sdp"))
- fix_nated_sdp("10");
- fix_nated_contact();
- }
- }
- /*
- For Testing purposes only. By using a Perl script it's possible to change a received "183 - In Progress" to "180 - Ringing"
- The resulting 180 message is not logged into SIP-trace
- */
- /*
- if(t_check_status("183")) {
- perl_exec("sendReplyAs180");
- drop();
- }
- */
- }
- failure_route[1] {
- if ( t_was_cancelled() ) {
- exit;
- }
- if ( t_check_status("[34][0-9][0-9]") && $avp(s:is_inbound) == 1 ) {
- xlog("Inbound call with 3XX or 4XX, go for voicemail if active");
- # if the failure code is "408 - timeout", "486 - busy" or "480 - temporarily unavailable"
- # forward the calls to voicemail recording
- if ( t_check_status("CLIENT_ERROR_BUSY|CLIENT_ERROR_UNAVAILABLE") )
- {
- avp_db_query("SELECT sub.vmail FROM subscriber sub, dbaliases dba WHERE sub.username = dba.username AND ( sub.username = '$(tU{s.escape.common})' OR dba.alias_username = '$(tU{s.escape.common})')", "$avp(s:is_voicemail)");
- if( $avp(s:is_voicemail) == 1)
- {
- # ASTERISK HOOK - BEGIN
- # First revert the RURI to get the original user in RURI
- # Then add the VM recording prefix to the RURI
- revert_uri();
- if(t_check_status("CLIENT_ERROR_BUSY"))
- prefix("VMR_B_");
- else
- prefix("VMR_U_");
- # forward to the call to Asterisk (replace below with real IP and port)
- rewritehostport("VOICEMAIL_IP:VOICEMAIL_PORT");
- t_relay();
- # ASTERISK HOOK - END
- }
- }
- exit;
- }
- if ( t_check_status("GW_RETURN_ERRORS") && $avp(s:is_inbound) == 0 )
- {
- xlog("Problems with this Gateway, jumping to the next one if possible");
- resetflag(10);
- if (use_next_gw()) {
- t_relay();
- exit;
- } else {
- t_reply ("503", "Service not available");
- exit;
- }
- }
- }
- route[21] { # Suppresses SST announcements
- # For removing header Require: timer
- if (is_present_hf("Require")) {
- if (subst('/^(Require:.*)timer\s*,(.*)$/\1\2/i')) {
- #xlog("L_INFO", "Removed timer support (1)\n");
- } else if (subst('/^(Require:.*),\s*timer(.*)$/\1\2/i')) {
- #xlog("L_INFO", "Removed timer support (2)\n");
- } else if (search('^Require:.*timer.*$')) {
- remove_hf("Require");
- #xlog("L_INFO", "Removed timer support (3)\n");
- }
- }
- }
- /**** CALL-LIMIT ROUTES ****/
- #Outbound-route for call-limit control
- route[39]
- {
- ## have we done our checking on this call?
- if(!isflagset(21))
- {
- xlog("Call from $fU");
- avp_db_query("SELECT sub.username, sub.call_limit FROM dbaliases dba, subscriber sub WHERE (dba.pmp_username = '$(au{s.escape.common})' OR dba.alias_username = '$(au{s.escape.common})') AND dba.username = sub.username ", "$avp(s:from_user);$avp(s:channels)");
- if( $avp(s:from_user) != NULL && $avp(s:from_user) != '' )
- {
- # user has max channel limit set as preference
- if(is_avp_set("$avp(s:channels)/n") && avp_check("$avp(s:channels)", "gt/i:0") && $avp(s:channels) > 0)
- {
- # get current calls for uuid
- get_profile_size("accountcalls","$avp(s:from_user)","$var(calls)");
- # check within limit
- if($avp(s:channels) > $var(calls))
- {
- xlog("L_ERR","Call control [outbound]: user '$avp(s:from_user)' currently has '$var(calls)' of '$avp(s:channels)' active calls before this one\n");
- $var(setprofile) = 1;
- }
- else
- {
- xlog("L_ERR","Call control [outbound]: user '$avp(s:from_user)' channel limit exceeded [$var(calls)/$avp(s:channels)]\n");
- avp_db_query("INSERT INTO G9_ProxyLogs (CallingStationID, CalledStationID, call_id, type, source, error_code, description, datetime_created) VALUES ('$(fU{s.escape.common})','$(tU{s.escape.common})','$(ci{s.escape.common})','outbound','$si:$sp','486 - Busy Here','NAME: Channel limit exceeded [$var(calls)/$avp(s:channels)]',NOW())");
- sl_send_reply("486", "Busy Here");
- exit;
- }
- }
- else
- {
- $var(setprofile) = 0;
- }
- if($var(setprofile) > 0)
- {
- setflag(15);
- if ( is_present_hf("Session-Expires") )
- {
- setflag(12);
- setflag(13);
- }
- create_dialog();
- set_dlg_profile("accountcalls","$avp(s:from_user)");
- }
- ## mark checking done
- setflag(21);
- }
- }
- }
- #Inbound-route for call-limit control
- route[40]
- {
- ## have we done our checking on this call?
- if(!isflagset(21))
- {
- avp_db_query("SELECT call_limit FROM subscriber WHERE username='$tU'", "$avp(s:channels)");
- # user has max channel limit set as preference
- if(is_avp_set("$avp(s:channels)/n") && avp_check("$avp(s:channels)", "gt/i:0") && $avp(s:channels) > 0)
- {
- # get current calls for uuid
- get_profile_size("accountcalls","$tU","$var(calls)");
- # check within limit
- if($avp(s:channels) > $var(calls))
- {
- xlog("Call control [inbound]: user '$tU' currently has '$var(calls)' of '$avp(s:channels)' active calls before this one\n");
- $var(setprofile) = 1;
- }
- else
- {
- setflag(22);
- sip_trace();
- xlog("Call control [inbound]: user '$tU' channel limit exceeded [$var(calls)/$avp(s:channels)] - Go for voicemail, if active!\n");
- avp_db_query("INSERT INTO G9_ProxyLogs (CallingStationID, CalledStationID, call_id, type, source, error_code, description, datetime_created) VALUES ('$(fU{s.escape.common})','$(tU{s.escape.common})','$(ci{s.escape.common})','inbound','$si:$sp','486 - Busy Here','NAME: Channel limit exceeded [$var(calls)/$avp(s:channels)]',NOW())");
- avp_db_query("SELECT dba.vmail FROM dbaliases dba WHERE dba.alias_username = '$(tU{s.escape.common})' ", "$avp(s:is_voicemail)");
- if( $avp(s:is_voicemail) == 1)
- {
- # ASTERISK HOOK - BEGIN
- # First revert the RURI to get the original user in RURI
- # Then add the VM recording prefix to the RURI
- revert_uri();
- prefix("VMR_B_");
- # forward to the call to Asterisk (replace below with real IP and port)
- if (!t_relay("udp:VOICEMAIL_IP:VOICEMAIL_PORT")) {
- sl_send_reply("486", "Busy Here");
- };
- # ASTERISK HOOK - END
- }
- else
- sl_send_reply("486", "Busy Here");
- exit;
- }
- }
- else
- {
- $var(setprofile) = 0;
- }
- if($var(setprofile) > 0)
- {
- setflag(15);
- setflag(12);
- setflag(13);
- create_dialog();
- set_dlg_profile("accountcalls","$tU");
- }
- ## mark checking done
- setflag(21);
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement