Skip to content

Instantly share code, notes, and snippets.

@Carlos-Escalona94
Created April 29, 2022 17:01
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Carlos-Escalona94/4d681bb189c6190941d291965e123889 to your computer and use it in GitHub Desktop.
Save Carlos-Escalona94/4d681bb189c6190941d291965e123889 to your computer and use it in GitHub Desktop.
#!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