[Devel] Problem regarding use of drop in failure_route and then using sl_send_reply() in a route() statement

Tavis P tavis.lists at galaxytelecom.net
Thu Aug 3 00:37:48 CEST 2006


I'm encountering an issue with call forwarding logic, i'm triggering
call forward busy from failure_route()
---
    if ( t_check_status("486") )
    {
        route(15);
        drop();
    }
---
Inside which i call another route() block
---
route[15]
{
    sl_send_reply("404", "Well i tried, but they're nowhere to be found");
}
---

After returning to the failure_route drop() is executed

What i'm seeing is that both the message i'm generating with
sl_send_reply and the "486 Busy" are being sent on to the client.  Strange


I've attached a really simple configuration that will reproduce this issue.

This config is designed to handle incoming registrations (so that you
can register a phone and then leave it off hook so that it will respond
"486" to any incoming INVITE) and store the location information in
memory. 
It will the handle incoming INVITE and execute a lookup("location"); so
that the call may be routed to a registered user. 
A failure route is defined that looks for a status of 486, upon finding
this it will execute route(15) which simply calls sl_send_reply and then
returns, at this point a drop() will be executed and you will see both
the result of the sl_send_reply sent to the client AND the "486 Busy".

This was found on an OpenSER 1.0 cvs checkout about 2 weeks ago

tavis
-------------- next part --------------
# ----------- global configuration parameters ------------------------

debug=1         # debug level 
#fork=yes
#log_stderror=no        # (cmd line: -E)

# Debug level to log memory information at
memlog=10

/* Uncomment these lines to enter debugging mode
fork=no
log_stderror=yes
*/


# Parameter to set alias hostnames for the server. It can be set many times, 
# each value being added in a list to match the hostname when "myself" is checked.
#
alias=127.0.0.1


# Syslog Name 
#
log_name="OpenSER"


# User and Group To Run SER As
#
user=openser
group=openser

# ------------------ module loading ----------------------------------
# Module Directory
mpath="/openser/lib/openser/modules"

#loadmodule "mysql.so"
#loadmodule "enum.so"
#loadmodule "exec.so"
#loadmodule "pike.so"
#loadmodule "permissions.so"
#loadmodule "domain.so" # needed by mediaproxy.so
#loadmodule "avpops.so"
#loadmodule "avp_radius.so"
#loadmodule "group_radius.so"
#loadmodule "avp.so"
loadmodule "sl.so"
#loadmodule "options.so"
loadmodule "tm.so"
#loadmodule "acc.so"
loadmodule "rr.so"
loadmodule "maxfwd.so"
#loadmodule "uri_db.so"
loadmodule "usrloc.so"
#loadmodule "cpl-c.so"
loadmodule "registrar.so"
#loadmodule "mediaproxy.so"
loadmodule "nathelper.so"
#loadmodule "diversion.so"
loadmodule "textops.so"
loadmodule "uri.so"
#loadmodule "auth.so"
#loadmodule "auth_db.so"
#loadmodule "auth_radius.so"
loadmodule "xlog.so"


# -[ nathelper.so ]- ###########################################################
# {
    # Stop nathelper from trying to connect to rtpproxy on startup
    modparam("nathelper", "rtpproxy_disable", 1)
  
    # How often should nathelper send keepalive messages
    modparam("nathelper", "natping_interval", 45)
  
    # Send Keep-Alive Packets To Client Behind NAT Only
    modparam("nathelper", "ping_nated_only", 1)
  
    # Send keep-alive messages to clients behing NAT only
    modparam("nathelper", "ping_nated_only", 1)
  
    # Sets the SIP URI for SIP based keepalives (OPTIONS or INFO)
    # SIP keepalives will only be sent to clients who have been flagged 
    modparam("nathelper", "sipping_from", "sip:keepalive at srs.rgns.net")
  
    # Sets the SIP method used for SIP keepalives (OPTIONS or INFO)
    modparam("nathelper", "sipping_method", "OPTIONS")
# }
  

# -[ usrloc.so ]- ##############################################################
# {
    # 0 - Use memory based location storage
    # 1 - Use database for persistent storage and lookup.  Propogate location information directly to the DB
    # 2 - Use database for persistent storage, sync based on timer
    modparam("usrloc", "db_mode", 0)
  
    # Timer interval, used to sync with database, delete expired contacts and other tasks (?)
    modparam("usrloc", "timer_interval", 5)
# }
  

# -[ registrar.so ]- ###########################################################
# {
    # Default value (in seconds) if client doesn't specify the expires field
    modparam("registrar", "default_expires", 900)
  
    # Minimum "expires" value, anything lower will be set to this value (0 disables check)
    modparam("registrar", "min_expires", 120)
  
    # Maximum "expires" value, anything higher will be set to this value (0 disables check)
    modparam("registrar", "max_expires", 900)
  
    # Sets the default "q" (priority) of a contact if it is not specified (divide by 100)
    modparam("registrar", "default_q", 0)
  
    # Determines how the lookup function process' multiple contacts.
    # If set to one, it will overwrite the URI with the highest "q" rated contact
    # and create brances for the rest
    modparam("registrar", "append_branches", 1)
  
    # Determine if the domain is included in the address of record
    modparam("registrar", "use_domain", 0)
  
    # Determines if AOR check will be case sensitive
    modparam("registrar", "case_sensitive", 0)
  
    # If set to 1, then all contacts will be ordered in descending modification time order
    # starting from the most recently modified contact
    #
    # - Currently not Functional?
    #
    # modparam("registrar", "desc_time_order", 1)

    # Limits the number of contacts per AOR
    # Otherwise, limits the maximum concurrent registrations
    modparam("registrar", "max_contacts", 5)
  
    # Enable and define the time (s) to use the "reply_after" field in a 5xx response to a
    # REGISTER message. 0 Disables its use
    modparam("registrar", "retry_after", 120)
  
    # NULL UDP Keep-Alives will be sent to accounts that have this flag set
    modparam("registrar",  "nat_flag", 2)
  
    # SIP based keepalives (configurable through nathelper) will be sent to 
    # accounts with this flag
    modparam("registrar", "sip_natping_flag", 2)
  
    # NAT flags for branches will be pushed in branch flags through the branch dset array
    # instead of just for the message (local flags)
    modparam("registrar", "use_branch_flags", 1)
# }
  



route

{


    # -----------------------------------------------------------------
    # - Initial Sanity Checks -
    # messages with max_forwards==0, or excessively long requests
    # If its an ACK, we simply want to break, not respond.
    # -----------------------------------------------------------------
    if ( !mf_process_maxfwd_header("10") )
    {
        # Any messages that are not expecting a response don't need one
        if ( !is_method("ACK") )
        {
            sl_send_reply("483", "Too many hops");
        }

        xlog("L_WARN", "[$fU] Route{main}: Message Max-Forwards == 0");
        exit;
    }

    if ( msg:len >= max_len )
    {
        # Any messages that are not expecting a response don't need one
        if ( !is_method("ACK") )
        {
            sl_send_reply("513", "Message too big");
        }

        xlog("L_WARN", "[$fU] Route{main}: Message was too big");
        exit;
    }


    route(10);
}
	



# ------------------------------------------------------------------------
# -[ Outbound Routing Block ]-
# ------------------------------------------------------------------------
route[10]
{
    xlog("L_WARN", "[$fU] Route{10}: Starting Outbound Routing Block.");

    if ( method=="REGISTER" )
    {
        # ------------------------------------
	# NAT Detection / Work-Around
	# Make sure the client isn't trying to unregister (search for contact *)
	# ------------------------------------
	# Add "rport" to topmost via
	force_rport();
	    
	# Mark registration so keepalives can be sent to it.
	setflag(2);
        xlog("L_NOTICE", "[$fU] Route{1}: Registration taking place, client is behind NAT");

	fix_nated_register();
	
	# If somthing goes wrong saving the registration, generate an error.
	if ( !save("location") )
	{
	    xlog("L_ERR", "[$fU] ERROR Route{1}: Saving Registration Location FAILED.");
	    sl_reply_error();
	}
	
        exit;	
    }

    
    
    
    if ( method=="INVITE" )
    {
        t_on_failure("10");
	lookup("location");

    }


    xlog("L_WARN", "[$fU] Route{10}: Destination Set = [ $ds ]");

    # Route Message Out
    if ( !t_relay() )
    {
        xlog("L_WARN", "[$fU] Route{10}: t_relay error in Outbound Routing Block");
        sl_reply_error();
    }
}




###################################################################################
# - Failure_Route Section -
###################################################################################

failure_route[10]
{
    xlog("L_NOTICE", "[$fU] failure_route{10}: -- Entering Failure Route. --");
      
      
    if ( t_check_status("486") )
    {
	route(15);
	drop();
    }
    
    xlog("L_NOTICE", "[$fU] failure_route{10}: This is the end. The end of the failure route");
    
}


route[15]
{
    sl_send_reply("404", "Well i tried, but they're nowhere to be found");   
}



More information about the Devel mailing list