kamailio.cfg

#!KAMAILIO
#

####### Include Local Config If Exists #########
import_file "kamailio-local.cfg"

##!define WITH_MULTIDOMAIN
#!define WITH_NAT 1
#!define WITH_NATSIPPING 1
#!define WITH_BLOCK3XX 1
####!define WITH_TRUNK 0
#!define WITH_REGISTER 1

####### Defined Values #########
#!ifdef WITH_MULTIDOMAIN
#!define MULTIDOMAIN 1
#!else
#!define MULTIDOMAIN 0
#!endif

#!define DBURL "text:///etc/kamailio/database"

#!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
debug=2
log_stderror=no

memdbg=5
memlog=5

log_facility=LOG_LOCAL7

# number of SIP routing processes
children=4

/* uncomment the next line to disable TCP (default on) */
#disable_tcp=yes

server_header="Server: SBC-OS"
user_agent_header="User-Agent: SBC-OS"
  
#!ifdef WITH_TLS
enable_tls=yes
#!endif

# life time of TCP connection when there is no traffic
# - a bit higher than registration expires to cope with UA behind NAT
tcp_connection_lifetime=3605

#Fake topology hostname
topology.hostname_hide = "sbc01.voiceboys.sbc" desc "Fake topology hostname"

####### Modules Section ########

# set paths to location of modules (to sources or installation folders)
#!ifdef WITH_SRCPATH
mpath="modules/"
#!else
mpath="/usr/lib64/kamailio/modules/"
#!endif

loadmodule "jsonrpcs.so"
loadmodule "db_text.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 "textops.so"
loadmodule "siputils.so"
loadmodule "xlog.so"
loadmodule "sanity.so"
loadmodule "ctl.so"
loadmodule "cfg_rpc.so"
loadmodule "acc.so"
loadmodule "path.so"
loadmodule "ndb_redis.so"
loadmodule "topos_redis.so"
loadmodule "topos.so"
loadmodule "uac.so"
loadmodule "permissions.so"
loadmodule "rtpengine.so"
loadmodule "nathelper.so"
loadmodule "nat_traversal.so"
loadmodule "htable.so"
loadmodule "pike.so"
loadmodule "dispatcher.so"

#!ifdef WITH_MULTIDOMAIN
loadmodule "domain.so"
#!endif

#!ifdef WITH_TLS
loadmodule "tls.so"
#!endif

#!ifdef WITH_DEBUG
loadmodule "debugger.so"
#!endif


# ----------------- setting module-specific parameters ---------------
modparam("path", "use_received", 1)

# ----- jsonrpcs params -----
modparam("jsonrpcs", "pretty_format", 1)
/* set the path to RPC fifo control file */
#modparam("jsonrpcs", "fifo_name", "/var/run/kamailio/kamailio_rpc.fifo")
/* set the path to RPC unix socket control file */
#modparam("jsonrpcs", "dgram_socket", "/var/run/kamailio/kamailio_rpc.sock")

# ----- ctl params -----
#modparam("ctl", "binrpc", "unix:/var/run/kamailio/kamailio_ctl")

# ----- tm params -----
# auto-discard branches from previous serial forking leg
modparam("tm", "failure_reply_mode", 3)
# default retransmission timeout: 30sec
modparam("tm", "fr_timer", 30000)
# default invite retransmission timeout after 1xx: 120sec
modparam("tm", "fr_inv_timer", 120000)


# ----- rr params -----
# set next param to 1 to add value to ;lr param (helps with some UAs)
modparam("rr", "enable_full_lr", 0)
# do not append from tag to the RR (no need for this script)
modparam("rr", "append_fromtag", 1)


# ----- acc params -----
/* what special events should be accounted ? */
modparam("acc", "early_media", 1)
modparam("acc", "report_ack", 0)
modparam("acc", "report_cancels", 1)
modparam("acc", "detect_direction", 1)
modparam("acc", "log_flag", FLT_ACC)
modparam("acc", "log_facility", "LOG_LOCAL7")
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)

modparam("permissions", "db_url", DBURL)
modparam("permissions", "db_mode", 1)

# ----- domain params -----
#!ifdef WITH_MULTIDOMAIN
modparam("domain", "db_url", DBURL)
# register callback to match myself condition with domains list
modparam("domain", "register_myself", 1)
#!endif

#!ifdef WITH_NAT
# ----- rtpproxy params -----
modparam("rtpengine", "rtpengine_sock","0 == udp:127.0.0.1:22222")
modparam("rtpengine", "rtpengine_tout_ms", 2000)
modparam("rtpengine", "rtpengine_disable_tout", 20)
#modparam("rtpengine", "setid_avp", "$avp(setid)")


modparam("nat_traversal", "keepalive_from", "sip:keepalive@qsc.de")
modparam("nat_traversal", "keepalive_extra_headers", "User-Agent: SBC-OS 1.0\r\nX-KeepAlive: true\r\n")
modparam("nat_traversal", "keepalive_method", "OPTIONS")
modparam("nat_traversal", "keepalive_interval", 30)
modparam("nat_traversal", "keepalive_state_file", "/var/run/kamailio/keepalive_state")

#!endif


#!ifdef WITH_TLS
# ----- tls params -----
modparam("tls", "config", "/etc/kamailio/tls.cfg")
#!endif

modparam("pike", "sampling_time_unit", 10)
modparam("pike", "reqs_density_per_unit", 160)
modparam("pike", "remove_latency", 30)

# ----- htable params -----
# ip ban htable with autoexpire after 5 minutes
modparam("htable", "htable", "ipban=>size=8;autoexpire=300;")

#!ifdef WITH_XMLRPC
# ----- xmlrpc params -----
modparam("xmlrpc", "route", "XMLRPC");
modparam("xmlrpc", "url_match", "^/RPC")
#!endif

#!ifdef WITH_DEBUG
# ----- debugger params -----
modparam("debugger", "cfgtrace", 1)
modparam("debugger", "log_level_name", "exec")
#!endif

#Distpatcher
modparam("dispatcher", "list_file", "/etc/kamailio/dispatcher.list")
modparam("dispatcher", "ds_ping_method", "OPTIONS")
modparam("dispatcher", "ds_ping_from", "<sip:ping@qsc.de>")
modparam("dispatcher", "ds_ping_interval", 30)
modparam("dispatcher", "ds_probing_mode", 1)
modparam("dispatcher", "ds_probing_threshold", 2)
modparam("dispatcher", "setid_pvname", "$var(setid)")
modparam("dispatcher", "attrs_pvname", "$var(attrs)")

#TOPOS
#TOPOS
modparam("ndb_redis", "server", "name=srv8;addr=127.0.0.1;port=6379;db=8")
modparam("topos", "storage", "redis")
modparam("topos_redis", "serverid", "srv8")
#modparam("topos", "mask_callid", 0)
#modparam("topos", "sanity_checks", 0)
modparam("topos", "branch_expire", 14400)
modparam("topos", "dialog_expire", 14400)
#modparam("topos", "clean_interval", 60)

#dont' restore
modparam("uac","restore_mode","none")
modparam("uac","restore_dlg",0)

####### Routing Logic ########

include_file "kamailio-hmr.cfg"

# Main SIP request routing logic
# - processing of any incoming SIP request starts with this route
# - note: this is the same as route { ... }
request_route {

	# per request initial checks
	#xlog("Request route RM:[$rm], Cseq: [$cs], IP:[$sndto(ip)], SourceIP:[$si], Received IP: [$Ri]\n");

	route(REQINIT);

	# 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)

	# handle retransmissions
	if(t_precheck_trans()) {
		t_check_trans();
		exit;
	}
	t_check_trans();

	#Hackers ?
        if($ua != $null && $ua =~ "friendly-scanner") {
                append_to_reply("P-SBC-Error: unknow destination\r\n");
                sl_send_reply("501", "Server Error");
                exit;
        }

	if (is_method("OPTIONS"))
        {
                if (uri=~"sip:.*[@]+.*") sl_send_reply("501", "Not Implemented");
                else options_reply();
                exit;
        }

	# record routing for dialog forming requests (in case they are routed)
	# - remove preloaded route headers
	#To fix Route;
	if (is_method("INVITE|SUBSCRIBE|OPTIONS") && allow_trusted()) {
		loose_route();
	}

	remove_hf("Route");
	if (is_method("INVITE|SUBSCRIBE|OPTIONS")) {
		record_route();
	}

	route(HEADER_MANIPULATION);

	# account only INVITEs
	if (is_method("INVITE")) {
		setflag(FLT_ACC); # do accounting
	}

	# dispatch requests to foreign domains
	#route(SIPOUT);
	
	# handle registrations
	route(REGISTRAR);


	if (is_method("INVITE|SUBSCRIBE|OPTIONS")) {
#!ifdef WITH_TRUNK
                route(CHECKTRUNK);
#!endif
#!ifdef WITH_REGISTER
                route(CHECKREGISTER);
#!endif
		append_to_reply("P-SBC-Error: not registered destination [$Ri] [$si:$sp]\r\n");
                sl_send_reply("501", "Server Error");
                exit;
	}
	
	### requests for my local domains
	# handle presence related requests
	route(PRESENCE);

	if ($rU==$null) {
		# request with no Username in RURI
		sl_send_reply("484","Address Incomplete");
		exit;
	}

	append_to_reply("P-SBC-Error: unknow destination\r\n");
        sl_send_reply("501", "Server Error");
        exit;

}

# Wrapper for relaying requests
route[RELAY] {

	if (is_method("ACK") && has_body("application/sdp")) {
                route(MEDIAPROXY);
        }

	# 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] {

	# flood detection 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 && !allow_trusted()) {
		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");
			append_to_reply("P-SBC-Error: limit exceeded\r\n");
			$sht(ipban=>$si) = 1;
			exit;
		}
	}
	if($ua =~ "friendly-scanner|sipcli") {
		# 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()) return;

	# sequential request withing a dialog should
	# take the path determined by record-routing
	if (loose_route()) {
		#xlog("L_ALERT","WE ARE LOOSE CODE:[$rm]!\n");
		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 statelessy
			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
		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;
}


route[MEDIAPROXY] {


	#set_rtpengine_set("0");      
        #RTPENGINE MODULE ONLY!!!
        #$avp(rtpengine_offer_flags) = "replace-session-connection rtcp-mux-demux force trust-address replace-origin replace-session-connection ICE=force RTP/SAVPF";
        #rtpengine_manage($avp(rtpengine_offer_flags));
        #rtpengine_manage("replace-session-connection replace-origin direction=external direction=internal ICE=remove");

	if(is_method("REGISTER|SUBSCRIBE|OPTIONS") || $rm=~ "^(REGISTER|SUBSCRIBE|OPTIONS)") {
			return;
	}

	if(is_method("INVITE") && $rs == $null && !has_totag()) {

		#$var(mediagroup) = allow_address_group($Ri, $Rp);
                #Match any port
                $var(mediagroup) = allow_address_group($Ri, 0);

		if ($var(mediagroup) == -1) {
			xlog("IP not activated for trunks [1] IP:[$Ri] Port:[$Rp] Src: [$si]\n");
                        append_to_reply("P-SBC-Error: ip trunks not registered [$Ri] [$Rp] [$si]\r\n");
                        sl_send_reply("500","IP not registered for media");
                        exit;
                }	

		#Group == 1 - 100 - internal GROUP IP
		if($var(mediagroup) < 100) {
                        $var(destgroup) = $var(mediagroup) + 100;
			#Das ist mein check
			#if(!is_present_hf("X-RTP-Proxy")){
			#    append_hf("X-RTP-Proxy: true\r\n");
			#    rtpengine_manage("replace-session-connection replace-origin ICE=remove direction=$var(mediagroup) direction=$var(destgroup)");
			#    add_rr_param(";proxy_media=yes");
			#}

			rtpengine_manage("replace-session-connection replace-origin ICE=remove direction=$var(mediagroup) direction=$var(destgroup)");
			add_rr_param(";proxy_media=yes");
			#append_hf("X-IN-SBC: $var(destgroup);$var(mediagroup)\r\n");
		        #xlog("L_ALERT","THIS IS INVITE External to Internal status [$rs]!\n");
		}
		#Group > 100 = external
		else if($var(mediagroup) >= 100) {
                        $var(destgroup) = $var(mediagroup) - 100;
			rtpengine_manage("replace-session-connection replace-origin ICE=remove direction=$var(mediagroup) direction=$var(destgroup)");
			add_rr_param(";proxy_media=yes");

			#if(!is_present_hf("X-RTP-Proxy")){
			#    append_hf("X-RTP-Proxy: true\r\n");
			#    rtpengine_manage("replace-session-connection replace-origin ICE=remove direction=$var(mediagroup) direction=$var(destgroup)");
			#    add_rr_param(";proxy_media=yes");
			#}

			#append_hf("X-OUT-SBC: $var(destgroup);$var(mediagroup)\r\n");
		        #xlog("L_ALERT","THIS IS INVITE Internal -> External, status [$rs]!\n");
		}
		else {
			xlog("Uknown GROUP [$var(mediagroup)] for trunks [1] IP:[$Ri] Port:[$Rp]\n");
                        append_to_reply("P-SBC-Error: unknown group [$var(mediagroup)] for sbc [$Ri][$Rp]\r\n");
                        sl_send_reply("500","Group not registered");
		}	        
	}
	else if(is_method("INVITE") && $rs == $null && has_totag()) {

		#if(!is_present_hf("X-RTP-Proxy")){
		#    append_hf("X-RTP-Proxy: true\r\n");
		#    rtpengine_offer("replace-session-connection replace-origin");
		#    add_rr_param(";proxy_media=yes");
		#}
                rtpengine_offer("replace-session-connection replace-origin");
                #xlog("L_ALERT","DO reINVITE offer!!\n");
        }
	else {
		#if(!is_present_hf("X-RTP-Proxy")){
		#    append_hf("X-RTP-Proxy: true\r\n");
		#    rtpengine_manage("replace-session-connection replace-origin ICE=remove");
		#    add_rr_param(";proxy_media=yes");
		#}
	        rtpengine_manage("replace-session-connection replace-origin ICE=remove");
	        #xlog("L_ALERT","THI IS status [$rs] [$rm]!\n");
	}

	#rtpengine_manage("direction=external direction=internal");
	#rtpengine_manage("ICE=remove");

        return;
}


route[CHECKTRUNK] {

	#xlog("L_ALERT","This request come from [$si]!\n");

        $var(dns) = "trunk-["+$Ri+"]-["+$si+"].sbc";

        #xlog("L_ALERT", "SBC DOMAIN: $var(dns) - $Rp");

	#port can be also changed to $Rp
        $var(group) = allow_address_group($var(dns), $Rp);

        if ($var(group) == -1) {
                xlog("Trunk is not active DNS_GROUP:[$var(dns)], Source: [$si], Destination: [$Ri] Port:[$Rp]\n");
		return;
        }

	if(ds_is_from_list("$var(group)"))
	{		
		
		$var(setid) = $(var(group){s.int});		
		#xlog("INCOMING FROM: $var(attrs) and $var(setid)");
		#TRUNK UN2TR
		if($var(setid) >= 1000 && $var(setid) < 2000)
		{
			#TOPOS
			route(TOPOLOGYHIDE);

			$var(destgroup) = $var(setid) + 1000;
			if(!ds_select_domain("$var(destgroup)", "8"))
                	{
                        	xlog("There is no destination $var(destgroup)\n");
		                append_to_reply("P-SBC-Error: b leg trunks is not available  $var(destgroup)\r\n");
        		        sl_send_reply("500","B-Trunk is not available");
				exit;                
			}

			#xlog("USING: UN2TR $var(access_socket) and $var(destgroup)");
	                append_hf("X-Group-SBC: $var(destgroup)\r\n");
        	        append_hf("X-Routing-SBC: un2tr-cgn-trunk\r\n");
        		route(RELAY);
		        exit;
		}
		#TRUNK TR2UN
		else if($var(setid) >= 2000 && $var(setid) < 3000)
		{
			#TOPOS
			route(TOPOLOGYHIDE);
			
			$var(destgroup) = $var(setid) - 1000;
			if(!ds_select_domain("$var(destgroup)", "8"))
                	{
                        	xlog("There is no destination $var(destgroup)\n");
		                append_to_reply("P-SBC-Error: a leg trunks is not available  $var(destgroup)\r\n");
        		        sl_send_reply("500","A-Trunk is not available");
				exit;                
			}

			#xlog("USING: TR2UN $var(access_socket) and $var(destgroup)");
	                append_hf("X-Group-SBC: $var(destgroup)\r\n");
        	        append_hf("X-Routing-SBC: tr2un\r\n");
        		route(RELAY);
		        exit;
		}
		else {
	        	xlog("There is no destination for trunk $var(setid), $var(group)\n");
			append_to_reply("P-SBC-Error: wrong trunk group $var(setid) $var(group)\r\n");
        		sl_send_reply("500","Wrong trunk group");
			exit;                
		}
	}
}

route[CHECKREGISTER] {

	#xlog("L_ALERT","This request come from [$si]!\n");

        #5:1002:registrar-[92.197.201.226].sbc:32:0:NULL:Internal Sip trunk - trusted
        $var(dns) = "registrar-["+$Ri+"].sbc";

        #xlog("L_ALERT", "SBC REG-DOMAIN: $var(dns) - $Rp");

	#port can be also changed to $Rp
        $var(group) = allow_address_group($var(dns), $Rp);

        if ($var(group) == -1) {
                xlog("Trunk is not activate for registrar DNS_GROUP:[$var(dns)], Source: [$si], Destination: [$Ri] Port:[$Rp]\n");
		return;
        }

	if($var(group) < 200 || $var(group) > 400)
        {
                xlog("Not register trunk [$var(group)], Source: [$si], Destination: [$Ri] Port:[$Rp]\n");
                return;
        }

        #If the group is from 300-400 - this is trusted
        #and we should check source IP for Allow!
        if($var(group) >= 300 && $var(group) < 400)
        {
                $var(urlreg) = "sip:"+$si+":"+$sp;
        }
        else
        {
                $var(urlreg) = "sip:"+$Ri+":"+$Rp;
        }


	if(ds_is_from_list("$var(group)", "3","$var(urlreg)"))
	{		
		$var(setid) = $(var(group){s.int});		
		#xlog("INCOMING REGISTER FROM: $var(attrs) and $var(setid)");
		#TRUNK UN2TR
		if($var(setid) >= 200 && $var(setid) < 300)
		{
			route(TOPOLOGYHIDE);
			
			if(is_method("REGISTER"))
			{
				if (!add_path_received()) {
					sl_send_reply("503", "Internal Path Error");
				};
			}

			$var(destgroup) = $var(setid) + 100;
			if(!ds_select_domain("$var(destgroup)", "8"))
                	{
                        	xlog("There is no destination $var(destgroup)\n");
		                append_to_reply("P-SBC-Error: b leg trunks is not available  $var(destgroup)\r\n");
        		        sl_send_reply("500","B-Trunk is not available");
				exit;                
			}

			if(is_method("REGISTER"))
                        {
                                if($rd != $td) {
                                        remove_hf("To");
                                        insert_hf("To: <sip:$tU@$rd;user=phone>\r\n", "CSeq");
                                }
                        }


			#xlog("USING: REGISTER UN2TR $var(access_socket) and $var(setid)");
	                append_hf("X-Group-SBC: $var(destgroup)\r\n");
        	        append_hf("X-Routing-SBC: register un2tr-cgn-reg\r\n");
        		route(RELAY);
		        exit;
		}
		#TRUNK TR2UN
		else if($var(setid) >= 300 && $var(setid) < 400)
		{
			#TOPOS
			route(TOPOLOGYHIDE);
                        
                        $avp(access) = $(var(attrs){param.value,access});
                        #xlog("USING: REGISTER TR2UN $var(access_socket) and $var(setid) AC: $avp(force) [A: $var(attrs)]");
                        $fs = $avp(access);

                        #xlog("USING: REGISTER TR2UN! to INTERNET!");
                        append_hf("X-Routing-SBC: register tr2un\r\n");
                        route(RELAY);
                        exit;

		}
		else {
	        	xlog("There is no destination for registrar $var(setid), $var(group)\n");
			append_to_reply("P-SBC-Error: wrong registrar group $var(setid) $var(group)\r\n");
        		sl_send_reply("500","Wrong registrar group");
			exit;                
		}
	}
}

# Handle SIP registrations
route[REGISTRAR] {

	if (!is_method("REGISTER")) return;

	if(isflagset(FLT_NATS)) {

		setbflag(FLB_NATB);
		# do SIP NAT pinging
		setbflag(FLB_NATSIPPING);	
	}	

#!ifdef WITH_REGISTER
	route(CHECKREGISTER);
#!endif

	append_to_reply("P-SBC-Error: B-Trunk access\r\n");
	sl_send_reply("500", "Service not available");		
        exit;	
}

route[TOPOLOGYHIDE] {
        if(is_method("INVITE") && !strempty($sel(cfg_get.topology.hostname_hide)))
        {

                if(defined $fU && !strempty($fU)) {
                        $var(from)="sip:"+$fU+"@"+$sel(cfg_get.topology.hostname_hide);
                }
                else {
                        $var(from)="sip:"+$sel(cfg_get.topology.hostname_hide);
                }

                if(defined $tU && !strempty($tU)) {
                        $var(to)="sip:"+$tU+"@"+$sel(cfg_get.topology.hostname_hide);
                }
                else {
                        $var(to)="sip:"+$sel(cfg_get.topology.hostname_hide);
                }
                uac_replace_from("$var(from)");
                uac_replace_to("$var(to)");
        }
}



# Presence server processing
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;
	}

	# if presence enabled, this part will not be executed
	if (is_method("PUBLISH") || $rU==$null) {
		sl_send_reply("404", "Not here");
		exit;
	}
	return;
}

# Caller NAT detection
route[NATDETECT] {
#!ifdef WITH_NAT
	force_rport();
	if (client_nat_test("3")) {
		if (is_method("REGISTER")) {
			#append_hf("X-Nat-SBC: true\r\n");
		        nat_keepalive();
		        append_hf("X-NAT-URI: $source_uri\r\n");
			xlog("NAT PING: $fU");
			#fix_contact();
			#fix_nated_contact();
			#fix_nated_register();
	
		} 
		else {
			if(is_first_hop()) {
				set_contact_alias();
			}
		}
		
		setflag(FLT_NATS);
	}
#!endif
	return;
}

# RTPProxy control and signaling updates for NAT traversal
route[NATMANAGE] {
#!ifdef WITH_NAT
	if (is_request()) {
		if(has_totag()) {
			if(check_route_param("nat=yes")) {
				setbflag(FLB_NATB);
			}
		}
	}

	route(MEDIAPROXY);

	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();
		}
	}
#!endif
	return;
}

# URI update for dialog requests
route[DLGURI] {
#!ifdef WITH_NAT
	if(!isdsturiset()) {
		handle_ruri_alias();
	}
#!endif
	return;
}

# Routing to foreign domains
route[SIPOUT] {
	if (uri==myself) return;

	append_hf("P-hint: outbound\r\n");
	route(RELAY);
	exit;
}

# XMLRPC routing
#!ifdef WITH_XMLRPC
route[XMLRPC] {
	# allow XMLRPC from localhost
	if ((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

# Manage outgoing branches
branch_route[MANAGE_BRANCH] {
	xdbg("new branch [$T_branch_idx] to $ru\n");
	route(NATMANAGE);	

}

# Manage incoming replies
onreply_route[MANAGE_REPLY] {
	if(status=~"[12][0-9][0-9]") {
		route(NATDETECT);
		route(NATMANAGE);	
	}
}

# Manage failure routing cases
failure_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
}

event_route[topos:msg-outgoing] {
  if($sndto(ip)=="10.1.1.10") {
    drop;
  }
}

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值