Building A Phone System Capable of scaling up in every direction
Load Balancing 2 a2billing/freepbx Servers and 2 BlueBox Server while terminating local calls itself. It also handles nated agents And soon to handle presence.
In these Configuiration i have a total of 6 servers.
- OpenSips Server
- Database Server
- 2 * A2billing Servers (Working as billing/ Authentication Servers)
- 2 * BlueBox Servers (Working as Media Servers)
All Servers Connect to the same database And we have created an a2billing View insde the Opensips database which mirrors a2billing cc_sip_buddies table.
With this set all asterisk and bluebox servers can remain on a private ip address since opensips is the proxy and and has public interface and private ip address (I used 2 nics, but a 1 to 1 Nat may work)
FYI (I use Untangle as my Firewall.. great firewall if you have the right hardware. But with this firewall i had to disable Sip Helper. Sip Helper conflicts with nat transversal technics used. After disabling i had to restart the untangle server.)
This Config Is Still Being Worked on. The following is still a work in progress. (will take help from others)
- Presence Server isnt configured
- Multi-domain is supported yet.. ( I added bluebox servers to impliment multi-tenet ) although partitioning context should work, clients will not yet be able to have to same extenstion as that another client has until i get this working
- Checking voicmail without typing password
All Phones Connects to the proxy.. My services include residential and Commercial phone service along with sip trunking. later ill include IM Support so that instant messangers will work and be able to make calls as well.
Opensips registers users that are in a2billing.. It then reads all calls, in this config extenstions are 4 digits long it will terminate all calls 2XXX Itself and send other calls too the loadbalancer Module.
The load Balancer will read all calls and send Voicemails calls to to the server is the database for voicemail Calls, And it will send all calls for confrences to the server designated for confrences and do the same thing for PSTN Calls
Installing Opensips
yum install gcc bison flex zlib-devel openssl-devel openssl-devel libxml-devel mysql-devel perl-DBI libcurl-devel
make include_modules="db_mysql Load-Balancer presence MEDIAPROXY PRESENCE_MWI PRESENCE_XML" prefix="/" all
make include_modules="db_mysql Load-Balancer presence MEDIAPROXY PRESENCE_MWI PRESENCE_XML" prefix="/" install
Edit config for database
#nano /etc/opensips/opensips.cfg
create database
/sbin/opensipsdbctl create
In my setup opensips connects to a2billing using a MySQL VIEW
CREATE VIEW a2billing AS select `mya2billing`.`cc_sip_buddies`.`id` AS `id`,`mya2billing`.`cc_sip_buddies`.`username` AS `username`,`mya2billing`.`cc_sip_buddies`.`outboundproxy` AS `domain`,`mya2billing`.`cc_sip_buddies`.`secret` AS `password`,_latin1'' AS `ha1`,_latin1'' AS `ha2`,_latin1'' AS `rpid` from `mya2billing`.`cc_sip_buddies`
I suppose if you want to use freepbx/trixbox you may can create this view
CREATE VIEW `opensips`.`subscriber` AS select
`asterisk`.`sip`.`id` AS `id`, `asterisk`.`sip`.`id` AS `username`, _latin1'emunited' AS `domain`, `asterisk`.`sip`.`data` AS `password`, _latin1'' AS `ha1`, _latin1'' AS `ha2`, _latin1'' AS `rpid`
from `asterisk`.`sip` where keyword='secret';
OpenSips Config File
#
# $Id: opensips.cfg 8591 2011-11-26 08:27:25Z bogdan_iancu $
#
# OpenSIPS basic configuration script
# by Anca Vamanu <
This e-mail address is being protected from spambots. You need JavaScript enabled to view it.
>
#
# Please refer to the Core CookBook at:
# http://www.opensips.org/Resources/DocsCookbooks
# for a explanation of possible statements, functions and parameters.
#
####### Global Parameters #########
#debug=6
#log_stderror=no
#log_facility=LOG_LOCAL0
#fork=yes
#children=4
debug=3
log_stderror=no
log_facility=LOG_LOCAL0
fork=yes
children=4
/* uncomment the next line to disable TCP (default on) */
#disable_tcp=yes
/* uncomment the next line to enable the auto temporary blacklisting of
not available destinations (default disabled) */
#disable_dns_blacklist=no
/* uncomment the next line to enable IPv6 lookup after IPv4 dns
lookup failures (default disabled) */
#dns_try_ipv6=yes
/* uncomment the next line to disable the auto discovery of local aliases
based on revers DNS on IPs (default on) */
#auto_aliases=no
/* uncomment the following lines to enable TLS support (default off) */
#disable_tls = no
#listen = tls:your_IP:5061
#tls_verify_server = 1
#tls_verify_client = 1
#tls_require_client_certificate = 0
#tls_method = TLSv1
#tls_certificate = "//etc/opensips/tls/user/user-cert.pem"
#tls_private_key = "//etc/opensips/tls/user/user-privkey.pem"
#tls_ca_list = "//etc/opensips/tls/user/user-calist.pem"
/* default db_url to be used by modules requiring DB connection;
uncomment it if you use any module requiring DB connectivity */
db_default_url="mysql://opensips:opensipsrw@Database-Server/opensips"
port=5060
/* uncomment and configure the following line if you want opensips to
bind on a specific interface/port/proto (default bind on all available) */
#listen=udp:192.168.1.2:5060
####### Modules Section ########
#set module path
mpath="//lib64/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 "acc.so"
loadmodule "dialog.so"
loadmodule "load_balancer.so"
loadmodule "nathelper.so"
loadmodule "siptrace.so"
loadmodule "rtpproxy.so"
/* uncomment next lines for MySQL based authentication support
NOTE: a DB (like db_mysql) module must be also loaded */
loadmodule "auth.so"
loadmodule "auth_db.so"
/* uncomment next line for aliases support
NOTE: a DB (like db_mysql) module must be also loaded */
#loadmodule "alias_db.so"
/* uncomment next line for multi-domain support
NOTE: a DB (like db_mysql) module must be also loaded
NOTE: be sure and enable multi-domain support in all used modules
(see "multi-module params" section ) */
loadmodule "domain.so"
/* uncomment the next two lines for presence server support
NOTE: a DB (like db_mysql) module must be also loaded */
loadmodule "presence.so"
#loadmodule "presence_xml.so"
# ----------------- setting module-specific parameters ---------------
# ----- load_balancer -----
modparam("load_balancer", "db_url", "mysql://opensips:opensipsrw@Database-Server/opensips")
# ----- siptrace -----
modparam("siptrace", "db_url", "mysql://opensips:opensipsrw@Database-Server/opensips")
modparam("siptrace", "trace_flag", 22)
modparam("siptrace", "trace_on", 1)
modparam("siptrace", "enable_ack_trace", 1)
#modparam("siptrace", "traced_user_avp", "$avp(123)")
#modparam("siptrace", "traced_user_avp", "$avp(user)")
# ----- rtpproxy -----
#modparam("rtpproxy", "db_url","mysql://opensips:opensipsrw@Database-Server/opensips")
modparam("rtpproxy", "rtpproxy_sock","udp:localhost:12221 udp:localhost:12222")
# ----- dialog -----
#modparam("dialog", "dlg_flag", 13)
modparam("dialog", "db_mode", 1)
modparam("dialog", "db_url", "mysql://opensips:opensipsrw@Database-Server/opensips")
# ----- nathelper -----
modparam("nathelper", "natping_interval", 10)
#modparam("nathelper", "ping_nated_only", 1)
modparam("nathelper", "natping_processes", 3)
modparam("nathelper", "natping_socket", "localhost:5006")
modparam("nathelper", "received_avp", "$avp(42)")
modparam("nathelper", "force_socket", "localhost:33333")
modparam("nathelper", "sipping_from", "sip:pinger@ProxyServer-Domain")
modparam("nathelper", "sipping_method", "INFO")
modparam("nathelper", "sipping_bflag", 7)
# ----- mi_fifo params -----
modparam("mi_fifo", "fifo_name", "/tmp/opensips_fifo")
# ----- rr params -----
# do not append from tag to the RR (no need for this script)
modparam("rr","enable_double_rr",1)
modparam("rr","append_fromtag",1)
# ----- registrar params -----
/* uncomment the next line not to allow more than 10 contacts per AOR */
modparam("registrar", "max_contacts", 10)
# ----- usrloc params -----
modparam("usrloc", "db_mode", 2)
/* uncomment the following lines if you want to enable DB persistency
for location entries */
#modparam("usrloc", "db_mode", 2)
modparam("usrloc", "db_url","mysql://opensips:opensipsrw@Database-Server/opensips")
# ----- uri params -----
#modparam("uri_db", "use_uri_table", 0)
#modparam("uri_db", "db_url", "mysql://opensips:opensipsrw@Database-Server/opensips")
# ----- acc params -----
/* what sepcial events should be accounted ? */
modparam("acc", "early_media", 1)
modparam("acc", "report_cancels", 1)
/* by default ww do not adjust the direct of the sequential requests.
if you enable this parameter, be sure the enable "append_fromtag"
in "rr" module */
modparam("acc", "detect_direction", 0)
/* account triggers (flags) */
modparam("acc", "failed_transaction_flag", 3)
modparam("acc", "log_flag", 1)
modparam("acc", "log_missed_flag", 2)
/* uncomment the following lines to enable DB accounting also */
modparam("acc", "db_flag", 1)
modparam("acc", "db_missed_flag", 2)
# ----- auth_db params -----
/* uncomment the following lines if you want to enable the DB based
authentication */
modparam("auth_db", "password_column", "password")
modparam("auth_db", "password_column_2", "ha1b")
modparam("auth_db", "calculate_ha1", 1)
modparam("auth_db", "db_url",
"mysql://opensips:opensipsrw@Database-Server/opensips")
modparam("auth_db", "load_credentials", "")
modparam("auth_db", "skip_version_check", 1)
# ----- alias_db params -----
/* uncomment the following lines if you want to enable the DB based
aliases */
#modparam("alias_db", "db_url",
# "mysql://opensips:opensipsrw@Database-Server/opensips")
# ----- domain params -----
/* uncomment the following lines to enable multi-domain detection
support */
modparam("domain", "db_url",
"mysql://opensips:opensipsrw@Database-Server/opensips")
modparam("domain", "db_mode", 1) # Use caching
# ----- multi-module params -----
/* uncomment the following line if you want to enable multi-domain support
in the modules (dafault off) */
modparam("auth_db|usrloc|uri", "use_domain", 1)
# ----- presence params -----
/* uncomment the following lines if you want to enable presence */
modparam("presence|presence_xml", "db_url",
"mysql://opensips:opensipsrw@Database-Server/opensips")
#modparam("presence_xml", "force_active", 1)
modparam("presence", "server_address", "sip:192.168.111.109:5060")
####### Routing Logic ########
# main request routing logic
route{
$avp(s:user)=$fu; #for sip_trace
# -----------------------------------------------------------------
# Sanity Check Section
# -----------------------------------------------------------------
if (!mf_process_maxfwd_header("256")) {
if (method!="ACK") {
sl_send_reply("483", "Too Many Hops");
};
return;
};
if (msg:len > max_len) {
if (method!="ACK") {
sl_send_reply("513", "Message Overflow");
};
return;
};
if (status=="482") { #loop detection
xlog("L_ERR", "Webur: $mi $rm $fu -> $ru status 482 Loop Detected\n");
return;
};
if (!mf_process_maxfwd_header("3")) {
sl_send_reply("483","looping");
exit;
}
if (!has_totag()) {
# initial request
} else {
# sequential request -> obey Route indication
loose_route();
t_relay();
exit;
}
# -----------------------------------------------------------------
# Call Type Processing Section
# -----------------------------------------------------------------
if (method=="INVITE") {
route(3);
return;
} else if (method=="ACK") {
route(9);
return;
} else if (method=="BYE" || method=="CANCEL") {
route(5);
return;
} else if (method=="REGISTER" || method=="MESSAGE") {
route(1);
return;
} else if(method=="PUBLISH" || method=="SUBSCRIBE") {
route(2);
return;
} else if (method == "NOTIFY") {
sl_send_reply("200", "Understood");
return;
} else if (method == "OPTIONS") {
sl_send_reply("200", "Got it");
return;
};
}
route[1] {
# -----------------------------------------------------------------
# Register
# -----------------------------------------------------------------
if (is_method("REGISTER")) {
route(4);
if (isflagset(5)) {
record_route(";nat=yes");
} else {
record_route();
};
if (!www_authorize("", "a2billing")) {
www_challenge("", "0");
}
# auth done -> send it to registrar
consume_credentials();
$du = "sip:192.168.222.109:5060";
save("location");
t_relay();
exit;
}
}
route[2]
# -----------------------------------------------------------------
# Presence
# -----------------------------------------------------------------
{
if (!t_newtran())
{
sl_reply_error();
exit;
};
if(is_method("PUBLISH"))
{
handle_publish();
}
else
if( is_method("SUBSCRIBE"))
{
handle_subscribe();
}
return;
}
# requests for my domain
## uncomment this if you want to enable presence server
## and comment the next 'if' block
## NOTE: uncomment also the definition of route[2] from below
route[3] {
# -----------------------------------------------------------------
# Handle Calls
# -----------------------------------------------------------------
xlog("L_DBG", "Place Holder");
if (!has_totag()) {
if(is_method("INVITE")) {
trace_dialog();
} else {
sip_trace();
}
}
if (loose_route()) {
if(!has_totag()) {
xlog("L_INFO", "Initial loose-routing rejected - M=$rm RURI=$ru F=$fu T=$tu IP=$si ID=$ci\n");
sl_send_reply("403", "Initial Loose-Routing Rejected");
exit;
}
if (is_method("INVITE")) {
route(5);
};
append_hf("P-hint: rr-enforced\r\n");
route(6);
};
# NAT detection
route(4);
record_route();
if ($rU =~ "^2[0-9]{3}$") { lookup("location");
route(8);
t_on_failure("1");
exit;
};
route(10);
return;
}
# -----------------------------------------------------------------
# Handle Handle NAT
# -----------------------------------------------------------------
route[4]
{
if (is_method("INVITE") &&
has_totag()) {engage_rtp_proxy();};
force_rport();
if (1) {
if (nat_uac_test("19")) {
xlog("L_DBG", "NAT detected1");
if (method=="REGISTER") {
fix_nated_register();
} else {
fix_nated_contact();
fix_nated_sdp("1");
xlog("L_DBG", "NAT detected2");
};
setflag(5);
return;
};
}
}
# -----------------------------------------------------------------
# Gotta Go
# -----------------------------------------------------------------
route[5] {
if (is_method("BYE|CANCEL")) {
unforce_rtp_proxy();
} else if (is_method("INVITE")) {
if (has_body("application/sdp"))
rtpproxy_offer("foc");
t_on_failure("3");
} else if (is_method("ASK")) {
if (has_body("application/sdp"))
rtpproxy_answer("foc");
t_on_failure("3");
}
t_on_reply("3");
}
# -----------------------------------------------------------------
# Handle Handle NAT
# -----------------------------------------------------------------
route[6] {
if (subst_uri('/(sip:.*);nat=yes/\1/')){
setbflag(0);
};
xlog("L_DBG", "NAT detected");
if (isflagset(5)||isbflagset(0)) {
route(5);
if (!t_relay()) {
sl_reply_error();
};
}
}
# -----------------------------------------------------------------
# Gotta Go
# -----------------------------------------------------------------
route[7] {
if (is_method("BYE|CANCEL")) {
unforce_rtp_proxy();
drop();
} else if (is_method("INVITE")) {
if (has_body("application/sdp"))
rtpproxy_offer("foc");
t_on_failure("3");
} else if (is_method("ASK")) {
if (has_body("application/sdp"))
rtpproxy_answer("foc");
t_on_failure("3");
}
t_on_reply("3");
exit;
}
route[8] {
# -----------------------------------------------------------------
# Extenstion Calls
# -----------------------------------------------------------------
force_rport();
fix_nated_contact();
if (has_body("application/sdp")){
rtpproxy_offer("foc");
xlog("L_DBG", "NAT detected");
t_on_failure("3");
} else if (is_method("ASK")) {
if (has_body("application/sdp"))
fix_nated_sdp("1"); # Add direction=active to SDP
rtpproxy_answer("foc");
xlog("L_DBG", "NAT detected");
}
t_on_reply("3");
if (!t_relay()) {
sl_reply_error();
# Error detection
route(13);
xlog("L_DBG", "Sent out From OPenSips");
exit;
}
}
# -----------------------------------------------------------------
# Media Start
# -----------------------------------------------------------------
route[9] {
setflag(4);
force_rport();
force_tcp_alias();
rtpproxy_answer();
return;
}
# -----------------------------------------------------------------
# Load Balance -detect resources
# -----------------------------------------------------------------
route[10] {
# detect resources and do balancing
if ($rU=~"^1") {
# looks like a Conference call
load_balance("1","conf");
} else if ($rU=~"^2") {
# looks like a VoiceMail call
load_balance("1","vm");
} else if ($rU=="*2113") {
# looks like a VoiceMail call
load_balance("1","vm");
} else {
# PSTN call, but the GWs supports only G711
# for calls without G711, transcoding will be used on the GW
if ( !search_body("G711") ) {
load_balance("1","transc;pstn");
} else {
load_balance("1","pstn");
}
route(11);
}
return;
}
# -----------------------------------------------------------------
# Load Balance - Send It out
# -----------------------------------------------------------------
route[11] {
# LB function returns negative if no suitable destination (for requested resources) is found,
# or if all destinations are full
if ($retcode<0) {
sl_send_reply("500","Service full");
exit;
}
xlog("Selected Load Balance destination is: $du\n");
# send it out
route(4);
if (!t_relay()) {
sl_reply_error();
# ERROR detection
route(13);
}
return;
}
route[13] {
# -----------------------------------------------------------------
# Debuging info
# -----------------------------------------------------------------
if (status=="100") {
xlog("L_NOTICE",
"Webur: $mi $rm $fu -> $ru status 100 Trying\n");
} else if (status=="180") {
xlog("L_NOTICE",
"Webur: $mi $rm $fu -> $ru status 180 Ringing\n");
} else if (status=="181") {
xlog("L_NOTICE",
"Webur: $mi $rm $fu -> $ru status 181 Call Is Being Forwarded\n");
} else if (status=="182") {
xlog("L_NOTICE",
"Webur: $mi $rm $fu -> $ru status 182 Queued\n");
} else if (status=="183") {
xlog("L_NOTICE",
"Webur: $mi $rm $fu -> $ru status 183 Session Progress\n");
} else if (status=="200") {
xlog("L_NOTICE",
"Webur: $mi $rm $fu -> $ru status 200 OK\n");
} else if (status=="202") {
xlog("L_NOTICE",
"Webur: $mi $rm $fu -> $ru status 202 Accepted\n");
} else if (status=="300") {
xlog("L_NOTICE",
"Webur: $mi $rm $fu -> $ru status 300 Multiple Choices $ct\n");
} else if (status=="301") {
xlog("L_NOTICE",
"Webur: $mi $rm $fu -> $ru status 301 Moved Permanently $ct\n");
} else if (status=="302") {
xlog("L_NOTICE",
"Webur: $mi $rm $fu -> $ru status 302 Moved Temporarily $ct\n");
} else if (status=="305") {
xlog("L_NOTICE",
"Webur: $mi $rm $fu -> $ru status 305 Use Proxy\n");
} else if (status=="380") {
xlog("L_NOTICE",
"Webur: $mi $rm $fu -> $ru status 380 Alternative Service\n");
} else if (status=="400") {
xlog("L_NOTICE",
"Webur: $mi $rm $fu -> $ru status 400 Bad Request\n");
} else if (status=="401") {
xlog("L_NOTICE",
"Webur: $mi $rm $fu -> $ru status 401 Unauthorized\n");
} else if (status=="402") {
xlog("L_NOTICE",
"Webur: $mi $rm $fu -> $ru status 402 Payment Required\n");
} else if (status=="403") {
xlog("L_NOTICE",
"Webur: $mi $rm $fu -> $ru status 403 Forbidden\n");
} else if (status=="404") {
xlog("L_NOTICE",
"Webur: $mi $rm $fu -> $ru status 404 Not Found\n");
} else if (status=="405") {
xlog("L_NOTICE",
"Webur: $mi $rm $fu -> $ru status 405 Method Not Allowed\n");
} else if (status=="406") {
xlog("L_NOTICE",
"Webur: $mi $rm $fu -> $ru status 406 Not Acceptable\n");
} else if (status=="407") {
xlog("L_NOTICE",
"Webur: $mi $rm $fu -> $ru status 407 Proxy Authentication Required\n");
} else if (status=="408") {
xlog("L_NOTICE",
"Webur: $mi $rm $fu -> $ru status 408 Request Timeout\n");
} else if (status=="409") {
xlog("L_NOTICE",
"Webur: $mi $rm $fu -> $ru status 409 Conflict\n");
} else if (status=="410") {
xlog("L_NOTICE",
"Webur: $mi $rm $fu -> $ru status 410 Gone\n");
} else if (status=="411") {
xlog("L_NOTICE",
"Webur: $mi $rm $fu -> $ru status 411 Length Required\n");
} else if (status=="412") {
xlog("L_NOTICE",
"Webur: $mi $rm $fu -> $ru status 412 Conditional Request Failed\n");
} else if (status=="413") {
xlog("L_NOTICE",
"Webur: $mi $rm $fu -> $ru status 413 Request Entity Too Large\n");
} else if (status=="414") {
xlog("L_NOTICE",
"Webur: $mi $rm $fu -> $ru status 414 Request-URI Too Long\n");
} else if (status=="415") {
xlog("L_NOTICE",
"Webur: $mi $rm $fu -> $ru status 415 Unsupported Media Type\n");
} else if (status=="416") {
xlog("L_NOTICE",
"Webur: $mi $rm $fu -> $ru status 416 Unsupported URI Scheme\n");
} else if (status=="420") {
xlog("L_NOTICE",
"Webur: $mi $rm $fu -> $ru status 420 Bad Extension\n");
} else if (status=="421") {
xlog("L_NOTICE",
"Webur: $mi $rm $fu -> $ru status 421 Extension Required\n");
} else if (status=="422") {
xlog("L_NOTICE",
"Webur: $mi $rm $fu -> $ru status 422 Session Interval Too Small\n");
} else if (status=="423") {
xlog("L_NOTICE",
"Webur: $mi $rm $fu -> $ru status 423 Interval Too Brief\n");
} else if (status=="429") {
xlog("L_NOTICE",
"Webur: $mi $rm $fu -> $ru status 429 Provide Referrer Identity\n");
} else if (status=="480") {
xlog("L_NOTICE",
"Webur: $mi $rm $fu -> $ru status 480 Temporarily Unavailable\n");
} else if (status=="481") {
xlog("L_NOTICE",
"Webur: $mi $rm $fu -> $ru status 481 Call Leg/Transaction Does Not Exist\n");
} else if (status=="482") {
xlog("L_NOTICE",
"Webur: $mi $rm $fu -> $ru status 482 Loop Detected\n");
} else if (status=="483") {
xlog("L_NOTICE",
"Webur: $mi $rm $fu -> $ru status 483 Too Many Hops\n");
} else if (status=="484") {
xlog("L_NOTICE",
"Webur: $mi $rm $fu -> $ru status 484 Address Incomplete\n");
} else if (status=="485") {
xlog("L_NOTICE",
"Webur: $mi $rm $fu -> $ru status 485 Ambiguous\n");
} else if (status=="486") {
xlog("L_NOTICE",
"Webur: $mi $rm $fu -> $ru status 486 Busy Here\n");
} else if (status=="487") {
xlog("L_NOTICE",
"Webur: $mi $rm $fu -> $ru status 487 Busy Here; Request Terminated\n");
} else if (status=="488") {
xlog("L_NOTICE", "Webur: $mi $rm $fu -> $ru status 488 Not Acceptable Here\n");
} else if (status=="489") {
xlog("L_NOTICE",
"Webur: $mi $rm $fu -> $ru status 489 Bad Event\n");
} else if (status=="491") {
xlog("L_NOTICE",
"Webur: $mi $rm $fu -> $ru status 491 Request Pending\n");
} else if (status=="493") {
xlog("L_NOTICE",
"Webur: $mi $rm $fu -> $ru status 493 Undecipherable\n");
} else if (status=="494") {
xlog("L_NOTICE",
"Webur: $mi $rm $fu -> $ru status 494 Security Agreement Required\n");
} else if (status=="500") {
xlog("L_NOTICE",
"Webur: $mi $rm $fu -> $ru status 500 Server Internal Error\n");
} else if (status=="501") {
xlog("L_NOTICE",
"Webur: $mi $rm $fu -> $ru status 501 Not Implemented\n");
} else if (status=="502") {
xlog("L_NOTICE",
"Webur: $mi $rm $fu -> $ru status 502 Bad Gateway\n");
} else if (status=="503") {
xlog("L_NOTICE",
"Webur: $mi $rm $fu -> $ru status 503 Service Unavailable\n");
} else if (status=="504") {
xlog("L_NOTICE",
"Webur: $mi $rm $fu -> $ru status 504 Server Timeout\n");
} else if (status=="505") {
xlog("L_NOTICE",
"Webur: $mi $rm $fu -> $ru status 505 Version Not Supported\n");
} else if (status=="513") {
xlog("L_NOTICE",
"Webur: $mi $rm $fu -> $ru status 513 Message Too Large\n");
} else if (status=="580") {
xlog("L_NOTICE",
"Webur: $mi $rm $fu -> $ru status 580 Precondition Failure\n");
} else if (status=="600") {
xlog("L_NOTICE",
"Webur: $mi $rm $fu -> $ru status 600 Busy Everywhere\n");
} else if (status=="603") {
xlog("L_NOTICE",
"Webur: $mi $rm $fu -> $ru status 603 Decline\n");
} else if (status=="604") {
xlog("L_NOTICE",
"Webur: $mi $rm $fu -> $ru status 604 Does Not Exist Anywhere\n");
} else if (status=="606") {
xlog("L_NOTICE",
"Webur: $mi $rm $fu -> $ru status 606 Not Acceptable\n");
} else {
xlog("L_NOTICE", "Webur: $mi $rm $fu -> $ru status not listed\n");
};
xlog("L_NOTICE", "Webur: $mi $mb\n");
return;
}
# -----------------------------------------------------------------
# Handle Handle NAT
# -----------------------------------------------------------------
branch_route[2] {
xlog("MIS: new branch at $ru\n");
}
# -----------------------------------------------------------------
# Handle Handle NAT
# -----------------------------------------------------------------
onreply_route[2] {
xlog("MIS: incoming reply\n");
force_rport();
if (status =~ "(183)|(2[0-9][0-9][0-9])"&& has_body("application/sdp")) {
if(nat_uac_test("19")) {
log("MIS: Hem detectat NAT");
setbflag(2); # flag for NAT
# fix_nated_contact();
fix_nated_sdp("11");
rtpproxy_answer();
};
};
}
onreply_route[3] {
# sip_trace();
if ((isflagset(5) || isbflagset(0)) && status=~"(183)|(2[0-9][0-9][0-9])" && has_body("application/sdp")) {
rtpproxy_answer();
}
if (!subst_uri('/(sip:.*);nat=yes/\1/')) {
search_append('Contact:.*sip:[^>[:cntrl:]]*', ';nat=yes');
}
if (isbflagset(0)) {
#fix_nated_contact();
}
exit;
}
failure_route[1] {
if (t_was_cancelled()) {
exit;
}
# if the failure code is "408 - timeout" or "486 - busy",
# forward the calls to voicemail recording
if (t_check_status("486|408")) {
# ASTERISK HOOK - BEGIN
# First revert the RURI to get the original user in RURI
# Then add the VM recording prefix to the RURI
# forward to the call to Asterisk (replace below with real IP and port)
load_balance("1","vm");
prefix("*");
rewritehostport("default");
route(11);
# ASTERISK HOOK - END
exit;
}
}
failure_route[3] {
# sip_trace();
if (isbflagset(0) || isflagset(5)) {
unforce_rtp_proxy();
}
}
{jcomments on}





