<p>This is my config.<br>
#!KAMAILIO<br>
#!define WITH_MYSQL<br>
#!define WITH_AUTH<br>
#!define WITH_USRLOCDB<br>
#!define WITH_PRESENCE<br>
#!define WITH_ACCDB</p>
<h1></h1>
<h1>Kamailio (OpenSER) SIP Server v5.2 - default configuration script</h1>
<h1>- web: <a href="https://www.kamailio.org" rel="nofollow">https://www.kamailio.org</a></h1>
<h1>- git: <a href="https://github.com/kamailio/kamailio">https://github.com/kamailio/kamailio</a></h1>
<h1></h1>
<h1>Direct your questions about this file to: <a href="mailto:sr-users@lists.kamailio.org">sr-users@lists.kamailio.org</a></h1>
<h1></h1>
<h1>Refer to the Core CookBook at <a href="https://www.kamailio.org/wiki/" rel="nofollow">https://www.kamailio.org/wiki/</a></h1>
<h1>for an explanation of possible statements, functions and parameters.</h1>
<h1></h1>
<h1>Note: the comments can be:</h1>
<h1>- lines starting with #, but not the pre-processor directives,</h1>
<h1>which start with #!, like #!define, #!ifdef, #!endif, #!else, #!trydef,</h1>
<h1>#!subst, #!substdef, ...</h1>
<h1>- lines starting with //</h1>
<h1>- blocks enclosed in between /* */</h1>
<h1></h1>
<h1>Several features can be enabled using '#!define WITH_FEATURE' directives:</h1>
<h1></h1>
<h1>*** To run in debug mode:</h1>
<h1>- define WITH_DEBUG</h1>
<h1></h1>
<h1>*** To enable mysql:</h1>
<h1>- define WITH_MYSQL</h1>
<h1></h1>
<h1>*** To enable authentication execute:</h1>
<h1>- enable mysql</h1>
<h1>- define WITH_AUTH</h1>
<h1>- add users using 'kamctl'</h1>
<h1></h1>
<h1>*** To enable IP authentication execute:</h1>
<h1>- enable mysql</h1>
<h1>- enable authentication</h1>
<h1>- define WITH_IPAUTH</h1>
<h1>- add IP addresses with group id '1' to 'address' table</h1>
<h1></h1>
<h1>*** To enable persistent user location execute:</h1>
<h1>- enable mysql</h1>
<h1>- define WITH_USRLOCDB</h1>
<h1></h1>
<h1>*** To enable presence server execute:</h1>
<h1>- enable mysql</h1>
<h1>- define WITH_PRESENCE</h1>
<h1></h1>
<h1>*** To enable nat traversal execute:</h1>
<h1>- define WITH_NAT</h1>
<h1>- install RTPProxy: <a href="http://www.rtpproxy.org" rel="nofollow">http://www.rtpproxy.org</a></h1>
<h1>- start RTPProxy:</h1>
<h1>rtpproxy -l <em>your_public_ip</em> -s udp:localhost:7722</h1>
<h1>- option for NAT SIP OPTIONS keepalives: WITH_NATSIPPING</h1>
<h1></h1>
<h1>*** To enable PSTN gateway routing execute:</h1>
<h1>- define WITH_PSTN</h1>
<h1>- set the value of pstn.gw_ip</h1>
<h1>- check route[PSTN] for regexp routing condition</h1>
<h1></h1>
<h1>*** To enable database aliases lookup execute:</h1>
<h1>- enable mysql</h1>
<h1>- define WITH_ALIASDB</h1>
<h1></h1>
<h1>*** To enable speed dial lookup execute:</h1>
<h1>- enable mysql</h1>
<h1>- define WITH_SPEEDDIAL</h1>
<h1></h1>
<h1>*** To enable multi-domain support execute:</h1>
<h1>- enable mysql</h1>
<h1>- define WITH_MULTIDOMAIN</h1>
<h1></h1>
<h1>*** To enable TLS support execute:</h1>
<h1>- adjust CFGDIR/tls.cfg as needed</h1>
<h1>- define WITH_TLS</h1>
<h1></h1>
<h1>*** To enable XMLRPC support execute:</h1>
<h1>- define WITH_XMLRPC</h1>
<h1>- adjust route[XMLRPC] for access policy</h1>
<h1></h1>
<h1>*** To enable anti-flood detection execute:</h1>
<h1>- adjust pike and htable=>ipban settings as needed (default is</h1>
<h1>block if more than 16 requests in 2 seconds and ban for 300 seconds)</h1>
<h1>- define WITH_ANTIFLOOD</h1>
<h1></h1>
<h1>*** To block 3XX redirect replies execute:</h1>
<h1>- define WITH_BLOCK3XX</h1>
<h1></h1>
<h1>*** To block 401 and 407 authentication replies execute:</h1>
<h1>- define WITH_BLOCK401407</h1>
<h1></h1>
<h1>*** To enable VoiceMail routing execute:</h1>
<h1>- define WITH_VOICEMAIL</h1>
<h1>- set the value of voicemail.srv_ip</h1>
<h1>- adjust the value of voicemail.srv_port</h1>
<h1></h1>
<h1>*** To enhance accounting execute:</h1>
<h1>- enable mysql</h1>
<h1>- define WITH_ACCDB</h1>
<h1>- add following columns to database</h1>
<p>#!ifdef ACCDB_COMMENT<br>
ALTER TABLE acc ADD COLUMN src_user VARCHAR(64) NOT NULL DEFAULT '';<br>
ALTER TABLE acc ADD COLUMN src_domain VARCHAR(128) NOT NULL DEFAULT '';<br>
ALTER TABLE acc ADD COLUMN src_ip varchar(64) NOT NULL default '';<br>
ALTER TABLE acc ADD COLUMN dst_ouser VARCHAR(64) NOT NULL DEFAULT '';<br>
ALTER TABLE acc ADD COLUMN dst_user VARCHAR(64) NOT NULL DEFAULT '';<br>
ALTER TABLE acc ADD COLUMN dst_domain VARCHAR(128) NOT NULL DEFAULT '';<br>
ALTER TABLE missed_calls ADD COLUMN src_user VARCHAR(64) NOT NULL DEFAULT '';<br>
ALTER TABLE missed_calls ADD COLUMN src_domain VARCHAR(128) NOT NULL DEFAULT '';<br>
ALTER TABLE missed_calls ADD COLUMN src_ip varchar(64) NOT NULL default '';<br>
ALTER TABLE missed_calls ADD COLUMN dst_ouser VARCHAR(64) NOT NULL DEFAULT '';<br>
ALTER TABLE missed_calls ADD COLUMN dst_user VARCHAR(64) NOT NULL DEFAULT '';<br>
ALTER TABLE missed_calls ADD COLUMN dst_domain VARCHAR(128) NOT NULL DEFAULT '';<br>
#!endif</p>
<p>############################################################################## Defined Values ####################################################################</p>
<h1>*** Value defines - IDs used later in config</h1>
<p>#!ifdef WITH_MYSQL</p>
<h1>- database URL - used to connect to database server by modules such</h1>
<h1>as: auth_db, acc, usrloc, a.s.o.</h1>
<p>#!ifndef DBURL<br>
#!define DBURL "mysql://kamailio:kamailiorw@localhost/kamailio"<br>
#!endif<br>
#!endif<br>
#!ifdef WITH_MULTIDOMAIN</p>
<h1>- the value for 'use_domain' parameters</h1>
<p>#!define MULTIDOMAIN 1<br>
#!else<br>
#!define MULTIDOMAIN 0<br>
#!endif</p>
<h1>- flags</h1>
<h1>FLT_ - per transaction (message) flags</h1>
<h1>FLB_ - per branch flags</h1>
<p>#!define FLT_ACC 1<br>
#!define FLT_ACCMISSED 2<br>
#!define FLT_ACCFAILED 3<br>
#!define FLT_NATS 5</p>
<p>#!define FLB_NATB 6<br>
#!define FLB_NATSIPPING 7</p>
<p>####################################################################### Global Parameters ###############################################################</p>
<h3>LOG Levels: 3=DBG, 2=INFO, 1=NOTICE, 0=WARN, -1=ERR</h3>
<p>#!ifdef WITH_DEBUG<br>
debug=4<br>
log_stderror=yes<br>
#!else<br>
debug=3<br>
log_stderror=yes<br>
#!endif</p>
<p>memdbg=5<br>
memlog=5</p>
<p>log_facility=LOG_LOCAL0<br>
log_prefix="{$mt $hdr(CSeq) $ci} "</p>
<p>/* number of SIP routing processes */<br>
children=8</p>
<p>/* uncomment the next line to disable TCP (default on) */</p>
<h1>disable_tcp=yes</h1>
<p>/* uncomment the next line to disable the auto discovery of local aliases</p>
<ul>
<li>based on reverse DNS on IPs (default on) */</li>
</ul>
<h1>auto_aliases=no</h1>
<p>/* add local domain aliases */</p>
<h1>alias="sip.mydomain.com"</h1>
<p>/* uncomment and configure the following line if you want Kamailio to</p>
<ul>
<li>bind on a specific interface/port/proto (default bind on all available) */</li>
</ul>
<h1>listen=udp:10.0.0.10:5060</h1>
<p>#!ifdef WITH_TLS<br>
enable_tls=no<br>
#!endif</p>
<p>/* life time of TCP connection when there is no traffic</p>
<ul>
<li>
<ul>
<li>a bit higher than registration expires to cope with UA behind NAT */<br>
tcp_connection_lifetime=3605</li>
</ul>
</li>
</ul>
<p>########################################################################### Custom Parameters ###################################################################</p>
<p>/* These parameters can be modified runtime via RPC interface</p>
<ul>
<li>
<ul>
<li>see the documentation of 'cfg_rpc' module.</li>
</ul>
</li>
<li></li>
<li>Format: group.id = value 'desc' description</li>
<li>Access: $sel(cfg_get.group.id) or @cfg_get.group.id */</li>
</ul>
<p>#!ifdef WITH_PSTN<br>
/* PSTN GW Routing<br>
*</p>
<ul>
<li>
<ul>
<li>pstn.gw_ip: valid IP or hostname as string value, example:</li>
</ul>
</li>
<li>pstn.gw_ip = "10.0.0.101" desc "My PSTN GW Address"</li>
<li></li>
<li>
<ul>
<li>by default is empty to avoid misrouting */<br>
pstn.gw_ip = "" desc "PSTN GW Address"<br>
pstn.gw_port = "" desc "PSTN GW Port"<br>
#!endif</li>
</ul>
</li>
</ul>
<p>#!ifdef WITH_VOICEMAIL<br>
/* VoiceMail Routing on offline, busy or no answer<br>
*</p>
<ul>
<li>
<ul>
<li>by default Voicemail server IP is empty to avoid misrouting */<br>
voicemail.srv_ip = "" desc "VoiceMail IP Address"<br>
voicemail.srv_port = "5060" desc "VoiceMail Port"<br>
#!endif</li>
</ul>
</li>
</ul>
<p>####### Modules Section ########</p>
<p>/* set paths to location of modules */</p>
<h1>mpath="/usr/lib64/kamailio/modules/"</h1>
<p>#!ifdef WITH_MYSQL<br>
loadmodule "db_mysql.so"<br>
#!endif</p>
<p>loadmodule "jsonrpcs.so"<br>
loadmodule "kex.so"<br>
loadmodule "corex.so"<br>
loadmodule "tm.so"<br>
loadmodule "tmx.so"<br>
loadmodule "sl.so"<br>
loadmodule "rr.so"<br>
loadmodule "pv.so"<br>
loadmodule "maxfwd.so"<br>
loadmodule "usrloc.so"<br>
loadmodule "registrar.so"<br>
loadmodule "textops.so"<br>
loadmodule "siputils.so"<br>
loadmodule "xlog.so"<br>
loadmodule "sanity.so"<br>
loadmodule "ctl.so"<br>
loadmodule "cfg_rpc.so"<br>
loadmodule "acc.so"<br>
loadmodule "counters.so"<br>
loadmodule "rtimer.so"<br>
loadmodule "sqlops.so"<br>
loadmodule "dispatcher.so"</p>
<p>#!ifdef WITH_AUTH<br>
loadmodule "auth.so"<br>
loadmodule "auth_db.so"<br>
#!ifdef WITH_IPAUTH<br>
loadmodule "permissions.so"<br>
#!endif<br>
#!endif</p>
<p>#!ifdef WITH_ALIASDB<br>
loadmodule "alias_db.so"<br>
#!endif</p>
<p>#!ifdef WITH_SPEEDDIAL<br>
loadmodule "speeddial.so"<br>
#!endif</p>
<p>#!ifdef WITH_MULTIDOMAIN<br>
loadmodule "domain.so"<br>
#!endif</p>
<p>#!ifdef WITH_PRESENCE<br>
loadmodule "presence.so"<br>
loadmodule "presence_xml.so"<br>
#!endif</p>
<p>#!ifdef WITH_NAT<br>
loadmodule "nathelper.so"<br>
loadmodule "rtpproxy.so"<br>
#!endif</p>
<p>#!ifdef WITH_TLS<br>
loadmodule "tls.so"<br>
#!endif</p>
<p>#!ifdef WITH_ANTIFLOOD<br>
loadmodule "htable.so"<br>
loadmodule "pike.so"<br>
#!endif</p>
<p>#!ifdef WITH_XMLRPC<br>
loadmodule "xmlrpc.so"<br>
#!endif</p>
<p>#!ifdef WITH_DEBUG<br>
loadmodule "debugger.so"<br>
#!endif</p>
<h1>----------------- setting module-specific parameters ---------------</h1>
<h1>----- jsonrpcs params -----</h1>
<p>modparam("jsonrpcs", "pretty_format", 1)<br>
/* set the path to RPC fifo control file */</p>
<h1>modparam("jsonrpcs", "fifo_name", "/var/run/kamailio/kamailio_rpc.fifo")</h1>
<p>/* set the path to RPC unix socket control file */</p>
<h1>modparam("jsonrpcs", "dgram_socket", "/var/run/kamailio/kamailio_rpc.sock")</h1>
<h1>----- ctl params -----</h1>
<p>/* set the path to RPC unix socket control file */</p>
<h1>modparam("ctl", "binrpc", "unix:/var/run/kamailio/kamailio_ctl")</h1>
<h1>----- tm params -----</h1>
<h1>auto-discard branches from previous serial forking leg</h1>
<p>modparam("tm", "failure_reply_mode", 3)</p>
<h1>default retransmission timeout: 30sec</h1>
<p>modparam("tm", "fr_timer", 30000)</p>
<h1>default invite retransmission timeout after 1xx: 120sec</h1>
<p>modparam("tm", "fr_inv_timer", 120000)</p>
<h1>----- rr params -----</h1>
<h1>set next param to 1 to add value to ;lr param (helps with some UAs)</h1>
<p>modparam("rr", "enable_full_lr", 0)</p>
<h1>do not append from tag to the RR (no need for this script)</h1>
<p>modparam("rr", "append_fromtag", 0)</p>
<h1>----- registrar params -----</h1>
<p>modparam("registrar", "method_filtering", 1)<br>
/* uncomment the next line to disable parallel forking via location */</p>
<h1>modparam("registrar", "append_branches", 0)</h1>
<p>/* uncomment the next line not to allow more than 10 contacts per AOR */</p>
<h1>modparam("registrar", "max_contacts", 10)</h1>
<p>/* max value for expires of registrations <em>/<br>
modparam("registrar", "max_expires", 3600)<br>
/</em> set it to 1 to enable GRUU */<br>
modparam("registrar", "gruu_enabled", 0)</p>
<h1>----- acc params -----</h1>
<p>/* what special events should be accounted ? <em>/<br>
modparam("acc", "early_media", 0)<br>
modparam("acc", "report_ack", 0)<br>
modparam("acc", "report_cancels", 0)<br>
/</em> by default ww do not adjust the direct of the sequential requests.</p>
<ul>
<li>if you enable this parameter, be sure the enable "append_fromtag"</li>
<li>in "rr" module <em>/<br>
modparam("acc", "detect_direction", 0)<br>
/</em> account triggers (flags) <em>/<br>
modparam("acc", "log_flag", FLT_ACC)<br>
modparam("acc", "log_missed_flag", FLT_ACCMISSED)<br>
modparam("acc", "log_extra",<br>
"src_user=$fU;src_domain=$fd;src_ip=$si;"<br>
"dst_ouser=$tU;dst_user=$rU;dst_domain=$rd")<br>
modparam("acc", "failed_transaction_flag", FLT_ACCFAILED)<br>
/</em> enhanced DB accounting */<br>
#!ifdef WITH_ACCDB<br>
modparam("acc", "db_flag", FLT_ACC)<br>
modparam("acc", "db_missed_flag", FLT_ACCMISSED)<br>
modparam("acc", "db_url", DBURL)<br>
modparam("acc", "db_extra",<br>
"src_user=$fU;src_domain=$fd;src_ip=$si;"<br>
"dst_ouser=$tU;dst_user=$rU;dst_domain=$rd")<br>
#!endif</li>
</ul>
<h1>----- usrloc params -----</h1>
<p>/* enable DB persistency for location entries */<br>
#!ifdef WITH_USRLOCDB<br>
modparam("usrloc", "db_url", DBURL)<br>
modparam("usrloc", "db_mode", 2)<br>
modparam("usrloc", "use_domain", MULTIDOMAIN)<br>
#!endif</p>
<h1>----- auth_db params -----</h1>
<p>#!ifdef WITH_AUTH<br>
modparam("auth_db", "db_url", DBURL)<br>
modparam("auth_db", "calculate_ha1", yes)<br>
modparam("auth_db", "password_column", "password")<br>
modparam("auth_db", "load_credentials", "")<br>
modparam("auth_db", "use_domain", MULTIDOMAIN)</p>
<h1>----- permissions params -----</h1>
<p>#!ifdef WITH_IPAUTH<br>
modparam("permissions", "db_url", DBURL)<br>
modparam("permissions", "db_mode", 1)<br>
#!endif</p>
<p>#!endif</p>
<h1>----- alias_db params -----</h1>
<p>#!ifdef WITH_ALIASDB<br>
modparam("alias_db", "db_url", DBURL)<br>
modparam("alias_db", "use_domain", MULTIDOMAIN)<br>
#!endif</p>
<h1>----- speeddial params -----</h1>
<p>#!ifdef WITH_SPEEDDIAL<br>
modparam("speeddial", "db_url", DBURL)<br>
modparam("speeddial", "use_domain", MULTIDOMAIN)<br>
#!endif</p>
<h1>----- domain params -----</h1>
<p>#!ifdef WITH_MULTIDOMAIN<br>
modparam("domain", "db_url", DBURL)<br>
/* register callback to match myself condition with domains list */<br>
modparam("domain", "register_myself", 1)<br>
#!endif</p>
<p>#!ifdef WITH_PRESENCE</p>
<h1>----- presence params -----</h1>
<p>modparam("presence", "db_url", DBURL)</p>
<h1>----- presence_xml params -----</h1>
<p>modparam("presence_xml", "db_url", DBURL)<br>
modparam("presence_xml", "force_active", 1)<br>
#!endif</p>
<p>#!ifdef WITH_NAT</p>
<h1>----- rtpproxy params -----</h1>
<p>modparam("rtpproxy", "rtpproxy_sock", "udp:127.0.0.1:7722")</p>
<h1>----- nathelper params -----</h1>
<p>modparam("nathelper", "natping_interval", 30)<br>
modparam("nathelper", "ping_nated_only", 1)<br>
modparam("nathelper", "sipping_bflag", FLB_NATSIPPING)<br>
modparam("nathelper", "sipping_from", "sip:<a href="mailto:pinger@kamailio.org">pinger@kamailio.org</a>")</p>
<h1>params needed for NAT traversal in other modules</h1>
<p>modparam("nathelper|registrar", "received_avp", "$avp(RECEIVED)")<br>
modparam("usrloc", "nat_bflag", FLB_NATB)<br>
#!endif</p>
<p>#!ifdef WITH_TLS</p>
<h1>----- tls params -----</h1>
<p>modparam("tls", "config", "/etc/kamailio/tls.cfg")<br>
#!endif</p>
<p>#!ifdef WITH_ANTIFLOOD</p>
<h1>----- pike params -----</h1>
<p>modparam("pike", "sampling_time_unit", 2)<br>
modparam("pike", "reqs_density_per_unit", 16)<br>
modparam("pike", "remove_latency", 4)</p>
<h1>----- htable params -----</h1>
<p>/* ip ban htable with autoexpire after 5 minutes */<br>
modparam("htable", "htable", "ipban=>size=8;autoexpire=300;")<br>
#!endif</p>
<p>#!ifdef WITH_XMLRPC</p>
<h1>----- xmlrpc params -----</h1>
<p>modparam("xmlrpc", "route", "XMLRPC");<br>
modparam("xmlrpc", "url_match", "^/RPC")<br>
#!endif</p>
<p>#!ifdef WITH_DEBUG</p>
<h1>----- debugger params -----</h1>
<p>modparam("debugger", "cfgtrace", 1)<br>
modparam("debugger", "log_level_name", "exec")<br>
#!endif</p>
<p>modparam("rtimer", "timer", "name=cdr;interval=300;mode=1;")<br>
modparam("rtimer", "exec", "timer=cdr;route=CDRS")<br>
modparam("sqlops", "sqlcon", "cb=>mysql://kamailio:kamailiorw@localhost/kamailio")</p>
<h1>----- dispatcher params -----</h1>
<p>#modparam("dispatcher", "db_url", "mysql://kamailio:kamailiorw@localhost/kamailio")<br>
modparam("dispatcher", "list_file", "/etc/kamailio/dispatcher.list")<br>
modparam("dispatcher", "ds_ping_interval", 30)</p>
<p>########################################################## Routing Logic #################################################################################</p>
<p>/* Main SIP request routing logic</p>
<ul>
<li>
<ul>
<li>processing of any incoming SIP request starts with this route</li>
</ul>
</li>
<li>
<ul>
<li>note: this is the same as route { ... } */</li>
</ul>
</li>
</ul>
<p>request_route {</p>
<pre><code># per request initial checks
route(REQINIT);

# NAT detection
route(NATDETECT);
t_check_trans();

if ( method=="INVITE" ) {
        ds_select_dst("1","4");
        sl_send_reply("100","Trying");
        forward();
        exit();
}

# CANCEL processing
if (is_method("CANCEL")) {
        if (t_check_trans()) {
                route(RELAY);
        }
        exit;
}

# handle retransmissions
if (!is_method("ACK")) {
        if(t_precheck_trans()) {
                t_check_trans();
                exit;
        }
        t_check_trans();
}

# handle requests within SIP dialogs
route(WITHINDLG);

### only initial requests (no To tag)

# 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();
}

# account only INVITEs
if (is_method("INVITE")) {
        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);
</code></pre>
<p>}</p>
<h1>Wrapper for relaying requests</h1>
<p>route[RELAY] {</p>
<pre><code># enable additional event routes for forwarded requests
# - serial forking, RTP relaying handling, a.s.o.
if (is_method("INVITE|BYE|SUBSCRIBE|UPDATE")) {
        if(!t_is_set("branch_route")) t_on_branch("MANAGE_BRANCH");
}
if (is_method("INVITE|SUBSCRIBE|UPDATE")) {
        if(!t_is_set("onreply_route")) t_on_reply("MANAGE_REPLY");
}
if (is_method("INVITE")) {
        if(!t_is_set("failure_route")) t_on_failure("MANAGE_FAILURE");
}

if (!t_relay()) {
        sl_reply_error();
}
exit;
</code></pre>
<p>}</p>
<h1>Per SIP request initial checks</h1>
<p>route[REQINIT] {<br>
#!ifdef WITH_ANTIFLOOD<br>
# flood detection from same IP and traffic ban for a while<br>
# be sure you exclude checking trusted peers, such as pstn gateways<br>
# - local host excluded (e.g., loop to self)<br>
if(src_ip!=myself) {<br>
if($sht(ipban=>$si)!=$null) {<br>
# ip is already blocked<br>
xdbg("request from blocked IP - $rm from $fu (IP:$si:$sp)\n");<br>
exit;<br>
}<br>
if (!pike_check_req()) {<br>
xlog("L_ALERT","ALERT: pike blocking $rm from $fu (IP:$si:$sp)\n");<br>
$sht(ipban=>$si) = 1;<br>
exit;<br>
}<br>
}<br>
#!endif<br>
if($ua =~ "friendly-scanner|sipcli|VaxSIPUserAgent") {<br>
# silent drop for scanners - uncomment next line if want to reply<br>
# sl_send_reply("200", "OK");<br>
exit;<br>
}</p>
<pre><code>if (!mf_process_maxfwd_header("10")) {
        sl_send_reply("483","Too Many Hops");
        exit;
}

if(is_method("OPTIONS") && uri==myself && $rU==$null) {
        sl_send_reply("200","Keepalive");
        exit;
}

if(!sanity_check("17895", "7")) {
        xlog("Malformed SIP message from $si:$sp\n");
        exit;
}
</code></pre>
<p>}</p>
<h1>Handle requests within SIP dialogs</h1>
<p>route[WITHINDLG] {<br>
if (!has_totag()) return;</p>
<pre><code># sequential request withing a dialog should
# take the path determined by record-routing
if (loose_route()) {
        route(DLGURI);
        if (is_method("BYE")) {
                setflag(FLT_ACC); # do accounting ...
                setflag(FLT_ACCFAILED); # ... even if the transaction fails
        } else if ( is_method("ACK") ) {
                # ACK is forwarded statelessly
                route(NATMANAGE);
        } else if ( is_method("NOTIFY") ) {
                # Add Record-Route for in-dialog NOTIFY as per RFC 6665.
                record_route();
        }
        route(RELAY);
        exit;
}

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
                route(RELAY);
                exit;
        } else {
                # ACK without matching transaction ... ignore and discard
                exit;
        }
}
sl_send_reply("404","Not here");
exit;
</code></pre>
<p>}</p>
<h1>Handle SIP registrations</h1>
<p>route[REGISTRAR] {<br>
if (!is_method("REGISTER")) return;</p>
<pre><code>if(isflagset(FLT_NATS)) {
        setbflag(FLB_NATB);
</code></pre>
<p>#!ifdef WITH_NATSIPPING<br>
# do SIP NAT pinging<br>
setbflag(FLB_NATSIPPING);<br>
#!endif<br>
}<br>
if (!save("location")) {<br>
sl_reply_error();<br>
}<br>
exit;<br>
}</p>
<h1>User location service</h1>
<p>route[LOCATION] {</p>
<p>#!ifdef WITH_SPEEDDIAL<br>
# search for short dialing - 2-digit extension<br>
if($rU=~"^[0-9][0-9]$") {<br>
if(sd_lookup("speed_dial")) {<br>
route(SIPOUT);<br>
}<br>
}<br>
#!endif</p>
<p>#!ifdef WITH_ALIASDB<br>
# search in DB-based aliases<br>
if(alias_db_lookup("dbaliases")) {<br>
route(SIPOUT);<br>
}<br>
#!endif</p>
<pre><code>$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);
}

route(RELAY);
exit;
</code></pre>
<p>}</p>
<h1>Presence server processing</h1>
<p>route[PRESENCE] {<br>
if(!is_method("PUBLISH|SUBSCRIBE")) return;</p>
<pre><code>if(is_method("SUBSCRIBE") && $hdr(Event)=="message-summary") {
        route(TOVOICEMAIL);
        # returns here if no voicemail server is configured
        sl_send_reply("404", "No voicemail service");
        exit;
}
</code></pre>
<p>#!ifdef WITH_PRESENCE<br>
if (!t_newtran()) {<br>
sl_reply_error();<br>
exit;<br>
}</p>
<pre><code>if(is_method("PUBLISH")) {
        handle_publish();
        t_release();
} else if(is_method("SUBSCRIBE")) {
        handle_subscribe();
        t_release();
}
exit;
</code></pre>
<p>#!endif</p>
<pre><code># if presence enabled, this part will not be executed
if (is_method("PUBLISH") || $rU==$null) {
        sl_send_reply("404", "Not here");
        exit;
}
return;
</code></pre>
<p>}</p>
<h1>IP authorization and user authentication</h1>
<p>route[AUTH] {<br>
#!ifdef WITH_AUTH</p>
<p>#!ifdef WITH_IPAUTH<br>
if((!is_method("REGISTER")) && allow_source_address()) {<br>
# source IP allowed<br>
return;<br>
}<br>
#!endif</p>
<pre><code>if (is_method("REGISTER") || from_uri==myself) {
        # authenticate requests
        if (!auth_check("$fd", "subscriber", "1")) {
                auth_challenge("$fd", "0");
                exit;
        }
        # user authenticated - remove auth header
        if(!is_method("REGISTER|PUBLISH"))
                consume_credentials();
}
# if caller is not local subscriber, then check if it calls
# a local destination, otherwise deny, not an open relay here
if (from_uri!=myself && uri!=myself) {
        sl_send_reply("403","Not relaying");
        exit;
}
</code></pre>
<p>#!else</p>
<pre><code># authentication not enabled - do not relay at all to foreign networks
if(uri!=myself) {
        sl_send_reply("403","Not relaying");
        exit;
}
</code></pre>
<p>#!endif<br>
return;<br>
}</p>
<h1>Caller NAT detection</h1>
<p>route[NATDETECT] {<br>
#!ifdef WITH_NAT<br>
force_rport();<br>
if (nat_uac_test("19")) {<br>
if (is_method("REGISTER")) {<br>
fix_nated_register();<br>
} else {<br>
if(is_first_hop()) {<br>
set_contact_alias();<br>
}<br>
}<br>
setflag(FLT_NATS);<br>
}<br>
#!endif<br>
return;<br>
}</p>
<h1>RTPProxy control and signaling updates for NAT traversal</h1>
<p>route[NATMANAGE] {<br>
#!ifdef WITH_NAT<br>
if (is_request()) {<br>
if(has_totag()) {<br>
if(check_route_param("nat=yes")) {<br>
setbflag(FLB_NATB);<br>
}<br>
}<br>
}<br>
if (!(isflagset(FLT_NATS) || isbflagset(FLB_NATB))) return;</p>
<pre><code>if(nat_uac_test("8")) {
        rtpproxy_manage("co");
} else {
        rtpproxy_manage("cor");
}

if (is_request()) {
        if (!has_totag()) {
                if(t_is_branch_route()) {
                        add_rr_param(";nat=yes");
                }
        }
}
if (is_reply()) {
        if(isbflagset(FLB_NATB)) {
                if(is_first_hop())
                        set_contact_alias();
        }
}
</code></pre>
<p>#!endif<br>
return;<br>
}</p>
<h1>URI update for dialog requests</h1>
<p>route[DLGURI] {<br>
#!ifdef WITH_NAT<br>
if(!isdsturiset()) {<br>
handle_ruri_alias();<br>
}<br>
#!endif<br>
return;<br>
}</p>
<h1>Routing to foreign domains</h1>
<p>route[SIPOUT] {<br>
if (uri==myself) return;</p>
<pre><code>append_hf("P-hint: outbound\r\n");
route(RELAY);
exit;
</code></pre>
<p>}</p>
<h1>PSTN GW routing</h1>
<p>route[PSTN] {<br>
#!ifdef WITH_PSTN<br>
# check if PSTN GW IP is defined<br>
if (strempty($sel(cfg_get.pstn.gw_ip))) {<br>
xlog("SCRIPT: PSTN routing enabled but pstn.gw_ip not defined\n");<br>
return;<br>
}</p>
<pre><code># 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;
}

# normalize target number for pstn gateway
# - convert leading 00 to +
if (starts_with("$rU", "00")) {
        strip(2);
        prefix("+");
}

if (strempty($sel(cfg_get.pstn.gw_port))) {
        $ru = "sip:" + $rU + "@" + $sel(cfg_get.pstn.gw_ip);
} else {
        $ru = "sip:" + $rU + "@" + $sel(cfg_get.pstn.gw_ip) + ":"
                                + $sel(cfg_get.pstn.gw_port);
}

route(RELAY);
exit;
</code></pre>
<p>#!endif</p>
<pre><code>return;
</code></pre>
<p>}</p>
<h1>XMLRPC routing</h1>
<p>#!ifdef WITH_XMLRPC<br>
route[XMLRPC] {<br>
# allow XMLRPC from localhost<br>
if ((method=="POST" || method=="GET")<br>
&& (src_ip==127.0.0.1)) {<br>
# close connection only for xmlrpclib user agents (there is a bug in<br>
# xmlrpclib: it waits for EOF before interpreting the response).<br>
if ($hdr(User-Agent) =~ "xmlrpclib")<br>
set_reply_close();<br>
set_reply_no_connect();<br>
dispatch_rpc();<br>
exit;<br>
}<br>
send_reply("403", "Forbidden");<br>
exit;<br>
}<br>
#!endif</p>
<h1>Routing to voicemail server</h1>
<p>route[TOVOICEMAIL] {<br>
#!ifdef WITH_VOICEMAIL<br>
if(!is_method("INVITE|SUBSCRIBE")) return;</p>
<pre><code># check if VoiceMail server IP is defined
if (strempty($sel(cfg_get.voicemail.srv_ip))) {
        xlog("SCRIPT: VoiceMail routing enabled but IP not defined\n");
        return;
}
if(is_method("INVITE")) {
        if($avp(oexten)==$null) return;

        $ru = "sip:" + $avp(oexten) + "@" + $sel(cfg_get.voicemail.srv_ip)
                        + ":" + $sel(cfg_get.voicemail.srv_port);
} else {
        if($rU==$null) return;

        $ru = "sip:" + $rU + "@" + $sel(cfg_get.voicemail.srv_ip)
                        + ":" + $sel(cfg_get.voicemail.srv_port);
}
route(RELAY);
exit;
</code></pre>
<p>#!endif</p>
<pre><code>return;
</code></pre>
<p>}</p>
<h1>Dispatch requests</h1>
<p>route[DISPATCH] {<br>
if(!ds_select_dst("1", "4"))<br>
{<br>
send_reply("404", "No destination");<br>
exit;<br>
}<br>
xlog("L_DBG", "--- SCRIPT: going to <$ru> via <$du>\n");<br>
t_on_failure("RTF_DISPATCH");<br>
return;<br>
}</p>
<p>failure_route[RTF_DISPATCH] {<br>
if (t_is_canceled()) {<br>
exit;<br>
}<br>
if (t_check_status("500")<br>
or (t_branch_timeout() and !t_branch_replied()))<br>
{<br>
if(ds_next_dst())<br>
{<br>
t_on_failure("RTF_DISPATCH");<br>
route(RELAY);<br>
exit;<br>
}<br>
}<br>
}</p>
<h1>Manage outgoing branches</h1>
<p>branch_route[MANAGE_BRANCH] {<br>
xdbg("new branch [$T_branch_idx] to $ru\n");<br>
route(NATMANAGE);<br>
}</p>
<h1>Manage incoming replies</h1>
<p>onreply_route[MANAGE_REPLY] {<br>
xdbg("incoming reply\n");<br>
if(status=~"[12][0-9][0-9]") {<br>
route(NATMANAGE);<br>
}<br>
}</p>
<h1>Manage failure routing cases</h1>
<p>failure_route[MANAGE_FAILURE] {<br>
route(NATMANAGE);</p>
<pre><code>if (t_is_canceled()) exit;
</code></pre>
<p>#!ifdef WITH_BLOCK3XX<br>
# block call redirect based on 3xx replies.<br>
if (t_check_status("3[0-9][0-9]")) {<br>
t_reply("404","Not found");<br>
exit;<br>
}<br>
#!endif</p>
<p>#!ifdef WITH_BLOCK401407<br>
# block call redirect based on 401, 407 replies.<br>
if (t_check_status("401|407")) {<br>
t_reply("404","Not found");<br>
exit;<br>
}<br>
#!endif</p>
<p>#!ifdef WITH_VOICEMAIL<br>
# serial forking<br>
# - route to voicemail on busy or no answer (timeout)<br>
if (t_check_status("486|408")) {<br>
$du = $null;<br>
route(TOVOICEMAIL);<br>
exit;<br>
}<br>
#!endif<br>
}<br>
route[CDRS] {<br>
sql_query("cb","call kamailio_cdrs()","rb");<br>
sql_query("cb","call kamailio_rating('default')","rb");<br>
}</p>

<p style="font-size:small;-webkit-text-size-adjust:none;color:#666;">—<br />You are receiving this because you are subscribed to this thread.<br />Reply to this email directly, <a href="https://github.com/kamailio/kamailio/issues/1841#issuecomment-462615787">view it on GitHub</a>, or <a href="https://github.com/notifications/unsubscribe-auth/AF36ZWtF8OeU8Puxd3nW9Ar8BiiFNO65ks5vMklwgaJpZM4anCmc">mute the thread</a>.<img src="https://github.com/notifications/beacon/AF36Zb-dtaftgAEcM1_-dTHOoGxlcBA2ks5vMklwgaJpZM4anCmc.gif" height="1" width="1" alt="" /></p>
<script type="application/json" data-scope="inboxmarkup">{"api_version":"1.0","publisher":{"api_key":"05dde50f1d1a384dd78767c55493e4bb","name":"GitHub"},"entity":{"external_key":"github/kamailio/kamailio","title":"kamailio/kamailio","subtitle":"GitHub repository","main_image_url":"https://github.githubassets.com/images/email/message_cards/header.png","avatar_image_url":"https://github.githubassets.com/images/email/message_cards/avatar.png","action":{"name":"Open in GitHub","url":"https://github.com/kamailio/kamailio"}},"updates":{"snippets":[{"icon":"PERSON","message":"@alkorik in #1841: This is my config. \r\n#!KAMAILIO\r\n#!define WITH_MYSQL\r\n#!define WITH_AUTH\r\n#!define WITH_USRLOCDB\r\n#!define WITH_PRESENCE\r\n#!define WITH_ACCDB\r\n#\r\n# Kamailio (OpenSER) SIP Server v5.2 - default configuration script\r\n#     - web: https://www.kamailio.org\r\n#     - git: https://github.com/kamailio/kamailio\r\n#\r\n# Direct your questions about this file to: \u003csr-users@lists.kamailio.org\u003e\r\n#\r\n# Refer to the Core CookBook at https://www.kamailio.org/wiki/\r\n# for an explanation of possible statements, functions and parameters.\r\n#\r\n# Note: the comments can be:\r\n#     - lines starting with #, but not the pre-processor directives,\r\n#       which start with #!, like #!define, #!ifdef, #!endif, #!else, #!trydef,\r\n#       #!subst, #!substdef, ...\r\n#     - lines starting with //\r\n#     - blocks enclosed in between /* */\r\n#\r\n# Several features can be enabled using '#!define WITH_FEATURE' directives:\r\n#\r\n# *** To run in debug mode:\r\n#     - define WITH_DEBUG\r\n#\r\n# *** To enable mysql:\r\n#     - define WITH_MYSQL\r\n#\r\n# *** To enable authentication execute:\r\n#     - enable mysql\r\n#     - define WITH_AUTH\r\n#     - add users using 'kamctl'\r\n#\r\n# *** To enable IP authentication execute:\r\n#     - enable mysql\r\n#     - enable authentication\r\n#     - define WITH_IPAUTH\r\n#     - add IP addresses with group id '1' to 'address' table\r\n#\r\n# *** To enable persistent user location execute:\r\n#     - enable mysql\r\n#     - define WITH_USRLOCDB\r\n#\r\n# *** To enable presence server execute:\r\n#     - enable mysql\r\n#     - define WITH_PRESENCE\r\n#\r\n# *** To enable nat traversal execute:\r\n#     - define WITH_NAT\r\n#     - install RTPProxy: http://www.rtpproxy.org\r\n#     - start RTPProxy:\r\n#        rtpproxy -l _your_public_ip_ -s udp:localhost:7722\r\n#     - option for NAT SIP OPTIONS keepalives: WITH_NATSIPPING\r\n#\r\n# *** To enable PSTN gateway routing execute:\r\n#     - define WITH_PSTN\r\n#     - set the value of pstn.gw_ip\r\n#     - check route[PSTN] for regexp routing condition\r\n#\r\n# *** To enable database aliases lookup execute:\r\n#     - enable mysql\r\n#     - define WITH_ALIASDB\r\n#\r\n# *** To enable speed dial lookup execute:\r\n#     - enable mysql\r\n#     - define WITH_SPEEDDIAL\r\n#\r\n# *** To enable multi-domain support execute:\r\n#     - enable mysql\r\n#     - define WITH_MULTIDOMAIN\r\n#\r\n# *** To enable TLS support execute:\r\n#     - adjust CFGDIR/tls.cfg as needed\r\n#     - define WITH_TLS\r\n#\r\n# *** To enable XMLRPC support execute:\r\n#     - define WITH_XMLRPC\r\n#     - adjust route[XMLRPC] for access policy\r\n#\r\n# *** To enable anti-flood detection execute:\r\n#     - adjust pike and htable=\u003eipban settings as needed (default is\r\n#       block if more than 16 requests in 2 seconds and ban for 300 seconds)\r\n#     - define WITH_ANTIFLOOD\r\n#\r\n# *** To block 3XX redirect replies execute:\r\n#     - define WITH_BLOCK3XX\r\n#\r\n# *** To block 401 and 407 authentication replies execute:\r\n#     - define WITH_BLOCK401407\r\n#\r\n# *** To enable VoiceMail routing execute:\r\n#     - define WITH_VOICEMAIL\r\n#     - set the value of voicemail.srv_ip\r\n#     - adjust the value of voicemail.srv_port\r\n#\r\n# *** To enhance accounting execute:\r\n#     - enable mysql\r\n#     - define WITH_ACCDB\r\n#     - add following columns to database\r\n#!ifdef ACCDB_COMMENT\r\n  ALTER TABLE acc ADD COLUMN src_user VARCHAR(64) NOT NULL DEFAULT '';\r\n  ALTER TABLE acc ADD COLUMN src_domain VARCHAR(128) NOT NULL DEFAULT '';\r\n  ALTER TABLE acc ADD COLUMN src_ip varchar(64) NOT NULL default '';\r\n  ALTER TABLE acc ADD COLUMN dst_ouser VARCHAR(64) NOT NULL DEFAULT '';\r\n  ALTER TABLE acc ADD COLUMN dst_user VARCHAR(64) NOT NULL DEFAULT '';\r\n  ALTER TABLE acc ADD COLUMN dst_domain VARCHAR(128) NOT NULL DEFAULT '';\r\n  ALTER TABLE missed_calls ADD COLUMN src_user VARCHAR(64) NOT NULL DEFAULT '';\r\n  ALTER TABLE missed_calls ADD COLUMN src_domain VARCHAR(128) NOT NULL DEFAULT '';\r\n  ALTER TABLE missed_calls ADD COLUMN src_ip varchar(64) NOT NULL default '';\r\n  ALTER TABLE missed_calls ADD COLUMN dst_ouser VARCHAR(64) NOT NULL DEFAULT '';\r\n  ALTER TABLE missed_calls ADD COLUMN dst_user VARCHAR(64) NOT NULL DEFAULT '';\r\n  ALTER TABLE missed_calls ADD COLUMN dst_domain VARCHAR(128) NOT NULL DEFAULT '';\r\n#!endif\r\n\r\n############################################################################## Defined Values ####################################################################\r\n\r\n# *** Value defines - IDs used later in config\r\n#!ifdef WITH_MYSQL\r\n# - database URL - used to connect to database server by modules such\r\n#       as: auth_db, acc, usrloc, a.s.o.\r\n#!ifndef DBURL\r\n#!define DBURL \"mysql://kamailio:kamailiorw@localhost/kamailio\"\r\n#!endif\r\n#!endif\r\n#!ifdef WITH_MULTIDOMAIN\r\n# - the value for 'use_domain' parameters\r\n#!define MULTIDOMAIN 1\r\n#!else\r\n#!define MULTIDOMAIN 0\r\n#!endif\r\n\r\n# - flags\r\n#   FLT_ - per transaction (message) flags\r\n#\tFLB_ - per branch flags\r\n#!define FLT_ACC 1\r\n#!define FLT_ACCMISSED 2\r\n#!define FLT_ACCFAILED 3\r\n#!define FLT_NATS 5\r\n\r\n#!define FLB_NATB 6\r\n#!define FLB_NATSIPPING 7\r\n\r\n####################################################################### Global Parameters ###############################################################\r\n\r\n### LOG Levels: 3=DBG, 2=INFO, 1=NOTICE, 0=WARN, -1=ERR\r\n#!ifdef WITH_DEBUG\r\ndebug=4\r\nlog_stderror=yes\r\n#!else\r\ndebug=3\r\nlog_stderror=yes\r\n#!endif\r\n\r\nmemdbg=5\r\nmemlog=5\r\n\r\nlog_facility=LOG_LOCAL0\r\nlog_prefix=\"{$mt $hdr(CSeq) $ci} \"\r\n\r\n/* number of SIP routing processes */\r\nchildren=8\r\n\r\n/* uncomment the next line to disable TCP (default on) */\r\n# disable_tcp=yes\r\n\r\n/* uncomment the next line to disable the auto discovery of local aliases\r\n * based on reverse DNS on IPs (default on) */\r\n# auto_aliases=no\r\n\r\n/* add local domain aliases */\r\n# alias=\"sip.mydomain.com\"\r\n\r\n/* uncomment and configure the following line if you want Kamailio to\r\n * bind on a specific interface/port/proto (default bind on all available) */\r\n# listen=udp:10.0.0.10:5060\r\n\r\n#!ifdef WITH_TLS\r\nenable_tls=no\r\n#!endif\r\n\r\n/* life time of TCP connection when there is no traffic\r\n * - a bit higher than registration expires to cope with UA behind NAT */\r\ntcp_connection_lifetime=3605\r\n\r\n########################################################################### Custom Parameters ###################################################################\r\n\r\n/* These parameters can be modified runtime via RPC interface\r\n * - see the documentation of 'cfg_rpc' module.\r\n *\r\n * Format: group.id = value 'desc' description\r\n * Access: $sel(cfg_get.group.id) or @cfg_get.group.id */\r\n\r\n#!ifdef WITH_PSTN\r\n/* PSTN GW Routing\r\n *\r\n * - pstn.gw_ip: valid IP or hostname as string value, example:\r\n * pstn.gw_ip = \"10.0.0.101\" desc \"My PSTN GW Address\"\r\n *\r\n * - by default is empty to avoid misrouting */\r\npstn.gw_ip = \"\" desc \"PSTN GW Address\"\r\npstn.gw_port = \"\" desc \"PSTN GW Port\"\r\n#!endif\r\n\r\n#!ifdef WITH_VOICEMAIL\r\n/* VoiceMail Routing on offline, busy or no answer\r\n *\r\n * - by default Voicemail server IP is empty to avoid misrouting */\r\nvoicemail.srv_ip = \"\" desc \"VoiceMail IP Address\"\r\nvoicemail.srv_port = \"5060\" desc \"VoiceMail Port\"\r\n#!endif\r\n\r\n####### Modules Section ########\r\n\r\n/* set paths to location of modules */\r\n# mpath=\"/usr/lib64/kamailio/modules/\"\r\n\r\n#!ifdef WITH_MYSQL\r\nloadmodule \"db_mysql.so\"\r\n#!endif\r\n\r\nloadmodule \"jsonrpcs.so\"\r\nloadmodule \"kex.so\"\r\nloadmodule \"corex.so\"\r\nloadmodule \"tm.so\"\r\nloadmodule \"tmx.so\"\r\nloadmodule \"sl.so\"\r\nloadmodule \"rr.so\"\r\nloadmodule \"pv.so\"\r\nloadmodule \"maxfwd.so\"\r\nloadmodule \"usrloc.so\"\r\nloadmodule \"registrar.so\"\r\nloadmodule \"textops.so\"\r\nloadmodule \"siputils.so\"\r\nloadmodule \"xlog.so\"\r\nloadmodule \"sanity.so\"\r\nloadmodule \"ctl.so\"\r\nloadmodule \"cfg_rpc.so\"\r\nloadmodule \"acc.so\"\r\nloadmodule \"counters.so\"\r\nloadmodule \"rtimer.so\" \r\nloadmodule \"sqlops.so\"\r\nloadmodule \"dispatcher.so\" \r\n\r\n#!ifdef WITH_AUTH\r\nloadmodule \"auth.so\"\r\nloadmodule \"auth_db.so\"\r\n#!ifdef WITH_IPAUTH\r\nloadmodule \"permissions.so\"\r\n#!endif\r\n#!endif\r\n\r\n#!ifdef WITH_ALIASDB\r\nloadmodule \"alias_db.so\"\r\n#!endif\r\n\r\n#!ifdef WITH_SPEEDDIAL\r\nloadmodule \"speeddial.so\"\r\n#!endif\r\n\r\n#!ifdef WITH_MULTIDOMAIN\r\nloadmodule \"domain.so\"\r\n#!endif\r\n\r\n#!ifdef WITH_PRESENCE\r\nloadmodule \"presence.so\"\r\nloadmodule \"presence_xml.so\"\r\n#!endif\r\n\r\n#!ifdef WITH_NAT\r\nloadmodule \"nathelper.so\"\r\nloadmodule \"rtpproxy.so\"\r\n#!endif\r\n\r\n#!ifdef WITH_TLS\r\nloadmodule \"tls.so\"\r\n#!endif\r\n\r\n#!ifdef WITH_ANTIFLOOD\r\nloadmodule \"htable.so\"\r\nloadmodule \"pike.so\"\r\n#!endif\r\n\r\n#!ifdef WITH_XMLRPC\r\nloadmodule \"xmlrpc.so\"\r\n#!endif\r\n\r\n#!ifdef WITH_DEBUG\r\nloadmodule \"debugger.so\"\r\n#!endif\r\n\r\n# ----------------- setting module-specific parameters ---------------\r\n\r\n\r\n# ----- jsonrpcs params -----\r\nmodparam(\"jsonrpcs\", \"pretty_format\", 1)\r\n/* set the path to RPC fifo control file */\r\n# modparam(\"jsonrpcs\", \"fifo_name\", \"/var/run/kamailio/kamailio_rpc.fifo\")\r\n/* set the path to RPC unix socket control file */\r\n# modparam(\"jsonrpcs\", \"dgram_socket\", \"/var/run/kamailio/kamailio_rpc.sock\")\r\n\r\n# ----- ctl params -----\r\n/* set the path to RPC unix socket control file */\r\n# modparam(\"ctl\", \"binrpc\", \"unix:/var/run/kamailio/kamailio_ctl\")\r\n\r\n# ----- tm params -----\r\n# auto-discard branches from previous serial forking leg\r\nmodparam(\"tm\", \"failure_reply_mode\", 3)\r\n# default retransmission timeout: 30sec\r\nmodparam(\"tm\", \"fr_timer\", 30000)\r\n# default invite retransmission timeout after 1xx: 120sec\r\nmodparam(\"tm\", \"fr_inv_timer\", 120000)\r\n\r\n# ----- rr params -----\r\n# set next param to 1 to add value to ;lr param (helps with some UAs)\r\nmodparam(\"rr\", \"enable_full_lr\", 0)\r\n# do not append from tag to the RR (no need for this script)\r\nmodparam(\"rr\", \"append_fromtag\", 0)\r\n\r\n# ----- registrar params -----\r\nmodparam(\"registrar\", \"method_filtering\", 1)\r\n/* uncomment the next line to disable parallel forking via location */\r\n# modparam(\"registrar\", \"append_branches\", 0)\r\n/* uncomment the next line not to allow more than 10 contacts per AOR */\r\n# modparam(\"registrar\", \"max_contacts\", 10)\r\n/* max value for expires of registrations */\r\nmodparam(\"registrar\", \"max_expires\", 3600)\r\n/* set it to 1 to enable GRUU */\r\nmodparam(\"registrar\", \"gruu_enabled\", 0)\r\n\r\n# ----- acc params -----\r\n/* what special events should be accounted ? */\r\nmodparam(\"acc\", \"early_media\", 0)\r\nmodparam(\"acc\", \"report_ack\", 0)\r\nmodparam(\"acc\", \"report_cancels\", 0)\r\n/* by default ww do not adjust the direct of the sequential requests.\r\n * if you enable this parameter, be sure the enable \"append_fromtag\"\r\n * in \"rr\" module */\r\nmodparam(\"acc\", \"detect_direction\", 0)\r\n/* account triggers (flags) */\r\nmodparam(\"acc\", \"log_flag\", FLT_ACC)\r\nmodparam(\"acc\", \"log_missed_flag\", FLT_ACCMISSED)\r\nmodparam(\"acc\", \"log_extra\",\r\n\t\"src_user=$fU;src_domain=$fd;src_ip=$si;\"\r\n\t\"dst_ouser=$tU;dst_user=$rU;dst_domain=$rd\")\r\nmodparam(\"acc\", \"failed_transaction_flag\", FLT_ACCFAILED)\r\n/* enhanced DB accounting */\r\n#!ifdef WITH_ACCDB\r\nmodparam(\"acc\", \"db_flag\", FLT_ACC)\r\nmodparam(\"acc\", \"db_missed_flag\", FLT_ACCMISSED)\r\nmodparam(\"acc\", \"db_url\", DBURL)\r\nmodparam(\"acc\", \"db_extra\",\r\n\t\"src_user=$fU;src_domain=$fd;src_ip=$si;\"\r\n\t\"dst_ouser=$tU;dst_user=$rU;dst_domain=$rd\")\r\n#!endif\r\n\r\n# ----- usrloc params -----\r\n/* enable DB persistency for location entries */\r\n#!ifdef WITH_USRLOCDB\r\nmodparam(\"usrloc\", \"db_url\", DBURL)\r\nmodparam(\"usrloc\", \"db_mode\", 2)\r\nmodparam(\"usrloc\", \"use_domain\", MULTIDOMAIN)\r\n#!endif\r\n\r\n# ----- auth_db params -----\r\n#!ifdef WITH_AUTH\r\nmodparam(\"auth_db\", \"db_url\", DBURL)\r\nmodparam(\"auth_db\", \"calculate_ha1\", yes)\r\nmodparam(\"auth_db\", \"password_column\", \"password\")\r\nmodparam(\"auth_db\", \"load_credentials\", \"\")\r\nmodparam(\"auth_db\", \"use_domain\", MULTIDOMAIN)\r\n\r\n# ----- permissions params -----\r\n#!ifdef WITH_IPAUTH\r\nmodparam(\"permissions\", \"db_url\", DBURL)\r\nmodparam(\"permissions\", \"db_mode\", 1)\r\n#!endif\r\n\r\n#!endif\r\n\r\n# ----- alias_db params -----\r\n#!ifdef WITH_ALIASDB\r\nmodparam(\"alias_db\", \"db_url\", DBURL)\r\nmodparam(\"alias_db\", \"use_domain\", MULTIDOMAIN)\r\n#!endif\r\n\r\n# ----- speeddial params -----\r\n#!ifdef WITH_SPEEDDIAL\r\nmodparam(\"speeddial\", \"db_url\", DBURL)\r\nmodparam(\"speeddial\", \"use_domain\", MULTIDOMAIN)\r\n#!endif\r\n\r\n# ----- domain params -----\r\n#!ifdef WITH_MULTIDOMAIN\r\nmodparam(\"domain\", \"db_url\", DBURL)\r\n/* register callback to match myself condition with domains list */\r\nmodparam(\"domain\", \"register_myself\", 1)\r\n#!endif\r\n\r\n#!ifdef WITH_PRESENCE\r\n# ----- presence params -----\r\nmodparam(\"presence\", \"db_url\", DBURL)\r\n\r\n# ----- presence_xml params -----\r\nmodparam(\"presence_xml\", \"db_url\", DBURL)\r\nmodparam(\"presence_xml\", \"force_active\", 1)\r\n#!endif\r\n\r\n#!ifdef WITH_NAT\r\n# ----- rtpproxy params -----\r\nmodparam(\"rtpproxy\", \"rtpproxy_sock\", \"udp:127.0.0.1:7722\")\r\n\r\n# ----- nathelper params -----\r\nmodparam(\"nathelper\", \"natping_interval\", 30)\r\nmodparam(\"nathelper\", \"ping_nated_only\", 1)\r\nmodparam(\"nathelper\", \"sipping_bflag\", FLB_NATSIPPING)\r\nmodparam(\"nathelper\", \"sipping_from\", \"sip:pinger@kamailio.org\")\r\n\r\n# params needed for NAT traversal in other modules\r\nmodparam(\"nathelper|registrar\", \"received_avp\", \"$avp(RECEIVED)\")\r\nmodparam(\"usrloc\", \"nat_bflag\", FLB_NATB)\r\n#!endif\r\n\r\n#!ifdef WITH_TLS\r\n# ----- tls params -----\r\nmodparam(\"tls\", \"config\", \"/etc/kamailio/tls.cfg\")\r\n#!endif\r\n\r\n#!ifdef WITH_ANTIFLOOD\r\n# ----- pike params -----\r\nmodparam(\"pike\", \"sampling_time_unit\", 2)\r\nmodparam(\"pike\", \"reqs_density_per_unit\", 16)\r\nmodparam(\"pike\", \"remove_latency\", 4)\r\n\r\n# ----- htable params -----\r\n/* ip ban htable with autoexpire after 5 minutes */\r\nmodparam(\"htable\", \"htable\", \"ipban=\u003esize=8;autoexpire=300;\")\r\n#!endif\r\n\r\n#!ifdef WITH_XMLRPC\r\n# ----- xmlrpc params -----\r\nmodparam(\"xmlrpc\", \"route\", \"XMLRPC\");\r\nmodparam(\"xmlrpc\", \"url_match\", \"^/RPC\")\r\n#!endif\r\n\r\n#!ifdef WITH_DEBUG\r\n# ----- debugger params -----\r\nmodparam(\"debugger\", \"cfgtrace\", 1)\r\nmodparam(\"debugger\", \"log_level_name\", \"exec\")\r\n#!endif\r\n\r\nmodparam(\"rtimer\", \"timer\", \"name=cdr;interval=300;mode=1;\")\r\nmodparam(\"rtimer\", \"exec\", \"timer=cdr;route=CDRS\")\r\nmodparam(\"sqlops\", \"sqlcon\", \"cb=\u003emysql://kamailio:kamailiorw@localhost/kamailio\")\r\n\r\n# ----- dispatcher params -----\r\n#modparam(\"dispatcher\", \"db_url\", \"mysql://kamailio:kamailiorw@localhost/kamailio\")\r\nmodparam(\"dispatcher\", \"list_file\", \"/etc/kamailio/dispatcher.list\")\r\nmodparam(\"dispatcher\", \"ds_ping_interval\", 30)\r\n\r\n\r\n########################################################## Routing Logic #################################################################################\r\n\r\n\r\n/* Main SIP request routing logic\r\n * - processing of any incoming SIP request starts with this route\r\n * - note: this is the same as route { ... } */\r\n\r\nrequest_route {\r\n\r\n\t# per request initial checks\r\n\troute(REQINIT);\r\n\r\n\t# NAT detection\r\n\troute(NATDETECT);\r\n\tt_check_trans();\r\n\t\r\n\tif ( method==\"INVITE\" ) {\r\n\t\tds_select_dst(\"1\",\"4\");\r\n\t\tsl_send_reply(\"100\",\"Trying\");\r\n\t\tforward();\r\n\t\texit();\r\n\t}\r\n\r\n\t# CANCEL processing\r\n\tif (is_method(\"CANCEL\")) {\r\n\t\tif (t_check_trans()) {\r\n\t\t\troute(RELAY);\r\n\t\t}\r\n\t\texit;\r\n\t}\r\n\r\n\t# handle retransmissions\r\n\tif (!is_method(\"ACK\")) {\r\n\t\tif(t_precheck_trans()) {\r\n\t\t\tt_check_trans();\r\n\t\t\texit;\r\n\t\t}\r\n\t\tt_check_trans();\r\n\t}\r\n\r\n\t# handle requests within SIP dialogs\r\n\troute(WITHINDLG);\r\n\r\n\t### only initial requests (no To tag)\r\n\r\n\t# authentication\r\n\troute(AUTH);\r\n\r\n\t# record routing for dialog forming requests (in case they are routed)\r\n\t# - remove preloaded route headers\r\n\tremove_hf(\"Route\");\r\n\tif (is_method(\"INVITE|SUBSCRIBE\")) {\r\n\t\trecord_route();\r\n\t}\r\n\r\n\t# account only INVITEs\r\n\tif (is_method(\"INVITE\")) {\r\n\t\tsetflag(FLT_ACC); # do accounting\r\n\t}\r\n\r\n\t# dispatch requests to foreign domains\r\n\troute(SIPOUT);\r\n\r\n\t### requests for my local domains\r\n\r\n\t# handle presence related requests\r\n\troute(PRESENCE);\r\n\r\n\t# handle registrations\r\n\troute(REGISTRAR);\r\n\r\n\tif ($rU==$null) {\r\n\t\t# request with no Username in RURI\r\n\t\tsl_send_reply(\"484\",\"Address Incomplete\");\r\n\t\texit;\r\n\t}\r\n\r\n\t# dispatch destinations to PSTN\r\n\troute(PSTN);\r\n\r\n\t# user location service\r\n\troute(LOCATION);\r\n}\r\n\r\n# Wrapper for relaying requests\r\nroute[RELAY] {\r\n\r\n\t# enable additional event routes for forwarded requests\r\n\t# - serial forking, RTP relaying handling, a.s.o.\r\n\tif (is_method(\"INVITE|BYE|SUBSCRIBE|UPDATE\")) {\r\n\t\tif(!t_is_set(\"branch_route\")) t_on_branch(\"MANAGE_BRANCH\");\r\n\t}\r\n\tif (is_method(\"INVITE|SUBSCRIBE|UPDATE\")) {\r\n\t\tif(!t_is_set(\"onreply_route\")) t_on_reply(\"MANAGE_REPLY\");\r\n\t}\r\n\tif (is_method(\"INVITE\")) {\r\n\t\tif(!t_is_set(\"failure_route\")) t_on_failure(\"MANAGE_FAILURE\");\r\n\t}\r\n\r\n\tif (!t_relay()) {\r\n\t\tsl_reply_error();\r\n\t}\r\n\texit;\r\n}\r\n\r\n# Per SIP request initial checks\r\nroute[REQINIT] {\r\n#!ifdef WITH_ANTIFLOOD\r\n\t# flood detection from same IP and traffic ban for a while\r\n\t# be sure you exclude checking trusted peers, such as pstn gateways\r\n\t# - local host excluded (e.g., loop to self)\r\n\tif(src_ip!=myself) {\r\n\t\tif($sht(ipban=\u003e$si)!=$null) {\r\n\t\t\t# ip is already blocked\r\n\t\t\txdbg(\"request from blocked IP - $rm from $fu (IP:$si:$sp)\\n\");\r\n\t\t\texit;\r\n\t\t}\r\n\t\tif (!pike_check_req()) {\r\n\t\t\txlog(\"L_ALERT\",\"ALERT: pike blocking $rm from $fu (IP:$si:$sp)\\n\");\r\n\t\t\t$sht(ipban=\u003e$si) = 1;\r\n\t\t\texit;\r\n\t\t}\r\n\t}\r\n#!endif\r\n\tif($ua =~ \"friendly-scanner|sipcli|VaxSIPUserAgent\") {\r\n\t\t# silent drop for scanners - uncomment next line if want to reply\r\n\t\t# sl_send_reply(\"200\", \"OK\");\r\n\t\texit;\r\n\t}\r\n\r\n\tif (!mf_process_maxfwd_header(\"10\")) {\r\n\t\tsl_send_reply(\"483\",\"Too Many Hops\");\r\n\t\texit;\r\n\t}\r\n\r\n\tif(is_method(\"OPTIONS\") \u0026\u0026 uri==myself \u0026\u0026 $rU==$null) {\r\n\t\tsl_send_reply(\"200\",\"Keepalive\");\r\n\t\texit;\r\n\t}\r\n\r\n\tif(!sanity_check(\"17895\", \"7\")) {\r\n\t\txlog(\"Malformed SIP message from $si:$sp\\n\");\r\n\t\texit;\r\n\t}\r\n}\r\n\r\n# Handle requests within SIP dialogs\r\nroute[WITHINDLG] {\r\n\tif (!has_totag()) return;\r\n\r\n\t# sequential request withing a dialog should\r\n\t# take the path determined by record-routing\r\n\tif (loose_route()) {\r\n\t\troute(DLGURI);\r\n\t\tif (is_method(\"BYE\")) {\r\n\t\t\tsetflag(FLT_ACC); # do accounting ...\r\n\t\t\tsetflag(FLT_ACCFAILED); # ... even if the transaction fails\r\n\t\t} else if ( is_method(\"ACK\") ) {\r\n\t\t\t# ACK is forwarded statelessly\r\n\t\t\troute(NATMANAGE);\r\n\t\t} else if ( is_method(\"NOTIFY\") ) {\r\n\t\t\t# Add Record-Route for in-dialog NOTIFY as per RFC 6665.\r\n\t\t\trecord_route();\r\n\t\t}\r\n\t\troute(RELAY);\r\n\t\texit;\r\n\t}\r\n\r\n\tif (is_method(\"SUBSCRIBE\") \u0026\u0026 uri == myself) {\r\n\t\t# in-dialog subscribe requests\r\n\t\troute(PRESENCE);\r\n\t\texit;\r\n\t}\r\n\tif ( is_method(\"ACK\") ) {\r\n\t\tif ( t_check_trans() ) {\r\n\t\t\t# no loose-route, but stateful ACK;\r\n\t\t\t# must be an ACK after a 487\r\n\t\t\t# or e.g. 404 from upstream server\r\n\t\t\troute(RELAY);\r\n\t\t\texit;\r\n\t\t} else {\r\n\t\t\t# ACK without matching transaction ... ignore and discard\r\n\t\t\texit;\r\n\t\t}\r\n\t}\r\n\tsl_send_reply(\"404\",\"Not here\");\r\n\texit;\r\n}\r\n\r\n# Handle SIP registrations\r\nroute[REGISTRAR] {\r\n\tif (!is_method(\"REGISTER\")) return;\r\n\r\n\tif(isflagset(FLT_NATS)) {\r\n\t\tsetbflag(FLB_NATB);\r\n#!ifdef WITH_NATSIPPING\r\n\t\t# do SIP NAT pinging\r\n\t\tsetbflag(FLB_NATSIPPING);\r\n#!endif\r\n\t}\r\n\tif (!save(\"location\")) {\r\n\t\tsl_reply_error();\r\n\t}\r\n\texit;\r\n}\r\n\r\n# User location service\r\nroute[LOCATION] {\r\n\r\n#!ifdef WITH_SPEEDDIAL\r\n\t# search for short dialing - 2-digit extension\r\n\tif($rU=~\"^[0-9][0-9]$\") {\r\n\t\tif(sd_lookup(\"speed_dial\")) {\r\n\t\t\troute(SIPOUT);\r\n\t\t}\r\n\t}\r\n#!endif\r\n\r\n#!ifdef WITH_ALIASDB\r\n\t# search in DB-based aliases\r\n\tif(alias_db_lookup(\"dbaliases\")) {\r\n\t\troute(SIPOUT);\r\n\t}\r\n#!endif\r\n\r\n\t$avp(oexten) = $rU;\r\n\tif (!lookup(\"location\")) {\r\n\t\t$var(rc) = $rc;\r\n\t\troute(TOVOICEMAIL);\r\n\t\tt_newtran();\r\n\t\tswitch ($var(rc)) {\r\n\t\t\tcase -1:\r\n\t\t\tcase -3:\r\n\t\t\t\tsend_reply(\"404\", \"Not Found\");\r\n\t\t\t\texit;\r\n\t\t\tcase -2:\r\n\t\t\t\tsend_reply(\"405\", \"Method Not Allowed\");\r\n\t\t\t\texit;\r\n\t\t}\r\n\t}\r\n\r\n\t# when routing via usrloc, log the missed calls also\r\n\tif (is_method(\"INVITE\")) {\r\n\t\tsetflag(FLT_ACCMISSED);\r\n\t}\r\n\r\n\troute(RELAY);\r\n\texit;\r\n}\r\n\r\n# Presence server processing\r\nroute[PRESENCE] {\r\n\tif(!is_method(\"PUBLISH|SUBSCRIBE\")) return;\r\n\r\n\tif(is_method(\"SUBSCRIBE\") \u0026\u0026 $hdr(Event)==\"message-summary\") {\r\n\t\troute(TOVOICEMAIL);\r\n\t\t# returns here if no voicemail server is configured\r\n\t\tsl_send_reply(\"404\", \"No voicemail service\");\r\n\t\texit;\r\n\t}\r\n\r\n#!ifdef WITH_PRESENCE\r\n\tif (!t_newtran()) {\r\n\t\tsl_reply_error();\r\n\t\texit;\r\n\t}\r\n\r\n\tif(is_method(\"PUBLISH\")) {\r\n\t\thandle_publish();\r\n\t\tt_release();\r\n\t} else if(is_method(\"SUBSCRIBE\")) {\r\n\t\thandle_subscribe();\r\n\t\tt_release();\r\n\t}\r\n\texit;\r\n#!endif\r\n\r\n\t# if presence enabled, this part will not be executed\r\n\tif (is_method(\"PUBLISH\") || $rU==$null) {\r\n\t\tsl_send_reply(\"404\", \"Not here\");\r\n\t\texit;\r\n\t}\r\n\treturn;\r\n}\r\n\r\n# IP authorization and user authentication\r\nroute[AUTH] {\r\n#!ifdef WITH_AUTH\r\n\r\n#!ifdef WITH_IPAUTH\r\n\tif((!is_method(\"REGISTER\")) \u0026\u0026 allow_source_address()) {\r\n\t\t# source IP allowed\r\n\t\treturn;\r\n\t}\r\n#!endif\r\n\r\n\tif (is_method(\"REGISTER\") || from_uri==myself) {\r\n\t\t# authenticate requests\r\n\t\tif (!auth_check(\"$fd\", \"subscriber\", \"1\")) {\r\n\t\t\tauth_challenge(\"$fd\", \"0\");\r\n\t\t\texit;\r\n\t\t}\r\n\t\t# user authenticated - remove auth header\r\n\t\tif(!is_method(\"REGISTER|PUBLISH\"))\r\n\t\t\tconsume_credentials();\r\n\t}\r\n\t# if caller is not local subscriber, then check if it calls\r\n\t# a local destination, otherwise deny, not an open relay here\r\n\tif (from_uri!=myself \u0026\u0026 uri!=myself) {\r\n\t\tsl_send_reply(\"403\",\"Not relaying\");\r\n\t\texit;\r\n\t}\r\n\r\n#!else\r\n\r\n\t# authentication not enabled - do not relay at all to foreign networks\r\n\tif(uri!=myself) {\r\n\t\tsl_send_reply(\"403\",\"Not relaying\");\r\n\t\texit;\r\n\t}\r\n\r\n#!endif\r\n\treturn;\r\n}\r\n\r\n# Caller NAT detection\r\nroute[NATDETECT] {\r\n#!ifdef WITH_NAT\r\n\tforce_rport();\r\n\tif (nat_uac_test(\"19\")) {\r\n\t\tif (is_method(\"REGISTER\")) {\r\n\t\t\tfix_nated_register();\r\n\t\t} else {\r\n\t\t\tif(is_first_hop()) {\r\n\t\t\t\tset_contact_alias();\r\n\t\t\t}\r\n\t\t}\r\n\t\tsetflag(FLT_NATS);\r\n\t}\r\n#!endif\r\n\treturn;\r\n}\r\n\r\n# RTPProxy control and signaling updates for NAT traversal\r\nroute[NATMANAGE] {\r\n#!ifdef WITH_NAT\r\n\tif (is_request()) {\r\n\t\tif(has_totag()) {\r\n\t\t\tif(check_route_param(\"nat=yes\")) {\r\n\t\t\t\tsetbflag(FLB_NATB);\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\tif (!(isflagset(FLT_NATS) || isbflagset(FLB_NATB))) return;\r\n\r\n\tif(nat_uac_test(\"8\")) {\r\n\t\trtpproxy_manage(\"co\");\r\n\t} else {\r\n\t\trtpproxy_manage(\"cor\");\r\n\t}\r\n\r\n\tif (is_request()) {\r\n\t\tif (!has_totag()) {\r\n\t\t\tif(t_is_branch_route()) {\r\n\t\t\t\tadd_rr_param(\";nat=yes\");\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\tif (is_reply()) {\r\n\t\tif(isbflagset(FLB_NATB)) {\r\n\t\t\tif(is_first_hop())\r\n\t\t\t\tset_contact_alias();\r\n\t\t}\r\n\t}\r\n#!endif\r\n\treturn;\r\n}\r\n\r\n# URI update for dialog requests\r\nroute[DLGURI] {\r\n#!ifdef WITH_NAT\r\n\tif(!isdsturiset()) {\r\n\t\thandle_ruri_alias();\r\n\t}\r\n#!endif\r\n\treturn;\r\n}\r\n\r\n# Routing to foreign domains\r\nroute[SIPOUT] {\r\n\tif (uri==myself) return;\r\n\r\n\tappend_hf(\"P-hint: outbound\\r\\n\");\r\n\troute(RELAY);\r\n\texit;\r\n}\r\n\r\n# PSTN GW routing\r\nroute[PSTN] {\r\n#!ifdef WITH_PSTN\r\n\t# check if PSTN GW IP is defined\r\n\tif (strempty($sel(cfg_get.pstn.gw_ip))) {\r\n\t\txlog(\"SCRIPT: PSTN routing enabled but pstn.gw_ip not defined\\n\");\r\n\t\treturn;\r\n\t}\r\n\r\n\t# route to PSTN dialed numbers starting with '+' or '00'\r\n\t#     (international format)\r\n\t# - update the condition to match your dialing rules for PSTN routing\r\n\tif(!($rU=~\"^(\\+|00)[1-9][0-9]{3,20}$\")) return;\r\n\r\n\t# only local users allowed to call\r\n\tif(from_uri!=myself) {\r\n\t\tsl_send_reply(\"403\", \"Not Allowed\");\r\n\t\texit;\r\n\t}\r\n\r\n\t# normalize target number for pstn gateway\r\n\t# - convert leading 00 to +\r\n\tif (starts_with(\"$rU\", \"00\")) {\r\n\t\tstrip(2);\r\n\t\tprefix(\"+\");\r\n\t}\r\n\r\n\tif (strempty($sel(cfg_get.pstn.gw_port))) {\r\n\t\t$ru = \"sip:\" + $rU + \"@\" + $sel(cfg_get.pstn.gw_ip);\r\n\t} else {\r\n\t\t$ru = \"sip:\" + $rU + \"@\" + $sel(cfg_get.pstn.gw_ip) + \":\"\r\n\t\t\t\t\t+ $sel(cfg_get.pstn.gw_port);\r\n\t}\r\n\r\n\troute(RELAY);\r\n\texit;\r\n#!endif\r\n\r\n\treturn;\r\n}\r\n\r\n# XMLRPC routing\r\n#!ifdef WITH_XMLRPC\r\nroute[XMLRPC] {\r\n\t# allow XMLRPC from localhost\r\n\tif ((method==\"POST\" || method==\"GET\")\r\n\t\t\t\u0026\u0026 (src_ip==127.0.0.1)) {\r\n\t\t# close connection only for xmlrpclib user agents (there is a bug in\r\n\t\t# xmlrpclib: it waits for EOF before interpreting the response).\r\n\t\tif ($hdr(User-Agent) =~ \"xmlrpclib\")\r\n\t\t\tset_reply_close();\r\n\t\tset_reply_no_connect();\r\n\t\tdispatch_rpc();\r\n\t\texit;\r\n\t}\r\n\tsend_reply(\"403\", \"Forbidden\");\r\n\texit;\r\n}\r\n#!endif\r\n\r\n# Routing to voicemail server\r\nroute[TOVOICEMAIL] {\r\n#!ifdef WITH_VOICEMAIL\r\n\tif(!is_method(\"INVITE|SUBSCRIBE\")) return;\r\n\r\n\t# check if VoiceMail server IP is defined\r\n\tif (strempty($sel(cfg_get.voicemail.srv_ip))) {\r\n\t\txlog(\"SCRIPT: VoiceMail routing enabled but IP not defined\\n\");\r\n\t\treturn;\r\n\t}\r\n\tif(is_method(\"INVITE\")) {\r\n\t\tif($avp(oexten)==$null) return;\r\n\r\n\t\t$ru = \"sip:\" + $avp(oexten) + \"@\" + $sel(cfg_get.voicemail.srv_ip)\r\n\t\t\t\t+ \":\" + $sel(cfg_get.voicemail.srv_port);\r\n\t} else {\r\n\t\tif($rU==$null) return;\r\n\r\n\t\t$ru = \"sip:\" + $rU + \"@\" + $sel(cfg_get.voicemail.srv_ip)\r\n\t\t\t\t+ \":\" + $sel(cfg_get.voicemail.srv_port);\r\n\t}\r\n\troute(RELAY);\r\n\texit;\r\n#!endif\r\n\r\n\treturn;\r\n}\r\n\r\n# Dispatch requests\r\nroute[DISPATCH] {\r\nif(!ds_select_dst(\"1\", \"4\"))\r\n{\r\nsend_reply(\"404\", \"No destination\");\r\nexit;\r\n}\r\nxlog(\"L_DBG\", \"--- SCRIPT: going to \u003c$ru\u003e via \u003c$du\u003e\\n\");\r\nt_on_failure(\"RTF_DISPATCH\");\r\nreturn;\r\n}\r\n\r\nfailure_route[RTF_DISPATCH] {\r\nif (t_is_canceled()) {\r\nexit;\r\n}\r\nif (t_check_status(\"500\")\r\nor (t_branch_timeout() and !t_branch_replied()))\r\n{\r\nif(ds_next_dst())\r\n{\r\nt_on_failure(\"RTF_DISPATCH\");\r\nroute(RELAY);\r\nexit;\r\n}\r\n}\r\n}\r\n\r\n# Manage outgoing branches\r\nbranch_route[MANAGE_BRANCH] {\r\n\txdbg(\"new branch [$T_branch_idx] to $ru\\n\");\r\n\troute(NATMANAGE);\r\n}\r\n\r\n# Manage incoming replies\r\nonreply_route[MANAGE_REPLY] {\r\n\txdbg(\"incoming reply\\n\");\r\n\tif(status=~\"[12][0-9][0-9]\") {\r\n\t\troute(NATMANAGE);\r\n\t}\r\n}\r\n\r\n# Manage failure routing cases\r\nfailure_route[MANAGE_FAILURE] {\r\n\troute(NATMANAGE);\r\n\r\n\tif (t_is_canceled()) exit;\r\n\r\n#!ifdef WITH_BLOCK3XX\r\n\t# block call redirect based on 3xx replies.\r\n\tif (t_check_status(\"3[0-9][0-9]\")) {\r\n\t\tt_reply(\"404\",\"Not found\");\r\n\t\texit;\r\n\t}\r\n#!endif\r\n\r\n#!ifdef WITH_BLOCK401407\r\n\t# block call redirect based on 401, 407 replies.\r\n\tif (t_check_status(\"401|407\")) {\r\n\t\tt_reply(\"404\",\"Not found\");\r\n\t\texit;\r\n\t}\r\n#!endif\r\n\r\n#!ifdef WITH_VOICEMAIL\r\n\t# serial forking\r\n\t# - route to voicemail on busy or no answer (timeout)\r\n\tif (t_check_status(\"486|408\")) {\r\n\t\t$du = $null;\r\n\t\troute(TOVOICEMAIL);\r\n\t\texit;\r\n\t}\r\n#!endif\r\n}\r\nroute[CDRS] {\r\n    sql_query(\"cb\",\"call kamailio_cdrs()\",\"rb\");\r\n    sql_query(\"cb\",\"call kamailio_rating('default')\",\"rb\");\r\n    }"}],"action":{"name":"View Issue","url":"https://github.com/kamailio/kamailio/issues/1841#issuecomment-462615787"}}}</script>
<script type="application/ld+json">[
{
"@context": "http://schema.org",
"@type": "EmailMessage",
"potentialAction": {
"@type": "ViewAction",
"target": "https://github.com/kamailio/kamailio/issues/1841#issuecomment-462615787",
"url": "https://github.com/kamailio/kamailio/issues/1841#issuecomment-462615787",
"name": "View Issue"
},
"description": "View this Issue on GitHub",
"publisher": {
"@type": "Organization",
"name": "GitHub",
"url": "https://github.com"
}
}
]</script>