[OpenSIPS-Users] Problem proxying a SIP connection with t_relay and rtpproxy

Thomas Pircher thp.opensips at p5r.uk
Wed Sep 28 13:27:54 UTC 2022


Hi,

I'm trying to set up an OpenSIPS 3.2.6 server that is connected to two networks and I'd like to proxy SIP and RTP through the OpenSIPS server.
The OpenSIPS server is sitting on these two networks:

- 10.30.8.0/24: network with the sipp client
- 10.30.9.0/24: network with the sipp server

A crude network diagram is here:

[ 10.30.8.203 (sipp client) ]----[ 10.30.8.201 (OpenSIPS) 10.30.9.10 ]---[ 10.30.9.11 (sipp server) ]


The problem I am seeing is when I initiate a connection from the sipp
client then I see RTP flowing only in one direction (sipp client to sipp
server). I believe this is due to a missing ACK from OpenSIPS to the
sipp server following the 200 OK.

This is a tcpdump on the client side:

> 12:54:38.891222 IP 10.30.8.203.5060 > 10.30.8.201.5060: SIP: INVITE sip:5678 at 10.30.8.201:5060 SIP/2.0
> 12:54:38.895104 IP 10.30.8.201.5060 > 10.30.8.203.5060: SIP: SIP/2.0 100 Giving it a try
> 12:54:38.896523 IP 10.30.8.201.5060 > 10.30.8.203.5060: SIP: SIP/2.0 180 Ringing
> 12:54:38.898255 IP 10.30.8.201.5060 > 10.30.8.203.5060: SIP: SIP/2.0 200 OK
> 12:54:38.899385 IP 10.30.8.203.5060 > 10.30.8.201.5060: SIP: ACK sip:5678 at 10.30.8.201:5060 SIP/2.0
> 12:54:39.398922 IP 10.30.8.201.5060 > 10.30.8.203.5060: SIP: SIP/2.0 200 OK
> 12:54:39.399489 IP 10.30.8.203.5060 > 10.30.8.201.5060: SIP: ACK sip:5678 at 10.30.8.201:5060 SIP/2.0
> 12:54:40.403883 IP 10.30.8.201.5060 > 10.30.8.203.5060: SIP: SIP/2.0 200 OK
> 12:54:40.404357 IP 10.30.8.203.5060 > 10.30.8.201.5060: SIP: ACK sip:5678 at 10.30.8.201:5060 SIP/2.0
> 12:54:42.407114 IP 10.30.8.201.5060 > 10.30.8.203.5060: SIP: SIP/2.0 200 OK
> 12:54:42.407652 IP 10.30.8.203.5060 > 10.30.8.201.5060: SIP: ACK sip:5678 at 10.30.8.201:5060 SIP/2.0
> 12:54:47.910201 IP 10.30.8.203.5060 > 10.30.8.201.5060: SIP: BYE sip:5678 at 10.30.8.201:5060 SIP/2.0
> 12:54:47.910373 IP 10.30.8.201.5060 > 10.30.8.203.5060: SIP: SIP/2.0 404 Not here
> 12:54:47.911090 IP 10.30.8.203.5060 > 10.30.8.201.5060: SIP: BYE sip:5678 at 10.30.8.201:5060 SIP/2.0
> 12:54:47.911287 IP 10.30.8.201.5060 > 10.30.8.203.5060: SIP: SIP/2.0 404 Not here

And on the network with the sipp server:

> 12:54:38.895726 IP 10.30.9.10.5060 > 10.30.9.11.5060: SIP: INVITE sip:5678 at 10.30.8.201:5060 SIP/2.0
> 12:54:38.895931 IP 10.30.9.11.5060 > 10.30.9.10.5060: SIP: SIP/2.0 180 Ringing
> 12:54:38.897219 IP 10.30.9.11.5060 > 10.30.9.10.5060: SIP: SIP/2.0 200 OK
> 12:54:39.397731 IP 10.30.9.11.5060 > 10.30.9.10.5060: SIP: SIP/2.0 200 OK
> 12:54:40.401824 IP 10.30.9.11.5060 > 10.30.9.10.5060: SIP: SIP/2.0 200 OK
> 12:54:42.406023 IP 10.30.9.11.5060 > 10.30.9.10.5060: SIP: SIP/2.0 200 OK
> 12:54:46.410604 IP 10.30.9.11.5060 > 10.30.9.10.5060: SIP: SIP/2.0 200 OK
> 12:54:50.414512 IP 10.30.9.11.5060 > 10.30.9.10.5060: SIP: SIP/2.0 200 OK
> 12:54:54.418603 IP 10.30.9.11.5060 > 10.30.9.10.5060: SIP: SIP/2.0 200 OK
> 12:54:58.422011 IP 10.30.9.11.5060 > 10.30.9.10.5060: SIP: SIP/2.0 200 OK
> 12:55:02.422177 IP 10.30.9.11.5060 > 10.30.9.10.5060: SIP: SIP/2.0 200 OK
> 12:55:06.425519 IP 10.30.9.11.5060 > 10.30.9.10.5060: SIP: SIP/2.0 200 OK

I would expect an ACK from OpenSIPS to the sipp server, after the first
200 OK, right?


The full OpenSIPS config is attached. Some salient bits of the configuration are:

> /* The server is multi-homed */
> mhomed=1
>
> socket=udp:10.30.9.10:5060
> socket=udp:10.30.8.201:5060
>
> ...
>
> #### rtpproxy
> loadmodule "dialog.so"
> loadmodule "rtp_relay.so"
> loadmodule "rtpproxy.so"
>
> # RTP proxy to 10.30.8.0/24
> modparam("rtpproxy", "rtpproxy_sock", "0 == udp:localhost:22222")
>
> ...
>
> route {
> ...
>
>     route(byNumber);
> ...
> }
>
> route[byNumber] {
>     xlog("L_NOTICE", "Routing by Numbers ru=$rU fu=$fU tu=$tU ou=$oU\n");
>
>     #Simulated VoIP phones: sipp
>     if ($tU =~ "^567[0-9]{1,5}$")
>     {
>         route(SimVoIP);
>         exit;
>     }
> }
>
> route[SimVoIP] {
>     xlog("SimVoIP $rm: $si:$sp -> $ru\n");
>
>     # If coming from the Chassis to the VoIP network.
>     if ($si =~ "^10.159.60." || $si =~ "^10.30.8.") {
>         if (is_method("INVITE") && !has_totag()) {
>             create_dialog();
>             $rtp_relay = "coeir";  # check the RTPProxy documentation for the meaning of these (optional) flags
>             $rtp_relay_peer = "coier"; # do the same thing for the callee
>             rtp_relay_engage("rtpproxy", 0);
>         }
>     }
>
>     if (!t_relay(, "udp:10.30.9.11:5060")) {
>         sl_reply_error();
>     }
>     exit;
> }
> ...


I have briefly experimented with B2Bua top hiding, but I must have
gotten things quite wrong, as every connection ended i a flood of error
messages (ERROR:b2b_entities:b2b_send_reply: Tm transaction not saved!).
So I went down the t_relay option, as it sounded simpler.

Any help to how to fix this is greatly appreciated. Be gentle, I'm
relatively new to OpenSIPS, so I might have gotten quite a few bits
wrong.

Thanks,
Thomas
-------------- next part --------------
#
# OpenSIPS residential configuration script
#     by OpenSIPS Solutions <team at opensips-solutions.com>
#
# This script was generated via "make menuconfig", from
#   the "Residential" scenario.
# You can enable / disable more features / functionalities by
#   re-generating the scenario with different options.#
#
# Please refer to the Core CookBook at:
#      https://opensips.org/Resources/DocsCookbooks
# for a explanation of possible statements, functions and parameters.
#


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

/* uncomment the following lines to enable debugging */
#debug_mode=yes

log_level=3
xlog_level=3
log_stderror=no
log_facility=LOG_LOCAL0

udp_workers=4

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


/* The server is multi-homed */
mhomed=1

socket=udp:10.30.9.10:5060
socket=udp:10.30.8.201:5060




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

#set module path
mpath="/usr/lib/x86_64-linux-gnu/opensips/modules/"

#### 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", 0)

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

#### USeR LOCation module
loadmodule "usrloc.so"
modparam("usrloc", "nat_bflag", "NAT")
modparam("usrloc", "working_mode_preset", "single-instance-no-db")

#### REGISTRAR module
loadmodule "registrar.so"
modparam("registrar", "tcp_persistent_flag", "TCP_PERSISTENT")
/* 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 to enable "append_fromtag"
   in "rr" module */
modparam("acc", "detect_direction", 0)

loadmodule "proto_udp.so"

#### rtpproxy
loadmodule "dialog.so"
loadmodule "rtp_relay.so"
loadmodule "rtpproxy.so"

# RTP proxy to 10.30.8.0/24
modparam("rtpproxy", "rtpproxy_sock", "0 == udp:localhost:22222")


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

# main request routing logic

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

    if (has_totag()) {
        # handle hop-by-hop ACK (no routing required)
        if (is_method("ACK") && t_check_trans()) {
            t_relay();
            exit;
        }

        # sequential request within a dialog should
        # take the path determined by record-routing
        if (!loose_route()) {
            # we do record-routing for all our traffic, so we should not
            # receive any sequential requests without Route hdr.
            send_reply(404, "Not here");
            exit;
        }

        if (is_method("BYE")) {
            # do accounting even if the transaction fails
            do_accounting("log", "failed");
        }

        # route it out to whatever destination was set by loose_route()
        # in $du (destination URI).
        route(relay);
        exit;
    }

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

    # absorb retransmissions, but do not create transaction
    t_check_trans();

    if (!(is_method("REGISTER"))) {
        if (is_myself("$fd")) {

        } else {
            # if caller is not local, then called number must be local
            if (!is_myself("$rd")) {
                send_reply(403, "Relay Forbidden");
                exit;
            }
        }
    }

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

    # record routing
    if (!is_method("REGISTER|MESSAGE")) {
        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")) {
        send_reply(503, "Service Unavailable");
        exit;
    }

    if (is_method("REGISTER")) {
        # store the registration and generate a SIP reply
        if (!save("location"))
            sl_reply_error();

        exit;
    }

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

    # Route by number
    route(byNumber);

    # do lookup with method filtering
    if (!lookup("location", "m")) {
        t_reply(404, "Not Found");
        exit;
    }

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

route[byNumber] {
    xlog("L_NOTICE", "Routing by Numbers ru=$rU fu=$fU tu=$tU ou=$oU\n");

    #Simulated VoIP phones: sipp
    if ($tU =~ "^567[0-9]{1,5}$")
    {
        route(SimVoIP);
        exit;
    }
}

route[SimVoIP] {
    xlog("SimVoIP $rm: $si:$sp -> $ru\n");

    # If coming from the Chassis to the VoIP network.
    if ($si =~ "^10.159.60." || $si =~ "^10.30.8.") {
        if (is_method("INVITE") && !has_totag()) {
            create_dialog();
            $rtp_relay = "coeir";  # check the RTPProxy documentation for the meaning of these (optional) flags
            $rtp_relay_peer = "coier"; # do the same thing for the callee
            rtp_relay_engage("rtpproxy", 0);
        }
    }

    if (!t_relay(, "udp:10.30.9.11:5060")) {
        sl_reply_error();
    }
    exit;
}

route[relay] {
    xlog("Relay $rm: $si:$sp -> $ru\n");

    # for INVITEs enable some additional helper routes
    if (is_method("INVITE")) {
        t_on_branch("per_branch_ops");
        t_on_reply("handle_nat");
        t_on_failure("missed_call");
    }

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




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


onreply_route[handle_nat] {
    xlog("incoming reply\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;
    ##}
}


More information about the Users mailing list