[SR-Users] Dispatcher No destinations available

Cristian Livadaru cristian at lcx.at
Fri Feb 15 17:13:21 CET 2019


Hi,
I have a Kamailio running as Load Balancer and it works great but since 
a couple of weeks I kept noticing 404s in Homer and when looked into it 
they came from Kamailio.

```
route[LOADBALANCE] {
   #ds_select_dst(destination_set, algorithm) function chooses the 
destination for the call. For this it can use a lot of algorithms.
   #Alg. 0 is the default one that does the the choosing over the call 
ID hash
   #Alg. 4 is a Round-Robin
   #Alg. 10 is the one that chooses the destination based on the minimum 
load of all destinations
   if(!ds_select_dst("1", "4"))
   {
     #if we are here that means no destination is available. We notify 
the user by 404 and exit the script.
     xlog("L_NOTICE", "No destination available!");
     send_reply("404", "No destination");
     exit;
   }
   xlog("L_NOTICE", "Routing call to <$ru> via <$du>\n");
   #set the no_reply_recieved timeout to 2 second ... adjust the value 
to your need
   #note: The first value "0" is invite timeout .. we do not need to 
change it
   #This means that is the selected media server fails to respond within 
2 seconds the failure_route "MANAGE_FAILURE" is called
   #note: this implies that ale the signaling from media servers on the 
way back to the user goes through the proxy as well
   t_set_fr(0,2000);
   t_on_failure("MANAGE_FAILURE");
   return;
}
```

The two asterisks behind it seem fine and I can’t really see why this 
started happening. Also I thing that returning 404 might be misleading, 
wouldn’t it be better if I would return 503 instead?

I enabled debugging in Kamailio but can’t really seem to notice 
anything wrong here:

```
Feb 15 09:50:28 wlb kamailio[6659]:  6(6668) DEBUG: <core> 
[core/udp_server.c:491]: udp_rcv_loop(): received on udp socket: 
(106/100/1104) [[INVITE sip:431230123 at 213.137.140.230:5060 SIP/2.0 0D  
0A Via: SIP/2.0/UDP 196.27.235.76:5060;branch=z9h]]
Feb 15 09:50:28 wlb kamailio[6659]:  6(6668) DEBUG: <core> 
[core/parser/msg_parser.c:604]: parse_msg(): SIP Request:
Feb 15 09:50:28 wlb kamailio[6659]:  6(6668) DEBUG: <core> 
[core/parser/msg_parser.c:606]: parse_msg():  method:  <INVITE>
Feb 15 09:50:28 wlb kamailio[6659]:  6(6668) DEBUG: <core> 
[core/parser/msg_parser.c:608]: parse_msg():  uri:     
<sip:431230123 at 213.137.140.230:5060>
Feb 15 09:50:28 wlb kamailio[6659]:  6(6668) DEBUG: <core> 
[core/parser/msg_parser.c:610]: parse_msg():  version: <SIP/2.0>
Feb 15 09:50:28 wlb kamailio[6659]:  6(6668) DEBUG: <core> 
[core/parser/parse_via.c:1303]: parse_via_param(): Found param type 232, 
<branch> = <z9hG4bK0080827005DD9C0D8E963B2EA293>; state=16
Feb 15 09:50:28 wlb kamailio[6659]:  6(6668) DEBUG: <core> 
[core/parser/parse_via.c:2639]: parse_via(): end of header reached, 
state=5
Feb 15 09:50:28 wlb kamailio[6659]:  6(6668) DEBUG: <core> 
[core/parser/msg_parser.c:492]: parse_headers(): Via found, flags=2
Feb 15 09:50:28 wlb kamailio[6659]:  6(6668) DEBUG: <core> 
[core/parser/msg_parser.c:494]: parse_headers(): this is the first via
Feb 15 09:50:28 wlb kamailio[6659]:  6(6668) DEBUG: <core> 
[core/parser/parse_addr_spec.c:864]: parse_addr_spec(): end of header 
reached, state=10
Feb 15 09:50:28 wlb kamailio[6659]:  6(6668) DEBUG: <core> 
[core/parser/msg_parser.c:171]: get_hdr_field(): <To> [52]; 
uri=[sip:431230123 at 213.137.140.230]
Feb 15 09:50:28 wlb kamailio[6659]:  6(6668) DEBUG: <core> 
[core/parser/msg_parser.c:172]: get_hdr_field(): to body ["431230123" 
<sip:431230123 at 213.137.140.230>
Feb 15 09:50:28 wlb kamailio[6659]: ]
Feb 15 09:50:28 wlb kamailio[6659]:  6(6668) DEBUG: <core> 
[core/parser/msg_parser.c:152]: get_hdr_field(): cseq <CSeq>: <36825> 
<INVITE>
Feb 15 09:50:28 wlb kamailio[6659]:  6(6668) DEBUG: <core> 
[core/receive.c:200]: receive_msg(): --- received sip message - request 
- call-id: [2610e00004f5-5c66843f-6400386f-2c1b8100-6c4782 at 127.0.0.1] - 
cseq: [36825 INVITE]
Feb 15 09:50:28 wlb kamailio[6659]:  6(6668) DEBUG: <core> 
[core/receive.c:248]: receive_msg(): preparing to run routing scripts...
Feb 15 09:50:28 wlb kamailio[6659]:  6(6668) DEBUG: <core> 
[core/parser/parse_addr_spec.c:185]: parse_to_param(): add param: 
tag=0080827005DD9C0D8E96C55CF6CD
Feb 15 09:50:28 wlb kamailio[6659]:  6(6668) DEBUG: <core> 
[core/parser/parse_addr_spec.c:864]: parse_addr_spec(): end of header 
reached, state=29
Feb 15 09:50:28 wlb kamailio[6659]:  6(6668) DEBUG: siptrace 
[siptrace.c:507]: sip_trace_store_db(): database connection not 
initialized
Feb 15 09:50:28 wlb kamailio[6659]:  6(6668) DEBUG: siptrace 
[siptrace_hep.c:498]: pipport2su(): the port string is 5060
Feb 15 09:50:28 wlb kamailio[6659]:  6(6668) DEBUG: siptrace 
[siptrace_hep.c:498]: pipport2su(): the port string is 5060
Feb 15 09:50:28 wlb kamailio[6659]:  6(6668) DEBUG: <core> 
[core/proxy.c:264]: mk_proxy(): doing DNS lookup...
Feb 15 09:50:28 wlb kamailio[6659]:  6(6668) DEBUG: siptrace 
[siptrace_hep.c:302]: trace_send_hep2_duplicate(): setting up the 
socket_info
Feb 15 09:50:28 wlb kamailio[6659]:  6(6668) NOTICE: <script>: Tracing 
6(6668) DEBUG: maxfwd [mf_funcs.c:74]: is_maxfwd_present(): value = 70
Feb 15 09:50:28 wlb kamailio[6659]:  6(6668) DEBUG: <core> 
[core/parser/msg_parser.c:183]: get_hdr_field(): content_length=355
Feb 15 09:50:28 wlb kamailio[6659]:  6(6668) DEBUG: <core> 
[core/parser/msg_parser.c:89]: get_hdr_field(): found end of header
Feb 15 09:50:28 wlb kamailio[6659]:  6(6668) DEBUG: sanity 
[sanity_mod.c:256]: w_sanity_check(): sanity checks result: 1
Feb 15 09:50:28 wlb kamailio[6659]:  6(6668) DEBUG: <core> 
[core/socket_info.c:559]: grep_sock_info(): checking if host==us: 14==9 
&& [213.137.140.230] == [127.0.0.1]
Feb 15 09:50:28 wlb kamailio[6659]:  6(6668) DEBUG: <core> 
[core/socket_info.c:566]: grep_sock_info(): checking if port 5060 
(advertise 0) matches port 5060
Feb 15 09:50:28 wlb kamailio[6659]:  6(6668) DEBUG: <core> 
[core/socket_info.c:559]: grep_sock_info(): checking if host==us: 14==14 
&& [213.137.140.230] == [213.137.140.230]
Feb 15 09:50:28 wlb kamailio[6659]:  6(6668) DEBUG: <core> 
[core/socket_info.c:566]: grep_sock_info(): checking if port 5060 
(advertise 0) matches port 5060
Feb 15 09:50:28 wlb kamailio[6659]:  6(6668) NOTICE: <script>: OPTIONS 
from 196.27.235.76:5060
Feb 15 09:50:28 wlb kamailio[6659]:  6(6668) DEBUG: siputils 
[checks.c:120]: has_totag(): no totag
Feb 15 09:50:28 wlb kamailio[6659]:  6(6668) DEBUG: tm 
[t_lookup.c:1018]: t_check_msg(): msg (0x7f7e7edd3be8) id=6845 global 
id=6844 T start=(nil)
Feb 15 09:50:28 wlb kamailio[6659]:  6(6668) DEBUG: tm [t_lookup.c:476]: 
t_lookup_request(): start searching: hash=29308, isACK=0
Feb 15 09:50:28 wlb kamailio[6659]:  6(6668) DEBUG: tm [t_lookup.c:435]: 
matching_3261(): RFC3261 transaction matching failed
Feb 15 09:50:28 wlb kamailio[6659]:  6(6668) DEBUG: tm [t_lookup.c:659]: 
t_lookup_request(): no transaction found
Feb 15 09:50:28 wlb kamailio[6659]:  6(6668) DEBUG: tm 
[t_lookup.c:1087]: t_check_msg(): msg (0x7f7e7edd3be8) id=6845 global 
id=6845 T end=(nil)
Feb 15 09:50:28 wlb kamailio[6659]:  6(6668) DEBUG: rr [loose.c:1209]: 
is_direction(): param ftag not found
Feb 15 09:50:28 wlb kamailio[6659]:  6(6668) DEBUG: dispatcher 
[dispatch.c:1832]: ds_select_dst_limit(): set [1]
Feb 15 09:50:28 wlb kamailio[6659]:  6(6668) DEBUG: dispatcher 
[dispatch.c:1935]: ds_select_dst_limit(): alg hash [1]
Feb 15 09:50:28 wlb kamailio[6659]:  6(6668) NOTICE: <script>: No 
destination available! 6(6668) DEBUG: sl [sl.c:282]: send_reply(): reply 
in stateless mode (sl)
```

My kamailio.cfg

```
#!KAMAILIO
#
# sample config file for dispatcher module
# - load balancing of VoIP calls with round robin
# - no TPC listening
# - don't dispatch REGISTER and presence requests
#
# Kamailio (OpenSER) SIP Server v3.2
#     - web: http://www.kamailio.org
#     - git: http://sip-router.org
#
# Direct your questions about this file to: 
sr-users at lists.sip-router.org
#
# Refer to the Core CookBook at 
http://www.kamailio.org/dokuwiki/doku.php
# for an explanation of possible statements, functions and parameters.
#
# Several features can be enabled using '#!define WITH_FEATURE' 
directives:
#
# *** To run in debug mode:
#     - define WITH_DEBUG
#

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

#!define WITH_HOMER
#!define WITH_DEBUG

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

/* comment the next line to enable TCP */
disable_tcp=yes

/* uncomment the next line to disable the auto discovery of local 
aliases
    based on revers DNS on IPs (default on) */
auto_aliases=yes

/* add local domain aliases */

port=5060

/* uncomment and configure the following line if you want Kamailio to
    bind on a specific interface/port/proto (default bind on all 
available) */
# listen=udp:127.0.0.1:5060

sip_warning=no

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

#set module path
mpath="/usr/lib/x86_64-linux-gnu/kamailio/modules/"

# loadmodule "db_mysql.so"
# loadmodule "mi_fifo.so"
loadmodule "jsonrpcs.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 "registrar.so"
loadmodule "textops.so"
loadmodule "siputils.so"
loadmodule "xlog.so"
loadmodule "sanity.so"
loadmodule "ctl.so"
loadmodule "cfg_rpc.so"
loadmodule "acc.so"
loadmodule "counters.so"

loadmodule "dispatcher.so"

#!ifdef WITH_HOMER
loadmodule "siptrace.so"
#!endif

#loadmodule "kex.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 "mi_rpc.so"
#loadmodule "acc.so"

# ----- acc params -----
modparam("acc", "log_flag", 1)
modparam("acc", "failed_transaction_flag", 3)
modparam("acc", "log_extra",
   "src_user=$fU;src_domain=$fd;dst_ouser=$tU;dst_user=$rU;dst_domain=$rd;src_ip=$si")

#!ifdef WITH_HOMER
# check IP and port of your capture node
modparam("siptrace", "duplicate_uri", "sip:213.136.47.31:9060")
modparam("siptrace", "hep_mode_on", 1)
modparam("siptrace", "trace_to_database", 0)
modparam("siptrace", "trace_flag", 22)
modparam("siptrace", "trace_on", 1)
#!endif

# ----------------- setting module-specific parameters ---------------
# modparam("dispatcher", "db_url", DBURL)
modparam("dispatcher", "table_name", "dispatcher")
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", "sock_avp", "$avp(dssocket)")
modparam("dispatcher", "attrs_avp", "$avp(dsattrs)")

#set next two parameters if you want to enable balance alg. no. 10
#modparam("dispatcher", "dstid_avp", "$avp(dsdstid)")
#modparam("dispatcher", "ds_hash_size", 8)
modparam("dispatcher", "ds_ping_interval", 20)
modparam("dispatcher", "ds_ping_from", "sip:kamailio at example.com")
#modparam("dispatcher", "ds_ping_method", "INFO")
modparam("dispatcher", "ds_probing_mode", 1)
modparam("dispatcher", "ds_probing_threshold", 1)
#configure codes or classes of SIP replies to list only allowed replies 
(i.e. when temporarily unavailable=480)
modparam("dispatcher", "ds_ping_reply_codes", 
"class=2;code=480;code=404")



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


# main request routing logic

route {
   #!ifdef WITH_HOMER
     #start duplicate the SIP message now
     sip_trace();
     setflag(22);
     xlog("L_NOTICE","Tracing");
   #!endif
   # per request initial checks
   route(REQINIT);

   # handle requests within SIP dialogs
   route(WITHINDLG);

   # CANCEL processing
   if (is_method("CANCEL"))
   {
     if (t_check_trans())
       t_relay();
     exit;
   }

   t_check_trans();

   # 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 (is_method("INVITE"))
   #{
   #  ds_select_domain("1","4");
   #  #sl_send_reply("300","Redirect");
   #  #t_relay();
   #  exit;
   #}

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

   # handle presence related requests
   route(PRESENCE);

   # handle registrations
   route(REGISTRAR);

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

   route(LOADBALANCE);

   route(RELAY);
}

# Per SIP request initial checks
route[REQINIT] {
   if (!mf_process_maxfwd_header("10")) {
     sl_send_reply("483","Too Many Hops");
     exit;
   }

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

   # Reply to options
   if (uri==myself) {
     xlog("L_NOTICE","OPTIONS from $si:$sp\n");
     if ((method==OPTIONS) && (! uri=~"sip:.*[@]+.*")) {
       xlog("L_NOTICE","answering options $si:$sp\n");
       options_reply();
     }
   }
}

# Handle requests within SIP dialogs
route[WITHINDLG] {
   if (has_totag()) {
     # sequential request withing a dialog should
     # take the path determined by record-routing
     if (loose_route()) {
       if (is_method("BYE")) {
         setflag(1); # do accounting ...
         setflag(3); # ... even if the transaction fails
       }
       route(RELAY);
     } else {
       if (is_method("SUBSCRIBE") && uri == myself) {
         # in-dialog subscribe requests
         route(PRESENCE);
         exit;
       }
       if ( is_method("ACK") ) {
         if ( t_check_trans() ) {
           # non loose-route, but stateful ACK;
           # must be 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;
   }
}

# Handle SIP registrations
route[REGISTRAR] {
   if(!is_method("REGISTER"))
     return;
   #sl_send_reply("404", "No registrar");
   #t_relay();
   if(!ds_select_dst("1", "4"))
   {
     sl_send_reply("404", "No registrar");
     exit;
   }
   forward();

   exit;
}

# Presence server route
route[PRESENCE] {
   if(!is_method("PUBLISH|SUBSCRIBE"))
     return;

   sl_send_reply("404", "Not here");
   exit;
}


route[LOADBALANCE] {
   #ds_select_dst(destination_set, algorithm) function chooses the 
destination for the call. For this it can use a lot of algorithms.
   #Alg. 0 is the default one that does the the choosing over the call 
ID hash
   #Alg. 4 is a Round-Robin
   #Alg. 10 is the one that chooses the destination based on the minimum 
load of all destinations
   if(!ds_select_dst("1", "4"))
   {
     #if we are here that means no destination is available. We notify 
the user by 404 and exit the script.
     xlog("L_NOTICE", "No destination available!");
     send_reply("404", "No destination");
     exit;
   }
   xlog("L_NOTICE", "Routing call to <$ru> via <$du>\n");
   #set the no_reply_recieved timeout to 2 second ... adjust the value 
to your need
   #note: The first value "0" is invite timeout .. we do not need to 
change it
   #This means that is the selected media server fails to respond within 
2 seconds the failure_route "MANAGE_FAILURE" is called
   #note: this implies that ale the signaling from media servers on the 
way back to the user goes through the proxy as well
   t_set_fr(0,2000);
   t_on_failure("MANAGE_FAILURE");
   return;
}

# manage failure routing cases
failure_route[MANAGE_FAILURE] {
   # route(NATMANAGE);
   if (t_is_canceled()) {
     exit;
   }

   xlog("L_NOTICE", "Media server $du failed to answer, selecting other 
one!");
   # next DST - only for 500 reply or local timeout (set by t_set_fr())
   if (t_check_status("500") || t_branch_timeout() || 
!t_branch_replied())
   {
     #we mark the destination Inactive and Probing
     ds_mark_dst("ip");
     #select the new destination
     if(ds_next_dst())
     {
       #again set local timeout for reply
       t_set_fr(0,2000);
       t_on_failure("MANAGE_FAILURE");
       route(RELAY);
       exit;
     }
     else
     {
       #last available node failed to reply, no other destinations 
available
       send_reply("404", "No destination");
       exit;
     }
   }
}

route[RELAY] {
   xlog("L_NOTICE", "going to <$ru> via <$du>");
   if (!t_relay()) {
     sl_reply_error();
   }
   exit;
}
```

and my dispatcher.list

```
# line format
# id(int,auto) setid(int) destination(string) flags(int) priority(int) 
attrs(string) description(string)

1 sip:196.27.235.76:5060
1 sip:213.137.140.230:5060
```

any help to understand these issues would be greatly appreciated.

Cris

---
Cristian Livadaru
LcX IT Solutions

Web: http://lcx.at/
Tel: +43 1 37 37 37
Fax: +43 1 37 37 37 - 25

**24/7 Support:  0900 474 455** (1,81€/Min)
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.kamailio.org/pipermail/sr-users/attachments/20190215/da92d6af/attachment.html>


More information about the sr-users mailing list