[OpenSIPS-Users] Pass calls to another realm via gateway

Bogdan-Andrei Iancu bogdan at voice-system.ro
Tue Oct 6 14:43:14 CEST 2009


Hello Alexander,

For the initial request (like INVITE), you can set a simple logic on 
opensips:
    1) if does not come from platform -> forward to the platform
    2) if does come from platform -> route based on RURI (this will 
cover the foreign domains also)

For sequential requests (ACK, BYE, etc), you should follow the 
loose_route() - nothing special to do; but take care and do 
record_route() for the initial requests...

Regards,
Bogdan

Alexander wrote:
>   Hello all!
>
>   I've encountered one problem I can not solve :( The situation is following:
> we've  got  Opensips working together with our own SIP platform. Our platform is
> about  various  call  processing  business logic and billing. All calls from SIP
> users  should  pass  through  our platform. For now we successfully can make and
> receive  calls  inside  our  domain - NAT is handled fine in most cases, instant
> messages are handled and so on. It looks like that:
>   - Opensips receives a call from caller
>   - Call is redirected to our platform
>   - Platform redirects call back to Opensips and Opensips looks for callee.
>
>   This  works  fine  when both caller and callee are inside our domain. But when
> callee  is  in  another  domain, I can't make Opensips pass the call through our
> platform  correctly. Caller and callee can't see each other's ACKs and so on, if
> I  use  rewritehostport()  or  something.  But if I bypass our platform (!uri ==
> myself) - everything is fine.
>
>   What I need (in addition to written above):
>   - Opensips receives a call to another domain ('!uri == myself' branch)
>   - This call is redirected to our platform
>   - Platform redirects this  call  back  to Opensips and Opensips starts to call
>     to outside domain.
>
>   What  should  I  change  and/or add to my configuration file? For now it looks
> like this:
>
>  --------------------------------------------------------------------------------
>
>  # ----------- Global configuration parameters ------------------------
>
> debug        = 2
> fork         = yes
> log_stderror = no
> log_facility = LOG_DAEMON
> log_name     = "opensips"
>
> check_via     = no     # (cmd. line: -v)
> dns           = no     # (cmd. line: -r)
> rev_dns       = no     # (cmd. line: -R)
> children      = 4
>
> server_header = "Server: Our SIP Proxy"
>
> # Listen on both network interfaces
> listen        = udp:1.2.3.4:5060
> listen        = udp:192.168.2.1:5060
>
> # Aliases for SIP realm
> alias         = sip.our_domain.ru
> alias         = sip.our_domain.ru
> alias         = our_domain.ru
> alias         = our_domain.ru
>
> # Path to modules
> mpath         = "/usr/local/lib/opensips/modules/"
>
> # ------------------- Load modules  ----------------------------------
>
> loadmodule "signaling.so"
> loadmodule "uri_db.so"
> loadmodule "db_postgres.so"
> loadmodule "sl.so"
> loadmodule "tm.so"
> loadmodule "rr.so"
> loadmodule "maxfwd.so"
> loadmodule "usrloc.so"
> loadmodule "registrar.so"
> loadmodule "textops.so"
> loadmodule "dialog.so"
> loadmodule "nathelper.so"
> loadmodule "nat_traversal.so"
> loadmodule "auth.so"
> loadmodule "auth_db.so"
> loadmodule "xlog.so"
> loadmodule "presence.so"
> loadmodule "presence_mwi.so"
> loadmodule "presence_xml.so"
> loadmodule "msilo.so"
> loadmodule "mi_fifo.so"
>
>
> # ------------------- Set module-specific parameters -----------------
>
> # DB authorization params
> # -----------------------
> modparam("auth_db", "db_url",           "postgres://user:password@db/work")
> modparam("auth_db", "user_column",      "fsep_id")
> modparam("auth_db", "password_column",  "fspassword")
> modparam("auth_db", "load_credentials", "fsep_id")
> modparam("auth_db", "calculate_ha1",    yes)
>
> # usrloc params
> # -------------
> modparam("usrloc", "db_mode",   0)
> modparam("usrloc", "nat_bflag", 6)
>
> # registrar params (nathelper also uses "received_avp")
> # -----------------------------------------------------
> modparam("registrar|nathelper", "received_avp", "$avp(i:42)")
>
> # rr params
> # ---------
> modparam("rr", "enable_full_lr", 1)
>
> # dialog params
> # -------------
> modparam("dialog", "dlg_flag", 4)
>
> # nathelper
> # ---------
> modparam("nathelper", "rtpproxy_sock",    "udp:127.0.0.1:7877")
> modparam("nathelper", "natping_interval", 30)
> modparam("nathelper", "ping_nated_only",  1)
> modparam("nathelper", "sipping_bflag",    7)
> modparam("nathelper", "sipping_from",     "sip:pinger at sip.our_domain.ru")
>
> # nat_traversal params
> # --------------------
> modparam("nat_traversal", "keepalive_interval",   30)
> modparam("nat_traversal", "keepalive_method",     "NOTIFY")
> modparam("nat_traversal", "keepalive_state_file", "/var/run/opensips/keepalive_state")
>
> # presense params
> # ---------------
> modparam("presence", "db_url",         "postgres://opensips:password@db/opensips")
> modparam("presence", "server_address", "sip:1.2.3.4:5060")
>
> # presense_xml params
> # -------------------
> modparam("presence_xml", "db_url",       "postgres://opensips:password@db/opensips")
> modparam("presence_xml", "force_active", 1)
>
> # uri db params
> # -------------
> modparam("uri_db", "use_uri_table", 0)
> modparam("uri_db", "db_url",        "")
>
> # MSILO params
> # ------------
> modparam("msilo", "db_url",           "postgres://opensips:password@db/opensips")
> modparam("msilo", "content_type_hdr", "Content-Type: text/plain\r\n")
> modparam("msilo", "offline_message",  "*** User $rU is offline! ***")
>
> # mi_fifo params
> # --------------
> modparam("mi_fifo", "fifo_name", "/tmp/opensips_fifo")
> modparam("mi_fifo", "fifo_mode", 0666)
>
>
> # Main routing logic.
> # -------------------
> route
> {
>     if (!mf_process_maxfwd_header("30"))
>     {
>         xlog("L_ERR", "Too many hops: method <$rm>, from-header <$fu>\n");
>         sl_send_reply("483","Too Many Hops");
>         exit;
>     };
>
>     if (msg:len >=  2048)
>     {
>         sl_send_reply("513", "Message too big");
>         exit;
>     };
>
>     # NAT detection
>     # -------------
>     route(2);
>
>     if (!method == "REGISTER")
>         record_route();
>
>     # loose_route() returns true if route headers are present.
>     # It also removes any route header entries that match OpenSips own address(es).
>     # -----------------------------------------------------------------------------
>     if (loose_route())
>     {
>         append_hf("P-hint: rr-enforced\r\n"); 
>         route(1);
>     };
>
>     # Outgoing messages processing.
>     # -----------------------------
>     if (!uri == myself)
>     {
>         append_hf("P-hint: outbound\r\n"); 
>         
>         route(1);
>     };
>
>     # Incoming messages processing.
>     # -----------------------------
>     if (uri == myself)
>     {
>         if (method == "REGISTER")
>         {
>             # Perform authorization.
>             # ----------------------
>             if (!www_authorize("", "auth_table"))
>             {
>                 www_challenge("", "0");
>                 exit;
>             };
>                         
>             if (isflagset(5))
>             {
>                 setbflag(6);
>
>                 # If you want OPTIONS natpings uncomment next
>                 # setbflag(7);
>             };
>
>             # Remove authorized credentials from the message.
>             # This ensures that the proxy will not reveal information about credentials
>             # used to downstream elements and also makes the message a little bit shorter.
>             # ----------------------------------------------------------------------------
>             consume_credentials();
>
>             # Remember user.
>             # --------------
>             save("location");
>             
>             # Now user is online, try to deliver all undelivered messages
>             # (sent when user was offline).
>             # -----------------------------------------------------------
>             m_dump("$fu");
>             
>             exit;
>         }
>         else if (is_method("INVITE"))
>         {
>             # Calls from every IP (except of our platform's one) go to our platform.
>             # ----------------------------------------------------------------------
>             if ((uri =~ "sip:*@*") && ($si != "1.2.3.5"))
>             {
>                 xlog("L_INFO", "DBG [$Tf] Trying to authorize caller\n");
>
>               # Perform authorization. Accept calls from RED5 server without authorization.
>               # RED5's IP address is specified manually. "From" domain is checked manually - if
>               # it's not "sip.our_domain.ru" or "our_domain.ru" - the call belongs to other subnet.
>
>                 # -------------------------------------------------------------------------------
>                 if ($si != "192.168.2.2" && ($fd == "sip.our_domain.ru" || $fd == "our_domain.ru" || $fd == "1.2.3.4" || $fd == "1.2.3.4:5060"))
>                 {
>                     xlog("L_INFO", "Attempt to authorize caller $fu\n");
>         
>                     if (!proxy_authorize("", "auth_table"))
>                     {
>                         proxy_challenge("", "0");
>                         return(0);
>                     }
>                     else if (!check_from())
>                     {
>                         sl_send_reply("403", "Use From ID");
>                         return(0);
>                     };
>             
>                     consume_credentials();
>                 }
>                 else
>                 {
>                     xlog("L_INFO", "Accept trusted call from $fu\n");
>                     
>                     xlog("L_INFO", "Accepting INVITE from trusted $si without authorization\n");
>                 }
>             
>                 log("Redirecting call to our platform\n");
>                 rewritehostport("1.2.3.5:5061");
>                 route(1);
>                 return(0);
>             }
>         }
>         else if (is_method("BYE|CANCEL"))
>         {
>             route(1);
>             return(0);
>         }
>         else if (method == "OPTIONS")
>         {
>             sl_send_reply("200", "Got it");
>             return(0);
>         }
>         else if (method == "PING")
>         {
>             sl_send_reply("200", "OK Alive");
>             return(0);
>         }
>         else if (method == "SUBSCRIBE" || method == "PUBLISH" || method == "NOTIFY")
>           {
>             route(4);
>             return(0);
>         }
>
>         # Try to find user in usrloc.
>         # ---------------------------
>         if (!lookup("location"))
>         {
>             if (!t_newtran())
>           {
>               sl_reply_error();
>               exit;
>           };
>             
>           # User not found.
>           # Instant messages should be stored in database, in other case we respond
>           # with 404 and exit.
>           # -----------------------------------------------------------------------
>             if (!method == "MESSAGE")
>           {                                                                 
>                 sl_send_reply("404", "Not Found");
>                 exit;
>             }
>             
>             log("MESSAGE received -> storing using MSILO\n");
>             
>             # Store instant message in database.
>             # ----------------------------------
>             if (m_store("$ru"))
>           {
>               log("MSILO: offline message stored\n");
>
>               if (!t_reply("202", "Accepted")) 
>               {
>                   sl_reply_error();
>               };
>           }
>           else
>           {
>               log("MSILO: offline message NOT stored\n");
>         
>             if (!t_reply("503", "Service Unavailable")) 
>             {
>                 sl_reply_error();
>             };
>           };
>             
>           exit;
>         };
>         
>         # If the downstream UA does not support MESSAGE requests,
>         # we can handle it with failure_route[1].
>         t_on_failure("1");
>
>         append_hf("P-hint: usrloc applied\r\n"); 
>     };
>
>     route(1);
> }
>
> # Default Message Handling.
> # -------------------------
> route[1]
> {
>     if (subst_uri('/(sip:.*);nat=yes/\1/'))
>     {
>         setbflag(6);
>     };
>
>     if (isflagset(5) || isbflagset(6))
>     {
>         route(3);
>     }
>
>     if (!t_relay())
>     {
>         sl_reply_error();
>     };
>     
>     exit;
> }
>
> # Check for NAT. If needed, fix NATed headers.
> # --------------------------------------------
> route[2]
> {
>     force_rport();
>     
>     if (nat_uac_test("19"))
>     {
>         if (method == "REGISTER")
>         {
>             fix_nated_register();
>             nat_keepalive();
>         }
>         else
>         {
>             fix_nated_contact();
>             
>             if (method == "INVITE")
>             {
>                  fix_nated_sdp("1");
>             }
>         };
>
>         setflag(5);
>     };
> }
>
> # Process INVITE and BYE/CANCEL events.
> # Turns RTP proxy on/off.
> # -------------------------------------
> route[3]
> {
>     if (is_method("BYE|CANCEL"))
>     {
>         unforce_rtp_proxy();
>     }
>     else if (is_method("INVITE"))
>     {
>         force_rtp_proxy();
>     }
>
>     if (isflagset(5))
>         search_append('Contact:.*sip:[^>[:cntrl:]]*', ';nat=yes');
>
>     t_on_reply("1");
> }
>
> # SUBSCRIBE and PUBLISH Message Handling
> # --------------------------------------
> route[4]
> {
>     if (!t_newtran())
>     {
>         xlog("L_INFO", "Failed to create transaction\n");
>         sl_reply_error();
>         exit;
>     }
>     
>     if (is_method("PUBLISH"))
>     {
>         xlog("L_INFO", "Route 5 - PUBLISH \n");
>         handle_publish();
>     }  
>     else if (is_method("SUBSCRIBE"))
>     {
>         xlog("L_INFO", "Route 5 - SUBSCRIBE\n");
>         handle_subscribe();
>     }
>     else if (is_method("NOTIFY"))
>     {
>         xlog("L_INFO", "Route 5 - NOTIFY\n");
>         t_reply("200", "OK");
>         exit;           
>     }
>     
>     exit; 
> }
>
> # Failed transaction routing block. Contains actions for transanctions
> # that received negative replies (>= 300).
> # --------------------------------------------------------------------
> failure_route[1]
> {
>     if (is_method("MESSAGE"))
>     {
>         log("MSILO: the downstream UA doesn't support MESSAGEs\n");
>         
>         # $ou is used because we have changed the R-URI with the contact address
>         if (m_store("$ou"))
>         {
>             log("MSILO: offline message stored\n");
>             t_reply("202", "Accepted"); 
>         }
>         else
>         {
>             log("MSILO: offline message NOT stored\n");
>             t_reply("503", "Service Unavailable");
>         };                                                
>     }
>
>     if (isbflagset(6) || isflagset(5))
>     {
>         unforce_rtp_proxy();
>     }
> }
>
> # Reply routing block. Contains actions to be taken for SIP replies. 
> # ------------------------------------------------------------------
> onreply_route[1]
> {
>     # 180 - Ringing, 183 - Progress
>     if ((isflagset(5) || isbflagset(6)) && status=~"(180)|(183)|(2[0-9][0-9])")
>     {
>         if (!search("^Content-Length:[ ]*0"))
>         {
>             force_rtp_proxy();
>         }
>     }
>     
>     search_append('Contact:.*sip:[^>[:cntrl:]]*', ';nat=yes');
>
>     if (isbflagset(6))
>     {
>         fix_nated_contact();
>     }
> }
>
>
>
>   




More information about the Users mailing list