[SR-Users] Anybody using 2 instances with topos communicating with each other?

Daniel Tryba d.tryba at pocos.nl
Fri May 11 16:11:36 CEST 2018


Scenario:
endpoint (bob) <-> kamailio proxy (5.1.3) <-> kamailio backend (5.1.2)

Both kamailio instances are running the topos module (mysql backend).
Call setup is fine, but forwarding BYEs fail.

With a call from endpoint to kamailio, topos on the proxy scrambles
Contact to kamailio backend. But in responses from backend contact
remains untouched. In the ACK to the 200, topos on the proxy does
nothing. If the caller hangsup, the BYE will loop internally till max
hops is exceeded (483 which will be send to caller eventually).

When the backend initiates the call to the endpoint, topos appears to
work, but the BYE from the endpoint on hangup get a 404 Not here from
the proxy (route[WITHINDLG]).

Disabling topos on the proxy will result in a functioning proxy (config
attached).

Is there something wrong with my config? Or is this an unforseen
scenario that just doesn't work with topos?

* Endpoint to backend scenario

endpoint:5060 -> proxy:5060
INVITE sip:callee at sip.pocos.nl;transport=tcp SIP/2.0
Via: SIP/2.0/UDP endpoint:5060;rport;branch=...
Max-Forwards: 70
Route: <sip:proxy:5060;lr>
Contact: <sip:bob at endpoint:5060;ob>

proxy:5060 -> backend:5060
INVITE sip:callee at sip.itco.nl;transport=tcp SIP/2.0
Via: SIP/2.0/UDP proxy;branch=...
CSeq: 29848 INVITE
Route: <sip:proxy:5060;lr>
Contact: <sip:btpsh-5af5972d-bf5e-2 at proxy>

backend:5060 -> proxy:5060
SIP/2.0 200 OK
Via: SIP/2.0/UDP proxy;branch=...
Contact: <sip:atpsh-5af19bf0-9f94-7 at backend>

proxy:5060 -> endpoint:5060
SIP/2.0 200 OK
Contact: <sip:atpsh-5af19bf0-9f94-7 at backend>
Via: SIP/2.0/UDP endpoint:5060;received=endpoint;rport=5060;branch=...
Record-Route: <sip:proxy;lr>

endpoint:5060 -> proxy:5060
ACK sip:atpsh-5af19bf0-9f94-7 at backend SIP/2.0
Via: SIP/2.0/UDP endpoint:5060;rport;branch=...
Route: <sip:proxy;lr>

proxy:5060 -> backend:5060
ACK sip:atpsh-5af19bf0-9f94-7 at backend SIP/2.0
Via: SIP/2.0/UDP proxy;branch=...
Via: SIP/2.0/UDP endpoint:5060;received=endpoint;rport=5060;branch=...

endpoint:5060 -> proxy:5060
BYE sip:atpsh-5af19bf0-9f94-7 at backend SIP/2.0
Via: SIP/2.0/UDP endpoint:5060;rport;branch=...
Max-Forwards: 70
Route: <sip:proxy;lr>

proxy:5060 -> proxy:5060
BYE sip:atpsh-5af19bf0-9f94-7 at backend SIP/2.0
Via: SIP/2.0/UDP proxy;branch=...
Via: SIP/2.0/UDP endpoint:5060;received=endpoint;rport=5060;branch=...
Max-Forwards: 69
Route: <sip:proxy;lr>

proxy:5060 -> proxy:5060
BYE sip:atpsh-5af19bf0-9f94-7 at backend SIP/2.0
Via: SIP/2.0/UDP proxy;branch=...
Via: SIP/2.0/UDP proxy;rport=5060;branch=...
Via: SIP/2.0/UDP endpoint:5060;received=endpoint;rport=5060;branch=...
Max-Forwards: 68
Route: <sip:proxy;lr>

[not going to mention the 50+ BYEs adding Vias and decrementing
Max-Forwards.


* Backend to endpoint scenario

backend:5060 -> proxy:5060
INVITE sip:bob at endpoint:5060;ob SIP/2.0
Via: SIP/2.0/UDP backend;branch=...
Route: <sip:loadbalancer at proxy;lr;received=sip:endpoint:5060>
Contact: <sip:btpsh-5af07a27-72b-502c1 at backend>

proxy:5060 -> endpoint:5060
INVITE sip:bob at endpoint:5060;ob SIP/2.0
Via: SIP/2.0/UDP proxy;branch=...
Contact: <sip:btpsh-5af5972d-bf5d-5 at proxy>

endpoint:5060 -> proxy:5060
SIP/2.0 200 OK
Via: SIP/2.0/UDP proxy;received=proxy;branch=...
Contact: <sip:bob at endpoint:5060;ob>

proxy:5060 -> backend:5060
SIP/2.0 200 OK
Contact: <sip:bob at endpoint:5060;ob;alias=endpoint~5060~1>
Via: SIP/2.0/UDP backend;rport=5060;branch=...
Record-Route: <sip:proxy;lr>

endpoint:5060 -> proxy:5060
BYE sip:btpsh-5af5972d-bf5d-5 at proxy SIP/2.0
Via: SIP/2.0/UDP endpoint:5060;rport;branch=...

proxy:5060 -> endpoint:5060
SIP/2.0 404 Not here
Via: SIP/2.0/UDP endpoint:5060;rport=5060;branch=...

-------------- next part --------------
#!KAMAILIO
#
# vim: ai

####### Defined Values #########
#!define FLB_NATB 6
#!define FLB_NATSIPPING 7

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

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

fork=yes
children=4

dns_srv_lb=yes
dns_try_ipv6=no
dns_use_search_list=no
use_dns_failover=yes
dns_retr_time=1
dns_retr_no=1
dns_try_naptr=no
use_dns_cache=on
dns=no
rev_dns=no
check_via=no

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

/* add local domain aliases */
import_file "kamailio-aliases.cfg"

enable_tls=yes

# 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
force_rport=yes

mpath="/usr/lib/x86_64-linux-gnu/kamailio/modules/"

loadmodule "tm.so"
loadmodule "sl.so"
loadmodule "rr.so"
loadmodule "kex.so"
loadmodule "corex.so"
loadmodule "tmx.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 "ipops.so"

loadmodule "nathelper.so"

loadmodule "tls.so"

loadmodule "htable.so"
loadmodule "pike.so"

loadmodule "db_mysql.so"
loadmodule "topos.so"

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

loadmodule "path.so"
loadmodule "dispatcher.so"

loadmodule "siptrace.so"

modparam("path", "use_received", 1)

#!define DBURL "mysql://kam:kam@127.0.0.1:3306/kam"

modparam("db_mysql", "ping_interval", 10)
modparam("db_mysql", "auto_reconnect", 1)
modparam("db_mysql", "timeout_interval", 5)

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)

# ----- 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", 1);
modparam("dispatcher", "ds_probing_mode", 1);
modparam("dispatcher", "ds_ping_from", "sip:loadbalancer at proxy");


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

# ----- nathelper params -----
modparam("nathelper", "natping_interval", 30)
modparam("nathelper", "ping_nated_only", 0)
modparam("nathelper", "sipping_bflag", FLB_NATSIPPING)
modparam("nathelper", "sipping_from", "sip:pinger at kamailio.org")

# params needed for NAT traversal in other modules
modparam("nathelper|registrar", "received_avp", "$avp(RECEIVED)")
modparam("usrloc", "nat_bflag", FLB_NATB)

# ----- tls params -----
modparam("tls", "config", "/etc/kamailio/tls.cfg")

# ----- pike params -----
modparam("pike", "sampling_time_unit", 2)
modparam("pike", "reqs_density_per_unit", 64)
modparam("pike", "remove_latency", 4)

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


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

modparam("siptrace", "duplicate_uri", "sip:homer:9060")
modparam("siptrace", "hep_mode_on", 1)
modparam("siptrace", "hep_version", 2)
modparam("siptrace", "hep_capture_id", 800)
modparam("siptrace", "trace_to_database", 0)
modparam("siptrace", "trace_flag", 22)
modparam("siptrace", "trace_on", 1)
modparam("siptrace", "trace_mode", 1)

####### 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 {
	if(t_precheck_trans())
	{
		t_check_trans();
		exit;
	}
	else
	{
		if(is_method("INVITE") && !has_totag())
		{
			t_newtran();
			t_reply("100","Trying");
		}
	}

	route(REQINIT);

	remove_hf_re("^[XP]-");
	remove_hf_re("^User-Agent");
	remove_hf_re("^Server");

	route(NATDETECT);
	route(WITHINDLG);

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

	if(!is_in_subnet($si, "backend/30"))
	{
		if($ai!=$null)
		{
			append_hf("P-Asserted-Identity: <$ai>\r\n");
		}

		add_path_received("loadbalancer");

		ds_select_dst(1, 11);

	    t_on_failure("RTF_DISPATCH");
	}
	else
	{
		remove_hf_re("^Diversion");
		remove_hf("Route");

		loose_route();
	}
	
	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] {
	# 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;
		}
	}

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

	if($ua =~ "friendly-scanner") {
		drop;
	}

	if($ua =~ "sipcli") {
		drop;
	}

	if($ua =~ "VaxSIPUserAgent") {
		drop;
	}

	if (!mf_process_maxfwd_header("10")) {
		sl_send_reply("483","Too Many Hops");
		exit;
	}

	if(is_method("OPTIONS")) {
		sl_send_reply("200","Keepalive");
		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()) {
		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);
		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;
}

# Caller NAT detection
route[NATDETECT] {
	if(!is_in_subnet($si, "backends/30"))
	{
		if (!is_method("REGISTER") && is_first_hop()) 
		{
			set_contact_alias();
		}
	}

	return;
}

route[NATMANAGE] {
	if(!is_in_subnet($si, "backends/30"))
	{
		if (is_reply() && is_first_hop())
		{
			set_contact_alias();
		}
	}

	return;
}

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

# Manage outgoing branches
branch_route[MANAGE_BRANCH] {
	route(NATMANAGE);
}

# Manage incoming replies
onreply_route[MANAGE_REPLY] {
	remove_hf_re("^[XP]-");

	if(status=~"[12][0-9][0-9]")
		route(NATMANAGE);
}

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

	if (t_is_canceled()) {
		exit;
	}
}

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

	if (t_check_status("500") or (t_branch_timeout() and !t_branch_replied()))
	{
		if(ds_next_dst())
		{
			t_on_failure("RTF_DISPATCH");
			route(RELAY);
			exit;
		}
	}
}

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

	if (t_check_status("500") or (t_branch_timeout() and !t_branch_replied()))
	{
		ds_mark_dst("ip");

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


More information about the sr-users mailing list