Here, is a pre-release version of a script to put in front of FusionPBX servers as taught on mcrane's advanced class.
You need to edit the MY_PUBLIC_IP_ADDRESS/X.X.X.X and replace X.X.X.X with your IP address.
The postgres is unused for now but I'll bring that into play soon.
Way down in the dispatcher route, you will see another IP, this is one of my carrier IPs and is just for dealing with some inbound stuff I'm working with. Freeswitch needs amending to work with the inbound part and I'll write that up seperately.
For now, outbound should work fine, just point a domain name to your Kamailio IP.
Much more to come. This version will give per domain balancing, so pretty much all outbound stuff will work. Call transfer, parking, BLF, etc.
You will need to add a dispatcher list to /etc/kamailio, a sample is below along with the script for you to download.
You will also need to create a file called /etc/kamailio/dispatcher.list that contains a list of your FusionPBX servers similar to:
This should also work fine with a single server in the dispatcher list if you just want to have a play with Kamailio.
You need to edit the MY_PUBLIC_IP_ADDRESS/X.X.X.X and replace X.X.X.X with your IP address.
The postgres is unused for now but I'll bring that into play soon.
Way down in the dispatcher route, you will see another IP, this is one of my carrier IPs and is just for dealing with some inbound stuff I'm working with. Freeswitch needs amending to work with the inbound part and I'll write that up seperately.
For now, outbound should work fine, just point a domain name to your Kamailio IP.
Much more to come. This version will give per domain balancing, so pretty much all outbound stuff will work. Call transfer, parking, BLF, etc.
You will need to add a dispatcher list to /etc/kamailio, a sample is below along with the script for you to download.
Code:
#!KAMAILIO
#!subst "/MY_PUBLIC_IP_ADDRESS/X.X.X.X/"
#!subst "/POSTGRESQL_IP_ADDRESS/192.168.201.25/"
#!define DBPGURL "postgres://kamailio:Uhh7dk9uefv@POSTGRESQL_IP_ADDRESS:5432/kamailio"
####!define WITH_DEBUG
# - flags
#!define FLAG_FROM_FREESWITCH 1
### LOG Levels: 3=DBG, 2=INFO, 1=NOTICE, 0=WARN, -1=ERR
debug=2
log_stderror=no
memdbg=5
memlog=5
log_facility=LOG_LOCAL0
fork=yes
children=4
listen=udp:"MY_PUBLIC_IP_ADDRESS":5060
listen=tcp:"MY_PUBLIC_IP_ADDRESS":5060
listen=udp:"0.0.0.0":5777
tcp_connection_lifetime=3605
#enable_tls=yes
####### Modules Section ########
# set paths to location of modules (to sources or installation folders)
mpath="/usr/lib/x86_64-linux-gnu/kamailio/modules"
#loadmodule "db_postgres.so"
loadmodule "mi_fifo.so"
loadmodule "kex.so"
loadmodule "corex.so"
loadmodule "tm.so"
loadmodule "tmx.so"
loadmodule "sl.so"
loadmodule "rr.so"
loadmodule "pv.so"
loadmodule "maxfwd.so"
loadmodule "textops.so"
loadmodule "siputils.so"
loadmodule "xlog.so"
loadmodule "sanity.so"
loadmodule "ctl.so"
loadmodule "cfg_rpc.so"
loadmodule "mi_rpc.so"
loadmodule "usrloc.so"
loadmodule "regex.so"
loadmodule "registrar.so"
loadmodule "nathelper.so"
#loadmodule "tls.so"
loadmodule "path.so"
#!ifdef WITH_DEBUG
loadmodule "debugger.so"
#!endif
loadmodule "dispatcher.so"
loadmodule "htable.so"
#loadmodule "presence.so"
#loadmodule "presence_dialoginfo.so"
#loadmodule "presence_mwi.so"
#loadmodule "presence_xml.so"
#loadmodule "nsq.so"
#loadmodule "htable.so"
# ----------------- setting module-specific parameters ---------------
# ----- mi_fifo params -----
modparam("mi_fifo", "fifo_name", "/var/run/kamailio/kamailio_fifo")
modparam("ctl", "binrpc", "unix:/var/run/kamailio/kamailio_ctl")
# ----- tm params -----
# auto-discard branches from previous serial forking leg
modparam("tm", "failure_reply_mode", 3)
# default retransmission timeout: 30sec
modparam("tm", "fr_timer", 30000)
# default invite retransmission timeout after 1xx: 120sec
modparam("tm", "fr_inv_timer", 120000)
# ----- nathelper params -----
modparam("nathelper|registrar", "received_avp", "$avp(s:rcv)")
#!ifdef WITH_DEBUG
# ----- debugger params -----
modparam("debugger", "cfgtrace", 1)
#!endif
#modparam("dispatcher", "db_url",DBPGURL)
modparam("dispatcher", "list_file", "/etc/kamailio/dispatcher.list")
modparam("dispatcher", "table_name", "dispatcher")
modparam("dispatcher", "flags", 2)
modparam("dispatcher", "dst_avp", "$avp(dsdst)")
modparam("dispatcher", "grp_avp", "$avp(dsgrp)")
modparam("dispatcher", "cnt_avp", "$avp(dscnt)")
modparam("dispatcher", "attrs_avp", "$avp(dsattrs)")
#modparam("dispatcher", "sock_avp", "$avp(dssocket)")
modparam("dispatcher", "dstid_avp", "$avp(dsdstid)")
modparam("dispatcher", "ds_hash_size", 8)
modparam("dispatcher", "ds_ping_interval", 20)
modparam("dispatcher", "ds_ping_from", "sip:kamailio@dispatcher.local")
modparam("dispatcher", "ds_probing_mode", 1)
modparam("dispatcher", "ds_ping_reply_codes", "class=2;code=480;code=404")
modparam("dispatcher", "hash_pvar", "$td")
#modparam("presence_dialoginfo", "force_dummy_dialog", 1)
#modparam("presence_xml", "force_dummy_presence", 1)
#modparam("presence_xml", "force_active", 1)
#modparam("presence_xml", "disable_winfo", 1)
#modparam("presence_xml", "disable_bla", 1)
#modparam("htable", "db_url", DBPGURL)
#modparam("htable", "htable", "p=>size=32;autoexpire=3600;")
#modparam("presence", "subs_db_mode", 3)
#modparam("presence", "send_fast_notify", 1)
#modparam("presence", "clean_period", 30)
#modparam("presence", "publ_cache", 0)
#modparam("presence", "min_expires_action", 1)
#modparam("presence", "min_expires", 300)
#modparam("presence", "max_expires", 3600)
#modparam("presence", "sip_uri_match", 1)
#modparam("presence", "waitn_time", 1)
#modparam("presence", "notifier_processes", 1)
#modparam("presence", "force_delete", 1)
#modparam("presence", "db_url", DBPGURL)
#modparam("presence", "active_watchers_table", "active_watchers")
####### Routing Logic ########
# Main SIP request routing logic
# - processing of any incoming SIP request starts with this route
# - note: this is the same as route { ... }
request_route {
xlog("L_INFO", "$ci|log|SIP message [$rm] from $si:$sp");
# per request initial checks
route(REQINIT);
# CANCEL processing
if (is_method("CANCEL")) {
if (t_check_trans()) {
t_relay();
}
exit;
}
route(CHECK_SOURCE_IP);
# handle requests within SIP dialogs
route(WITHINDLG);
###############################
### HANDLE INITIAL REQUESTS ###
# handle retransmissions
if(t_precheck_trans()) {
t_check_trans();
exit;
}
t_check_trans();
if (is_method("INVITE|REFER|SUBSCRIBE")) {
record_route();
}
if (is_method("NOTIFY") && $hdr(event) == "check-sync" && isflagset(FLAG_FROM_FREESWITCH)) {
record_route();
xlog("L_INFO", "$ci|log|Rebooting phone [$ru]\n");
t_on_reply("REPLY_FROM_DEVICE"); # handle NAT
route(RELAY);
}
if (!isflagset(FLAG_FROM_FREESWITCH) && is_method("REGISTER")) {
add_path();
}
# handle INVITEs
route(DISPATCH);
route(RELAY);
}
# Per SIP request initial checks
route[REQINIT] {
if (!mf_process_maxfwd_header("10")) {
#xlog("L_WARN", "$ci|end|too much hops, not enough barley");
send_reply("483", "Too Many Hops");
exit;
}
if (!sanity_check()) {
#xlog("L_WARN", "$ci|end|message is insane");
exit;
}
if ($ua == "friendly-scanner" || $ua == "sundayddr" || $ua =~ "sipcli" ) {
#xlog("L_WARN", "$ci|end|dropping message with user-agent $ua");
exit;
}
if (is_method("PUBLISH")) {
xlog("L_WARN", "$ci|end|dropping PUBLISH messages for now $ua");
exit;
}
}
route[CHECK_SOURCE_IP] {
if (ds_is_from_list()) {
setflag(FLAG_FROM_FREESWITCH);
} else {
route(NAT_TEST_AND_CORRECT);
}
}
route[DISPATCH] {
if(src_ip==178.22.140.34){
append_hf("X-Auth-IP: $si\r\n");
}
if (isflagset(FLAG_FROM_FREESWITCH)) {
t_on_reply("REPLY_FROM_DEVICE"); # handle NAT
} else if (!ds_select_dst("1", "7")) {
#if we are here that means no destination is available. We notify the user by 404 and exit the script.
xlog("L_NOTICE", "No destination available!");
send_reply("404", "No destination");
exit;
}
}
route[RELAY] {
if (is_method("INVITE")) {
if(!t_is_set("failure_route")) t_on_failure("MANAGE_FAILURE");
}
if (!t_relay()) {
sl_reply_error();
}
exit;
}
onreply_route[REPLY_FROM_DEVICE] {
route(NAT_TEST_AND_CORRECT);
}
# manage failure routing cases
failure_route[MANAGE_FAILURE] {
if (t_is_canceled()) {
exit;
}
}
route[NAT_TEST_AND_CORRECT] {
if (is_method("REGISTER")) {
if (nat_uac_test("19")) {
fix_nated_contact();
force_rport();
}
} else {
if (nat_uac_test("3")) {
fix_nated_contact();
force_rport();
}
if (has_body("application/sdp") && nat_uac_test("8")) {
fix_nated_sdp("10");
}
}
}
# Handle requests within SIP dialogs
route[WITHINDLG] {
if (has_totag()) {
if (is_method("INVITE|UPDATE|NOTIFY")) { # fix reply from UPDATE or NOTIFY (in-dialog)
t_on_reply("REPLY_FROM_DEVICE"); # handle NAT
}
# sequential request withing a dialog should
# take the path determined by record-routing
if (loose_route()) {
route(RELAY);
} else {
if (is_method("NOTIFY")) {
route(RELAY);
}
if (is_method("SUBSCRIBE") && uri == myself) {
# in-dialog subscribe requests
route(PRESENCE);
exit;
}
if (is_method("ACK")) {
if (t_check_trans()) {
# no 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
#xlog("ACK without matching transaction ... ignore and discard");
exit;
}
}
sl_send_reply("404","Not here");
}
exit;
}
}
####### Presence Routes #######
route[PRESENCE] {
if(!is_method("PUBLISH|SUBSCRIBE"))
return;
route(TOFUSIONPBX);
exit;
}
# Send to FusionPBX
route[TOFUSIONPBX] {
route(DISPATCH);
route(RELAY);
exit;
}
You will also need to create a file called /etc/kamailio/dispatcher.list that contains a list of your FusionPBX servers similar to:
Code:
1 sip:37.187.X.X:5060
1 sip:176.31.X.X:5060
1 sip:77.240.X.X:5060
This should also work fine with a single server in the dispatcher list if you just want to have a play with Kamailio.
Attachments
Last edited: