302 Issues

juanito
2011-08-09
2013-05-09
  • juanito
    juanito
    2011-08-09

    Hi there,

    I'm having some hard time to understand what's going on here.

    I'm trying to handle 302 response from one of my SVI. The thing is that all of my answer goes to the onreply_route instead of the failure_route. The documentation says clearly this should not be the case :

    Failed transaction routing block. It contains a set of actions to be taken each transaction that received only negative replies (>=300) for all branches.

    The 302 answer is next relayed to the UAC and I can't send the invite to the correct server as indicated in the Contact header.

    Here is my script, I'm pretty sure I'm not missing anything here, but this is the first time I'm working with OpenSIPS :

    # From hb01-callcenter
            if ($si == "172.19.0.14") {
                    if ($rU=~"^1..$" || $rU=~"^25..$" || $rU=~"^30..$|^3..$") {
                       xlog("Forwarding call to hb01-ipbx01 $tu\n");
                       $du = "sip:172.19.0.10";
                    }
                    else if ($rU =~ "^20..$") {
                         xlog("Forwarding call to sibilo COMMON server\n");
                         $du = "sip:192.168.41.149";
                         t_on_failure("3");
                         t_on_reply("302_sibilo_r");
                    }
                    else {
                         xlog("Forwarding call to renta (x.x.x.x) as it seems to be an outside number\n");
                         if (nat_uac_test("19")) {
                            setflag(6);
                            fix_nated_contact();
                            fix_nated_sdp("2", "x.x.x.x");
                         }
                         $fs = "udp:x.x.x.x:5060";
                         $du = "sip:x.x.x.x";
                    }
               if (!t_relay()) {
                  xlog("On en est pas la non ? \n");
                  sl_reply_error();
               }
               exit();
            }

    If anybody has already seen this error, or can't point out something I'm doing wrong that'll be great. I'll keep looking anyway ;)

    Regards,

     
  • Are you sure you are setting the failure route on the correct call flow ? maybe the call you get the 3xx for does not hit t_on_failure()

    Regards,
    Bogdan

     
  • juanito
    juanito
    2011-08-09

    I'am 100% positive on this point since I do receive the 302 from my SIP server 192.168.41.149 and logs contain the message I set with xlog.

    I althought tried not to set the t_on_reply method, in case of a bug or anything. I never arrive in my failing route. I must say I'm pretty stuck at this point.

    FYI I'm using the version available in the debian repository.
    Version 1.7 under debian squeeze.

     
  • No offense,  but somehow I found hard to believe that there is something wrong with failure routing system. I would rather say you have somewhere a logical err in your script.

    Could you post your entire script ?

    Regards,
    Bogdan

     
  • juanito
    juanito
    2011-08-09

    Offense non taken ! The problem is most of the time between the chair and the keyboard :) And I'm new to OpenSIPS.

    Here is the script :

    #
    # $Id: opensips.cfg 8141 2011-07-08 12:17:13Z vladut-paiu $ # # OpenSIPS basic configuration script
    #     by Anca Vamanu <anca@voice-system.ro>
    #
    # Please refer to the Core CookBook at:
    #      http://www.opensips.org/Resources/DocsCookbooks
    # for a explanation of possible statements, functions and parameters.
    #
    #
    # v0.1 : Jean Praloran (jean.praloran@rueducommerce.com) - First and quick implementation for
    #        communication between hb01-ipbx01 and renta (incoming and outgoing). As well as routing
    #        for callcenter ipbx and admnistrative ipbx
    #

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

    debug=3
    log_stderror=no
    log_facility=LOG_LOCAL7

    fork=yes
    children=4

    # default db_url to be used by modules requiring DB connection db_default_url="mysql://opensips:opensipsrw@localhost/opensips"

    port=5060

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

    #set module path
    mpath="/usr/lib/opensips/modules/"

    /* uncomment next line for MySQL DB support */ #loadmodule "db_mysql.so"
    loadmodule "signaling.so"
    loadmodule "sl.so"
    loadmodule "tm.so"
    loadmodule "rr.so"
    loadmodule "maxfwd.so"
    loadmodule "usrloc.so"
    loadmodule "registrar.so"
    loadmodule "textops.so"
    loadmodule "mi_fifo.so"
    loadmodule "uri.so"
    loadmodule "acc.so"
    loadmodule "nathelper.so"
    loadmodule "uac_auth.so"
    loadmodule "uac.so"
    loadmodule "uac_redirect.so"

    # ----------- setting module-specific parameters ----------

    # --- mi_fifo params ---
    modparam("mi_fifo", "fifo_name", "/tmp/opensips_fifo")

    # --- rr params ---
    # do not append from tag to the RR (no need for this script) modparam("rr", "append_fromtag", 1)

    # --- registrar params ---
    /* uncomment the next line not to allow more than 10 contacts per AOR */ #modparam("registrar", "max_contacts", 10)

    # --- usrloc params ---
    modparam("usrloc", "db_mode",   0)
    /* uncomment the following lines if you want to enable DB persistency
       for location entries */
    #modparam("usrloc", "db_mode",   2)
    #modparam("usrloc", "db_url",
    # "mysql://opensips:opensipsrw@localhost/opensips")

    # --- uri params ---
    modparam("uri", "use_uri_table", 0)

    # --- acc params ---
    /* what sepcial events should be accounted ? */ modparam("acc", "early_media", 1) modparam("acc", "report_cancels", 1)
    /* by default ww 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)
    /* account triggers (flags) */
    modparam("acc", "failed_transaction_flag", 3) modparam("acc", "log_flag", 1) modparam("acc", "log_missed_flag", 2)
    /* uncomment the following lines to enable DB accounting also */ modparam("acc", "db_flag", 1) modparam("acc", "db_missed_flag", 2)

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

    # main request routing logic

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

    if (has_totag()) {
    # sequential request withing a dialog should
    # take the path determined by record-routing
    if (loose_route()) {
    if (is_method("BYE")) {

    # We have to send the BYE to the asterisk server
       if ($si == "x.x.x.x" && ($td =~ "172.19.0.10" || $tu =~ "\+33XXXXXX..\@.*" ||
       $tu =~ "\+33XXXXXX..\@.*" || $tu =~ "\+33XXXXXX..\@.*" || $tu =~ "\+33XXXXXX..\@.*")) {
       xlog("Forwarding BYE to hb01-ipbx01 $tu\n");
               $du = "sip:172.19.0.10";
       $fs = "udp:172.19.0.15:5060";
          setflag(1); # do accounting …
       setflag(3); # … even if the transaction fails
    }

       if ($si == "x.x.x.x" && $td =~ "172.19.0.14") {
          xlog("Forwarding BYE to hb01-callcenter01 $tu\n");
               $du = "sip:172.19.0.14";
       $fs = "udp:172.19.0.15:5060";
          setflag(1); # do accounting …
       setflag(3); # … even if the transaction fails
    }

    setflag(1); # do accounting …
    setflag(3); # … even if the transaction fails
    } else if (is_method("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();
    }
    # route it out to whatever destination was set by loose_route()
    # in $du (destination URI).
    route(1);
    } else {
    /* uncomment the following lines if you want to enable presence */
    ##if (is_method("SUBSCRIBE") && $rd == "your.server.ip.address") {
    ## # in-dialog subscribe requests
    ## route(2);
    ## exit;
    ##}
    if ( is_method("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

    # We have to send the ACK message to the asterisk so the call
    # won't be dropped on incoming call (match the callerid)
    if ($si == "X.X.X.X" && ($tu =~ "\+33XXXXXX..\@.*" || $tu =~ "\+33XXXXXX..\@.*" ||
       $tu =~ "\+33XXXXXX..\@.*" || $tu =~ "\+33XXXXXX..\@.*")) {
       xlog("Forwarding ACK to hb01-ipbx01 $tu\n");
       $du = "sip:172.19.0.10";
       $fs = "udp:172.19.0.15:5060";
       t_relay();
    }

    exit;
    } else {
    # ACK without matching transaction ->
    # ignore and discard
    exit;
    }
    }
    sl_send_reply("404","Not here");
    }
    exit;
    }

    #initial requests

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

    t_check_trans();

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

    if (!is_method("REGISTER|MESSAGE"))
    record_route();

    # account only INVITEs
    if (is_method("INVITE")) {
    setflag(1); # do accounting
    }
    if (!uri==myself)
    {
    append_hf("P-hint: outbound\r\n");
    route(1);
    }

    if (is_method("PUBLISH"))
    {
    sl_send_reply("503", "Service Unavailable");
    exit;
    }

    if (is_method("REGISTER"))
    {
    if (!save("location"))
    sl_reply_error();

    exit;
    }

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

    # From hb01-callcenter
    if ($si == "172.19.0.14") {
    if ($rU=~"^1..$" || $rU=~"^25..$" || $rU=~"^30..$|^3..$") {
             xlog("Forwarding call to hb01-ipbx01 $tu\n");
       $du = "sip:172.19.0.10";
    }
    else if ($rU =~ "^20..$") {
         xlog("Forwarding call to sibilo COMMON server\n");
         $du = "sip:192.168.41.149";
         t_on_failure("3");
         t_on_reply("302_sibilo_r");
    }
       else {
            xlog("Forwarding call to renta (x.x.x.x) as it seems to be an outside number\n");
         if (nat_uac_test("19")) {
         setflag(6);
    fix_nated_contact();
    fix_nated_sdp("2", "x.x.x.x");
         }
         $fs = "udp:x.x.x.x:5060";
            $du = "sip:x.x.x.x";
    }
       if (!t_relay()) {
          xlog("On en est pas la non ? \n");
          sl_reply_error();
       }
       exit();
    }

    # From hb01-ipbx01
    if ($si == "172.19.0.10" || $si == "x.x.x.x") {

       xlog("Entering hb01-ipbx01 context\n");\
       if ($rU>="5000" && $rU <="6000") {
          xlog("Forwarding call to hb01-callcenter01 for number $rU\n");
          $du = "sip:172.19.0.14";
       }
       else {
            xlog("Forwarding call to renta (x.x.x.x) as it seems to be an outside number $rU\n");

    # We test if this need to be nated in the SIP header and fix the SDP so we can be reached
    if (nat_uac_test("19")) {
    setflag(6);
    fix_nated_contact();
    fix_nated_sdp("2", "x.x.x.x");
    }
    # Force SIP packet to go out throught public interface
    $fs = "udp:x.x.x.x:5060";
    # Next Hop SIP server (renta)
       $du = "sip:x.x.x.x";
       }
       t_relay();
       exit();
    }

    # Fom sibilo common

      ########### There shouldn't be anything in here

    # From sibilo SVI

      ###### We'll fill out something in here

    # From renta
    if ($si == "x.x.x.x" && ($rU =~ "\+33XXXXXX" || $rU =~ "\+33XXXXXX" || $rU =~ "\+33XXXXXX" || $rU =~ "\+33XXXXXX")) {
       xlog("Incoming call from renta for $rU\n");
       # Force SIP packet to go out throught internal interface
       $fs = "udp:172.19.0.15:5060";
       # Next Hop server (hb01-ipbx01)
       $du = "sip:172.19.0.10";
       t_relay();
       # We have to handle correctly the reply on INVITE packet to modify the outcoming SDP information
       t_on_reply("2");
       exit();
    }

    # apply DB based aliases (uncomment to enable)
    ##alias_db_lookup("dbaliases");

    # do lookup with method filtering
    if (!lookup("location","m")) {
    switch ($retcode) {
    case -1:
    case -3:
    t_newtran();
    t_reply("404", "Not Found");
    exit;
    case -2:
    sl_send_reply("405", "Method Not Allowed");
    exit;
    }
    }
    # 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")) {
    t_on_branch("2");
    t_on_reply("2");
    t_on_failure("1");
    }

    if (!t_relay()) {
    sl_reply_error();
    };
    exit;
    }

    branch_route {
    xlog("new branch at $ru\n");
    }

    onreply_route {
    # On 200 OK and 183 from SVI due to 302 redirect we'll probably need to change the SDP only if calls go to the outised
    xlog("Incoming reply return code = $rs from $si - Just for logging purpose so far\n");
    if ($si == "192.168.41.149"  && $rs == "302") {
       xlog("To failure ?\n");
       t_on_failure("3");
    }
    }

    onreply_route {
    # On 200 OK and 183 Session in progress we need to change the SDP information

    # For hb01-ipbx01
    if ($si == "172.19.0.10" && $rs =~ "200|183") {
       xlog("Incoming reply Return Code = $rs - SDP is beeing changed from 172.19.0.10 to x.x.x.x\n");
       fix_nated_sdp("2", "x.x.x.x");   
    }
    if ($si == "172.19.0.14" && $rs =~ "200|183") {
       xlog("Incoming reply Return Code = $rs - SDP is beeing changed from 172.19.0.15 to x.x.x.x\n");
       fix_nated_sdp("2", "x.x.x.x");   
    }
    }

    failure_route {

    # On 302 from sibilo COMMON server we have to redirect to SVI's
    if ($si == "192.168.41.149"  && $rs == "302") {
       xlog("Incoming reply Return Code = $rs - We have to get Contact and relay them to a new branch\n");
       get_redirects("6:2","redirect"); # We should handle errors here if the Contact field is empty - We assume it isn't right now
       serialize_branches(1);
               next_branches();
       setbflag(3); # 302 in progress
       t_on_failure("3");
       resetflag(1);
       t_relay();
       exit;
    }
    if (isbflagset(3)) {
       xlog("We are trying to send the invite to the other hand\n");
       if (next_branches()) {
          t_on_failure("3");
          t_relay();
          exit;
       }
       else {
       # We should handle an error here
       }
       exit;
    }
    }

    failure_route {
    xlog("We have a failure route it seems $rs | $si \n");
    if (t_was_cancelled()) {
    exit;
    }
    }

    Please be advised the failure_route has not been tested yet so there is maybe error in this latter.

    Thanks for your help !

     
  • juanito
    juanito
    2011-08-09

    I can send you a pcap and debug output if you want !

     
  • juanito
    juanito
    2011-08-09

    I'm not sure if that helps but the server which sends the 302 also sends a 101 before.

     
  • juanito
    juanito
    2011-08-10

    Ok finally get what was wrong. It seems like I correctly passed in my failure route, even thought I was sure I had a xlog entering this latter. And the failure route was for sure not correct, it works now :)

    Anyway thanks for taking time to answer, and thanks for your work on opensips.

     
  • yeah, I just noticed that failure route 3 actually has no xlog in the beginning.

    Nevertheless, as said, for sure it was a scripting error.

    Regards,
    Bogdan