Just wanted to say, this thread has been very useful for me, as I’ve only started to get
into (or understand should I say) branches recently, and found the order of events, and
the way messages were updated (from original to new branch) a little confusing.
Thanks Daniel
Ben Merrills
From: sr-users <sr-users-bounces(a)lists.kamailio.org> On Behalf Of Daniel-Constantin
Mierla
Sent: 22 January 2020 08:35
To: Kamailio (SER) - Users Mailing List <sr-users(a)lists.kamailio.org>rg>; George
Diamantopoulos <georgediam(a)gmail.com>
Subject: Re: [SR-Users] Implicit branch creation and private variables questions - (Second
Post)
Hello,
a new branch is created every time a request is sent out to a new destination or resent to
same destination after additional processing in a failure route. append_branch() should
not be needed, unless you want to create more branches for parallel forking. Updating $ru
or $du and doing t_relay() in failure route should be all what is needed to send to a new
branch.
To have branch route execution, be sure you set it before t_relay(), also in failure
route, even if you set it previously in request_route for first branch -- in other words,
t_on_branch() must be used for each step of serial forking.
The branch route block is executed inside t_relay(), so it is in the same process that
sends out the request, but in case of failure routing, further branches are not created in
the same process as the first branch. The best is to use $xavp/$avp if you are not sure
where and when those branch processing happen.
Cheers,
Daniel
On 21.01.20 23:22, George Diamantopoulos wrote:
Hello all,
Some keyboard shortcut resulted in gmail previously sending the message out before I had
finished writing it, sorry about that. This is the complete message.
I'm trying to accomplish the following scenario, and some questions have arisen during
testing: I'd like to be able to fork serially to a number of downstream destinations
in case of failure, but also try several hosts which are available per destination network
(via dispatcher module) before failing over to the next one (e.g. try two gateways for
provider A and if both fail, then try two more gateways for provider B etc). I also need
to perform some network-specific handling per destination group (=provider), which I
thought I'd perform in respective branch routes. To that end, I'm using something
similar to the config pasted toward the end of the message.
Here's some points that have troubled me, if anyone can provide some insight:
1. After exhausting dispatcher group entries for first_provider, the request is indeed
forwarded to last_provider with this configuration. I've noticed a new branch is
created. I'm assuming this happens because there's some RURI manipulation taking
place in branch_route? I recall reading somewhere that even doing $ru = $ru will result in
a new branch being created. Is my assumption correct here, or is the new branch created
for some other reason? I mean if I did t_on_branch in a failure route following a t_relay
which failed, but without manipulating the RURI in the new branch_route, would that still
create an implicit new branch or would one have to use append_branch() or similar in this
case?
* I'm asking because several implicit or explicit branch creation mechanisms
are documented in various places (e.g. usrloc, lcr, alias_db, corex) but it's
there's no comprehensive list for reference.
1. If there are two destinations in the destination group for first_provider, and the
first one fails, then the second destination will be tried out in
tm:branch-failure:DISPATCH_FIRST_PROV_FAILOVER. Now the Via branch parameter for this
INVITE is different than the original (.1 instead of .0), which one can verify by
capturing the traffic on-net. However, in the logs, the respective branch route is only
run once, and there's no reference to the ".1" Via, even with cfg script
debugging enabled. I'm assuming this means that kamailio's definition of
"branch" in the context of the configuration file is different to the notion of
branch as a transaction identifier in SIP signalling in general? In simpler language,
distinct branch identifiers in Via headers between two requests does not mean that these
two requests were treated as separate branches in kamailio config: true or false?
2. This is causing the most problems for me right now: the $vn PVs seem to be available
for the first (main?) branch, but not for subsequent branches which are generated if the
first branch fails. I was under the impression that branch_routes are handled by the same
process as the request_route for a message, and as a consequence I was expecting private
variables to be available there. This doesn't seem to be the case with the example
configuration below. $vn(some_var) in branch_route[LAST_PROV_BRANCH] evaluates to NULL.
Any insight as to why this happens? And if I need these vars to be available in serial
forking, is the recommended solution to use shared variables or is my approach here
problematic in other ways?
Thanks!
George
request_route {
...
$vn(some_var) = "some_value";
$vn(some_other_var) = "some_other_value";
...
$avp(provider_order) = "last_provider";
$avp(provider_order) = "first_provider";
...
t_set_fr(120000, 2000);
route(PROVIDER_SELECTION);
}
route[PROVIDER_SELECTION] {
if ( is_avp_set("$avp(provider_order)") ) {
t_on_failure("PROVIDER_SERIAL");
if ( $avp(provider_order) == "first_provider" ) {
$avp(provider_order) = $null;
route(DISPATCH_FIRST_PROV);
} else if ( $avp(provider_order) == "last_provider" ) {
$avp(provider_order) = $null;
route(DISPATCH_LAST_PROV);
}
}
}
route[DISPATCH_FIRST_PROV] {
if ( !ds_select_dst("1", "4") ) {
if ( is_avp_set("$avp(provider_order)") ) {
route(PROVIDER_SELECTION);
} else {
t_send_reply("503", "Downstream carrier unavailable");
}
}
t_on_branch_failure("DISPATCH_FIRST_PROV_FAILOVER");
t_on_branch("FIRST_PROV_BRANCH");
route(RELAY);
exit;
}
route[DISPATCH_LAST_PROV] {
//Similar to First Prov
}
event_route[tm:branch-failure:DISPATCH_FIRST_PROV_FAILOVER] {
if (t_is_canceled()) exit;
# next DST - only for 5xx or local timeout
if ( t_check_status("5[[:digit:]]+") || (t_branch_timeout() &&
!t_branch_replied()) ) {
if ( ds_next_dst() ) {
t_on_branch_failure("DISPATCH_FIRST_PROV_FAILOVER");
route(RELAY);
exit;
} else {
xlog("L_ERR", "--- SCRIPT_DISPATCH_FIRST_PROV_FAILOVER: Failed to route
request to first prov.\n");
}
}
}
event_route[tm:branch-failure:DISPATCH_LAST_PROV_FAILOVER] {
//Similar to First Prov
}
branch_route[FIRST_PROV_BRANCH] {
uac_replace_to("$vn(some_var)");
$ru = $vn(some_other_var);
}
branch_route[LAST_PROV_BRANCH] {
uac_replace_to("$vn(some_var)");
$ru = $vn(some_other_var);
}
failure_route[PROVIDER_SERIAL] {
if (t_is_canceled()) exit;
# next Provider - only for 5xx or local timeout
if ( (t_check_status("5[[:digit:]]+") || (t_branch_timeout() &&
!t_branch_replied())) && is_avp_set("$avp(provider_order)") ) {
xlog("L_NOTICE", "--- SCRIPT_PROVIDER_SERIAL: A failover provider was
selected: Forwarding to $avp(provider_order)\n");
route(PROVIDER_SELECTION);
route(RELAY);
exit;
} else if ( t_check_status("5[[:digit:]]+") || (t_branch_timeout() &&
!t_branch_replied()) ) {
xlog("L_NOTICE", "--- SCRIPT_PROVIDER_SERIAL: No more provider options,
giving up\n");
exit;
} else {
xlog("L_NOTICE", "--- SCRIPT_PROVIDER_SERIAL: Non-5xx error received,
relaying\n");
}
}
route[RELAY] {
// Mostly identical to the sample config file
}
_______________________________________________
Kamailio (SER) - Users Mailing List
sr-users@lists.kamailio.org<mailto:sr-users@lists.kamailio.org>
https://lists.kamailio.org/cgi-bin/mailman/listinfo/sr-users
--
Daniel-Constantin Mierla --
www.asipto.com<http://www.asipto.com>
www.twitter.com/miconda<http://www.twitter.com/miconda> --
www.linkedin.com/in/miconda<http://www.linkedin.com/in/miconda>
Kamailio Advanced Training - March 9-11, 2020, Berlin -
www.asipto.com<http://www.asipto.com>
Kamailio World Conference - April 27-29, 2020, in Berlin --
www.kamailioworld.com<http://www.kamailioworld.com>