-
-
Save Carlos-Escalona94/4d681bb189c6190941d291965e123889 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!KAMAILIO | |
# | |
#!define WITH_MYSQL | |
##!define WITH_AUTH | |
#!define WITH_USRLOCDB | |
#!define WITH_TLS | |
##!define WITH_HOMER | |
#!define WITH_WEBSOCKETS | |
#!define WITH_ANTIFLOOD | |
#!define WITH_ASTERISK | |
##!define WITH_IPV6 | |
##!define WITH_BRIDGE_ON_FAIL | |
##!define WITH_LOCALHOST_WS | |
##!define WITH_LOCALHOST_SIP | |
#!substdef "!MY_SIP_PORT!5060!g" | |
#!substdef "!MY_SIPS_PORT!5061!g" | |
#!substdef "!MY_WS_PORT!8080!g" | |
#!substdef "!MY_WSS_PORT!4443!g" | |
#!substdef "!MY_RPC_PORT!80!g" | |
#!substdef "!MY_DOMAIN!domain!g" | |
#!substdef "!DISCONNECTION_NOTIFICATION_API!httpurl!g" | |
# *** Value defines - IDs used later in config | |
#!ifdef WITH_MYSQL | |
# - database URL - used to connect to database server by modules such | |
# as: auth_db, acc, usrloc, a.s.o. | |
#!ifndef DBURL | |
#!define DBURL "mysql://user:password@host/kamailio" | |
#!endif | |
#!endif | |
# - flags | |
# FLT_ - per transaction (message) flags | |
# FLB_ - per branch flags | |
#!define FLT_NATS 5 | |
#!define FLB_NATB 6 | |
#!define FLB_NATSIPPING 7 | |
#!define FLB_RTPWS 8 | |
#!define FLB_IPV6 9 | |
#!define FLB_V4V6 10 | |
#!define FLB_BRIDGE 11 | |
####### Global Parameters ######### | |
### LOG Levels: 3=DBG, 2=INFO, 1=NOTICE, 0=WARN, -1=ERR | |
#!ifdef WITH_DEBUG | |
debug=4 | |
log_stderror=no | |
#!else | |
debug=2 | |
log_stderror=no | |
#!endif | |
memdbg=5 | |
memlog=5 | |
log_facility=LOG_LOCAL0 | |
fork=yes | |
children=4 | |
port=MY_SIP_PORT | |
tls_port_no=MY_SIPS_PORT | |
#!ifdef WITH_TLS | |
enable_tls=yes | |
#!endif | |
listen=PRIVATEIP advertise PUBLICIP | |
listen=tcp:PRIVATEIP:5062 | |
listen=udp:PRIVATEIP:5062 | |
listen= RPC_LISTENER advertise PUBLICIP:80 | |
#!ifdef WITH_WEBSOCKETS | |
listen=PRIVATE advertise PUBLICIP:8080 | |
#!ifdef WITH_TLS | |
listen=PRIVATEIP advertise PUBLICIP:4443 | |
#!endif | |
#!endif | |
use_dns_cache = on # Use KAMAILIO internal DNS cache | |
use_dns_failover = on # Depends on KAMAILIO internal DNS cache | |
dns_srv_loadbalancing = on # | |
dns_try_naptr = on # | |
dns_retr_time=1 # Time in seconds before retrying a DNS request | |
dns_retr_no=3 # Number of DNS retransmissions before giving up | |
# Set protocol preference order - ignore target priority | |
dns_naptr_ignore_rfc= yes # Ignore target NAPTR priority | |
dns_tls_pref=50 # First priority: TLS | |
dns_tcp_pref=30 # Second priority: TCP | |
dns_udp_pref=10 # Third priority: UDP | |
tcp_connection_lifetime=3604 | |
tcp_accept_no_cl=yes | |
tcp_rd_buf_size=16384 | |
# set paths to location of modules (to sources or installation folders) | |
mpath="/usr/lib/x86_64-linux-gnu/kamailio/modules/" | |
#!ifdef WITH_MYSQL | |
loadmodule "db_mysql.so" | |
#!endif | |
loadmodule "sqlops.so" | |
loadmodule "jsonrpcs.so" | |
loadmodule "xhttp.so" | |
loadmodule "kex.so" | |
loadmodule "corex.so" | |
loadmodule "tm.so" | |
loadmodule "tmx.so" | |
loadmodule "sl.so" | |
loadmodule "rr.so" | |
loadmodule "pv.so" | |
loadmodule "maxfwd.so" | |
loadmodule "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 "sdpops.so" | |
loadmodule "textopsx.so" | |
#!ifdef WITH_AUTH | |
loadmodule "auth.so" | |
#loadmodule "auth_db.so" | |
loadmodule "auth_ephemeral.so" | |
#!ifdef WITH_IPAUTH | |
loadmodule "permissions.so" | |
#!endif | |
#!endif | |
#!ifdef WITH_PRESENCE | |
loadmodule "presence.so" | |
loadmodule "presence_xml.so" | |
#!endif | |
#!ifdef WITH_TLS | |
loadmodule "tls.so" | |
#!endif | |
#!ifdef WITH_HOMER | |
loadmodule "siptrace.so" | |
#!endif | |
#!ifdef WITH_WEBSOCKETS | |
loadmodule "websocket.so" | |
loadmodule "nathelper.so" | |
loadmodule "rtpengine.so" | |
loadmodule "http_async_client.so" | |
#!endif | |
#!ifdef WITH_ANTIFLOOD | |
loadmodule "htable.so" | |
loadmodule "pike.so" | |
#!endif | |
#!ifdef WITH_DEBUG | |
loadmodule "debugger.so" | |
#!endif | |
#!ifdef WITH_ASTERISK | |
loadmodule "dispatcher.so" | |
#!endif | |
loadmodule "uac.so" | |
# ----------------- setting module-specific parameters --------------- | |
modparam("sqlops", "sqlcon", "cb=>mysql://user:password@host/kamailio") #TODO | |
modparam("jsonrpcs", "pretty_format", 1) | |
modparam("jsonrpcs", "transport", 1) | |
# ----- rr params ----- | |
# add value to ;lr param to cope with most of the UAs | |
modparam("rr", "enable_full_lr", 1) | |
# do not append from tag to the RR (no need for this script) | |
#!ifdef WITH_ASTERISK | |
modparam("rr", "append_fromtag", 1) | |
modparam("rr", "enable_double_rr", 1) | |
#!else | |
modparam("rr", "append_fromtag", 0) | |
#!endif | |
# ----- registrar params ----- | |
modparam("registrar", "method_filtering", 1) | |
# max value for expires of registrations | |
modparam("registrar", "max_expires", 3600) | |
# ----- usrloc params ----- | |
/* enable DB persistency for location entries */ | |
#!ifdef WITH_USRLOCDB | |
modparam("usrloc", "db_url", DBURL) | |
modparam("usrloc", "db_mode", 2) | |
#!endif | |
# ----- auth_db params ----- | |
#!ifdef WITH_AUTH | |
modparam("auth_ephemeral", "secret", "IPADRNMs3Nt4HhXnPHoGnwVfN1CCmsaQ") | |
// modparam("auth_db", "db_url", DBURL) | |
// modparam("auth_db", "calculate_ha1", 1) | |
// modparam("auth_db", "password_column", "password") | |
// modparam("auth_db", "load_credentials", "") | |
#!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("rtpengine", "rtpengine_sock", "udp:127.0.0.1:22222") | |
modparam("rtpengine", "extra_id_pv", "$avp(extra_id)") | |
# ----- nathelper params ----- | |
modparam("nathelper", "natping_interval", 30) | |
modparam("nathelper", "ping_nated_only", 1) | |
modparam("nathelper", "sipping_bflag", FLB_NATSIPPING) | |
modparam("nathelper", "sipping_from", "sip:pinger@XXXX-XXXX") | |
modparam("nathelper|registrar", "received_avp", "$avp(RECEIVED)") | |
modparam("usrloc", "nat_bflag", FLB_NATB) | |
##!endif | |
# ----- corex params ----- | |
modparam("corex", "alias_subdomains", "MY_DOMAIN") | |
#!ifdef WITH_TLS | |
# ----- tls params ----- | |
modparam("tls", "config", "/etc/kamailio/tls.cfg") | |
modparam("tls", "tls_force_run", 1) | |
#!endif | |
#!ifdef WITH_WEBSOCKETS | |
modparam("nathelper|registrar", "received_avp", "$avp(RECEIVED)") | |
modparam("htable", "htable", "wsusers=>size=13;") | |
#!endif | |
#!ifdef WITH_HOMER | |
#Siptrace | |
modparam("siptrace", "duplicate_uri", "sip:127.0.0.1:9060") | |
modparam("siptrace", "hep_mode_on", 1) | |
modparam("siptrace", "trace_to_database", 0) | |
modparam("siptrace", "trace_flag", 22) | |
modparam("siptrace", "trace_on", 1) | |
#!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_DEBUG | |
# ----- debugger params ----- | |
modparam("debugger", "cfgtrace", 1) | |
#!endif | |
modparam("uac", "reg_contact_addr", "domain:5060") | |
modparam("uac", "reg_db_url", "mysql://user:password@host/kamailio") | |
modparam("uac","auth_username_avp","$avp(auser)") | |
modparam("uac","auth_password_avp","$avp(apass)") | |
modparam("uac","auth_realm_avp","$avp(arealm)") | |
####### Routing Logic ######## | |
request_route { | |
if(route(SENDEDTOPUBLIC)){ | |
route(PUBLIC); | |
exit; | |
} | |
if(route(SENDEDTOPRIVATE)){ | |
route(PRIVATE); | |
exit; | |
} | |
} | |
route[PUBLIC]{ | |
#!ifdef WITH_HOMER | |
# start duplicate the SIP message here | |
sip_trace(); | |
setflag(22); | |
#!endif | |
# per request initial checks | |
route(REQINIT); | |
xlog("L_INFO", "START: $rm from $fu (IP:$si:$sp)\n"); | |
#!ifdef WITH_WEBSOCKETS | |
if (nat_uac_test(64)) { | |
# Do NAT traversal stuff for requests from a WebSocket | |
# connection - even if it is not behind a NAT! | |
# This won't be needed in the future if Kamailio and the | |
# WebSocket client support Outbound and Path. | |
force_rport(); | |
if (is_method("REGISTER")) { | |
fix_nated_register(); | |
} else if (!add_contact_alias()) { | |
xlog("L_ERR", "Error aliasing contact <$ct>\n"); | |
sl_send_reply("400", "Bad Request"); | |
exit; | |
} | |
} | |
#!endif | |
# NAT detection | |
route(NATDETECT); | |
# CANCEL processing | |
if (is_method("CANCEL")) { | |
if (t_check_trans()) { | |
route(RELAY); | |
} | |
exit; | |
} | |
# handle requests within SIP dialogs | |
route(WITHINDLG); | |
### only initial requests (no To tag) | |
t_check_trans(); | |
if(!route(FROMPRIVATE)){ | |
route(AUTH); | |
} | |
remove_hf("Route"); | |
if (is_method("INVITE|SUBSCRIBE")) { | |
record_route(); | |
} | |
### 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; | |
} | |
if(is_method("INVITE") && !route(FROMPRIVATE)){ | |
route(SENDTOPRIVATE); | |
exit; | |
} | |
# user location service | |
route(LOCATION); | |
} | |
route[PRIVATE]{ | |
// # handle requests within SIP dialogs | |
route(WITHINDLG); | |
### only initial requests (no To tag) | |
// t_check_trans(); | |
remove_hf("Route"); | |
if (is_method("INVITE|SUBSCRIBE")) { | |
record_route(); | |
} | |
if(is_method("INVITE") && route(SENDEDTOPRIVATE) && !route(FROMASTERISK)){ | |
route(TOASTERISK); | |
exit; | |
} | |
if(is_method("INVITE") && route(FROMASTERISK)){ | |
route(SENDTOPUBLIC); | |
exit; | |
} | |
} | |
# Wrapper for relaying requests | |
route[RELAY] { | |
# 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; | |
} | |
# 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($ua =~ "friendly-scanner|sipcli|VaxSIPUserAgent") { | |
# silent drop for scanners - uncomment next line if want to reply | |
# sl_send_reply("200", "OK"); | |
exit; | |
} | |
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("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()) { | |
#!ifdef WITH_WEBSOCKETS | |
if ($du == "") { | |
if (!handle_ruri_alias()) { | |
xlog("L_ERR", "Bad alias <$ru>\n"); | |
sl_send_reply("400", "Bad Request"); | |
exit; | |
} | |
} | |
#!endif | |
route(DLGURI); | |
if (is_method("ACK")) { | |
# ACK is forwarded statelessy | |
route(NATMANAGE); | |
} else if (is_method("NOTIFY")) { | |
# Add Record-Route for in-dialog NOTIFY as per RFC 6665. | |
record_route(); | |
} | |
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 | |
route(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")) { | |
$sht(wsusers=>$sp) = $aU; | |
xlog("L_INFO", "Registrar WS Port: $sht(wsusers=>$sp)\n"); | |
if (isflagset(FLT_NATS)) { | |
setbflag(FLB_NATB); | |
# uncomment next line to do SIP NAT pinging | |
## setbflag(FLB_NATSIPPING); | |
} | |
#!ifdef WITH_IPV6 | |
if (af == INET6) { | |
setbflag(FLB_IPV6); | |
} | |
#!endif | |
if (!save("location")) { | |
sl_reply_error(); | |
} | |
exit; | |
} | |
} | |
# USER location service | |
route[LOCATION] { | |
#!ifdef WITH_ASTERISK | |
if(is_method("INVITE") && !route(FROMASTERISK)){ | |
route(TOASTERISK); | |
exit; | |
} | |
#!endif | |
if(is_method("INVITE") && is_present_hf("X-CARRIERID")){ | |
route(TOCARRIER); | |
exit; | |
} | |
if (!lookup("location")) { | |
$var(rc) = $rc; | |
t_newtran(); | |
switch ($var(rc)) { | |
case -1: | |
case -3: | |
send_reply("404", "Not Found"); | |
exit; | |
case -2: | |
send_reply("405", "Method Not Allowed"); | |
exit; | |
} | |
} | |
route(RELAY); | |
exit; | |
} | |
# Presence server route | |
route[PRESENCE] { | |
if (!is_method("PUBLISH|SUBSCRIBE")) { | |
return; | |
} | |
if (is_method("SUBSCRIBE") && $hdr(Event) == "message-summary") { | |
# returns here if no voicemail server is configured | |
sl_send_reply("404", "No voicemail service"); | |
exit; | |
} | |
#!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") || from_uri == myself) { | |
# authenticate requests | |
xlog("L_INFO", "FD: $fd\n"); | |
if (!autheph_check("$fd")) { | |
auth_challenge("$fd", "1"); | |
exit; | |
} | |
if (!autheph_check_from()) { | |
sl_send_reply("403", "Forbidden"); | |
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; | |
// } | |
//TODO | |
#!endif | |
return; | |
} | |
# Caller NAT detection route | |
route[NATDETECT] { | |
#!ifdef WITH_IPV6 | |
if(af==INET6) { | |
return; | |
} | |
#!endif | |
force_rport(); | |
if (nat_uac_test("19")) { | |
if (is_method("REGISTER")) { | |
fix_nated_register(); | |
} else if (is_first_hop()) { | |
set_contact_alias(); | |
} | |
setflag(FLT_NATS); | |
} | |
return; | |
} | |
# NAT handling | |
route[NATMANAGE] { | |
if (is_request()) { | |
if (has_totag()) { | |
if (check_route_param("nat=yes")) { | |
setbflag(FLB_NATB); | |
} | |
if (check_route_param("rtp=bridge")) { | |
setbflag(FLB_BRIDGE); | |
} | |
if (check_route_param("rtp=ws")) { | |
setbflag(FLB_RTPWS); | |
} | |
#!ifdef WITH_IPV6 | |
if (check_route_param("rtp=v46")) { | |
setbflag(FLB_V4V6); | |
} | |
#!endif | |
} | |
} | |
if (!isbflagset(FLB_BRIDGE)) { | |
return; | |
} | |
if ( | |
!(isflagset(FLT_NATS) | |
|| isbflagset(FLB_NATB) | |
|| isbflagset(FLB_RTPWS) | |
#!ifdef WITH_IPV6 | |
|| isbflagset(FLB_V4V6) | |
#!endif | |
)) { | |
return; | |
} | |
if (is_request()) { | |
if (!has_totag()) { | |
if (t_is_branch_route()) { | |
if (isbflagset(FLB_NATB)) { | |
add_rr_param(";nat=yes"); | |
} | |
if (isbflagset(FLB_BRIDGE)) { | |
add_rr_param(";rtp=bridge"); | |
} | |
if (isbflagset(FLB_RTPWS)) { | |
add_rr_param(";rtp=ws"); | |
} | |
#!ifdef WITH_IPV6 | |
if (isbflagset(FLB_V4V6)) { | |
add_rr_param(";rtp=v46"); | |
} | |
#!endif | |
} | |
} | |
} | |
if (is_reply()) { | |
if (isbflagset(FLB_NATB)) { | |
if (is_first_hop()) { | |
if (af == INET) { | |
set_contact_alias(); | |
} | |
} | |
} | |
} | |
return; | |
} | |
route[RTPENGINE]{ | |
$xavp(r=>$T_branch_idx) = "replace-origin replace-session-connection"; | |
if (!nat_uac_test("8")) { | |
$xavp(r=>$T_branch_idx) = $xavp(r=>$T_branch_idx) + " trust-address"; | |
} | |
if (is_request()) { | |
if (!has_totag()) { | |
if (!t_is_failure_route()) { | |
$avp(extra_id) = @via[1].branch + $T_branch_idx; | |
$xavp(r=>$T_branch_idx) = $xavp(r=>$T_branch_idx) + " via-branch=extra"; | |
} | |
} | |
} | |
if (is_reply()) { | |
$avp(extra_id) = @via[2].branch + $T_branch_idx; | |
$xavp(r=>$T_branch_idx) = $xavp(r=>$T_branch_idx) + " via-branch=extra"; | |
} | |
#!ifdef WITH_IPV6 | |
if (af == INET && isbflagset(FLB_IPV6)) { # IPv4 --> IPv6 | |
$xavp(r=>$T_branch_idx) = $xavp(r=>$T_branch_idx) + " address-family=IP6"; | |
} else if (af == INET6 && !isbflagset(FLB_IPV6)) { # IPv6 --> IPv4 | |
$xavp(r=>$T_branch_idx) = $xavp(r=>$T_branch_idx) + " address-family=IP4"; | |
} | |
#!endif | |
if (isbflagset(FLB_RTPWS)) { | |
if ($proto =~ "ws") { # web --> SIP | |
$xavp(r=>$T_branch_idx) = $xavp(r=>$T_branch_idx) + " rtcp-mux-demux DTLS=off SDES-off ICE=remove RTP/AVP"; | |
} else { # SIP --> web | |
$xavp(r=>$T_branch_idx) = $xavp(r=>$T_branch_idx) + " rtcp-mux-offer generate-mid DTLS=passive SDES-off ICE=force RTP/SAVPF"; | |
} | |
} else { | |
if ($proto =~ "ws") { # web --> web | |
$xavp(r=>$T_branch_idx) = $xavp(r=>$T_branch_idx) + " generate-mid DTLS=passive SDES-off ICE=force"; | |
} | |
# else { | |
# $xavp(r=>$T_branch_idx) = $xavp(r=>$T_branch_idx) + ""; | |
# } | |
} | |
if(route(FROMASTERISK)){ | |
$xavp(r=>$T_branch_idx) = $xavp(r=>$T_branch_idx) + " direction=internal direction=external"; | |
}else{ | |
$xavp(r=>$T_branch_idx) = $xavp(r=>$T_branch_idx) + " direction=external direction=internal"; | |
} | |
xlog("L_INFO", "NATMANAGE branch_id:$T_branch_idx ruri: $ru, method:$rm, status:$rs, extra_id: $avp(extra_id), rtpengine_manage: $xavp(r=>$T_branch_idx)\n"); | |
rtpengine_manage($xavp(r=>$T_branch_idx)); | |
} | |
# URI update for dialog requests | |
route[DLGURI] { | |
if (!isdsturiset()) { | |
handle_ruri_alias(); | |
} | |
return; | |
} | |
# Routing to foreign domains | |
route[SIPOUT] { | |
if (!uri == myself) { | |
append_hf("P-hint: outbound\r\n"); | |
route(RELAY); | |
} | |
} | |
route[BRIDGING] { | |
if (!has_totag()) { | |
if ($proto =~ "ws" && !($ru =~ "transport=ws")) { # Coming from WS, NOT to WS | |
setbflag(FLB_RTPWS); # Need bridging | |
} else if (!($proto =~ "ws") && $ru =~ "transport=ws") { # Coming from NOT WS, going to WS | |
setbflag(FLB_RTPWS); # Need bridging | |
} | |
#!ifdef WITH_IPV6 | |
if (af == INET6 && !isbflagset(FLB_IPV6)) { | |
setbflag(FLB_V4V6); | |
} else if(af == INET && isbflagset(FLB_IPV6)) { | |
setbflag(FLB_V4V6); | |
} | |
#!endif | |
} | |
} | |
route[SENDEDTOPRIVATE]{ | |
if(dst_port==5062){ | |
return 1; | |
} | |
return -1; | |
} | |
route[FROMPRIVATE]{ | |
if(src_ip=='PRIVATEIP' && !route(FROMPUBLIC)){ | |
return 1; | |
} | |
return -1; | |
} | |
route[SENDEDTOPUBLIC]{ | |
if(dst_port==5060 || dst_port==5061 || dst_port==4443){ | |
return 1; | |
} | |
return -1; | |
} | |
route[FROMPUBLIC]{ | |
if(src_port==5060){ | |
return 1; | |
} | |
return -1; | |
} | |
route[SENDTOPRIVATE]{ | |
$du = "sip:" + "PRIVATEIP" + ":" + "5062"; | |
route(RELAY); | |
} | |
route[SENDTOPUBLIC]{ | |
$du = "sip:" + "PRIVATEIP" + ":" + "5060"; | |
route(RELAY); | |
} | |
#!ifdef WITH_ASTERISK | |
#Test if coming from Asterisk | |
route[FROMASTERISK]{ | |
if(ds_is_from_list(-1, 3)){ | |
return 1; | |
} | |
return -1; | |
} | |
route[TOASTERISK]{ | |
ds_select_dst("1","4"); | |
route(RELAY); | |
exit; | |
} | |
#!endif | |
route[TOCARRIER]{ | |
$var(carrier) = @hf_value.x_carrierid[0]; | |
sql_query("cb", "select l_uuid,r_username,r_domain,auth_username,auth_password from uacreg where l_uuid='$var(carrier)'", "ra"); | |
if($dbr(ra=>rows)>=1){ | |
$var(i) = 0; | |
$var(domain) = $null; | |
$var(username) = $null; | |
while($var(i)<$dbr(ra=>cols)){ | |
switch ($dbr(ra=>colname[$var(i)])) { | |
case 'r_username': | |
$var(username) = $dbr(ra=>[0,$var(i)]); | |
case 'r_domain': | |
$var(domain) = $dbr(ra=>[0,$var(i)]); | |
case 'auth_username': | |
$avp(auser) = $dbr(ra=>[0,$var(i)]); | |
case 'auth_password': | |
$avp(apass) = $dbr(ra=>[0,$var(i)]); | |
} | |
$var(i) = $var(i) + 1; | |
} | |
sql_result_free("ra"); | |
remove_hf("X-CARRIERID"); | |
$du = "sip:" + $var(domain); | |
route(RELAY); | |
exit; | |
} | |
sl_send_reply("404", "Not Found"); | |
} | |
# manage outgoing branches | |
branch_route[MANAGE_BRANCH] { | |
xlog("L_INFO", "MANAGE_BRANCH: New branch [$T_branch_idx] to $ru\n"); | |
t_on_branch_failure("rtpengine"); | |
#!ifndef WITH_BRIDGE_ON_FAIL | |
setbflag(FLB_BRIDGE); | |
#!endif | |
route(BRIDGING); | |
route(NATMANAGE); | |
route(RTPENGINE); | |
} | |
# manage incoming replies | |
onreply_route[MANAGE_REPLY] { | |
xdbg("incoming reply\n"); | |
if (status =~ "[12][0-9][0-9]") { | |
route(NATMANAGE); | |
route(RTPENGINE); | |
} | |
} | |
# manage failure routing cases | |
failure_route[MANAGE_FAILURE] { | |
xlog("L_INFO", "Failure: $rs \n"); | |
if (t_is_canceled()) { | |
exit; | |
} | |
if(t_check_status("401|407")) { | |
# $avp(apass) = "36d0a02793542b4961e8348347236dbf"; | |
# if (uac_auth("1")) { | |
if (uac_auth()) { | |
t_relay(); | |
} | |
exit; | |
} | |
} | |
onreply_route { | |
if ((($Rp == MY_WS_PORT || $Rp == MY_WSS_PORT) | |
&& !(proto == WS || proto == WSS))) { | |
xlog("L_WARN", "SIP response received on $Rp\n"); | |
drop; | |
} | |
if (nat_uac_test(64)) { | |
# Do NAT traversal stuff for replies to a WebSocket connection | |
# - even if it is not behind a NAT! | |
# This won't be needed in the future if Kamailio and the | |
# WebSocket client support Outbound and Path. | |
add_contact_alias(); | |
} | |
} | |
event_route[tm:branch-failure:rtpengine] { | |
xlog("L_INFO", "BRANCH FAILED: $sel(via[1].branch) + $T_branch_idx"); | |
#!ifdef WITH_BRIDGE_ON_FAIL | |
if (!isbflagset(FLB_BRIDGE) && t_check_status("415|488")) { | |
t_reuse_branch(); | |
setbflag(FLB_BRIDGE); | |
xlog("L_INFO", "event_route[branch-failure:rtpengine]: trying again\n"); | |
route(RELAY); | |
} else { | |
$avp(extra_id) = @via[1].branch + $T_branch_idx; | |
rtpengine_delete("via-branch=extra"); | |
xlog("L_INFO", "event_route[branch-failure:rtpengine]: failed\n"); | |
} | |
#!else | |
$avp(extra_id) = @via[1].branch + $T_branch_idx; | |
rtpengine_delete("via-branch=extra"); | |
#!endif | |
} | |
event_route[xhttp:request] { | |
set_reply_close(); | |
set_reply_no_connect(); | |
if ($hu =~ "^/rpc") { | |
if(dst_port==80){ | |
jsonrpc_dispatch(); | |
return; | |
}else{ | |
xhttp_reply("403", "Forbidden", "", ""); | |
exit; | |
} | |
} | |
if ($Rp != MY_WS_PORT | |
#!ifdef WITH_TLS | |
&& $Rp != MY_WSS_PORT | |
#!endif | |
) { | |
xlog("L_WARN", "HTTP request received on $Rp\n"); | |
xhttp_reply("403", "Forbidden", "", ""); | |
exit; | |
} | |
if ($hdr(Upgrade) =~ "websocket" | |
&& $hdr(Connection) =~ "Upgrade" | |
&& $rm =~ "GET" | |
) { | |
# Validate Host - make sure the client is using the correct | |
# alias for WebSockets | |
if ($hdr(Host) == $null || !is_myself("sip:" + $hdr(Host))) { | |
xlog("L_WARN", "Bad host $hdr(Host)\n"); | |
xhttp_reply("403", "Forbidden", "", ""); | |
exit; | |
} | |
# Optional... validate Origin - make sure the client is from an | |
# authorised website. For example, | |
# | |
# if ($hdr(Origin) != "https://example.com" | |
# && $hdr(Origin) != "https://example.com") { | |
# xlog("L_WARN", "Unauthorised client $hdr(Origin)\n"); | |
# xhttp_reply("403", "Forbidden", "", ""); | |
# exit; | |
# } | |
# TODO | |
# Optional... perform HTTP authentication | |
# ws_handle_handshake() exits (no further configuration file | |
# processing of the request) when complete. | |
if (ws_handle_handshake()) { | |
# Optional... cache some information about the | |
# successful connection | |
exit; | |
} | |
} | |
xhttp_reply("404", "Not Found", "", ""); | |
} | |
event_route[websocket:closed] { | |
xlog("L_INFO", "UnRegistrar WS Port: $sht(wsusers=>$sp)\n"); | |
# GET | |
$http_req(timeout) = 5000; # 100 ms | |
$http_req(hdr) = "Content-Type: text/plain"; | |
$http_req(body) = $sht(wsusers=>$sp); | |
http_async_query("DISCONNECTION_NOTIFICATION_API", "HTTP_REPLY"); | |
# Clear Hashtable entry | |
$sht(wsusers=>$sp) = $null; | |
} | |
route[HTTP_REPLY] { | |
if ($http_ok) { | |
xlog("L_INFO", "route[HTTP_REPLY]: status $http_rs\n"); | |
xlog("L_INFO", "route[HTTP_REPLY]: body $http_rb\n"); | |
} else { | |
xlog("L_INFO", "route[HTTP_REPLY]: error $http_err)\n"); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment