[SR-Users] TOPOS (5.1.[23]) breaks PRACK

Daniel Tryba d.tryba at pocos.nl
Fri May 4 16:34:48 CEST 2018


Enabling topos breaks PRACK in my simple (near default) proxy setup
(attached kamailio.conf). 

asterisk 13 (10.0.3.147) <-> kamailio (10.0.3.87) <-> asterisk 13 (10.0.3.154)

With the event route topos:msg-outgoing dropping all. The flow of
messages is as expected.

INVITE ->
<- Ringing
PRACK ->
<- 200 OK

With topos enabled, the PRACK doesn't get past route[WITHINGDLG] and is
answered with the 
        sl_send_reply("404","Not here");

INVITE ->
<- Ringing
PRACK ->
<- 404 Not here

These specific tests were done on kamailio 5.1.2, but with 5.1.3 I see
the exact same messages.

-------------- next part --------------
#!KAMAILIO
#
# - 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

#!define FLG_DIALOG 8

####### Global Parameters #########

#!define DBURL "mysql://kam:bla@10.0.1.107:3306/kam"

### LOG Levels: 3=DBG, 2=INFO, 1=NOTICE, 0=WARN, -1=ERR
#!ifdef WITH_DEBUG
debug=4
log_stderror=yes
#!else
debug=2
log_stderror=no
#!endif

memdbg=5
memlog=5

log_facility=LOG_LOCAL0

# number of SIP routing processes
children=4

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

import_file "kamailio-aliases.cfg"

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

#server_signature=no

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

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

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

#loadmodule "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 "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"
loadmodule "ipops.so"

loadmodule "rtpengine.so"

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

loadmodule "dispatcher.so"
loadmodule "uac.so"
loadmodule "dialog.so"
#loadmodule "siptrace.so"

#loadmodule "db_mysql.so"
#modparam("db_mysql", "ping_interval", 10)
#modparam("db_mysql", "auto_reconnect", 1)
#modparam("db_mysql", "timeout_interval", 5)

loadmodule "ndb_redis.so"
loadmodule "topos_redis.so"
loadmodule "topos.so"

# ----------------- setting module-specific parameters ---------------
modparam("uac","restore_mode","manual")
modparam("uac","restore_from_avp","$avp(s:original_uri_from)")
modparam("uac","restore_to_avp","$avp(s:original_uri_to)")

# ----- dialog ---------
modparam("dialog", "dlg_flag", FLG_DIALOG)
modparam("dialog", "enable_stats", 1)
modparam("dialog", "dlg_match_mode", 2)
modparam("dialog", "profiles_with_value", "POCS2TE;TE2POCS;totals")

# ----- dispatcher -----
modparam("dispatcher", "list_file", "/etc/kamailio/dispatcher.list")
modparam("dispatcher", "flags", 2)
modparam("dispatcher", "dst_avp", "$avp(AVP_DST)")
modparam("dispatcher", "grp_avp", "$avp(AVP_GRP)")
modparam("dispatcher", "cnt_avp", "$avp(AVP_CNT)")
modparam("dispatcher", "ds_ping_method", "OPTIONS");
modparam("dispatcher", "ds_ping_interval", 16);
modparam("dispatcher", "ds_probing_mode", 1);
modparam("dispatcher", "ds_ping_from", "sip:ping at pocs");

# ----- mi_fifo params -----
#modparam("mi_fifo", "fifo_name", "/var/run/kamailio/kamailio_fifo")

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

# ----- rtpproxy params -----
modparam("rtpengine", "rtpengine_sock", RTPENGINE)

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

# topos
modparam("ndb_redis", "server", "name=srv2;addr=127.0.0.1;port=6379;db=2")
modparam("topos", "storage", "redis")
modparam("topos_redis", "serverid", "srv2")

#modparam("topos", "storage", "db")
#modparam("topos", "db_url", DBURL)

modparam("topos", "mask_callid", 0)
modparam("topos", "sanity_checks", 0)
modparam("topos", "branch_expire", 10800)
modparam("topos", "dialog_expire", 10800)
modparam("topos", "clean_interval", 60)

####### 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 {
	force_rport();

	# per request initial checks
	route(REQINIT);

	# CANCEL processing
	if (is_method("CANCEL")) {
		rtpengine_manage();
		dlg_manage();

		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();

	# authentication
	route(AUTH);

	# record routing for dialog forming requests (in case they are routed)
	# - remove preloaded route headers
	remove_hf("Route");
	if (is_method("INVITE|SUBSCRIBE")) {
		record_route();
	}

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

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


	$avp(dispatcherid)="0";
	$avp(dispatcheralgo)="11";


	dlg_manage();
	set_dlg_profile("totals","$ci");

	if(ds_is_from_list("11",3) || ds_is_from_list("12",3))
	{
		$rd=""+$Ri;

		$avp(dispatcherid)="7";

		set_dlg_profile("TE2POCS","$ci");
	}
	else if(ds_is_from_list("7",3))
	{
		$avp(dispatcherid)="11";
		set_dlg_profile("POCS2TE","$ci");
	}
	else
	{
		send_reply("403", "No dispatcher available");
		exit;
	}

	route(DISPATCHER);
	route(RELAY);
}

# 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] {
	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")){
		sl_send_reply("200","Keepalive");
		exit;
	}

	if(!sanity_check("1511", "7")) {
#		xlog("Malformed SIP message from $si:$sp\n");
		exit;
	}

	if(is_method("SUBSCRIBE|REGISTER|SUBSCRIBE"))
	{
		sl_send_reply("403","Method not supported");
		exit;
	}
}

# Handle requests within SIP dialogs
route[WITHINDLG] {
	if (!has_totag()) return;

	dlg_manage();

	# sequential request withing a dialog should
	# take the path determined by record-routing
	if (loose_route()) {
		route(DLGURI);
		if (is_method("BYE")) {
			rtpengine_manage();
			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();
		}
		else if ( is_method("CANCEL") )
		{
			rtpengine_manage();
		}
		route(RELAY);
		exit;
	}

	if (is_method("SUBSCRIBE") && uri == myself) {
		# in-dialog subscribe requests
		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;
}


# IP authorization and user authentication
route[AUTH] {
	if(
	   ds_is_from_list("7",3) ||
	   ds_is_from_list("11",3)||
	   ds_is_from_list("12",3)
	  )
	{
		return;
	}

	sl_send_reply("403","Not relaying");
	exit;
}

# Caller NAT detection
route[NATDETECT] {
#!ifdef WITH_NAT
	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);
	}
#!endif
	return;
}

# RTPProxy control and signaling updates for NAT traversal
route[NATMANAGE] {
	rtpengine_manage("RTP trust-address replace-origin replace-session-connection ICE=remove");

	return;
}

# URI update for dialog requests
route[DLGURI] {
	return;
}

# 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(NATMANAGE);
	}
}

# Manage failure routing cases
failure_route[MANAGE_FAILURE] {
	route(NATMANAGE);

	if (t_is_canceled()) exit;
}

route[DISPATCHER]
{
	if(is_method("INVITE") && !($rU=~"^(\+|00)?[0-9]{3,20}$"))
	{
		send_reply("484", "Dispatcher Address Incomplete: rU [$rU]");
		exit;
	}

	if(!ds_select_dst($avp(dispatcherid), $avp(dispatcheralgo)))
	{
		send_reply("502", "No dispatcher available");
		exit;
	}

	t_on_failure("RTF_DISPATCH");

	return;
}

failure_route[RTF_DISPATCH]
{
	if (t_is_canceled()) {
		exit;
	}

	# next DST - only for 500 or local timeout
	if (t_check_status("500") or (t_branch_timeout() and !t_branch_replied()))
	{
		if(t_check_status("500"))
		{
			ds_mark_dst("ip");
		}

		if(ds_next_dst())
		{
			t_on_failure("RTF_DISPATCH");
			route(RELAY);
			exit;
		}
	}
}

event_route[dispatcher:dst-down] {
	xlog("L_ERR", "Destination down: $rm $ru ($du)\n");
}

event_route[dispatcher:dst-up] {
	xlog("L_ERR", "Destination up: $rm $ru\n");
}

event_route[topos:msg-outgoing] 
{
        if(1==0)
        {
                drop;
        }
}

-------------- next part --------------
A non-text attachment was scrubbed...
Name: topos-enabled.pcapng.gz
Type: application/gzip
Size: 1626 bytes
Desc: not available
URL: <http://lists.kamailio.org/pipermail/sr-users/attachments/20180504/6acb2d46/attachment.gz>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: topos-disabled.pcapng.gz
Type: application/gzip
Size: 1775 bytes
Desc: not available
URL: <http://lists.kamailio.org/pipermail/sr-users/attachments/20180504/6acb2d46/attachment-0001.gz>


More information about the sr-users mailing list