[OpenSIPS-Users] Problem with mid_registrar and nat

ppq at tuta.io ppq at tuta.io
Tue Dec 22 11:23:44 EST 2020


Hello,
I'm trying to set up a mid_registrar proxy but I'm having a problem with client devices behind nat.
When calling a device behind nat, with the device registered with opensips, the answering ACK from the upstream provider is sent to OpenSips which in turn sends it to the <private> ip address of the natted device.
Funny thing is I can hear the two-way audio at the natted device but the call is never established.
I'm pasting my opensips.cfg file here and a trace from a failed invite (is there a better way to post this info on the list, rather than pasting ?)
I'm sure there's a lot of issues with my routing script. Feel free to bash me ;)
In the attached trace:
- The upstream provider is at 188.10.10.10
- The opensips mid_proxy is at 5.20.20.20
- The public ip address of the natted device is 5.10.10.10
- The private ip address of the natted device is 192.168.100.125

I am missing something obvious here, but can't nail it.

Thank you for all and any help in advance.

The SIP trace (being long) is here: pastebin.com/zrs0er8Y <https://pastebin.com/zrs0er8Y>
My opensips.cfg is here: 
=====
####### Global Parameters ######### 

log_level=4
log_stderror=yes
log_facility=LOG_LOCAL0

#children=4

/* uncomment the following line to enable debugging */
#debug_mode=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


listen=udp:0.0.0.0:5060

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

#set module path
mpath="/usr/local/lib64/opensips/modules/"

loadmodule "mid_registrar.so"
modparam("mid_registrar", "mode", 2) /* 0 = mirror / 1 = ct / 2 = AoR */
modparam("mid_registrar", "outgoing_expires", 7200)
modparam("mid_registrar", "received_avp", "$avp(received)")
modparam("mid_registrar", "received_param", "received")
#### Removed ??? modparam("mid_registrar", "insertion_mode", 0) /* 0 = contact; 1 = path */

#### SIGNALING module
loadmodule "signaling.so"

#### StateLess module
loadmodule "sl.so"

#### Transaction Module
loadmodule "tm.so"
modparam("tm", "fr_timeout", 5)
modparam("tm", "fr_inv_timeout", 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", 1)

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

#### USeR LOCation module
loadmodule "usrloc.so"
modparam("usrloc", "nat_bflag", "NAT")
modparam("usrloc", "db_mode",   0)

#### REGISTRAR module
loadmodule "registrar.so"

/* 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)

### UAC Module ####
loadmodule "uac.so"
modparam("uac","restore_mode","auto")
modparam("rr", "append_fromtag", 1)

#### NAT modules
loadmodule "nathelper.so"
modparam("nathelper", "natping_interval", 60)
modparam("nathelper", "ping_nated_only", 1)
modparam("nathelper", "received_avp", "$avp(received)")
modparam("nathelper", "sipping_from", "sip:nat-alive at mid_registrar")

### Mediaproxy
loadmodule "mediaproxy.so"
modparam("mediaproxy", "media_relay_avp", "$avp(media_relay)")

#### UDP protocol
loadmodule "proto_udp.so"

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

# main request routing logic

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

   if ( nat_uac_test("31")) {
      if ( is_method("REGISTER")) {
         fix_nated_register() ;
      } else {
         fix_nated_contact() ;
      }
      force_rport() ;
      setbflag(NAT);
      xlog("L_INFO", "[LOG] NATed. [rm:$rm] [fu:$fu] [ou:$ou] [ru:$ru] [si:$si]");
   }

   if (has_totag()) {
      # sequential requests within a dialog should
      # take the path determined by record-routing
      if (loose_route()) {
         if (is_method("BYE")) {
            # do accunting, even if the transaction fails
            if (isbflagset(NAT)) {
                                        end_media_session();
                                }

            do_accounting("log","failed");
            xlog("L_INFO", "[LOG] BYE. [rm:$rm] [fu:$fu] [ou:$ou] [ru:$ru] [si:$si]");
         } 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.
            xlog("L_INFO", "[LOG] INVITE. [rm:$rm] [fu:$fu] [ou:$ou] [ru:$ru] [si:$si]");
            record_route();
         }

         # route it out to whatever destination was set by loose_route()
         # in $du (destination URI).
         route(relay);
      } else {
         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
               xlog("L_INFO", "[LOG] ACK. [rm:$rm] [fu:$fu] [ou:$ou] [ru:$ru] [si:$si]");
               t_relay();
               exit;
            } else {
               # ACK without matching transaction ->
               # ignore and discard
               xlog("L_INFO", "[LOG] ACK. not match [rm:$rm] [fu:$fu] [ou:$ou] [ru:$ru] [si:$si]");
               exit;
            }
         }
         xlog("L_INFO", "[LOG] BAD REQUEST. [rm:$rm] [fu:$fu] [ou:$ou] [ru:$ru] [si:$si]");
         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")) {
      xlog("L_INFO", "[LOG] REGISTER [rm:$rm] [fu:$fu] [ou:$ou] [ru:$ru] [si:$si]");
      mid_registrar_save("location","v"); #,"$avp(received)");
      switch ($retcode) {
         case 1:
            $ru = "sip:fusion.pbx:5060";

            t_relay();
            break;
         case 2:
            xlog("L_INFO", "[LOG] absorbing REGISTER! ($$ci=$ci)\n");
            break;
         default:
            xlog("L_INFO", "[LOG] failed to save registration! ($$ci=$ci)\n");
         }

      exit;
   }

   if ( is_method("INVITE|MESSAGE|CANCEL|BYE|NOTIFY") && ($si != "fusion.ip.add.ress" || $sp != 5060) ) {
         $ru = "sip:fusion.pbx:5060";
         xlog("L_INFO", "[LOG] relay to $avp(new_to_user) from $avp(new_from_user)\n");
   }

   # preloaded route checking
   if (loose_route()) {
      xlog("L_ERR", "[LOG] Attempt to route with preloaded Route's [$fu/$tu/$ru/$ci]");
      if (!is_method("ACK"))
         sl_send_reply("403","Preload Route denied");
      exit;
   }

   # record routing
   if (!is_method("REGISTER|MESSAGE|NOTIFY"))
      record_route();

   # account only INVITEs
   if (is_method("INVITE")) {
      do_accounting("log");
   }

   if (!is_myself("$rd")) {
      append_hf("P-hint: outbound\r\n");
      route(relay);
   }

   # requests for my domain
   if (is_method("PUBLISH|SUBSCRIBE"))
   {
      sl_send_reply("503", "Service Unavailable");
      exit;
   }

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

   # initial requests from main registrar, need to look them up!
   # $si = ip.
   if (is_method("INVITE|MESSAGE") && $si == "fusion.ip.add.ress" && $sp == 5060) {
      xlog("L_INFO", "[LOG] INVITE|MESSAGE Received. looking up $ru!\n");
      if (!mid_registrar_lookup("location")) {
         xlog("L_ERR", "[LOG] Cannot find $ru!\n");
         t_reply("404", "Not Found");
         exit;
      }

      t_relay();
      exit;
   }

   # when routing via usrloc, log the missed calls also
   do_accounting("log","missed");
   route(relay);
}


route[relay] {
   # for INVITEs enable some additional helper routes
   if (is_method("INVITE")) {
      if ( isbflagset(NAT)) {
         if ( has_body("application/sdp")) {
            xlog("L_INFO", "[LOG] using media proxy");
            use_media_proxy();
         }
      }
      t_on_branch("per_branch_ops");
      t_on_reply("handle_nat");
      t_on_failure("missed_call");
   }

        if (isbflagset(NAT)) {
                add_rr_param(";nat=yes");
        }

   if (!t_relay()) {
      send_reply("500","Internal Error");
   };
   exit;
}

branch_route[per_branch_ops] {

   xlog("L_INFO", "[LOG] new branch at $ru\n");
}


onreply_route[handle_nat] {
   xlog("L_INFO", "[LOG] (handle_nat) incoming reply\n");
   if ( nat_uac_test("1")) {
      fix_nated_contact() ;
   }
   if ( isbflagset(NAT)) {
      if ( has_body("application/sdp")) {
         use_media_proxy();
      }
   }
   if ( is_method("INVITE")) {
      xlog("L_INFO", "[LOG] re-INVITE. [rm:$rm] [fu:$fu] [ou:$ou] [ru:$ru] [si:$si]\n");
   }
}


failure_route[missed_call] {
   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[0-9][0-9]")) {
   ##t_reply("404","Not found");
   ##      exit;
   ##}

}
====
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.opensips.org/pipermail/users/attachments/20201222/f4a2bfc7/attachment-0001.html>


More information about the Users mailing list