#!KAMAILIO # #!ifdef ACCDB_COMMENT ALTER TABLE acc ADD COLUMN src_user VARCHAR(64) NOT NULL DEFAULT ''; ALTER TABLE acc ADD COLUMN src_domain VARCHAR(128) NOT NULL DEFAULT ''; ALTER TABLE acc ADD COLUMN src_ip varchar(64) NOT NULL default ''; ALTER TABLE acc ADD COLUMN dst_ouser VARCHAR(64) NOT NULL DEFAULT ''; ALTER TABLE acc ADD COLUMN dst_user VARCHAR(64) NOT NULL DEFAULT ''; ALTER TABLE acc ADD COLUMN dst_domain VARCHAR(128) NOT NULL DEFAULT ''; ALTER TABLE missed_calls ADD COLUMN src_user VARCHAR(64) NOT NULL DEFAULT ''; ALTER TABLE missed_calls ADD COLUMN src_domain VARCHAR(128) NOT NULL DEFAULT ''; ALTER TABLE missed_calls ADD COLUMN src_ip varchar(64) NOT NULL default ''; ALTER TABLE missed_calls ADD COLUMN dst_ouser VARCHAR(64) NOT NULL DEFAULT ''; ALTER TABLE missed_calls ADD COLUMN dst_user VARCHAR(64) NOT NULL DEFAULT ''; ALTER TABLE missed_calls ADD COLUMN dst_domain VARCHAR(128) NOT NULL DEFAULT ''; #!endif ####### Defined Values ######### #!define WITH_MYSQL #!define WITH_AUTH #!define WITH_ALIASDB #!define WITH_USRLOCDB #!define WITH_NAT #!ifdef WITH_MYSQL #!define DBURL "mysql://kamailio_admin:2Jx7kvT@localhost/kamailio_db" #!endif #!ifdef WITH_MULTIDOMAIN #!define MULTIDOMAIN 1 #!else #!define MULTIDOMAIN 0 #!endif #!define FLT_ACC 1 #!define FLT_ACCMISSED 2 #!define FLT_ACCFAILED 3 #!define FLT_NATS 5 #!define FLB_NATB 6 #!define FLB_NATSIPPING 7 ####### Global Parameters ######### #!ifdef WITH_DEBUG debug=4 log_stderror=yes #!else debug=2 log_stderror=no #!endif memdbg=5 memlog=5 log_facility=LOG_LOCAL0 fork=yes children=4 disable_tcp=yes auto_aliases=no alias="sip.malagasy.com" listen=udp:41.204.103.208 port=5060 #!ifdef WITH_TLS enable_tls=yes #!endif tcp_connection_lifetime=3605 ####### Custom Parameters ######### ####### Modules Section ######## # set paths to location of modules (to sources or installation folders) #!ifdef WITH_SRCPATH mpath="modules_k:modules" #!else mpath="/usr/lib/kamailio/modules_k/:/usr/lib/kamailio/modules/" #!endif #!ifdef WITH_MYSQL loadmodule "db_mysql.so" #!endif loadmodule "mi_fifo.so" loadmodule "kex.so" loadmodule "tm.so" loadmodule "tmx.so" loadmodule "sl.so" loadmodule "rr.so" loadmodule "pv.so" loadmodule "maxfwd.so" loadmodule "usrloc.so" loadmodule "registrar.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 "acc.so" #!ifdef WITH_AUTH loadmodule "auth.so" loadmodule "auth_db.so" #!ifdef WITH_IPAUTH loadmodule "permissions.so" #!endif #!endif #!ifdef WITH_ALIASDB loadmodule "alias_db.so" #!endif #!ifdef WITH_SPEEDDIAL loadmodule "speeddial.so" #!endif #!ifdef WITH_MULTIDOMAIN loadmodule "domain.so" #!endif #!ifdef WITH_PRESENCE loadmodule "presence.so" loadmodule "presence_xml.so" #!endif #!ifdef WITH_NAT loadmodule "nathelper.so" loadmodule "rtpproxy.so" #!endif #!ifdef WITH_TLS loadmodule "tls.so" #!endif #!ifdef WITH_ANTIFLOOD loadmodule "htable.so" loadmodule "pike.so" #!endif #!ifdef WITH_XMLRPC loadmodule "xmlrpc.so" #!endif #!ifdef WITH_DEBUG loadmodule "debugger.so" #!endif loadmodule "siptrace.so" loadmodule "acc_radius.so" loadmodule "mi_datagram.so" loadmodule "dialog.so" loadmodule "call_control.so" #loadmodule "mediaproxy.so" # ----------------- setting module-specific parameters --------------- # ----- mediaproxy ----- #modparam("mediaproxy", "mediaproxy_socket", "/var/run/mediaproxy/dispatcher.sock") #modparam("mediaproxy", "mediaproxy_timeout", 500) #modparam("mediaproxy", "signaling_ip_avp", "$avp(s:nat_ip)") #modparam("mediaproxy", "media_relay_avp", "$avp(s:media_relay)") # ----- dialog params ----- modparam("dialog", "dlg_flag", 4) # -------- mi_datagram params ------- modparam("mi_datagram", "socket_name", "/var/run/kamailio/mi_datagram.socket") # ------- Call Control params ------ modparam("call_control", "disable", 0) modparam("call_control", "socket_name", "/var/run/callcontrol/socket") # ------ CDRTOOL modparam("acc_radius", "radius_config", "/etc/radiusclient-ng/radiusclient.conf") modparam("acc_radius", "radius_flag", FLT_ACC) modparam("acc_radius", "radius_missed_flag", FLT_ACCMISSED) modparam("acc_radius", "radius_extra", "User-Name=$Au; \ Calling-Station-Id=$from; \ Called-Station-Id=$to; \ Sip-Translated-Request-URI=$ru; \ Sip-RPid=$avp(s:rpid); \ Source-IP=$avp(s:source_ip); \ Source-Port=$avp(s:source_port); \ SIP-Proxy-IP=$avp(s:sip_proxy_ip); \ Canonical-URI=$avp(s:can_uri); \ Billing-Party=$avp(billing_party); \ Divert-Reason=$avp(s:divert_reason); \ User-Agent=$hdr(user-agent); \ Contact=$hdr(contact); \ Event=$hdr(event); \ ENUM-TLD=$avp(s:enum_tld); \ From-Header=$hdr(from); \ SIP-Application-Type=$avp(s:sip_application_type)") # ----- siptrace params -----++ modparam("siptrace", "db_url", DBURL) modparam("siptrace", "table", "sip_trace") modparam("siptrace", "traced_user_avp", "$avp(s:traced_user)") modparam("siptrace", "trace_on",1) modparam("siptrace", "trace_flag",2) # ----- mi_fifo params ----- modparam("mi_fifo", "fifo_name", "/tmp/kamailio_tmp") # ----- tm params ----- modparam("tm", "failure_reply_mode", 3) #modparam("tm", "fr_timer", 30000) modparam("tm", "fr_timer", 5000) #modparam("tm", "fr_inv_timer", 120000) #modparam("tm", "fr_inv_timer", 20000) ## dur��e an le sonnerie fa par branche izany ??? modparam("tm", "max_inv_lifetime", 20000) ## mitov n eo ambon fa par transaction # ----- rr params ----- modparam("rr", "enable_full_lr", 1) modparam("rr", "append_fromtag", 0) # ----- registrar params ----- modparam("registrar", "method_filtering", 1) # modparam("registrar", "append_branches", 0) #modparam("registrar", "max_contacts", 10) modparam("registrar", "max_expires", 3600) # ----- acc params ----- modparam("acc", "early_media", 0) modparam("acc", "report_ack", 0) modparam("acc", "report_cancels", 0) modparam("acc", "detect_direction", 0) modparam("acc", "log_flag", FLT_ACC) modparam("acc", "log_missed_flag", FLT_ACCMISSED) modparam("acc", "log_extra", "src_user=$fU;src_domain=$fd;src_ip=$si;" "dst_ouser=$tU;dst_user=$rU;dst_domain=$rd") modparam("acc", "failed_transaction_flag", FLT_ACCFAILED) #!ifdef WITH_ACCDB modparam("acc", "db_flag", FLT_ACC) modparam("acc", "db_missed_flag", FLT_ACCMISSED) modparam("acc", "db_url", DBURL) modparam("acc", "db_extra", "src_user=$fU;src_domain=$fd;src_ip=$si;" "dst_ouser=$tU;dst_user=$rU;dst_domain=$rd") #!endif # ----- usrloc params ----- #!ifdef WITH_USRLOCDB modparam("usrloc", "db_url", DBURL) modparam("usrloc", "db_mode", 2) modparam("usrloc", "use_domain", MULTIDOMAIN) #!endif # ----- auth_db params ----- #!ifdef WITH_AUTH modparam("auth_db", "db_url", DBURL) modparam("auth_db", "calculate_ha1", yes) modparam("auth_db", "password_column", "password") modparam("auth_db", "load_credentials", "") modparam("auth_db", "use_domain", MULTIDOMAIN) # ----- permissions params ----- #!ifdef WITH_IPAUTH modparam("permissions", "db_url", DBURL) modparam("permissions", "db_mode", 1) #!endif #!endif # ----- alias_db params ----- #!ifdef WITH_ALIASDB modparam("alias_db", "db_url", DBURL) modparam("alias_db", "use_domain", MULTIDOMAIN) #!endif # ----- speedial params ----- #!ifdef WITH_SPEEDDIAL modparam("speeddial", "db_url", DBURL) modparam("speeddial", "use_domain", MULTIDOMAIN) #!endif # ----- domain params ----- #!ifdef WITH_MULTIDOMAIN modparam("domain", "db_url", DBURL) # use caching modparam("domain", "db_mode", 1) # register callback to match myself condition with domains list modparam("domain", "register_myself", 1) #!endif #!ifdef WITH_PRESENCE # ----- presence params ----- modparam("presence", "db_url", DBURL) # ----- presence_xml params ----- modparam("presence_xml", "db_url", DBURL) modparam("presence_xml", "force_active", 1) #!endif #!ifdef WITH_NAT # ----- rtpproxy params ----- modparam("rtpproxy", "rtpproxy_sock", "udp:127.0.0.1:22222") # ----- nathelper params ----- modparam("nathelper", "natping_interval", 30) modparam("nathelper", "ping_nated_only", 0) modparam("nathelper", "sipping_bflag", FLB_NATSIPPING) modparam("nathelper", "sipping_from", "sip:pinger@sip.malagasy.com") modparam("nathelper", "force_socket", "udp:127.0.0.1:22222") # params needed for NAT traversal in other modules modparam("nathelper|registrar", "received_avp", "$avp(RECEIVED)") modparam("usrloc", "nat_bflag", FLB_NATB) #!endif #!ifdef WITH_TLS # ----- tls params ----- modparam("tls", "config", "/etc/kamailio/tls.cfg") #!endif #!ifdef WITH_ANTIFLOOD # ----- pike params ----- modparam("pike", "sampling_time_unit", 2) modparam("pike", "reqs_density_per_unit", 16) modparam("pike", "remove_latency", 4) # ----- htable params ----- # ip ban htable with autoexpire after 5 minutes modparam("htable", "htable", "ipban=>size=8;autoexpire=300;") #!endif #!ifdef WITH_XMLRPC # ----- xmlrpc params ----- modparam("xmlrpc", "route", "XMLRPC"); modparam("xmlrpc", "url_match", "^/RPC") #!endif #!ifdef WITH_DEBUG # ----- debugger params ----- modparam("debugger", "cfgtrace", 1) #!endif ####### 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 { # per request initial checks route(REQINIT); # NAT detection route(NATDETECT); # handle requests within SIP dialogs route(WITHINDLG); ### only initial requests (no To tag) # CANCEL processing if (is_method("CANCEL")) { if (t_check_trans()) t_relay(); exit; } t_check_trans(); # authentication route(AUTH); # record routing for dialog forming requests (in case they are routed) # - remove preloaded route headers remove_hf("Route"); if (is_method("INVITE|SUBSCRIBE")) { record_route(); #force_rtp_proxy(); rtpproxy_offer(); t_on_reply("1"); } # account only INVITEs if (is_method("INVITE")) { route(CALLCONTROL); setflag(FLT_ACC); # do accounting } # dispatch requests to foreign domains route(SIPOUT); ### requests for my local domains # handle presence related requests route(PRESENCE); # handle registrations route(REGISTRAR); if ($rU==$null) { # request with no Username in RURI sl_send_reply("484","Address Incomplete"); exit; } # dispatch destinations to PSTN route(PSTN); # user location service route(LOCATION); route(RELAY); } route[CALLCONTROL] { # xlog("L_INFO", "Avant call_control\n"); call_control(); # xlog("L_INFO", "Apres callcontrol\n **** code averiny callctrl dia =$retcode"); switch ($retcode) { case 2: # Call with no limit xlog("L_INFO", "Call control: CODE_RETOUR $retcode, appel illimite\n"); case -1: # Not enough credit (prepaid call) xlog("L_INFO", "Call control: CODE_RETOUR $retcode, pas assez de credit\n"); acc_rad_request("402"); sl_send_reply("402", "Not enough credit"); exit; break; case 1: # Call with a limit under callcontrol management (either prepaid or postpaid) xlog("L_INFO", "Call control: CODE_RETOUR $retcode, appel avec limite\n"); break; case -2: # Locked by call in progress (prepaid call) xlog("L_INFO", "Call control: CODE_RETOUR $retcode, prepaid call locked by another call in progress\n"); acc_rad_request("403"); sl_send_reply("403", "Call locked by another call in progress"); exit; break; case -3: # Duplicated callid xlog("L_INFO", "Call control: CODE_RETOUR $retcode, Duplicated call id\n"); acc_rad_request("400"); sl_send_reply("400", "Duplicated callid"); exit; break; case -4: # Call limit reached xlog("L_INFO", "Call control: CODE_RETOUR $retcode, Call limit reached\n"); acc_rad_request("503"); sl_send_reply("503", "Too many concurrent calls"); exit; break; default: # Internal error (message parsing, communication, ...) xlog("L_INFO", "Call control: CODE_RETOUR default, internal server error\n"); acc_rad_request("500"); sl_send_reply("500", "Internal server error"); exit; } } route[RELAY] { # enable additional event routes for forwarded requests # - serial forking, RTP relaying handling, a.s.o. if (is_method("INVITE|SUBSCRIBE")) { #force_rtp_proxy(); rtpproxy_offer(); t_on_branch("MANAGE_BRANCH"); t_on_reply("MANAGE_REPLY"); t_on_reply("1"); } if (is_method("INVITE")) { t_on_failure("MANAGE_FAILURE"); } if (!t_relay()) { sl_reply_error(); } exit; } onreply_route[1] { if (status=~"[12][0-9][0-9]") #force_rtp_proxy(); rtpproxy_offer(); } # Per SIP request initial checks route[REQINIT] { #!ifdef WITH_ANTIFLOOD # flood dection from same IP and traffic ban for a while # be sure you exclude checking trusted peers, such as pstn gateways # - local host excluded (e.g., loop to self) if(src_ip!=myself) { if($sht(ipban=>$si)!=$null) { # ip is already blocked xdbg("request from blocked IP - $rm from $fu (IP:$si:$sp)\n"); exit; } if (!pike_check_req()) { xlog("L_ALERT","ALERT: pike blocking $rm from $fu (IP:$si:$sp)\n"); $sht(ipban=>$si) = 1; exit; } } #!endif if (!mf_process_maxfwd_header("10")) { sl_send_reply("483","Too Many Hops"); exit; } if(!sanity_check("1511", "7")) { xlog("Malformed SIP message from $si:$sp\n"); exit; } } # Handle requests within SIP dialogs route[WITHINDLG] { if (has_totag()) { # sequential request withing a dialog should # take the path determined by record-routing if (loose_route()) { if (is_method("BYE")) { setflag(FLT_ACC); # do accounting ... setflag(FLT_ACCFAILED); # ... even if the transaction fails } if ( is_method("ACK") ) { # ACK is forwarded statelessy route(NATMANAGE); } route(RELAY); }else { 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 exit; } } sl_send_reply("404","Not here"); } exit; } } # Handle SIP registrations route[REGISTRAR] { if (is_method("REGISTER")) { if(isflagset(FLT_NATS)) { setbflag(FLB_NATB); # uncomment next line to do SIP NAT pinging ## setbflag(FLB_NATSIPPING); } if (!save("location")) sl_reply_error(); exit; } } # USER location service route[LOCATION] { #!ifdef WITH_SPEEDIAL # search for short dialing - 2-digit extension if($rU=~"^[0-9][0-9]$") if(sd_lookup("speed_dial")) route(SIPOUT); #!endif #!ifdef WITH_ALIASDB # search in DB-based aliases if(alias_db_lookup("dbaliases")) route(SIPOUT); #!endif $avp(oexten) = $rU; if (!lookup("location")) { $var(rc) = $rc; route(TOVOICEMAIL); t_newtran(); switch ($var(rc)) { case -1: case -3: send_reply("404", "Not Found"); exit; case -2: send_reply("405", "Method Not Allowed"); exit; } } # when routing via usrloc, log the missed calls also if (is_method("INVITE")) { setflag(FLT_ACCMISSED); } } # Presence server route route[PRESENCE] { if(!is_method("PUBLISH|SUBSCRIBE")) return; #!ifdef WITH_PRESENCE if (!t_newtran()) { sl_reply_error(); exit; }; if(is_method("PUBLISH")) { handle_publish(); t_release(); } else if( is_method("SUBSCRIBE")) { handle_subscribe(); t_release(); } exit; #!endif # if presence enabled, this part will not be executed if (is_method("PUBLISH") || $rU==$null) { sl_send_reply("404", "Not here"); exit; } return; } # Authentication route route[AUTH] { #!ifdef WITH_AUTH if (is_method("REGISTER")) { # authenticate the REGISTER requests (uncomment to enable auth) if (!www_authorize("$td", "subscriber")) { www_challenge("$td", "0"); exit; } if ($au!=$tU) { sl_send_reply("403","Forbidden auth ID"); exit; } } else { #!ifdef WITH_IPAUTH if(allow_source_address()) { # source IP allowed return; } #!endif # authenticate if from local subscriber if (from_uri==myself) { if (!proxy_authorize("$fd", "subscriber")) { proxy_challenge("$fd", "0"); exit; } if (is_method("PUBLISH")) { if ($au!=$fU || $au!=$tU) { sl_send_reply("403","Forbidden auth ID"); exit; } if ($au!=$rU) { sl_send_reply("403","Forbidden R-URI"); exit; } #!ifdef WITH_MULTIDOMAIN if ($fd!=$rd) { sl_send_reply("403","Forbidden R-URI domain"); exit; } #!endif } else { if ($au!=$fU) { sl_send_reply("403","Forbidden auth ID"); exit; } } consume_credentials(); # caller authenticated } else { # caller is not local subscriber, then check if it calls # a local destination, otherwise deny, not an open relay here if (!uri==myself) { sl_send_reply("403","Not relaying"); exit; } } } #!endif return; } # Caller NAT detection route route[NATDETECT] { #!ifdef WITH_NAT force_rport(); if (nat_uac_test("19")) { if (is_method("REGISTER")) { fix_nated_register(); } else { fix_nated_contact(); } setflag(FLT_NATS); } #!endif return; } # RTPProxy control route[NATMANAGE] { #!ifdef WITH_NAT if (is_request()) { if(has_totag()) { if(check_route_param("nat=yes")) { setbflag(FLB_NATB); } } } if (!(isflagset(FLT_NATS) || isbflagset(FLB_NATB))) return; rtpproxy_manage(); if (is_request()) { if (!has_totag()) { add_rr_param(";nat=yes"); } } if (is_reply()) { if(isbflagset(FLB_NATB)) { fix_nated_contact(); } } #!endif return; } # Routing to foreign domains route[SIPOUT] { if (!uri==myself) { append_hf("P-hint: outbound\r\n"); route(RELAY); } } # PSTN GW routing route[PSTN] { #!ifdef WITH_PSTN # check if PSTN GW IP is defined if (strempty($sel(cfg_get.pstn.gw_ip))) { xlog("SCRIPT: PSTN rotuing enabled but pstn.gw_ip not defined\n"); return; } # route to PSTN dialed numbers starting with '+' or '00' # (international format) # - update the condition to match your dialing rules for PSTN routing if(!($rU=~"^(\+|00)[1-9][0-9]{3,20}$")) return; # only local users allowed to call if(from_uri!=myself) { sl_send_reply("403", "Not Allowed"); exit; } $ru = "sip:" + $rU + "@" + $sel(cfg_get.pstn.gw_ip); route(RELAY); exit; #!endif return; } # XMLRPC routing #!ifdef WITH_XMLRPC route[XMLRPC] { # allow XMLRPC from localhost if ((method=="POST" || method=="GET") && (src_ip==127.0.0.1)) { # close connection only for xmlrpclib user agents (there is a bug in # xmlrpclib: it waits for EOF before interpreting the response). if ($hdr(User-Agent) =~ "xmlrpclib") set_reply_close(); set_reply_no_connect(); dispatch_rpc(); exit; } send_reply("403", "Forbidden"); exit; } #!endif # route to voicemail server route[TOVOICEMAIL] { #!ifdef WITH_VOICEMAIL if(!is_method("INVITE")) return; # check if VoiceMail server IP is defined if (strempty($sel(cfg_get.voicemail.srv_ip))) { xlog("SCRIPT: VoiceMail rotuing enabled but IP not defined\n"); return; } if($avp(oexten)==$null) return; $ru = "sip:" + $avp(oexten) + "@" + $sel(cfg_get.voicemail.srv_ip) + $sel(cfg_get.voicemail.srv_port); route(RELAY); exit; #!endif return; } # manage outgoing branches branch_route[MANAGE_BRANCH] { xdbg("new branch [$T_branch_idx] to $ru\n"); route(NATMANAGE); } # manage incoming replies onreply_route[MANAGE_REPLY] { xdbg("incoming reply\n"); if(status=~"[12][0-9][0-9]") route(NATMANAGE); } # manage failure routing cases failure_route[MANAGE_FAILURE] { route(NATMANAGE); if (t_is_canceled()) { exit; } #!ifdef WITH_BLOCK3XX # block call redirect based on 3xx replies. if (t_check_status("3[0-9][0-9]")) { t_reply("404","Not found"); exit; } #!endif #!ifdef WITH_VOICEMAIL # serial forking # - route to voicemail on busy or no answer (timeout) if (t_check_status("486|408")) { route(TOVOICEMAIL); exit; } #!endif }