Hello all!I have a scenario here where I need to put more than two companies into the same Kamailio server and to accomplish this I'm using a multi-domain configuration.For now, I am able to create users in different domains and register all of them. The users are able to place and receive internal calls (as I am using this just to get internal communications working), so I am ok with this part of my configuration.The problem that I'm facing now is that users from domain "A" are able to place calls to users from domain "B". I need to deny calls between different domains, and I don't know the best way to achieve this.Here are my domains create (output from "kamctl domain show"):And here are my users created:username: bobdomain: enterprise.comusername: alicedomain: enterprise2.comSo, can you please help me to get this?Here is my .cfg file:#!KAMAILIO#!define WITH_PGSQL#!define WITH_AUTH#!define WITH_USRLOCDB##!define WITH_NAT##!define WITH_DEBUG#!define WITH_MULTIDOMAIN##!define WITH_SIPTRACE#!define WITH_SQLOPS#!define WITH_XMLRPC##!define WITH_603#!define WITH_TLS##!substdef "!MY_WS_PORT!80!g"#!substdef "!MY_WSS_PORT!81!g"#!substdef "!MY_WS_ADDR!eth1:MY_WS_PORT!g"#!substdef "!MY_WSS_ADDR!tls:eth1:MY_WSS_PORT!g"#!define WITH_WEBSOCKETS#!ifdef ACCDB_COMMENTALTER TABLE acc ADD COLUMN src_user VARCHAR(64) NOT NULL DEFAULT '';ALTER TABLE acc ADD COLUMN src_domain VARCHAR(128) NOT NULL DEFAULT '';ALTER TABLE acc ADD COLUMN src_ip varchar(64) NOT NULL default '';ALTER TABLE acc ADD COLUMN dst_ouser VARCHAR(64) NOT NULL DEFAULT '';ALTER TABLE acc ADD COLUMN dst_user VARCHAR(64) NOT NULL DEFAULT '';ALTER TABLE acc ADD COLUMN dst_domain VARCHAR(128) NOT NULL DEFAULT '';ALTER TABLE missed_calls ADD COLUMN src_user VARCHAR(64) NOT NULL DEFAULT '';ALTER TABLE missed_calls ADD COLUMN src_domain VARCHAR(128) NOT NULL DEFAULT '';ALTER TABLE missed_calls ADD COLUMN src_ip varchar(64) NOT NULL default '';ALTER TABLE missed_calls ADD COLUMN dst_ouser VARCHAR(64) NOT NULL DEFAULT '';ALTER TABLE missed_calls ADD COLUMN dst_user VARCHAR(64) NOT NULL DEFAULT '';ALTER TABLE missed_calls ADD COLUMN dst_domain VARCHAR(128) NOT NULL DEFAULT '';#!endif####### Include Local Config If Exists #########import_file "kamailio-local.cfg"####### Defined Values ########## *** Value defines - IDs used later in config#!ifdef WITH_PGSQL# - database URL - used to connect to database server by modules such# as: auth_db, acc, usrloc, a.s.o.#!define DBURL "postgres://kamailio:kamailiorw@localhost/kamailio"#!endif#!ifdef WITH_MULTIDOMAIN# - the value for 'use_domain' parameters#!define MULTIDOMAIN 1#!else#!define MULTIDOMAIN 0#!endif# - flags# FLT_ - per transaction (message) flags# FLB_ - per branch flags#!define FLT_ACC 1#!define FLT_ACCMISSED 2#!define FLT_ACCFAILED 3#!define FLT_NATS 5#!define FLB_NATB 6#!define FLB_NATSIPPING 7####### Global Parameters ############ LOG Levels: 3=DBG, 2=INFO, 1=NOTICE, 0=WARN, -1=ERR#!ifdef WITH_DEBUGdebug=4log_stderror=yes#!elsedebug=2log_stderror=no#!endifmemdbg=5memlog=5log_facility=LOG_LOCAL0fork=yeschildren=4/* uncomment the next line to disable TCP (default on) */disable_tcp=notcp_accept_no_cl=yes/* uncomment the next line to disable the auto discovery of local aliasesbased on reverse DNS on IPs (default on) */#auto_aliases=no/* add local domain aliases */#alias="sip.mydomain.com"/* uncomment and configure the following line if you want Kamailio tobind on a specific interface/port/proto (default bind on all available) */#listen=udp:10.0.0.10:5060/* port to listen to* - can be specified more than once if needed to listen on many ports */port=5060#!ifdef WITH_TLSenable_tls=yes#!endif# life time of TCP connection when there is no traffic# - a bit higher than registration expires to cope with UA behind NATtcp_connection_lifetime=3605tcp_rd_buf_size=6144listen=eth1#!ifdef WITH_WEBSOCKETSlisten=MY_WS_ADDR#!ifdef WITH_TLSlisten=eth1#!endif#!endif####### Custom Parameters ########## These parameters can be modified runtime via RPC interface# - see the documentation of 'cfg_rpc' module.## Format: group.id = value 'desc' description# Access: $sel(cfg_get.group.id) or @cfg_get.group.id##!ifdef WITH_PSTN# PSTN GW Routing## - pstn.gw_ip: valid IP or hostname as string value, example:# pstn.gw_ip = "10.0.0.101" desc "My PSTN GW Address"## - by default is empty to avoid misroutingpstn.gw_ip = "" desc "PSTN GW Address"pstn.gw_port = "" desc "PSTN GW Port"#!endif#!ifdef WITH_VOICEMAIL# VoiceMail Routing on offline, busy or no answer## - by default Voicemail server IP is empty to avoid misroutingvoicemail.srv_ip = "" desc "VoiceMail IP Address"voicemail.srv_port = "5060" desc "VoiceMail Port"#!endif####### Modules Section ######### set paths to location of modules (to sources or installation folders)#!ifdef WITH_SRCPATHmpath="modules/"#!elsempath="/usr/lib/x86_64-linux-gnu/kamailio/modules/"#!endif#!ifdef WITH_PGSQLloadmodule "db_postgres.so"#!endifloadmodule "mi_fifo.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 "mi_rpc.so"loadmodule "acc.so"#!ifdef WITH_AUTHloadmodule "auth.so"loadmodule "auth_db.so"#!ifdef WITH_IPAUTHloadmodule "permissions.so"#!endif#!endif#!ifdef WITH_ALIASDBloadmodule "alias_db.so"#!endif#!ifdef WITH_SPEEDDIALloadmodule "speeddial.so"#!endif#!ifdef WITH_MULTIDOMAINloadmodule "domain.so"#!endif#!ifdef WITH_PRESENCEloadmodule "presence.so"loadmodule "presence_xml.so"#!endif#!ifdef WITH_NATloadmodule "nathelper.so"loadmodule "rtpproxy.so"#!endif#!ifdef WITH_TLSloadmodule "tls.so"#!endif#!ifdef WITH_ANTIFLOODloadmodule "htable.so"loadmodule "pike.so"#!endif#!ifdef WITH_XMLRPCloadmodule "xmlrpc.so"#!endif#!ifdef WITH_DEBUGloadmodule "debugger.so"#!endif#!ifdef WITH_SIPTRACEloadmodule "siptrace.so"#!endif#!ifdef WITH_SQLOPSloadmodule "sqlops.so"#!endif#!ifdef WITH_WEBSOCKETSloadmodule "xhttp.so"loadmodule "websocket.so"loadmodule "nathelper.so"#!endif# ----------------- setting module-specific parameters ---------------# ---- sip_trace params ----#!ifdef WITH_SIPTRACEmodparam("siptrace", "db_url", "postgres://kamailio:kamailiorw@localhost/kamailio")modparam("siptrace", "trace_on", 1)modparam("siptrace", "trace_flag", 22)modparam("siptrace", "trace_sl_acks", 0)#!endif# ----- mi_fifo params -----modparam("mi_fifo", "fifo_name", "/tmp/kamailio_fifo")# ----- tm params -----# auto-discard branches from previous serial forking legmodparam("tm", "failure_reply_mode", 3)# default retransmission timeout: 30secmodparam("tm", "fr_timer", 30000)# default invite retransmission timeout after 1xx: 120secmodparam("tm", "fr_inv_timer", 120000)# add value to ;lr param to cope with most of the UAsmodparam("rr", "enable_full_lr", 1)# do not append from tag to the RR (no need for this script)modparam("rr", "append_fromtag", 0)# ----- registrar params -----modparam("registrar", "method_filtering", 1)/* uncomment the next line to disable parallel forking via location */# modparam("registrar", "append_branches", 0)/* uncomment the next line not to allow more than 10 contacts per AOR */#modparam("registrar", "max_contacts", 10)# max value for expires of registrationsmodparam("registrar", "max_expires", 300)modparam("registrar", "min_expires", 30)# set it to 1 to enable GRUUmodparam("registrar", "gruu_enabled", 0)# ----- acc params -----/* what special events should be accounted ? */modparam("acc", "early_media", 0)modparam("acc", "report_ack", 0)modparam("acc", "report_cancels", 0)/* by default ww do not adjust the direct of the sequential requests.if you enable this parameter, be sure the enable "append_fromtag"in "rr" module */modparam("acc", "detect_direction", 0)/* account triggers (flags) */modparam("acc", "log_flag", FLT_ACC)modparam("acc", "log_missed_flag", FLT_ACCMISSED)modparam("acc", "log_extra","src_user=$fU;src_domain=$fd;src_ip=$si;""dst_ouser=$tU;dst_user=$rU;dst_domain=$rd")modparam("acc", "failed_transaction_flag", FLT_ACCFAILED)/* enhanced DB accounting */#!ifdef WITH_ACCDBmodparam("acc", "db_flag", FLT_ACC)modparam("acc", "db_missed_flag", FLT_ACCMISSED)modparam("acc", "db_url", DBURL)modparam("acc", "db_extra","src_user=$fU;src_domain=$fd;src_ip=$si;""dst_ouser=$tU;dst_user=$rU;dst_domain=$rd")#!endif# ----- usrloc params -----/* enable DB persistency for location entries */#!ifdef WITH_USRLOCDBmodparam("usrloc", "db_url", DBURL)modparam("usrloc", "db_mode", 2)modparam("usrloc", "use_domain", MULTIDOMAIN)#!endif# ----- auth_db params -----#!ifdef WITH_AUTHmodparam("auth_db", "db_url", DBURL)modparam("auth_db", "calculate_ha1", 0)#modparam("auth_db", "password_column", "password")modparam("auth_db", "load_credentials", "")modparam("auth_db", "use_domain", MULTIDOMAIN)#modparam("auth_db", "use_domain", 1)# ----- permissions params -----#!ifdef WITH_IPAUTHmodparam("permissions", "db_url", DBURL)modparam("permissions", "db_mode", 1)#!endif#!endif# ----- alias_db params -----#!ifdef WITH_ALIASDBmodparam("alias_db", "db_url", DBURL)modparam("alias_db", "use_domain", MULTIDOMAIN)#!endif# ----- speeddial params -----#!ifdef WITH_SPEEDDIALmodparam("speeddial", "db_url", DBURL)modparam("speeddial", "use_domain", MULTIDOMAIN)#!endif# ----- domain params -----#!ifdef WITH_MULTIDOMAINmodparam("domain", "db_url", DBURL)# register callback to match myself condition with domains listmodparam("domain", "register_myself", 1)#!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("rtpproxy", "rtpproxy_sock", "udp:127.0.0.1:7722")# ----- 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@kamailio.org")# params needed for NAT traversal in other modulesmodparam("nathelper|registrar", "received_avp", "$avp(RECEIVED)")modparam("usrloc", "nat_bflag", FLB_NATB)#!endif#!ifdef WITH_TLS# ----- tls params -----modparam("tls", "connection_timeout", 60)modparam("tls", "tls_debug", 10)modparam("tls", "config", "/usr/local/etc/kamailio/tls.cfg")#modparam("tls", "verify_certificate", 1)#modparam("tls", "require_certificate", 0)#!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 minutesmodparam("htable", "htable", "ipban=>size=8;autoexpire=300;")#!endif#!ifdef WITH_XMLRPC# ----- xmlrpc params -----modparam("xmlrpc", "route", "XMLRPC");modparam("xmlrpc", "url_match", "^/RPC")#!endif#!ifdef WITH_DEBUG# ----- debugger params -----modparam("debugger", "cfgtrace", 1)#!endif#!ifdef WITH_WEBSOCKETS# ----- nathelper params -----modparam("nathelper|registrar", "received_avp", "$avp(RECEIVED)")# Note: leaving NAT pings turned off here as nathelper is _only_ being used for# WebSocket connections. NAT pings are not needed as WebSockets have# their own keep-alives.#!endif####### Routing Logic ######### Main SIP request routing logic# - processing of any incoming SIP request starts with this route# - note: this is the same as route { ... }request_route {route(REQINIT);#!ifdef WITH_SIPTRACEif($hdr(X-Omnz-SipTrace) !=$null){sip_trace();setflag(22);}#!endif#!ifdef WITH_WEBSOCKETSif (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 detectionroute(NATDETECT);# CANCEL processingif (is_method("CANCEL")){if (t_check_trans()) {route(RELAY);}exit;}# handle requests within SIP dialogsroute(WITHINDLG);### only initial requests (no To tag)t_check_trans();# authenticationroute(AUTH);# record routing for dialog forming requests (in case they are routed)# - remove preloaded route headersremove_hf("Route");if (is_method("INVITE|SUBSCRIBE"))record_route();# account only INVITEsif (is_method("INVITE")){setflag(FLT_ACC); # do accounting}# dispatch requests to foreign domainsroute(SIPOUT);### requests for my local domains# handle presence related requestsroute(PRESENCE);# handle registrationsroute(REGISTRAR);if ($rU==$null){# request with no Username in RURIsl_send_reply("484","Address Incomplete");exit;}# dispatch destinations to PSTNroute(PSTN);# user location serviceroute(LOCATION);}route[RELAY] {# enable additional event routes for forwarded requests# - serial forking, RTP relaying handling, a.s.o.#!ifdef WITH_603if (is_method("INVITE")) {if($hdr(X-Omz-int-Id) ==$null){# request with no Username in RURIsl_send_reply("603","Declined");exit;}}#!endifif (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 checksroute[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 blockedxdbg("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;}}#!endifif (!mf_process_maxfwd_header("10")) {sl_send_reply("483","Too Many Hops");exit;}if(!sanity_check("1511", "7")){xlog("Malformed SIP message from $si:$sp\n");exit;}}# Handle requests within SIP dialogsroute[WITHINDLG] {if (has_totag()) {# sequential request withing a dialog should# take the path determined by record-routingif (loose_route()) {#!ifdef WITH_WEBSOCKETSif ($du == "") {if (!handle_ruri_alias()) {xlog("L_ERR", "Bad alias <$ru>\n");sl_send_reply("400", "Bad Request");exit;}}#!endifroute(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 statelessyroute(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 requestsroute(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 serverroute(RELAY);exit;} else {# ACK without matching transaction ... ignore and discardexit;}}sl_send_reply("404","Not here");}exit;}}# Handle SIP registrationsroute[REGISTRAR] {if (is_method("REGISTER")){if(isflagset(FLT_NATS)){setbflag(FLB_NATB);# uncomment next line to do SIP NAT pinging## setbflag(FLB_NATSIPPING);}if (!save("location"))sl_reply_error();exit;}}# USER location serviceroute[LOCATION] {#!ifdef WITH_SPEEDDIAL# search for short dialing - 2-digit extensionif($rU=~"^[0-9][0-9]$")if(sd_lookup("speed_dial"))route(SIPOUT);#!endif#!ifdef WITH_ALIASDB# search in DB-based aliasesif(alias_db_lookup("dbaliases"))route(SIPOUT);#!endif$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 alsoif (is_method("INVITE")){setflag(FLT_ACCMISSED);}route(RELAY);exit;}# Presence server routeroute[PRESENCE] {if(!is_method("PUBLISH|SUBSCRIBE"))return;#!ifdef WITH_PRESENCEif (!t_newtran()){sl_reply_error();exit;};if(is_method("PUBLISH")){handle_publish();t_release();}elseif( is_method("SUBSCRIBE")){handle_subscribe();t_release();}exit;#!endif# if presence enabled, this part will not be executedif (is_method("PUBLISH") || $rU==$null){sl_send_reply("404", "Not here");exit;}return;}# Authentication routeroute[AUTH] {#!ifdef WITH_AUTH#!ifdef WITH_IPAUTHif((!is_method("REGISTER")) && allow_source_address()){# source IP allowedreturn;}#!endifif (is_method("REGISTER") || from_uri==myself){# authenticate requestsif (!auth_check("$fd", "subscriber", "1")) {auth_challenge("$fd", "0");exit;}# user authenticated - remove auth headerif(!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 hereif (from_uri!=myself && uri!=myself){sl_send_reply("403","Not relaying");exit;}#!endifreturn;}# Caller NAT detection routeroute[NATDETECT] {#!ifdef WITH_NATforce_rport();if (nat_uac_test("19")) {if (is_method("REGISTER")) {fix_nated_register();} else {add_contact_alias();}setflag(FLT_NATS);}#!endifreturn;}# RTPProxy controlroute[NATMANAGE] {#!ifdef WITH_NATif (is_request()) {if(has_totag()) {if(check_route_param("nat=yes")) {setbflag(FLB_NATB);}}}if (!(isflagset(FLT_NATS) || isbflagset(FLB_NATB)))return;rtpproxy_manage("co");if (is_request()) {if (!has_totag()) {if(t_is_branch_route()) {add_rr_param(";nat=yes");}}}if (is_reply()) {if(isbflagset(FLB_NATB)) {add_contact_alias();}}#!endifreturn;}# URI update for dialog requestsroute[DLGURI] {#!ifdef WITH_NATif(!isdsturiset()) {handle_ruri_alias();}#!endifreturn;}# Routing to foreign domainsroute[SIPOUT] {if (!uri==myself){append_hf("P-hint: outbound\r\n");route(RELAY);}}# PSTN GW routingroute[PSTN] {#!ifdef WITH_PSTN# check if PSTN GW IP is definedif (strempty($sel(cfg_get.pstn.gw_ip))) {xlog("SCRIPT: PSTN rotuing enabled but pstn.gw_ip not defined\n");return;}# route to PSTN dialed numbers starting with '+' or '00'# (international format)# - update the condition to match your dialing rules for PSTN routingif(!($rU=~"^(\+|00)[1-9][0-9]{3,20}$"))return;# only local users allowed to callif(from_uri!=myself) {sl_send_reply("403", "Not Allowed");exit;}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;#!endifreturn;}# XMLRPC routing#!ifdef WITH_XMLRPCroute[XMLRPC] {# allow XMLRPC from localhostif ((method=="POST" || method=="GET")&& (src_ip==127.0.0.1)) {# close connection only for xmlrpclib user agents (there is a bug in# xmlrpclib: it waits for EOF before interpreting the response).if ($hdr(User-Agent) =~ "xmlrpclib")set_reply_close();set_reply_no_connect();dispatch_rpc();exit;}send_reply("403", "Forbidden");exit;}#!endif# route to voicemail serverroute[TOVOICEMAIL] {#!ifdef WITH_VOICEMAILif(!is_method("INVITE"))return;# check if VoiceMail server IP is definedif (strempty($sel(cfg_get.voicemail.srv_ip))) {xlog("SCRIPT: VoiceMail rotuing enabled but IP not defined\n");return;}if($avp(oexten)==$null)return;$ru = "sip:" + $avp(oexten) + "@" + $sel(cfg_get.voicemail.srv_ip)+ ":" + $sel(cfg_get.voicemail.srv_port);route(RELAY);exit;#!endifreturn;}# manage outgoing branchesbranch_route[MANAGE_BRANCH] {xdbg("new branch [$T_branch_idx] to $ru\n");route(NATMANAGE);}# manage incoming repliesonreply_route[MANAGE_REPLY] {xdbg("incoming reply\n");if(status=~"[12][0-9][0-9]")route(NATMANAGE);}# manage failure routing casesfailure_route[MANAGE_FAILURE] {route(NATMANAGE);if (t_is_canceled()) {exit;}#!ifdef WITH_BLOCK3XX# block call redirect based on 3xx replies.if (t_check_status("3[0-9][0-9]")) {t_reply("404","Not found");exit;}#!endif#!ifdef WITH_VOICEMAIL# serial forking# - route to voicemail on busy or no answer (timeout)if (t_check_status("486|408")) {$du = $null;route(TOVOICEMAIL);exit;}#!endif}#!ifdef WITH_WEBSOCKETSonreply_route {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[xhttp:request] {set_reply_close();set_reply_no_connect();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;}xlog("L_DBG", "HTTP Request Received\n");if ($hdr(Upgrade)=~"websocket"&& $hdr(Connection)=~"Upgrade"&& $rm=~"GET") {xlog("L_DBG", "WebSocket\n");xlog("L_DBG", " Host: $hdr(Host)\n");xlog("L_DBG", " Origin: $hdr(Origin)\n");if ($hdr(Host) == $null ) {xlog("L_WARN", "Bad host $hdr(Host)\n");xhttp_reply("403", "Forbidden", "", "");exit;}# Optional... validate Origin# 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 abou the# successful connectionexit;}}xhttp_reply("404", "Not found", "", "");}event_route[websocket:closed] {xlog("L_INFO", "WebSocket connection from $si:$sp has closed\n");}#!endif