[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