securesocketfunneling / ssf

Secure Socket Funneling - Network tool and toolkit - TCP and UDP port forwarding, SOCKS proxy, remote shell, standalone and cross platform
https://securesocketfunneling.github.io/ssf/
Other
1.59k stars 234 forks source link

RTSP proxy #22

Open ckhung opened 8 years ago

ckhung commented 8 years ago

I have vlc streaming webcam at computer CX: cvlc v4l2:// :v4l-vdev=/dev/video0 :input-slave=alsa:// :sout='#transcode{vcodec=mjpg,acodec=vorbis} : rtp{sdp=rtsp://:5780/tv}' At CX I run ssfs

At computer CY I run: ssfc -L 8180:localhost:5780 -U 8180:localhost:5780 CX

From CY I can play the stream at CX directly, no problem: ffplay rtsp://CX:5780/tv However if I use the forward port: ffplay rtsp://localhost:8180/tv it fails to play. Both ssfc and ssfs prints "session[forwarder]: start" but ffplay (from the ffmpeg package) says: "UDP timeout, retrying with TCP".

Did I do something wrong? If you work it out, can you please add it to the HOWTO document?

My CX is running lubuntu 15.04 and CY is running lubuntu 16.04 .

securesocketfunneling commented 8 years ago

Labeled as bug at the moment.

We are going to reproduce your use case and make some tests.

securesocketfunneling commented 8 years ago

RTSP does dynamic UDP port negotiation on client connection. As a result, the forwarding must be done on the negotiated ports and not on 5780.

As a workaround, it seems that VLC has an option to force the destination and port for streaming :

cvlc v4l2:// :v4l-vdev=/dev/video0 :input-slave=alsa:// :sout='#transcode{vcodec=mjpg,acodec=vorbis} : rtp{dst=127.0.0.1,port=5780}'

Then, you must do remote UDP port forwarding to forward remote port 5780 to localhost:8180:

ssfc -V 5780:localhost:8180 CX

We didn't try it with ffplay but it seems to work with VLC client. Can you confirm ?

ffplay command line should be something like:

ffplay rtp://localhost:8180

[update: replace UDP port forwarding with remote UDP port forwarding]

ckhung commented 8 years ago

Thanks for quick help!

Sorry, I am not following why it should be remote forwarding but anyway I set things up as you suggested, and then vlc rtp://localhost:8180 at CY. I got this error message in the terminal:

VLC media player 2.2.2 Weatherwax (revision 2.2.2-0-g6259d80)
[0000000002586178] core libvlc: Running vlc with the default interface. Use 'cvlc' to use vlc without interface.
[00007f2e08000e88] rtp demux error: unspecified payload format (type 96)
[00007f2e08000e88] rtp demux: A valid SDP is needed to parse this RTP stream.

plus this message in the graphic window

SDP required:
A description in SDP format is required to receive the RTP stream. Note that rtp:// URIs cannot work with dynamic RTP payload format (96).

The ssfc terminal at CY does not print anything upon that command.

Additionally I am also confused about rtp and rtsp :-) rtp only transports the content, right? So I guess on CX we also need to specify mux on the vlc command line, no?

Finally I should mention that my original intention was to forward the rtsp stream generated by https://f-droid.org/repository/browse/?fdid=net.majorkernelpanic.spydroid on my old android phone. It's not as flexible as vlc and therefore I have to stick with rtsp:// and not rtp:// (whatever that means). However if the rtsp protocol has this inherent uncertainty that renders tunneling unworkable, then please go ahead and close this issue. (Would be nice to mention that or link to this in the documents.)

securesocketfunneling commented 8 years ago

I am not following why it should be remote forwarding

Because in that use case, we are waiting data from CX on localhost:8180. Remote forwarding says: all UDP packets to localhost:5780 of CX are forwarded to localhost:8180 CY.

Additionally I am also confused about rtp and rtsp :-) rtp only transports the content, right? So I guess on CX we also need to specify mux on the vlc command line, no?

Yes, you are right. I specified mux on the cvlc command line and it was vlc udp://localhost:8180 on the client side. Sorry, I wasn't focused when writing my answer.

if the rtsp protocol has this inherent uncertainty that renders tunneling unworkable, then please go ahead and close this issue. (Would be nice to mention that or link to this in the documents.)

It could be great to implement some sort of RTSP proxy in our project. We have all the base components (TCP forwarder, UDP forward, HTTP parser), it is all about assembling and parsing RTSP requests. We do not have the time to work on it right now but it is a good feature proposal.

lars18th commented 8 years ago

Hi,

I'm also involved on other projects using RTSP. So here some recomendations:

I have vlc streaming webcam at computer CX:

Here are THREE different protocols involved:

So, for forwarding a RTSP communication over SFF you need to do:

With this, if you have sufficient bandwith for the UDP transport the connection should work.

It could be great to implement some sort of RTSP proxy in our project

I suggest to assign resources to other functions (like SSF over Socks proxy, and enable/disable encryption), as the only requerement for support RTSP over SSF is that the client uses fixed (or known) udp ports. Perhaps, the support for PORT RANGE, instead of redirecting a single port, can be also useful. Several RTSP clients can define a range of ports, like 50000-50100, and if you can remap this range is sufficient for acting as a proxy.

I hope this helps!

lars18th commented 8 years ago

Hi @securesocketfunneling !

What about supporting "PORT RANGE redirections"?

I think is a great idea and simple to implement... obviously with a limit, as it's very complicated to open hundred of sockets for listening. I suggest to limit the range to 5 or 10 ports max.

Regards!

securesocketfunneling commented 8 years ago

Hey @lars18th !

Multiple port redirection is already possible (e.g. multiple -L or -R options) so create a port range option could be added at nearly no cost indeed. It is not a priority right now as the feature consists only of declaring multiple existing options but creating an issue for this is free :-)

lars18th commented 8 years ago

Hi @securesocketfunneling ,

I know, and there is no limit about the number of redirections. Also multiple declarations are possible. However, it's really verbose to set a range of 5-6 udp consecutive ports for redirection... Futhermore, for implement it, as you say is quite simple (is only parsing the parameter and execute one loop). For example, the command line can be:

-U [ --udp-forward ] [[loc_ip]:]loc_port:dest_ip:dest_port
-U [ --udp-forward ] [[loc_ip_start-loc_ip_end]:]loc_port:dest_ip:dest_port

The port range at destination is derived from the local; and the character "-" is used for declare the range.

You agree?

lars18th commented 6 years ago

Hi,

Any improvement in add "port range redirections"? Example:

-U 0.0.0.0:50000-50010:192.168.100.1:40000-40010

I know, this can be dangerous... as each port in the range it's a new listening port. So, a range of 100 ports are 100 listening sockets. A lot!

However, you can consider this other "safe" format:

-U 0.0.0.0:50000+2:192.168.100.1:40000

This "+2" instruct to use two more consecutive ports (so listening in 50000, 50001 and 50002). So the format be "loc_port[+N]". And you can limit the N to a low number (for example up to 5 or 9). This will simplifies the use of UDP protocols that use more than one port (for example RTP with 2 or 4 streams).

Please, consider it. Regards.