You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

690 lines
19 KiB

## NOTE: DO NOT CHANGE THIS FILE, EDIT local.cfg ##
####### Flags #######
flags
FLAG_INTERNALLY_SOURCED: 1,
FLAG_ASSOCIATE_SERVER: 2,
FLAG_SKIP_NAT_CORRECTION: 3,
FLAG_ASSOCIATE_USER: 4,
FLAG_TRUSTED_SOURCE: 5,
FLAG_SESSION_PROGRESS: 6;
####### Global Parameters #########
fork = yes
children = 25
server_signature = no
server_header = "Server: Kazoo"
user_agent_header = "User-Agent: Kazoo"
shm_force_alloc = yes
mlock_pages = yes
phone2tel = 1
max_while_loops = 500
####### Logging Parameters #########
debug = L_INFO
memdbg = 10
memlog = L_INFO
corelog = L_ERR
mem_summary = 12
log_stderror = no
log_facility = LOG_LOCAL0
log_name="kamailio"
####### Alias Parameters #########
auto_aliases = yes
####### Binding Parameters #########
tos = IPTOS_LOWDELAY
####### TCP Parameters #########
tcp_children = 25
disable_tcp = no
tcp_max_connections = 4096
tcp_connection_lifetime = 3605
tcp_accept_aliases = no
tcp_async = yes
tcp_connect_timeout = 10
tcp_conn_wq_max = 65536
tcp_crlf_ping = yes
tcp_delayed_ack = yes
tcp_fd_cache = yes
tcp_keepalive = yes
tcp_keepcnt = 3
tcp_keepidle = 30
tcp_keepintvl = 10
tcp_linger2 = 30
tcp_rd_buf_size = 80000
tcp_send_timeout = 10
tcp_wq_blk_size = 2100
tcp_wq_max = 10485760
####### UDP Parameters #########
udp4_raw = -1
####### DNS Parameters #########
dns = no
rev_dns = no
dns_try_ipv6 = no
use_dns_cache = on
dns_cache_del_nonexp = no
dns_cache_flags = 1
dns_cache_gc_interval = 120
dns_cache_init = 1
dns_cache_mem = 1000
dns_cache_negative_ttl = 60
dns_try_naptr = no
use_dns_failover = off
dns_srv_lb = off
####### SCTP Parameters #########
disable_sctp = yes
####### Modules Section ########
mpath="/usr/lib64/kamailio/modules/"
######## Kamailio control connector module ########
loadmodule "ctl.so"
######## Kamailio core extensions module ########
loadmodule "kex.so"
######## Transaction (stateful) module ########
loadmodule "tm.so"
loadmodule "tmx.so"
modparam("tm", "auto_inv_100", 1)
modparam("tm", "auto_inv_100_reason", "Attempting to connect your call")
modparam("tm", "cancel_b_method", 2)
modparam("tm", "ruri_matching", 0)
modparam("tm", "failure_reply_mode", 3)
# modparam("tm", "fr_timer", 30000)
# modparam("tm", "fr_inv_timer", 120000)
######## Stateless replier module ########
loadmodule "sl.so"
######## Record-Route and Route module ########
loadmodule "rr.so"
modparam("rr", "enable_full_lr", 1)
modparam("rr", "enable_double_rr", 1)
######## Max-Forward processor module ########
loadmodule "maxfwd.so"
modparam("maxfwd", "max_limit", 50)
######## SIP utilities [requires sl] ########
loadmodule "siputils.so"
######## SIP message formatting sanity checks [requires sl] ########
loadmodule "sanity.so"
modparam("sanity", "default_checks", 1511)
modparam("sanity", "uri_checks", 7)
modparam("sanity", "autodrop", 0)
######## Text operations module ########
loadmodule "textops.so"
loadmodule "textopsx.so"
######## Generic Hash Table container in shared memory ########
loadmodule "htable.so"
modparam("htable", "htable", "associations=>size=16;autoexpire=7200")
modparam("htable", "htable", "redirects=>size=16;autoexpire=5")
######## Pseudo-Variables module ########
loadmodule "pv.so"
######## Advanced logger module ########
loadmodule "xlog.so"
####### FIFO support for Management Interface ########
loadmodule "mi_fifo.so"
modparam("mi_fifo", "fifo_name", "/tmp/kamailio_fifo")
######## UAC Redirection module ########
loadmodule "uac_redirect.so"
####### DB Text module ##########
loadmodule "db_text.so"
modparam("db_text", "db_mode", 1)
####### Kazoo Integration module ##########
loadmodule "db_kazoo.so"
modparam("db_kazoo", "node_hostname", "MY_HOSTNAME")
modparam("db_kazoo", "amqp_connection", "MY_AMQP_URL")
#!ifdef MY_AMQP_URL_SECONDARY
modparam("db_kazoo", "amqp_connection", "MY_AMQP_URL_SECONDARY")
#!endif
#!ifdef MY_AMQP_URL_TERTIARY
modparam("db_kazoo", "amqp_connection", "MY_AMQP_URL_TERTIARY")
#!endif
#!ifdef MY_AMQP_MAX_CHANNELS
modparam("db_kazoo", "amqp_max_channels", MY_AMQP_MAX_CHANNELS)
#!else
modparam("db_kazoo", "amqp_max_channels", 100)
#!endif
modparam("db_kazoo", "amqp_internal_loop_count", 1);
modparam("db_kazoo", "amqp_consumer_loop_count", 4);
####### Role Configurations ##########
#!ifdef DISPATCHER-ROLE
include_file "dispatcher-role.cfg"
#!endif
#!ifdef REGISTRAR-ROLE
include_file "registrar-role.cfg"
#!endif
#!ifdef PRESENCE-ROLE
include_file "presence-role.cfg"
#!endif
#!ifdef MESSAGE-ROLE
include_file "message-role.cfg"
#!endif
#!ifdef NAT-TRAVERSAL-ROLE
include_file "nat-traversal-role.cfg"
#!endif
#!ifdef WEBSOCKETS-ROLE
include_file "websockets-role.cfg"
#!endif
#!ifdef TLS-ROLE
include_file "tls-role.cfg"
#!endif
#!ifdef ACCOUNTING-ROLE
include_file "accounting-role.cfg"
#!endif
#!ifdef ANTIFLOOD-ROLE
include_file "antiflood-role.cfg"
#!endif
#!ifdef TRAFFIC-FILTER-ROLE
include_file "traffic-filter-role.cfg"
#!endif
####### Permissions module ##########
loadmodule "permissions.so"
modparam("permissions", "db_url", "text:///etc/kazoo/kamailio/dbtext")
modparam("permissions", "db_mode", 1)
####### Routing Logic ########
route
{
# log the basic info regarding this call
xlog("L_INFO", "$ci|start|recieved $oP request $rm $ou");
xlog("L_INFO", "$ci|log|source $si:$sp");
xlog("L_INFO", "$ci|log|from $fu");
xlog("L_INFO", "$ci|log|to $tu");
route(SANITY_CHECK);
route(CLASSIFY_SOURCE);
#!ifdef ANTIFLOOD-ROLE
route(ANTIFLOOD_RATE_LIMIT);
route(ANITFLOOD_AUTH_LIMIT);
#!endif
#!ifdef TRAFFIC-FILTER-ROLE
route(TRAFFIC_FILTER);
#!endif
#!ifdef WEBSOCKETS-ROLE
route(HANDLE_WEBSOCKETS);
#!endif
route(HANDLE_OPTIONS);
route(HANDLE_NOTIFY);
route(HANDLE_MESSAGE);
#!ifdef PRESENCE-ROLE
route(HANDLE_SUBSCRIBE);
route(HANDLE_PUBLISH);
#!endif
#!ifdef REGISTRAR-ROLE
route(HANDLE_REGISTER);
#!endif
route(HANDLE_IN_DIALOG_REQUESTS);
route(PREPARE_INITIAL_REQUESTS);
if (isflagset(FLAG_INTERNALLY_SOURCED)) {
route(INTERNAL_TO_EXTERNAL_RELAY);
exit();
}
#!ifdef DISPATCHER-ROLE
route(DISPATCHER_FIND_ROUTES);
#!endif
route(EXTERNAL_TO_INTERNAL_RELAY);
}
route[SANITY_CHECK]
{
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;
}
}
route[CLASSIFY_SOURCE]
{
if (isflagset(FLAG_INTERNALLY_SOURCED) || allow_source_address(TRUSTED_ADR_GROUP) || is_myself($si)) {
xlog("L_INFO", "$ci|log|request from trusted IP");
setflag(FLAG_TRUSTED_SOURCE);
}
#!ifdef DISPATCHER-ROLE
route(DISPATCHER_CLASSIFY_SOURCE);
#!endif
}
route[HANDLE_OPTIONS]
{
if (is_method("OPTIONS")) {
if (isflagset(FLAG_INTERNALLY_SOURCED)) {
route(INTERNAL_TO_EXTERNAL_RELAY);
} else {
#!ifdef TRAFFIC-FILTER-ROLE
route(FILTER_REQUEST_DOMAIN);
#!endif
sl_send_reply("200", "Rawr!!");
}
exit;
}
}
route[HANDLE_NOTIFY]
{
if (is_method("NOTIFY")) {
if (isflagset(FLAG_INTERNALLY_SOURCED)) {
route(INTERNAL_TO_EXTERNAL_RELAY);
} else {
#!ifdef TRAFFIC-FILTER-ROLE
route(FILTER_REQUEST_DOMAIN);
#!endif
sl_send_reply("200", "Rawr!!");
}
exit;
}
}
route[HANDLE_MESSAGE]
{
#!ifdef MESSAGE-ROLE
if (is_method("MESSAGE")) {
xlog("L_INFO", "$ci|MESSAGE from $fu to $tu");
if (isflagset(FLAG_INTERNALLY_SOURCED) || src_ip == myself) {
xlog("L_INFO", "$ci| routing MESSAGE to external from $fu to $tu");
route(INTERNAL_TO_EXTERNAL_RELAY);
#!ifdef TRAFFIC-FILTER-ROLE
} else if (!isflagset(FLAG_TRUSTED_SOURCE)
&& $rd =~ "[0-9]{1,3}\.[0-9]{1,3}.[0-9]{1,3}\.[0-9]{1,3}") {
xlog("L_WARN", "$ci|end|dropping MESSAGE request with IP domain");
#!endif
} else {
xlog("L_WARN", "$ci|end|MESSAGE $(hdr(Content-Type))");
if( $hdr(Content-Type) == "application/im-iscomposing+xml" ) {
xlog("L_WARN", "$ci|end|dropping MESSAGE application/im-iscomposing+xml");
sl_send_reply("200", "OK");
} else {
route(DISPATCHER_FIND_ROUTES);
route(EXTERNAL_TO_INTERNAL_RELAY);
}
}
exit();
}
#!else
if (is_method("MESSAGE")) {
if (isflagset(FLAG_INTERNALLY_SOURCED)) {
route(INTERNAL_TO_EXTERNAL_RELAY);
} else {
sl_send_reply("202", "delivered to /dev/null");
exit;
}
}
#!endif
}
route[HANDLE_IN_DIALOG_REQUESTS]
{
if (has_totag()) {
if (is_method("INVITE")) {
record_route();
}
if (loose_route()) {
#!ifdef ACCOUNTING-ROLE
if (is_method("BYE")) {
setflag(FLAG_ACC);
setflag(FLAG_ACCFAILED);
}
#!endif
#!ifdef WEBSOCKETS-ROLE
if ($du == $null) {
handle_ruri_alias();
switch ($rc) {
case -1:
xlog("L_ERR", "$ci|stop|failed to handle alias of R-URI $ru\n");
send_reply("400", "Bad request");
exit;
case 1:
xlog("L_INFO", "$ci|log|loose_route in-dialog message with alias $du");
break;
case 2:
xlog("L_INFO", "$ci|log|loose_route in-dialog message with alias $du");
break;
}
}
#!endif
xlog("L_INFO", "$ci|log|loose_route in-dialog message");
# Called on in-dialog requests
# If the request in an Invite for on hold from external to internal,
# associate the contact with the media server
# if Invite for on hold, we need to associate the contact URI with the next hop
if (is_method("INVITE") && !isflagset(FLAG_INTERNALLY_SOURCED) && is_audio_on_hold()) {
setflag(FLAG_ASSOCIATE_USER);
}
route(RELAY);
} else if (isflagset(FLAG_INTERNALLY_SOURCED)) {
xlog("L_INFO", "$ci|log|relay internally sourced in-dialog message without loose_route");
route(RELAY);
} else if (t_check_trans()) {
xlog("L_INFO", "$ci|log|allow message for a known transaction");
route(RELAY);
} else {
xlog("L_INFO", "$ci|log|message had a to-tag but can't be loose routed");
sl_send_reply("481", "Call Leg/Transaction Does Not Exist");
}
exit();
}
}
route[PREPARE_INITIAL_REQUESTS]
{
if (is_method("CANCEL")) {
if (t_check_trans()) {
route(RELAY);
} else {
sl_send_reply("481", "Call leg/transaction does not exist");
}
exit();
} else if (is_method("ACK")) {
if (t_check_trans()) {
route(RELAY);
}
exit();
}
# handle re-transmissions
t_check_trans();
if (is_method("UPDATE")) {
xlog("L_WARN", "$ci|end|update outside dialog not allowed");
send_reply("403", "Dialog does not exist");
break;
}
if (is_method("BYE|PRACK")) {
xlog("L_WARN", "$ci|end|originating subsequent requests outside dialog not allowed");
send_reply("403", "Dialog does not exist");
break;
}
if (loose_route()) {
xlog("L_WARN", "$ci|end|denying initial request with route-set");
sl_send_reply("403", "No pre-loaded routes");
exit();
}
if (!is_method("MESSAGE")) {
record_route();
}
}
route[RELAY]
{
if (isflagset(FLAG_INTERNALLY_SOURCED)) {
route(INTERNAL_TO_EXTERNAL_RELAY);
} else {
route(EXTERNAL_TO_INTERNAL_RELAY);
}
exit();
}
route[INTERNAL_TO_EXTERNAL_RELAY]
{
#!ifdef ACCOUNTING-ROLE
if (is_method("INVITE")) {
setflag(FLAG_ACC);
setflag(FLAG_ACCFAILED);
}
#!endif
remove_hf_re("^X-.*");
t_on_reply("EXTERNAL_REPLY");
t_set_fr(0, 10000);
t_relay();
}
route[EXTERNAL_TO_INTERNAL_RELAY]
{
#!ifdef ACCOUNTING-ROLE
if (is_method("INVITE") && is_present_hf("Proxy-Authorization")) {
setflag(FLAG_ACC);
setflag(FLAG_ACCFAILED);
}
#!endif
#!ifdef NAT-TRAVERSAL-ROLE
if (!isflagset(FLAG_INTERNALLY_SOURCED)) {
route(NAT_TEST_AND_CORRECT);
}
#!endif
remove_hf_re("^X-.*");
append_hf("X-AUTH-IP: $si\r\n");
t_on_reply("INTERNAL_REPLY");
t_on_failure("INTERNAL_FAULT");
t_set_fr(0, 1000);
t_relay();
}
onreply_route[EXTERNAL_REPLY]
{
xlog("L_INFO", "$ci|log|external reply $T_reply_code");
#!ifdef WEBSOCKETS-ROLE
route(NAT_WEBSOCKETS_CORRECT);
#!endif
#!ifdef NAT-TRAVERSAL-ROLE
route(NAT_TEST_AND_CORRECT);
#!endif
}
onreply_route[INTERNAL_REPLY]
{
# this route handles replies that are comming from our media server
xlog("L_INFO", "$ci|start|recieved internal reply $T_reply_code $rr");
xlog("L_INFO", "$ci|log|source $si:$sp");
#!ifdef WEBSOCKETS-ROLE
route(NAT_WEBSOCKETS_CORRECT);
#!endif
if (is_method("INVITE") &&
!isflagset(FLAG_SESSION_PROGRESS) &&
t_check_status("(180)|(183)|(200)")
) {
if ($avp(AVP_REDIRECT_KEY) != $null &&
$sht(redirects=>$avp(AVP_REDIRECT_KEY)) != $null
) {
xlog("L_INFO", "$ci|log|removing redirect mapping $avp(AVP_REDIRECT_KEY)");
$sht(redirects=>$avp(AVP_REDIRECT_KEY)) = $null;
}
xlog("L_INFO", "$ci|log|call setup, now ignoring abnormal termination");
setflag(FLAG_SESSION_PROGRESS);
}
if ($rs < 300) {
xlog("L_INFO", "$ci|pass|$T_req($si):$T_req($sp)");
}
$var(reply_reason) = $rr;
}
failure_route[INTERNAL_FAULT]
{
# this branch handles failures (>=300) to our media servers,
# which we can sometimes overcome by routing to another server
# if the failure cause was due to the transaction being
# cancelled then we are complete
if (t_is_canceled()) {
xlog("L_INFO", "$ci|log|transaction was cancelled");
exit;
}
# Handle redirects
if (t_check_status("302")) {
$var(redirect) = @from.uri.user + "@" + @from.uri.host + "->"
+ $T_rpl($(ct{tobody.user})) + "@" + $T_rpl($(ct{tobody.host}));
if($T_rpl($hdr(X-Redirect-Server)) != $null) {
$sht(redirects=>$var(redirect)) = $T_rpl($hdr(X-Redirect-Server));
xlog("L_INFO", "$ci|log|stored redirect mapping $var(redirect) to $T_rpl($hdr(X-Redirect-Server))");
}
} else if (!t_check_status("407") &&
$avp(AVP_REDIRECT_KEY) != $null &&
$sht(redirects=>$avp(AVP_REDIRECT_KEY)) != $null
) {
xlog("L_INFO", "$ci|log|removing redirect mapping $avp(AVP_REDIRECT_KEY)");
$sht(redirects=>$avp(AVP_REDIRECT_KEY)) = $null;
}
remove_hf_re("^X-.*");
# change 6xx to 4xx
if (t_check_status("6[0-9][0-9]") && !t_check_status("600|603|604|606")) {
$var(new_code) = "4" + $(T_reply_code{s.substr,1,0});
xlog("L_INFO", "$ci|log|sending 6XX reply as $var(new_code) $var(reply_reason)");
t_reply("$(var(new_code){s.int})", "$var(reply_reason)");
# if the failure case was something that we should recover
# from then try to find a new media server
} else if ("$var(reply_reason)" =~ "call barred") {
xlog("L_INFO", "$ci|log|failure route ignoring call barred");
} else if (isflagset(FLAG_SESSION_PROGRESS)) {
xlog("L_INFO", "$ci|log|failure route ignoring failure after session progress");
} else if (t_check_status("(401)|(407)|(486)|(403)")) {
xlog("L_INFO", "$ci|log|failure route ignoring auth reply $T_reply_code $var(reply_reason)");
} else if (t_check_status("402")) {
xlog("L_INFO", "$ci|log|failure route overriding reply code 402 with 486");
send_reply("486", "Insufficient Funds");
} else if (t_check_status("(4[0-9][0-9])|(5[0-9][0-9])")) {
xlog("L_INFO", "$ci|start|received failure reply $T_reply_code $rr");
#!ifdef DISPATCHER-ROLE
route(DISPATCHER_NEXT_ROUTE);
#!endif
send_reply("486", "Unable to Comply");
} else {
xlog("L_INFO", "$ci|log|failure route ignoring reply $T_reply_code $rr");
}
xlog("L_INFO", "$ci|pass|$si:$sp");
}
onsend_route {
if (isflagset(FLAG_ASSOCIATE_USER)) {
$var(contact_uri) = $(ct{tobody.user}) + "@" + $(ct{tobody.host});
xlog("L_INFO", "$ci|log|associate user $var(contact_uri) with media server sip:$sndto(ip):$sndto(port)");
$sht(associations=>$var(contact_uri))= "sip:" + $sndto(ip) + ":" + $sndto(port);
}
xlog("L_INFO", "$ci|pass|$sndfrom(ip):$sndfrom(port) -> $sndto(ip):$sndto(port)");
}
event_route[kazoo:mod-init]
{
#!ifdef PRESENCE-ROLE
### use this simple form of binding a listener
### kazoo_subscribe("dialoginfo", "direct", "BLF-QUEUE-MY_HOSTNAME", "BLF-MY_HOSTNAME");
###
### or unleash the power of rabbit to kazoo-blf
###
### 'no_ack' : 1 => needs ack,
### 'wait_for_consumer_ack'
### : 1 => when it receives, it processses on the AMQP Worker ad after that it confirms
### : 0 => when it receives, it acks then processes in the AMQP Worker
### only works if no_ack : 0
###
### Rabbit Policy for ha-mode
### pattern : ^BLF
### definition : ha-mode: all
###
###
$var(payload) = '{ "exchange" : "dialoginfo" , "type" : "direct", "queue" : "BLF-QUEUE-MY_HOSTNAME", "routing" : "BLF-MY_HOSTNAME", "auto_delete" : 0, "durable" : 1, "no_ack" : 0, "wait_for_consumer_ack" : 1 }';
kazoo_subscribe("$var(payload)");
#!endif
#!ifdef MESSAGE-ROLE
$var(key) = "kamailio@MY_HOSTNAME";
$var(payload) = '{ "exchange" : "sms" , "type" : "topic", "queue" : "MSG-QUEUE-MY_HOSTNAME", "routing" : "message.route.' + $(var(key){kz.encode}) + '.*", "auto_delete" : 1, "durable" : 0, "no_ack" : 0, "wait_for_consumer_ack" : 1 }';
kazoo_subscribe("$var(payload)");
#!endif
#!ifdef REGISTRAR-ROLE
$var(payload) = "{ 'exchange' : 'callmgr' , 'type' : 'topic', 'queue' : 'MSG-FLUSH-MY_HOSTNAME', 'routing' : 'registration.flush.*', 'auto_delete' : 1, 'durable' : 0, 'no_ack' : 1, 'wait_for_consumer_ack' : 0 }";
kazoo_subscribe("$var(payload)");
#!endif
}
event_route[kazoo:consumer-event]
{
xlog("L_INFO","unhandled AMQP event, payload: $kzE");
}
event_route[kazoo:consumer-event-connection-open]
{
xlog("L_INFO","connection to $(kzE{kz.json,host}) opened");
}
event_route[kazoo:consumer-event-connection-closed]
{
xlog("L_INFO","connection to $(kzE{kz.json,host}) closed");
}
# vim: tabstop=4 softtabstop=4 shiftwidth=4 expandtab