Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature request: proxy support #427

Open
jech opened this issue Dec 11, 2024 · 3 comments
Open

Feature request: proxy support #427

jech opened this issue Dec 11, 2024 · 3 comments

Comments

@jech
Copy link
Member

jech commented Dec 11, 2024

Summary

There appears to be no way to configure the TURN client to work through an HTTP or SOCKS5 proxy, nor even over an SSH tunnel.

Motivation

While working on galene-stt, I was given access to a server with a powerful GPU. Unfortunately, the server was firewalled away from the Internet: the only ways it could communicate with the outside world were an HTTP proxy and ssh access.

The obvious solution would have been to configure Pion to use TURN over TCP over HTTP CONNECT. The other solution would have been to use the built-in SOCKS proxy of ssh. Unfortunately, there's no way to tell our TURN client to use a proxy.

Describe alternatives you've considered

I ended up hacking the client code to speak TURN over TCP over an ssh tunnel. It wasn't pretty.

Additional context

I think the right way to do that would be to have an implementation of transport.Net that uses golang.org/x/net/proxy. Not sure how the client code would request that ­— should it be honouring some environment variable, or should there be an extra option to pion.NewApi?

@rg0now
Copy link
Contributor

rg0now commented Dec 11, 2024

[Copying comment from Slack here for visibility]

My understanding is that the TURN client should work on top of anything that is a net.Conn, at least if you are using it directly (I mean, not via pion/ice.) So if you can open the ssh connection or the HTTP proxy and present it to the client as a net.Conn then you should be fine. Now of course the server should be able to decapsulate whatever tunnel you're using, so a TURN server listener should exist with a matching net.Listener.

@jech
Copy link
Member Author

jech commented Dec 11, 2024

My understanding is that the TURN client should work on top of anything that is a net.Conn

I could be wrong, but I believe that it requires a transport.Net, which is slightly more than a net.Conn.

if you are using it directly (I mean, not via pion/ice.)

The goal is to be able to use a proxy with an application that uses pion/turn through pion/ice through pion/webrtc.

@rg0now
Copy link
Contributor

rg0now commented Dec 12, 2024

[Update: removed silly idea]

I could be wrong, but I believe that it requires a transport.Net, which is slightly more than a net.Conn.

Sure, but isn't it the case that transport.Net is only needed if you want a relay connection over TCP? That is, you connect to the TURN server on TCP and make the TURN server forward the connection to the peer over TCP too as per RFC6062. But this will not work with pion's TURN server anyway until #315 is merged. If you're using the "standard" RFC5766/RFC8656 UDP relay connections (i.e., client->server over any transport, server->peer over UDP) then you can get away without a transport.Net. Just open a net.PacketConn using your selected transport and use that to create the TURN client and things should work fine.

But I agree that passing a transport.Net would be the right way to let the caller specify whatever transport they want. The only problem is that as per the above this will only affect TCP relay connections (i.e., the ones created using client.AllocateTCP) but not the "standard" UDP relay connections (i.e., the ones created using client.Allocate()). This is because the latter expects you to pass in a net.PacketConn but the former may need to create new TCP connections behind our back and hence needs the extended functionality from transport.Net.

BTW it would be nice to remove this inconsistency in the client:
1. if Conn is set in the ClientConfig but Net is not then use the user's net.PacketConn to run UDP allocations and use net.StdNet for TCP allocations;
2. if Net is specified then use that to create the client's net.PacketConn internally both for client.Allocate and client.AllocateTCP instead of using whatever is passed in Conn in by the user for the former;
3. if neither is set then fall back to net.StdNet and go to 2.

Is it worth creating an issue for this, WDYT?

The goal is to be able to use a proxy with an application that uses pion/turn through pion/ice through pion/webrtc.

Given that we seem to be having a solid understanding of how to do what you want using the existing pion/turn client, what remains to be done is to modify pion/ice, no? Maybe the next step would be to reopen this issue there?

For the record, ice.NewAgent seems to take a transport.Net, can we use this?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

No branches or pull requests

2 participants