Hello,
I try to write a script for parallel forking, but it doesn't work. The main script was generated by osipsconfig and it's a standard residential script with NAT traversal. For forking I use seturi(user1) and append_branch(user2), The user1 receives the INVITE but user2 not.
Any idea?
Hunor
My script:
fork=yes
children=4
/* uncomment the following lines to enable debugging */
debug=3
#fork=no
log_stderror=yes
/* uncomment the next line to enable the auto temporary blacklisting of
not available destinations (default disabled) */
#disable_dns_blacklist=no
/* uncomment the next line to enable IPv6 lookup after IPv4 dns
lookup failures (default disabled) */
#dns_try_ipv6=yes
/* comment the next line to enable the auto discovery of local aliases
based on revers DNS on IPs */
auto_aliases=no
#### USeR LOCation module
loadmodule "usrloc.so"
modparam("usrloc", "nat_bflag", 10)
modparam("usrloc", "db_mode", 2)
modparam("usrloc", "db_url", "mysql://opensips:opensipsrw@localhost/opensips") # CUSTOMIZE ME
#### REGISTRAR module
loadmodule "registrar.so"
modparam("registrar", "tcp_persistent_flag", 7)
modparam("registrar", "received_avp", "$avp(received_nh)")
/* uncomment the next line not to allow more than 10 contacts per AOR */
#modparam("registrar", "max_contacts", 10)
#### ACCounting module
loadmodule "acc.so"
/* what special events should be accounted ? */
modparam("acc", "early_media", 0)
modparam("acc", "report_cancels", 0)
/* by default we 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)
modparam("acc", "failed_transaction_flag", 3)
/* account triggers (flags) */
modparam("acc", "db_flag", 1)
modparam("acc", "db_missed_flag", 2)
modparam("acc", "db_url",
"mysql://opensips:opensipsrw@localhost/opensips") # CUSTOMIZE ME
loadmodule "rtpproxy.so"
modparam("rtpproxy", "rtpproxy_sock", "udp:127.0.0.1:7890") # CUSTOMIZE ME
####### Routing Logic ########
# main request routing logic
route{
xlog("\n\nROUTE\n\n");
force_rport();
if (nat_uac_test("23")) {
xlog("nat_uac_test\n");
if (is_method("REGISTER")) {
fix_nated_register();
setbflag(10);
} else {
fix_nated_contact();
setflag(10);
}
}
if (!mf_process_maxfwd_header("10")) {
sl_send_reply("483","Too Many Hops");
exit;
}
if (has_totag()) {
xlog("has totag\n");
# sequential request withing a dialog should
# take the path determined by record-routing
if (loose_route()) {
xlog("loose route\n");
# validate the sequential request against dialog
if ( $DLG_status!=NULL && !validate_dialog() ) {
xlog("In-Dialog $rm from $si (callid=$ci) is not valid according to dialog\n");
## exit;
}
if (is_method("BYE")) {
xlog("totag-BYE\n");
setflag(1); # do accounting …
setflag(3); # … even if the transaction fails
} else if (is_method("INVITE")) {
xlog("totag-INVITE");
# even if in most of the cases is useless, do RR for
# re-INVITEs alos, as some buggy clients do change route set
# during the dialog.
record_route();
}
if (check_route_param("nat=yes")) {
xlog("totag-nat=yes\n");
setflag(10);
}
# route it out to whatever destination was set by loose_route()
# in $du (destination URI).
route(1);
} else {
xlog("!loose route\n");
if ( is_method("ACK") ) {
xlog("!loose-ACK");
if ( t_check_trans() ) {
# non loose-route, but stateful ACK; must be an ACK after
# a 487 or e.g. 404 from upstream server
t_relay();
exit;
} else {
# ACK without matching transaction ->
# ignore and discard
exit;
}
}
sl_send_reply("404","Not here");
}
exit;
}
# CANCEL processing
if (is_method("CANCEL"))
{
if (t_check_trans())
t_relay();
exit;
}
t_check_trans();
if ( !(is_method("REGISTER") ) ) {
if (from_uri==myself)
{
# authenticate if from local subscriber
# authenticate all initial non-REGISTER request that pretend to be
# generated by local subscriber (domain from FROM URI is local)
if (!proxy_authorize("", "subscriber")) {
proxy_challenge("", "0");
exit;
}
if (!db_check_from()) {
sl_send_reply("403","Forbidden auth ID");
exit;
}
consume_credentials();
# caller authenticated
} else {
# if caller is not local, then called number must be local
if (!uri==myself) {
send_reply("403","Rely forbidden");
exit;
}
}
}
# preloaded route checking
if (loose_route()) {
xlog("L_ERR",
"Attempt to route with preloaded Route's ");
if (!is_method("ACK"))
sl_send_reply("403","Preload Route denied");
exit;
}
# record routing
if (!is_method("REGISTER|MESSAGE"))
record_route();
# account only INVITEs
if (is_method("INVITE")) {
xlog("\n\nINVITE\n\n");
if (!t_relay()) {
send_reply("500","Internal Error");
};
exit;
}
branch_route {
xlog("new branch at $ru\n");
}
onreply_route {
if (nat_uac_test("1"))
fix_nated_contact();
if ( isflagset(10) )
if (has_body("application/sdp"))
rtpproxy_answer("ro");
xlog("incoming reply\n");
}
failure_route {
xlog("on failure");
if (t_was_cancelled()) {
exit;
}
# uncomment the following lines if you want to block client
# redirect based on 3xx replies.
##if (t_check_status("3")) {
##t_reply("404","Not found");
## exit;
##}
}
local_route {
if (is_method("BYE") && $DLG_dir=="UPSTREAM") {
acc_db_request("200 Dialog Timeout", "acc");
}
}
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Hi,
I saw that the administrators were here, because they have answered other posts, but no mine. I need help!, because even the example script for forking doesn't work, from here: http://opensips.svn.sourceforge.net/viewvc/opensips/trunk/examples/fork.cfg?revision=5150&view=markup
The script in the link enters an infinite loop and consumes all memory at INVITE.
In normal mode the OpenSIPS proxy works fine for me, but I cannot modify it to enable parallel forking or to make it work behind a NAT.
Please just tell me if it's possible to do that!
Thanks,
Hunor
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Hi Bogdan,
Thank you for reply!
Now with this log a call looks like on log level 3:
RURI: sip:test1@193.231.162.167:5060;line=bf23940763471d6; branches: sip:test2@193.231.162.88
new branch at sip:test1@193.231.162.167:5060;line=bf23940763471d6
new branch at sip:test2@193.231.162.88
new branch at sip:test3@193.231.162.88
new branch at sip:test1@192.168.1.146;line=bf23940763471d6
incoming reply
incoming reply
incoming reply
incoming reply
incoming reply
RURI: sip:test4@192.168.1.199:4142;line=d1eef9b31a93120; branches: sip:test4@193.231.162.167:4142;line=d1eef9b31a93120
incoming reply
on failure
RURI: sip:193.231.162.88;lr; branches: <null>
The INVITE arrives to the test1, but to the other users(test2, test3) not.
Multumesc;)
Hunor
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I guess your problem is that lookup() fetches the location only for RURI (and not for the rest of the branches) - tthis is why only first destination gets to phone. The rest of them are probably sent out by opensips and spiralling back - check with ngrep on lo.
Regards,
Bogdan
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Well, the issue is clear - the additional branches (aside the RURI) are not resolved by lookup(), so they keep the IP of the server -> spiral and rejected by opensips.
What you can do is:
1) using the "branch" pseudo variable, you can do a small loop into script to make lookup() to go through all branches, so all original branches will be solved.
2) let the logic as it is, but when handling INVITEs, skip auth if the INVITE comes from opensips itself - allow spiralling without auth. In this case, the additional branches will be solved via lookup() at the second passing through opensips.
Regards,
Bogdan
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Hi,
The 2nd step is clear, I have documentation for $branch variable, too.
But I don't know how can I force the lookup() function to resolve different branches.
Could you give me a small example?
Thanks,
Hunor
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I tried to do the way you said, but I couldn't append the destinations to the branch while performing lookups. Instead, I appended all destinations at the beginning, and then made this small loop:
$var(i) = 0;
# the following line will evaluate to 3; there are 3 destinations
$var(itemNumber) = set_count("$avp(1)")+1;
while ($var(i) < $var(itemNumber)) {
if (!lookup("location","m")) {
xlog("in lookup location error\n");
if (!db_does_uri_exist()) {
send_reply("420","Bad Extension");
exit;
}
But, again, there is a problem with append_branch() (without parameters). When I use it the first time, it puts the first branch at the end of the $branch array, but then in the next iterations it only repeats the last element, not the first. Is there any kind of method to make a circular shift of the elements of the $branch array?
Regards,
Hunor
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
OK, I got the solution. I put all the destinations into an avp, then I loop through the elements and put them in the $ru variable. Then I call append_branch().
Regards,
Hunor
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Hi!
Something is still wrong now. The forking has to be done for a number of predefined clients. But when a client is not available (i.e. not registered on the SIP server) none of the others will receive the call. Is there a workaround for the unavailable contacts to be simply ignored?
Regards,
Hunor
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I guess your looping through the users breaks via a 404 Not Found if one of the users is not registered - you need to change that logic to send the 404 back only if *ALL* users are offline (and not if one is offline).
Regards,
Bogdan
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Hello,
I try to write a script for parallel forking, but it doesn't work. The main script was generated by osipsconfig and it's a standard residential script with NAT traversal. For forking I use seturi(user1) and append_branch(user2), The user1 receives the INVITE but user2 not.
Any idea?
Hunor
My script:
fork=yes
children=4
/* uncomment the following lines to enable debugging */
debug=3
#fork=no
log_stderror=yes
/* uncomment the next line to enable the auto temporary blacklisting of
not available destinations (default disabled) */
#disable_dns_blacklist=no
/* uncomment the next line to enable IPv6 lookup after IPv4 dns
lookup failures (default disabled) */
#dns_try_ipv6=yes
/* comment the next line to enable the auto discovery of local aliases
based on revers DNS on IPs */
auto_aliases=no
#advertised_address=193.231.162.88
#advertised_port=5060
listen=udp:193.231.162.88:5060 # CUSTOMIZE ME
disable_tcp=no
listen=tcp:193.231.162.88:5060 # CUSTOMIZE ME
#disable_tls=yes
####### Modules Section ########
#set module path
mpath="/usr/local/OpenSIPS/lib/opensips/modules/"
#### SIGNALING module
loadmodule "signaling.so"
#### StateLess module
loadmodule "sl.so"
#### Transaction Module
loadmodule "tm.so"
modparam("tm", "fr_timer", 10)
modparam("tm", "fr_inv_timer", 30)
modparam("tm", "restart_fr_on_each_reply", 0)
modparam("tm", "onreply_avp_mode", 1)
#### Record Route Module
loadmodule "rr.so"
/* do not append from tag to the RR (no need for this script) */
modparam("rr", "append_fromtag", 0)
#### MAX ForWarD module
loadmodule "maxfwd.so"
#### SIP MSG OPerationS module
loadmodule "sipmsgops.so"
#### FIFO Management Interface
loadmodule "mi_fifo.so"
modparam("mi_fifo", "fifo_name", "/tmp/opensips_fifo")
modparam("mi_fifo", "fifo_mode", 0666)
#### URI module
loadmodule "uri.so"
modparam("uri", "use_uri_table", 0)
modparam("uri", "db_url", "mysql://opensips:opensipsrw@localhost/opensips")
#### MYSQL module
loadmodule "db_mysql.so"
#### USeR LOCation module
loadmodule "usrloc.so"
modparam("usrloc", "nat_bflag", 10)
modparam("usrloc", "db_mode", 2)
modparam("usrloc", "db_url", "mysql://opensips:opensipsrw@localhost/opensips") # CUSTOMIZE ME
#### REGISTRAR module
loadmodule "registrar.so"
modparam("registrar", "tcp_persistent_flag", 7)
modparam("registrar", "received_avp", "$avp(received_nh)")
/* uncomment the next line not to allow more than 10 contacts per AOR */
#modparam("registrar", "max_contacts", 10)
#### ACCounting module
loadmodule "acc.so"
/* what special events should be accounted ? */
modparam("acc", "early_media", 0)
modparam("acc", "report_cancels", 0)
/* by default we 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)
modparam("acc", "failed_transaction_flag", 3)
/* account triggers (flags) */
modparam("acc", "db_flag", 1)
modparam("acc", "db_missed_flag", 2)
modparam("acc", "db_url",
"mysql://opensips:opensipsrw@localhost/opensips") # CUSTOMIZE ME
#### AUTHentication modules
loadmodule "auth.so"
loadmodule "auth_db.so"
modparam("auth_db", "calculate_ha1", yes)
modparam("auth_db", "password_column", "password")
modparam("auth_db", "db_url",
"mysql://opensips:opensipsrw@localhost/opensips") # CUSTOMIZE ME
modparam("auth_db", "load_credentials", "")
#### DIALOG module
loadmodule "dialog.so"
modparam("dialog", "dlg_match_mode", 1)
modparam("dialog", "default_timeout", 21600) # 6 hours timeout
modparam("dialog", "db_mode", 2)
modparam("dialog", "db_url",
"mysql://opensips:opensipsrw@localhost/opensips") # CUSTOMIZE ME
#### NAT modules
loadmodule "nathelper.so"
modparam("usrloc","nat_bflag", 6)
modparam("nathelper","received_avp", "$avp(42)")
modparam("nathelper", "natping_interval", 5)
modparam("nathelper", "ping_nated_only", 1)
modparam("nathelper", "sipping_bflag", 7)
modparam("nathelper", "sipping_from", "sip:pinger@193.231.162.88:5060")
loadmodule "rtpproxy.so"
modparam("rtpproxy", "rtpproxy_sock", "udp:127.0.0.1:7890") # CUSTOMIZE ME
####### Routing Logic ########
# main request routing logic
route{
xlog("\n\nROUTE\n\n");
force_rport();
if (nat_uac_test("23")) {
xlog("nat_uac_test\n");
if (is_method("REGISTER")) {
fix_nated_register();
setbflag(10);
} else {
fix_nated_contact();
setflag(10);
}
}
if (!mf_process_maxfwd_header("10")) {
sl_send_reply("483","Too Many Hops");
exit;
}
if (has_totag()) {
xlog("has totag\n");
# sequential request withing a dialog should
# take the path determined by record-routing
if (loose_route()) {
xlog("loose route\n");
# validate the sequential request against dialog
if ( $DLG_status!=NULL && !validate_dialog() ) {
xlog("In-Dialog $rm from $si (callid=$ci) is not valid according to dialog\n");
## exit;
}
if (is_method("BYE")) {
xlog("totag-BYE\n");
setflag(1); # do accounting …
setflag(3); # … even if the transaction fails
} else if (is_method("INVITE")) {
xlog("totag-INVITE");
# even if in most of the cases is useless, do RR for
# re-INVITEs alos, as some buggy clients do change route set
# during the dialog.
record_route();
}
if (check_route_param("nat=yes")) {
xlog("totag-nat=yes\n");
setflag(10);
}
# route it out to whatever destination was set by loose_route()
# in $du (destination URI).
route(1);
} else {
xlog("!loose route\n");
if ( is_method("ACK") ) {
xlog("!loose-ACK");
if ( t_check_trans() ) {
# non loose-route, but stateful ACK; must be an ACK after
# a 487 or e.g. 404 from upstream server
t_relay();
exit;
} else {
# ACK without matching transaction ->
# ignore and discard
exit;
}
}
sl_send_reply("404","Not here");
}
exit;
}
# CANCEL processing
if (is_method("CANCEL"))
{
if (t_check_trans())
t_relay();
exit;
}
t_check_trans();
if ( !(is_method("REGISTER") ) ) {
if (from_uri==myself)
{
# authenticate if from local subscriber
# authenticate all initial non-REGISTER request that pretend to be
# generated by local subscriber (domain from FROM URI is local)
if (!proxy_authorize("", "subscriber")) {
proxy_challenge("", "0");
exit;
}
if (!db_check_from()) {
sl_send_reply("403","Forbidden auth ID");
exit;
}
consume_credentials();
# caller authenticated
} else {
# if caller is not local, then called number must be local
if (!uri==myself) {
send_reply("403","Rely forbidden");
exit;
}
}
}
# preloaded route checking
if (loose_route()) {
xlog("L_ERR",
"Attempt to route with preloaded Route's ");
if (!is_method("ACK"))
sl_send_reply("403","Preload Route denied");
exit;
}
# record routing
if (!is_method("REGISTER|MESSAGE"))
record_route();
# account only INVITEs
if (is_method("INVITE")) {
xlog("\n\nINVITE\n\n");
#forking
if ( from_uri == "sip:test4@193.231.162.88" ) {
xlog("\nFORKING\n");
seturi("sip:test1@193.231.162.88");
append_branch("sip:test2@193.231.162.88");
append_branch("sip:test3@193.231.162.88");
}
# create dialog with timeout
if ( !create_dialog("B") ) {
send_reply("500","Internal Server Error");
exit;
}
setflag(1); # do accounting
}
if (!uri==myself) {
append_hf("P-hint: outbound\r\n");
route(1);
}
# requests for my domain
if (is_method("PUBLISH|SUBSCRIBE"))
{
sl_send_reply("503", "Service Unavailable");
exit;
}
if (is_method("REGISTER"))
{
# authenticate the REGISTER requests
if (!www_authorize("", "subscriber"))
{
www_challenge("", "0");
exit;
}
if (!db_check_to())
{
sl_send_reply("403","Forbidden auth ID");
exit;
}
if ( proto==TCP || 0 ) setflag(7);
if (!save("location"))
sl_reply_error();
exit;
}
if ($rU==NULL) {
# request with no Username in RURI
sl_send_reply("484","Address Incomplete");
exit;
}
# do lookup with method filtering
if (!lookup("location","m")) {
if (!db_does_uri_exist()) {
send_reply("420","Bad Extension");
exit;
}
t_newtran();
t_reply("404", "Not Found");
exit;
}
if (isbflagset(10)) setflag(10);
# when routing via usrloc, log the missed calls also
setflag(2);
route(1);
}
route {
# for INVITEs enable some additional helper routes
if (is_method("INVITE")) {
if (isflagset(10)) {
if (has_body("application/sdp"))
rtpproxy_offer("ro");
}
t_on_branch("2");
t_on_reply("2");
t_on_failure("1");
}
if (isflagset(10)) {
add_rr_param(";nat=yes");
}
if (!t_relay()) {
send_reply("500","Internal Error");
};
exit;
}
branch_route {
xlog("new branch at $ru\n");
}
onreply_route {
if (nat_uac_test("1"))
fix_nated_contact();
if ( isflagset(10) )
if (has_body("application/sdp"))
rtpproxy_answer("ro");
xlog("incoming reply\n");
}
failure_route {
xlog("on failure");
if (t_was_cancelled()) {
exit;
}
# uncomment the following lines if you want to block client
# redirect based on 3xx replies.
##if (t_check_status("3")) {
##t_reply("404","Not found");
## exit;
##}
}
local_route {
if (is_method("BYE") && $DLG_dir=="UPSTREAM") {
acc_db_request("200 Dialog Timeout", "acc");
}
}
Hi,
I saw that the administrators were here, because they have answered other posts, but no mine. I need help!, because even the example script for forking doesn't work, from here: http://opensips.svn.sourceforge.net/viewvc/opensips/trunk/examples/fork.cfg?revision=5150&view=markup
The script in the link enters an infinite loop and consumes all memory at INVITE.
In normal mode the OpenSIPS proxy works fine for me, but I cannot modify it to enable parallel forking or to make it work behind a NAT.
Please just tell me if it's possible to do that!
Thanks,
Hunor
Hi Hunor,
in the route try to print all the branches you have as destination:
xlog("RURI : $ru ; branches: $(branch(uri))\n" );
Regards,
Bogdan
Hi Bogdan,
Thank you for reply!
Now with this log a call looks like on log level 3:
RURI: sip:test1@193.231.162.167:5060;line=bf23940763471d6; branches: sip:test2@193.231.162.88
new branch at sip:test1@193.231.162.167:5060;line=bf23940763471d6
new branch at sip:test2@193.231.162.88
new branch at sip:test3@193.231.162.88
new branch at sip:test1@192.168.1.146;line=bf23940763471d6
incoming reply
incoming reply
incoming reply
incoming reply
incoming reply
RURI: sip:test4@192.168.1.199:4142;line=d1eef9b31a93120; branches: sip:test4@193.231.162.167:4142;line=d1eef9b31a93120
incoming reply
on failure
RURI: sip:193.231.162.88;lr; branches: <null>
The INVITE arrives to the test1, but to the other users(test2, test3) not.
Multumesc;)
Hunor
I guess your problem is that lookup() fetches the location only for RURI (and not for the rest of the branches) - tthis is why only first destination gets to phone. The rest of them are probably sent out by opensips and spiralling back - check with ngrep on lo.
Regards,
Bogdan
Hi,
Sorry for the late answer.
Here is the result:
ngrep -d lo port 5060
interface: lo (127.0.0.0/255.0.0.0)
filter: (ip or ip6) and ( port 5060 )
#
U 193.231.162.88:5060 -> 193.231.162.88:5060
INVITE sip:test2@193.231.162.88 SIP/2.0..Record-Route: <sip:193.231.162.88;lr;did=e0a.472afbd7>..Via: SIP/2.0/UDP 193.231.162.88;branch=z9hG4bKe8eb.865913e3.1..Via: SIP/2.0/UDP 193.231.
162.150:5060;received=193.231.162.150;rport=5060;branch=z9hG4bK1739..From: <sip:test4@193.231.162.88>;tag=27400..To: <sip:dummy@193.231.162.88>..Call-ID: 23192..CSeq: 21 INVITE..Contact
: <sip:test4@193.231.162.150>..Content-Type: application/sdp..Allow: INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, NOTIFY, MESSAGE, SUBSCRIBE, INFO..Max-Forwards: 69..User-Agent: Linphone/3
.5.2 (eXosip2/3.6.0)..Subject: Phone call..Content-Length: 318….v=0..o=test4 4076 4076 IN IP4 193.231.162.150..s=Talk..c=IN IP4 193.231.162.150..t=0 0..m=audio 7078 RTP/AVP 112 111
110 3 0 8 101..a=rtpmap:112 speex/32000..a=fmtp:112 vbr=on..a=rtpmap:111 speex/16000..a=fmtp:111 vbr=on..a=rtpmap:110 speex/8000..a=fmtp:110 vbr=on..a=rtpmap:101 telephone-event/8000..a
=fmtp:101 0-11..
#
U 193.231.162.88:5060 -> 193.231.162.88:5060
SIP/2.0 407 Proxy Authentication Required..Via: SIP/2.0/UDP 193.231.162.88;received=193.231.162.88;rport=5060;branch=z9hG4bKe8eb.865913e3.1..Via: SIP/2.0/UDP 193.231.162.150:5060;receiv
ed=193.231.162.150;rport=5060;branch=z9hG4bK1739..From: <sip:test4@193.231.162.88>;tag=27400..To: <sip:dummy@193.231.162.88>;tag=ec500a06cb2b870afbf5ea7b0b0d5e27.faa0..Call-ID: 23192..C
Seq: 21 INVITE..Proxy-Authenticate: Digest realm="193.231.162.88", nonce="4ff134470000001927f16e64199429fa97d4b7ddbd9f5d19"..Server: OpenSIPS (1.8.0-notls (i386/linux))..Content-Length:
0….
#
U 193.231.162.88:5060 -> 193.231.162.88:5060
ACK sip:test2@193.231.162.88 SIP/2.0..Via: SIP/2.0/UDP 193.231.162.88;branch=z9hG4bKe8eb.865913e3.1..From: <sip:test4@193.231.162.88>;tag=27400..Call-ID: 23192..To: <sip:dummy@193.231.1
62.88>;tag=ec500a06cb2b870afbf5ea7b0b0d5e27.faa0..CSeq: 21 ACK..Max-Forwards: 70..User-Agent: OpenSIPS (1.8.0-notls (i386/linux))..Content-Length: 0….
exit
(to test1 arrives the INVITE, but to test2 not)
P.S.: If it is easier for you, I can give you ssh access to the server.
Regards,
Hunor
Well, the issue is clear - the additional branches (aside the RURI) are not resolved by lookup(), so they keep the IP of the server -> spiral and rejected by opensips.
What you can do is:
1) using the "branch" pseudo variable, you can do a small loop into script to make lookup() to go through all branches, so all original branches will be solved.
2) let the logic as it is, but when handling INVITEs, skip auth if the INVITE comes from opensips itself - allow spiralling without auth. In this case, the additional branches will be solved via lookup() at the second passing through opensips.
Regards,
Bogdan
Hi,
The 2nd step is clear, I have documentation for $branch variable, too.
But I don't know how can I force the lookup() function to resolve different branches.
Could you give me a small example?
Thanks,
Hunor
It is a matter of scripting - keep all the destinations (where you want to fork) into AVPs and push the values one by one into RURI and call lookup().
Regards,
Bogdan
Hi!
I tried to do the way you said, but I couldn't append the destinations to the branch while performing lookups. Instead, I appended all destinations at the beginning, and then made this small loop:
$var(i) = 0;
# the following line will evaluate to 3; there are 3 destinations
$var(itemNumber) = set_count("$avp(1)")+1;
while ($var(i) < $var(itemNumber)) {
if (!lookup("location","m")) {
xlog("in lookup location error\n");
if (!db_does_uri_exist()) {
send_reply("420","Bad Extension");
exit;
}
t_newtran();
t_reply("404", "Not Found");
exit;
}
xlog("BEFORE: $(branch(uri))\t$(branch(uri))\t$(branch(uri))\t$(branch(uri))\n");
append_branch();
xlog("BRANCH: $(branch(uri))\t$(branch(uri))\t$(branch(uri))\t$(branch(uri))\n");
remove_branch(0);
xlog("AFTER: $(branch(uri))\t$(branch(uri))\t$(branch(uri))\t$(branch(uri))\n");
$var(i) = $var(i) + 1;
}
But, again, there is a problem with append_branch() (without parameters). When I use it the first time, it puts the first branch at the end of the $branch array, but then in the next iterations it only repeats the last element, not the first. Is there any kind of method to make a circular shift of the elements of the $branch array?
Regards,
Hunor
OK, I got the solution. I put all the destinations into an avp, then I loop through the elements and put them in the $ru variable. Then I call append_branch().
Regards,
Hunor
Hi!
Something is still wrong now. The forking has to be done for a number of predefined clients. But when a client is not available (i.e. not registered on the SIP server) none of the others will receive the call. Is there a workaround for the unavailable contacts to be simply ignored?
Regards,
Hunor
I guess your looping through the users breaks via a 404 Not Found if one of the users is not registered - you need to change that logic to send the 404 back only if *ALL* users are offline (and not if one is offline).
Regards,
Bogdan
Thank you, that helped!
Best regards,
Hunor