kamailio.cfg
```txt ### kamailio5.6.4
#!define MULTIDOMAIN 0
# - flags # FLT_ - per transaction (message) flags #!define FLT_ACC 1 #!define FLT_ACCMISSED 2 #!define FLT_ACCFAILED 3 #!define FLT_NATS 5
# FLB_ - per branch flags #!define FLB_NATB 6 #!define FLB_NATSIPPING 7
debug=2 log_stderror=no memdbg=5 memlog=5 log_facility=LOG_LOCAL0 log_prefix="{$mt $hdr(CSeq) $ci} " children=4 auto_aliases=no enable_sctp=no # listen=udp:192.168.31.63:5060
# mpath="/usr/local/lib/kamailio/modules/"
loadmodule "kex.so" loadmodule "corex.so" loadmodule "tm.so" loadmodule "tmx.so" loadmodule "sl.so" loadmodule "rr.so" loadmodule "pv.so" loadmodule "maxfwd.so" loadmodule "usrloc.so" loadmodule "registrar.so" loadmodule "textops.so" loadmodule "textopsx.so" loadmodule "siputils.so" loadmodule "xlog.so" loadmodule "sanity.so" loadmodule "ctl.so" loadmodule "cfg_rpc.so" loadmodule "counters.so" loadmodule "nathelper.so" loadmodule "jansson.so" loadmodule "nats.so"
# modparam("ctl", "binrpc", "unix:/run/kamailio/kamailio_ctl")
modparam("sanity", "autodrop", 0)
modparam("tm", "failure_reply_mode", 3) modparam("tm", "fr_timer", 30000) modparam("tm", "fr_inv_timer", 120000)
modparam("rr", "enable_full_lr", 0) modparam("rr", "append_fromtag", 0)
modparam("registrar", "method_filtering", 1) modparam("registrar", "max_expires", 3600) modparam("registrar", "gruu_enabled", 0) modparam("registrar", "use_path", 1) modparam("registrar", "path_mode", 0)
modparam("usrloc", "timer_interval", 60) modparam("usrloc", "timer_procs", 1) modparam("usrloc", "use_domain", MULTIDOMAIN) modparam("usrloc", "db_mode", 0)
modparam("nathelper", "natping_interval", 30) modparam("nathelper", "ping_nated_only", 1) modparam("nathelper", "sipping_bflag", FLB_NATSIPPING) modparam("nathelper", "sipping_from", "sip:pinger@kamailio.org") modparam("nathelper|registrar", "received_avp", "$avp(RECEIVED)")
modparam("usrloc", "nat_bflag", FLB_NATB)
modparam("nats", "nats_url", "nats://127.0.0.1:4222") modparam("nats", "subject_queue_group", "sipserver:group")
request_route { # per request initial checks route(REQINIT);
# NAT detection route(NATDETECT);
# CANCEL processing if (is_method("CANCEL")) { if (t_check_trans()) { route(RELAY); } exit; }
if (!is_method("ACK")) { if(t_precheck_trans()) { t_check_trans(); exit; } t_check_trans(); }
route(WITHINDLG);
### only initial requests (no To tag) route(AUTH);
remove_hf("Route"); if (is_method("INVITE|SUBSCRIBE")) { record_route(); }
route(SIPOUT);
# handle registrations route(REGISTRAR);
if ($rU==$null) { sl_send_reply("484","Address Incomplete"); exit; }
if (is_method("INVITE")) { route(NATS); } else { sl_send_reply("200","OK"); } return; }
# Wrapper for relaying requests route[RELAY] { 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; }
route[REQINIT] { # no connect for sending replies set_reply_no_connect(); # enforce symmetric signaling # - send back replies to the source address of request force_rport();
if (!mf_process_maxfwd_header("10")) { sl_send_reply("483","Too Many Hops"); exit; }
if(is_method("OPTIONS")) { sl_send_reply("200","Keepalive"); exit; }
if(!sanity_check("17895", "7")) { xlog("Malformed SIP request from $si:$sp\n"); exit; } }
route[WITHINDLG] { if (!has_totag()) return;
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 sl_send_reply("501","Not Implemented"); 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; }
route[REGISTRAR] { if (!is_method("REGISTER")) return;
if(isflagset(FLT_NATS)) { setbflag(FLB_NATB); # do SIP NAT pinging setbflag(FLB_NATSIPPING); } if (!save("location")) { sl_reply_error(); } exit; }
route[AUTH] { return; }
route[NATDETECT] { if (nat_uac_test("19")) { if (is_method("REGISTER")) { fix_nated_register(); } else { if(is_first_hop()) { set_contact_alias(); } } setflag(FLT_NATS); } return; }
route[NATMANAGE] { if (is_request()) { if(has_totag()) { if(check_route_param("nat=yes")) { setbflag(FLB_NATB); } } } if (!(isflagset(FLT_NATS) || isbflagset(FLB_NATB))) return;
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(); } }
if(isbflagset(FLB_NATB)) { # no connect message in a dialog involving NAT traversal if (is_request()) { if(has_totag()) { set_forward_no_connect(); } } }
return; }
route[DLGURI] { if(!isdsturiset()) { handle_ruri_alias(); } return; }
route[SIPOUT] { if (uri==myself) return;
append_hf("P-Hint: outbound\r\n"); route(RELAY); exit; }
branch_route[MANAGE_BRANCH] { xdbg("new branch [$T_branch_idx] to $ru\n"); route(NATMANAGE); return; }
reply_route { if(!sanity_check("17604", "6")) { xlog("Malformed SIP response from $si:$sp\n"); drop; } return; }
onreply_route[MANAGE_REPLY] { xdbg("incoming reply\n"); if(status=~"[12][0-9][0-9]") { route(NATMANAGE); } return; }
failure_route[MANAGE_FAILURE] { route(NATMANAGE); if (t_is_canceled()) exit; return; }
route[NATS] { send_reply("100", "Suspending"); # t_newtran(); if (!t_suspend()) { xerr("[SUSPEND] failed suspending trasaction [$T(id_index):$T(id_label)]\n"); send_reply("501", "Suspending error"); exit; } else { jansson_set("string", "jsonrpc", "2.0", "$var(body)"); jansson_set("string", "method", "route" ,"$var(body)"); jansson_set("integer", "tindex", $T(id_index), "$var(body)"); jansson_set("integer", "tlabel", $T(id_label), "$var(body)"); jansson_set("string", "from", $fu, "$var(body)"); jansson_set("string", "to", $to, "$var(body)"); xinfo("body = $var(body)\n"); nats_publish("routeserver", "$var(body)"); exit; } }
event_route[nats:connected] { xinfo("nats connected!\n"); }
event_route[nats:disconnected] { xinfo("nats disconnected!\n"); }
event_route[nats:sipserver] { xinfo("nats payload received [$natsData]\n"); if (!jansson_get("method", "$natsData", "$var(method)")) return; if ($var(method) != "route") return; if (!jansson_get("tindex", "$natsData", "$var(tindex)")) return; if (!jansson_get("tlabel", "$natsData", "$var(tlabel)")) return; if (!jansson_get("destination","$natsData", "$var(destination)")) return;
xinfo("tindex = $var(tindex), tlabel = $var(tlabel), destination = $var(destination)\n"); t_continue("$var(tindex)", "$var(tlabel)", "INVRESUME"); }
route[INVRESUME] { xinfo("INVRESUME, destination = $var(destination)\n"); $du = $var(destination); route(RELAY); } ```