TCP to UDP proxy

classic Classic list List threaded Threaded
5 messages Options
Reply | Threaded
Open this post in threaded view
|

TCP to UDP proxy

Simon Quigley
Hello,

I'm trying to use OpenSIPS as a TCP to UDP proxy, (with the registrar module disabled) connecting all sorts of devices from different IP addresses over TCP to a UDP switch.

So far I've managed to get OpenSIPS configured to change the contact header, and the SDP, append the transport, and forward the packets correctly, for making an outbound call (from TCP device to UDP switch).

I've got incoming to work somewhat (from UDP switch to TCP device), the INVITE will pass, and the TRYING/RINGING gets back to the switch, however the issue I'm having is that the OK packet from the TCP device is sent to the switch, which responds with the ACK, however the contact header is wrong, and OpenSIPS is trying to sent the ACK to the internal non routable IP of the device.

As a result the call comes up, but the device has an ACK timeout and drops the call.

I'm having difficulties working out how to get the contact header mangled sufficiently for the OK/ACK to contain the routable IP of the TCP device, rather than it's internal/behind NAT IP.

I've tried removing the header, using loose_route, using t_relay, and (am currently attempting) to use route(relay).

Also of relevance, is the fact that I'm running OpenSIPS on a Google Compute VM, so it's behind 1 to 1 NAT, with a non routable IP on the VM, but I have assigned a static routable IP to the 1 to 1 NAT, and I have DNS pointing to this routable IP.

Here's my config file, excluding default values/routes etc:

listen=udp:[internal VM IP]:5060
listen=tcp:[internal VM IP]:5060

disable_tcp=no

advertised_address="[DNS name]"
alias="[DNS name]"

route{
    if (src_ip != "[switch ip]"){
        # from device
        if (is_method("INVITE")) {
            fix_nated_sdp("7");
        }
        else if (is_method("OPTIONS")){
            exit;
        }

        fix_nated_contact();
        forward ("udp:[switch ip]:5060");
    }

    else if (src_ip == "[switch ip]"){
        # from switch
        if (is_method("INVITE")) {
            fix_nated_sdp("7");
        }
        else if (is_method("ACK")) {
            fix_nated_contact();
        }

        # mangle to TCP
        $du = $ru + ";transport=tcp";

        route(relay);
    }

        exit;
}

Is the issue perhaps related to the fact I'm not recording a route, so it doesn't know how to correctly route the response, or am I just missing something obvious?

Thanks,
Simon

--
Simon Quigley, Systems Engineer
Versature Corp.  |  877-498-3772 x128

Follow us on Twitter - http://twitter.com/Versature
Check out the Versature Blog - http://inside.versature.com

_______________________________________________
Users mailing list
[hidden email]
http://lists.opensips.org/cgi-bin/mailman/listinfo/users
Reply | Threaded
Open this post in threaded view
|

Re: TCP to UDP proxy

Bogdan-Andrei Iancu-2
Hello Simon,

Most probably it is a mistake on the way you do record_routing (for initial INVITE) and loose_route (for sequential requests). All sequential requests are driven by this mechanism. If the case, check how it suppose to work :
    http://www.opensips.org/Documentation/Webinars#toc12  (5.5)

Basically you need to do record_route() for INVITE and loose_route() for ACK - OpenSIPS will take care of changing the interface for the ACK after the loose_route() call.

Regards,
Bogdan-Andrei Iancu
OpenSIPS Founder and Developer
http://www.opensips-solutions.com

On 10/25/2013 07:42 PM, Simon Quigley wrote:
Hello,

I'm trying to use OpenSIPS as a TCP to UDP proxy, (with the registrar module disabled) connecting all sorts of devices from different IP addresses over TCP to a UDP switch.

So far I've managed to get OpenSIPS configured to change the contact header, and the SDP, append the transport, and forward the packets correctly, for making an outbound call (from TCP device to UDP switch).

I've got incoming to work somewhat (from UDP switch to TCP device), the INVITE will pass, and the TRYING/RINGING gets back to the switch, however the issue I'm having is that the OK packet from the TCP device is sent to the switch, which responds with the ACK, however the contact header is wrong, and OpenSIPS is trying to sent the ACK to the internal non routable IP of the device.

As a result the call comes up, but the device has an ACK timeout and drops the call.

I'm having difficulties working out how to get the contact header mangled sufficiently for the OK/ACK to contain the routable IP of the TCP device, rather than it's internal/behind NAT IP.

I've tried removing the header, using loose_route, using t_relay, and (am currently attempting) to use route(relay).

Also of relevance, is the fact that I'm running OpenSIPS on a Google Compute VM, so it's behind 1 to 1 NAT, with a non routable IP on the VM, but I have assigned a static routable IP to the 1 to 1 NAT, and I have DNS pointing to this routable IP.

Here's my config file, excluding default values/routes etc:

listen=udp:[internal VM IP]:5060
listen=tcp:[internal VM IP]:5060

disable_tcp=no

advertised_address="[DNS name]"
alias="[DNS name]"

route{
    if (src_ip != "[switch ip]"){
        # from device
        if (is_method("INVITE")) {
            fix_nated_sdp("7");
        }
        else if (is_method("OPTIONS")){
            exit;
        }

        fix_nated_contact();
        forward ("udp:[switch ip]:5060");
    }

    else if (src_ip == "[switch ip]"){
        # from switch
        if (is_method("INVITE")) {
            fix_nated_sdp("7");
        }
        else if (is_method("ACK")) {
            fix_nated_contact();
        }

        # mangle to TCP
        $du = $ru + ";transport=tcp";

        route(relay);
    }

        exit;
}

Is the issue perhaps related to the fact I'm not recording a route, so it doesn't know how to correctly route the response, or am I just missing something obvious?

Thanks,
Simon

--
Simon Quigley, Systems Engineer
Versature Corp.  |  877-498-3772 x128

Follow us on Twitter - http://twitter.com/Versature
Check out the Versature Blog - http://inside.versature.com
_______________________________________________ Users mailing list [hidden email] http://lists.opensips.org/cgi-bin/mailman/listinfo/users

_______________________________________________
Users mailing list
[hidden email]
http://lists.opensips.org/cgi-bin/mailman/listinfo/users
Reply | Threaded
Open this post in threaded view
|

Re: TCP to UDP proxy

Simon Quigley
Hi Bogdan,

Thanks for your response, your suggestion was much appreciated, and gave me a good direction to work in.

You are correct, I was trying to mix stateless and stateful routing together, I realised after watching the webinar.

I've made some changes to my configuration file to use record_route() and loose_route(), in a few different ways, but it hasn't made any difference.

The 200 OK is always sent back to the switch containing the non routable IP in the contact of the device, rather than fix_nated_contact changing it to the IP the packet arrives from, and it's also failing to match it and translate it for the ACK response to get to the device.

I've enabled debugging, and looking through the output, I think it's an issue with matching the dialogue.

Here's the config I'm using now:

listen=udp:[internal VM IP]:5060
listen=tcp:[internal VM IP]:5060

disable_tcp=no

advertised_address="[dns name]"
alias="[dns name]"

route{
    if (src_ip != "[switch ip]"){
        # from device
        if (!is_method("REGISTER|MESSAGE")) {
            if (is_method("INVITE")) {
                fix_nated_sdp("7");
                record_route();
            }
            else if (is_method("OPTIONS")){
                exit;
            }
            else {
                loose_route();
                fix_nated_contact();
                if (has_totag()){
                    fix_nated_sdp("7");
                }
                t_relay("udp:[switch ip]:5060");
            }
        }
    }

    else if (src_ip == "[switch ip]"){
        # from switch
        if (is_method("INVITE")) {
            fix_nated_contact();
            fix_nated_sdp("7");
            record_route();
        }
        else {
            loose_route();
        }
       
        # mangle to TCP
        $du = $ru + ";transport=tcp";

        t_relay();
    }
    exit;
}

Is there something obvious that I'm doing wrong?

Thanks again for your help.


On Wed, Oct 30, 2013 at 4:52 AM, Bogdan-Andrei Iancu <[hidden email]> wrote:
Hello Simon,

Most probably it is a mistake on the way you do record_routing (for initial INVITE) and loose_route (for sequential requests). All sequential requests are driven by this mechanism. If the case, check how it suppose to work :
    http://www.opensips.org/Documentation/Webinars#toc12  (5.5)

Basically you need to do record_route() for INVITE and loose_route() for ACK - OpenSIPS will take care of changing the interface for the ACK after the loose_route() call.

Regards,
Bogdan-Andrei Iancu
OpenSIPS Founder and Developer
http://www.opensips-solutions.com

On 10/25/2013 07:42 PM, Simon Quigley wrote:
Hello,

I'm trying to use OpenSIPS as a TCP to UDP proxy, (with the registrar module disabled) connecting all sorts of devices from different IP addresses over TCP to a UDP switch.

So far I've managed to get OpenSIPS configured to change the contact header, and the SDP, append the transport, and forward the packets correctly, for making an outbound call (from TCP device to UDP switch).

I've got incoming to work somewhat (from UDP switch to TCP device), the INVITE will pass, and the TRYING/RINGING gets back to the switch, however the issue I'm having is that the OK packet from the TCP device is sent to the switch, which responds with the ACK, however the contact header is wrong, and OpenSIPS is trying to sent the ACK to the internal non routable IP of the device.

As a result the call comes up, but the device has an ACK timeout and drops the call.

I'm having difficulties working out how to get the contact header mangled sufficiently for the OK/ACK to contain the routable IP of the TCP device, rather than it's internal/behind NAT IP.

I've tried removing the header, using loose_route, using t_relay, and (am currently attempting) to use route(relay).

Also of relevance, is the fact that I'm running OpenSIPS on a Google Compute VM, so it's behind 1 to 1 NAT, with a non routable IP on the VM, but I have assigned a static routable IP to the 1 to 1 NAT, and I have DNS pointing to this routable IP.

Here's my config file, excluding default values/routes etc:

listen=udp:[internal VM IP]:5060
listen=tcp:[internal VM IP]:5060

disable_tcp=no

advertised_address="[DNS name]"
alias="[DNS name]"

route{
    if (src_ip != "[switch ip]"){
        # from device
        if (is_method("INVITE")) {
            fix_nated_sdp("7");
        }
        else if (is_method("OPTIONS")){
            exit;
        }

        fix_nated_contact();
        forward ("udp:[switch ip]:5060");
    }

    else if (src_ip == "[switch ip]"){
        # from switch
        if (is_method("INVITE")) {
            fix_nated_sdp("7");
        }
        else if (is_method("ACK")) {
            fix_nated_contact();
        }

        # mangle to TCP
        $du = $ru + ";transport=tcp";

        route(relay);
    }

        exit;
}

Is the issue perhaps related to the fact I'm not recording a route, so it doesn't know how to correctly route the response, or am I just missing something obvious?

Thanks,
Simon

--
Simon Quigley, Systems Engineer
Versature Corp.  |  877-498-3772 x128

Follow us on Twitter - http://twitter.com/Versature
Check out the Versature Blog - http://inside.versature.com
_______________________________________________ Users mailing list [hidden email] http://lists.opensips.org/cgi-bin/mailman/listinfo/users



--
Simon Quigley, Systems Engineer
Versature Corp.  |  877-498-3772 x128

Follow us on Twitter - http://twitter.com/Versature
Check out the Versature Blog - http://inside.versature.com

_______________________________________________
Users mailing list
[hidden email]
http://lists.opensips.org/cgi-bin/mailman/listinfo/users
Reply | Threaded
Open this post in threaded view
|

Re: TCP to UDP proxy

Simon Quigley
Hi,

I've done some more testing, and it seems the issue I'm having with the NATed contact is related to the UA I'm using.

If I use empathy/telepathy-sofiasip, then the contact isn't being mangled properly, which causes it to send the 200 OK packet after answering, receive no ACK, and continue resending the 200 OK, until it gives up and sends a BYE.

The same behaviour occurs if I use sipdroid, however it doesn't send a BYE when it doesn't receive an ACK, but the call still isn't up properly, and when I do hang up, it doesn't send a BYE, so the originating UA (and switch) thinks the call is still up.

However, if I use the built in Android SIP client, it's contact is mangled properly, and so the OK / ACK process works properly.

How can I debug to see what the fix nated contact function is doing, to see if I can work out what the differences between these UA's packets are?

Thanks


On Fri, Nov 1, 2013 at 5:44 PM, Simon Quigley <[hidden email]> wrote:
Hi Bogdan,

Thanks for your response, your suggestion was much appreciated, and gave me a good direction to work in.

You are correct, I was trying to mix stateless and stateful routing together, I realised after watching the webinar.

I've made some changes to my configuration file to use record_route() and loose_route(), in a few different ways, but it hasn't made any difference.

The 200 OK is always sent back to the switch containing the non routable IP in the contact of the device, rather than fix_nated_contact changing it to the IP the packet arrives from, and it's also failing to match it and translate it for the ACK response to get to the device.

I've enabled debugging, and looking through the output, I think it's an issue with matching the dialogue.

Here's the config I'm using now:


listen=udp:[internal VM IP]:5060
listen=tcp:[internal VM IP]:5060

disable_tcp=no

advertised_address="[dns name]"
alias="[dns name]"


route{
    if (src_ip != "[switch ip]"){
        # from device
        if (!is_method("REGISTER|MESSAGE")) {

            if (is_method("INVITE")) {
                fix_nated_sdp("7");
                record_route();

            }
            else if (is_method("OPTIONS")){
                exit;
            }
            else {
                loose_route();
                fix_nated_contact();
                if (has_totag()){
                    fix_nated_sdp("7");
                }
                t_relay("udp:[switch ip]:5060");

            }
        }
    }

    else if (src_ip == "[switch ip]"){
        # from switch
        if (is_method("INVITE")) {
            fix_nated_contact();
            fix_nated_sdp("7");
            record_route();
        }
        else {
            loose_route();

        }
       
        # mangle to TCP
        $du = $ru + ";transport=tcp";

        t_relay();
    }
    exit;
}

Is there something obvious that I'm doing wrong?

Thanks again for your help.


On Wed, Oct 30, 2013 at 4:52 AM, Bogdan-Andrei Iancu <[hidden email]> wrote:
Hello Simon,

Most probably it is a mistake on the way you do record_routing (for initial INVITE) and loose_route (for sequential requests). All sequential requests are driven by this mechanism. If the case, check how it suppose to work :
    http://www.opensips.org/Documentation/Webinars#toc12  (5.5)

Basically you need to do record_route() for INVITE and loose_route() for ACK - OpenSIPS will take care of changing the interface for the ACK after the loose_route() call.

Regards,
Bogdan-Andrei Iancu
OpenSIPS Founder and Developer
http://www.opensips-solutions.com

On 10/25/2013 07:42 PM, Simon Quigley wrote:
Hello,

I'm trying to use OpenSIPS as a TCP to UDP proxy, (with the registrar module disabled) connecting all sorts of devices from different IP addresses over TCP to a UDP switch.

So far I've managed to get OpenSIPS configured to change the contact header, and the SDP, append the transport, and forward the packets correctly, for making an outbound call (from TCP device to UDP switch).

I've got incoming to work somewhat (from UDP switch to TCP device), the INVITE will pass, and the TRYING/RINGING gets back to the switch, however the issue I'm having is that the OK packet from the TCP device is sent to the switch, which responds with the ACK, however the contact header is wrong, and OpenSIPS is trying to sent the ACK to the internal non routable IP of the device.

As a result the call comes up, but the device has an ACK timeout and drops the call.

I'm having difficulties working out how to get the contact header mangled sufficiently for the OK/ACK to contain the routable IP of the TCP device, rather than it's internal/behind NAT IP.

I've tried removing the header, using loose_route, using t_relay, and (am currently attempting) to use route(relay).

Also of relevance, is the fact that I'm running OpenSIPS on a Google Compute VM, so it's behind 1 to 1 NAT, with a non routable IP on the VM, but I have assigned a static routable IP to the 1 to 1 NAT, and I have DNS pointing to this routable IP.

Here's my config file, excluding default values/routes etc:

listen=udp:[internal VM IP]:5060
listen=tcp:[internal VM IP]:5060

disable_tcp=no

advertised_address="[DNS name]"
alias="[DNS name]"

route{
    if (src_ip != "[switch ip]"){
        # from device
        if (is_method("INVITE")) {
            fix_nated_sdp("7");
        }
        else if (is_method("OPTIONS")){
            exit;
        }

        fix_nated_contact();
        forward ("udp:[switch ip]:5060");
    }

    else if (src_ip == "[switch ip]"){
        # from switch
        if (is_method("INVITE")) {
            fix_nated_sdp("7");
        }
        else if (is_method("ACK")) {
            fix_nated_contact();
        }

        # mangle to TCP
        $du = $ru + ";transport=tcp";

        route(relay);
    }

        exit;
}

Is the issue perhaps related to the fact I'm not recording a route, so it doesn't know how to correctly route the response, or am I just missing something obvious?

Thanks,
Simon

--
Simon Quigley, Systems Engineer
Versature Corp.  |  877-498-3772 x128

Follow us on Twitter - http://twitter.com/Versature
Check out the Versature Blog - http://inside.versature.com
_______________________________________________ Users mailing list [hidden email] http://lists.opensips.org/cgi-bin/mailman/listinfo/users



--
Simon Quigley, Systems Engineer
Versature Corp.  |  877-498-3772 x128

Follow us on Twitter - http://twitter.com/Versature
Check out the Versature Blog - http://inside.versature.com



--
Simon Quigley, Systems Engineer
Versature Corp.  |  877-498-3772 x128

Follow us on Twitter - http://twitter.com/Versature
Check out the Versature Blog - http://inside.versature.com

_______________________________________________
Users mailing list
[hidden email]
http://lists.opensips.org/cgi-bin/mailman/listinfo/users
Reply | Threaded
Open this post in threaded view
|

Re: TCP to UDP proxy

Ali Pey
Add this in your route:

subst_uri('/(sip:.*);transport=tcp/\1/');

To remove transport=tcp from request-uri. 

This should fix it.

Regards,
Ali Pey


On Wed, Nov 6, 2013 at 2:15 PM, Simon Quigley <[hidden email]> wrote:
Hi,

I've done some more testing, and it seems the issue I'm having with the NATed contact is related to the UA I'm using.

If I use empathy/telepathy-sofiasip, then the contact isn't being mangled properly, which causes it to send the 200 OK packet after answering, receive no ACK, and continue resending the 200 OK, until it gives up and sends a BYE.

The same behaviour occurs if I use sipdroid, however it doesn't send a BYE when it doesn't receive an ACK, but the call still isn't up properly, and when I do hang up, it doesn't send a BYE, so the originating UA (and switch) thinks the call is still up.

However, if I use the built in Android SIP client, it's contact is mangled properly, and so the OK / ACK process works properly.

How can I debug to see what the fix nated contact function is doing, to see if I can work out what the differences between these UA's packets are?

Thanks


On Fri, Nov 1, 2013 at 5:44 PM, Simon Quigley <[hidden email]> wrote:
Hi Bogdan,

Thanks for your response, your suggestion was much appreciated, and gave me a good direction to work in.

You are correct, I was trying to mix stateless and stateful routing together, I realised after watching the webinar.

I've made some changes to my configuration file to use record_route() and loose_route(), in a few different ways, but it hasn't made any difference.

The 200 OK is always sent back to the switch containing the non routable IP in the contact of the device, rather than fix_nated_contact changing it to the IP the packet arrives from, and it's also failing to match it and translate it for the ACK response to get to the device.

I've enabled debugging, and looking through the output, I think it's an issue with matching the dialogue.

Here's the config I'm using now:


listen=udp:[internal VM IP]:5060
listen=tcp:[internal VM IP]:5060

disable_tcp=no

advertised_address="[dns name]"
alias="[dns name]"


route{
    if (src_ip != "[switch ip]"){
        # from device
        if (!is_method("REGISTER|MESSAGE")) {

            if (is_method("INVITE")) {
                fix_nated_sdp("7");
                record_route();

            }
            else if (is_method("OPTIONS")){
                exit;
            }
            else {
                loose_route();
                fix_nated_contact();
                if (has_totag()){
                    fix_nated_sdp("7");
                }
                t_relay("udp:[switch ip]:5060");

            }
        }
    }

    else if (src_ip == "[switch ip]"){
        # from switch
        if (is_method("INVITE")) {
            fix_nated_contact();
            fix_nated_sdp("7");
            record_route();
        }
        else {
            loose_route();

        }
       
        # mangle to TCP
        $du = $ru + ";transport=tcp";

        t_relay();
    }
    exit;
}

Is there something obvious that I'm doing wrong?

Thanks again for your help.


On Wed, Oct 30, 2013 at 4:52 AM, Bogdan-Andrei Iancu <[hidden email]> wrote:
Hello Simon,

Most probably it is a mistake on the way you do record_routing (for initial INVITE) and loose_route (for sequential requests). All sequential requests are driven by this mechanism. If the case, check how it suppose to work :
    http://www.opensips.org/Documentation/Webinars#toc12  (5.5)

Basically you need to do record_route() for INVITE and loose_route() for ACK - OpenSIPS will take care of changing the interface for the ACK after the loose_route() call.

Regards,
Bogdan-Andrei Iancu
OpenSIPS Founder and Developer
http://www.opensips-solutions.com

On 10/25/2013 07:42 PM, Simon Quigley wrote:
Hello,

I'm trying to use OpenSIPS as a TCP to UDP proxy, (with the registrar module disabled) connecting all sorts of devices from different IP addresses over TCP to a UDP switch.

So far I've managed to get OpenSIPS configured to change the contact header, and the SDP, append the transport, and forward the packets correctly, for making an outbound call (from TCP device to UDP switch).

I've got incoming to work somewhat (from UDP switch to TCP device), the INVITE will pass, and the TRYING/RINGING gets back to the switch, however the issue I'm having is that the OK packet from the TCP device is sent to the switch, which responds with the ACK, however the contact header is wrong, and OpenSIPS is trying to sent the ACK to the internal non routable IP of the device.

As a result the call comes up, but the device has an ACK timeout and drops the call.

I'm having difficulties working out how to get the contact header mangled sufficiently for the OK/ACK to contain the routable IP of the TCP device, rather than it's internal/behind NAT IP.

I've tried removing the header, using loose_route, using t_relay, and (am currently attempting) to use route(relay).

Also of relevance, is the fact that I'm running OpenSIPS on a Google Compute VM, so it's behind 1 to 1 NAT, with a non routable IP on the VM, but I have assigned a static routable IP to the 1 to 1 NAT, and I have DNS pointing to this routable IP.

Here's my config file, excluding default values/routes etc:

listen=udp:[internal VM IP]:5060
listen=tcp:[internal VM IP]:5060

disable_tcp=no

advertised_address="[DNS name]"
alias="[DNS name]"

route{
    if (src_ip != "[switch ip]"){
        # from device
        if (is_method("INVITE")) {
            fix_nated_sdp("7");
        }
        else if (is_method("OPTIONS")){
            exit;
        }

        fix_nated_contact();
        forward ("udp:[switch ip]:5060");
    }

    else if (src_ip == "[switch ip]"){
        # from switch
        if (is_method("INVITE")) {
            fix_nated_sdp("7");
        }
        else if (is_method("ACK")) {
            fix_nated_contact();
        }

        # mangle to TCP
        $du = $ru + ";transport=tcp";

        route(relay);
    }

        exit;
}

Is the issue perhaps related to the fact I'm not recording a route, so it doesn't know how to correctly route the response, or am I just missing something obvious?

Thanks,
Simon

--
Simon Quigley, Systems Engineer
Versature Corp.  |  877-498-3772 x128

Follow us on Twitter - http://twitter.com/Versature
Check out the Versature Blog - http://inside.versature.com
_______________________________________________ Users mailing list [hidden email] http://lists.opensips.org/cgi-bin/mailman/listinfo/users



--
Simon Quigley, Systems Engineer
Versature Corp.  |  877-498-3772 x128

Follow us on Twitter - http://twitter.com/Versature
Check out the Versature Blog - http://inside.versature.com



--
Simon Quigley, Systems Engineer
Versature Corp.  |  877-498-3772 x128

Follow us on Twitter - http://twitter.com/Versature
Check out the Versature Blog - http://inside.versature.com

_______________________________________________
Users mailing list
[hidden email]
http://lists.opensips.org/cgi-bin/mailman/listinfo/users



_______________________________________________
Users mailing list
[hidden email]
http://lists.opensips.org/cgi-bin/mailman/listinfo/users