croc icon indicating copy to clipboard operation
croc copied to clipboard

webrtc for relay

Open ghost opened this issue 7 years ago • 27 comments

This is a proposal to use webrtc for relay, so that your relay can use standard webrtc approaches and ports.

This is a 100% golang implementation for webrtc. https://github.com/pions/webrtc

there are good examples shower it working and it should be relatively easy to refactor the relay and client code to use the webrtc approach.

ghost avatar Oct 25 '18 09:10 ghost

@gedw99 Thanks, what is the benefit of WebRTC? I'm not familiar with it.

schollz avatar Oct 25 '18 14:10 schollz

I, too, would like to know the advantages WebRTC would bring to croc.

Fastidious avatar Oct 31 '18 00:10 Fastidious

Hey @schollz @Fastidious I am the author of pion-WebRTC

If you used WebRTC for data-transfer you could have two users, both behind different NATs, and they would know be able to communicate without a central server. With UDP you can send/recv on your public IP and your gateway will pass through! Hole Punching

There is also a possibility of faster transfer speeds, but depends on the quality of the network connection.

If you are interested I would love to chat! I am in the gophers slack in the #pion channel. You can also PM me I am Sean-Der on there as well. We have some projects already that are using it https://github.com/maxmcd/webtty and https://github.com/rtctunnel/rtctunnel

Sean-Der avatar Nov 21 '18 09:11 Sean-Der

Came across this one today. Not the most elegant approach, but a working version.

Fastidious avatar Apr 08 '19 11:04 Fastidious

@Fastidious Awesome thanks! Its MIT, so I will fork it and work on it.

schollz avatar Apr 08 '19 14:04 schollz

There is a working prototype of this: https://github.com/schollz/croc/tree/v5

However, its buggy. It works sometimes, but not always and not for any reasons I can root out. I think it has to do with packets being dropped...but I'm not sure.

Also, when it works, its slower than using TCP sockets - up to four times slower. I'm not sure how it can be optimized. Anyways, it's there if someone wants to play with it.

schollz avatar May 03 '19 00:05 schollz

@schollz

Nice work! I would love to profile it, it is probably just exposing where Pion WebRTC falls down :) I am on a family vacation for another week, but will try to find some time!

When it doesn't work at what part do things fall down? Does it fail to connect, does it deadlock etc..?

WebRTC won't work under all network conditions (If you are behind a Symmetric NAT or UDP is blocked etc..) so there will for sure be cases where things don't work.

Sean-Der avatar May 04 '19 17:05 Sean-Der

@schollz

As @Sean-Der was talking about Webrtc works for about 80 to 90% of times without needing a rely. If you do need a WebRTC relay pion project has STUN and TURN Servers which do that for you automatically.

There are many examples out there as pion is very popular.

joeblew99 avatar Sep 04 '19 12:09 joeblew99

@schollz

We dramatically improved SCTP performance! If you have some time, would be curious what you think/see results wise with https://github.com/pion/webrtc/tree/master/examples/data-channels-flow-control

Don't want to burn your time, but I think running file transfers over WebRTC opens up a lot of stuff (especially if you are looking to hook croc up to the browser). It looks like there are other solutions, but seems really nice not having to depend on a custom backend!

thanks

Sean-Der avatar Nov 08 '19 09:11 Sean-Der

@Sean-Der Cool! Thanks for all your work, I'm looking forward to trying it out again!

schollz avatar Nov 08 '19 16:11 schollz

@Sean-Der I just tried it between two peers over internet. It's as fast as croc, without any of the multiplexing. Nice! I will definitely work on a version using webrtc using this :)

schollz avatar Nov 08 '19 17:11 schollz

That is fantastic news, I am really excited.

If anything comes up please throw it my way, would really love to see this. Having a killer Command Line <-> Browser file transfer is going to be great, especially with how easy it is to go get... croc it just can't be beat :)

thanks @schollz

Sean-Der avatar Nov 08 '19 21:11 Sean-Der

@Sean-Der Agreed. I've been waiting for certain pieces to fall into place. An efficient CLI<->browser data pipeline was one of them, and you've got that locked down nicely now :)

I've already got a good idea how to do the browser Javascript file handling (https://github.com/schollz/croc/issues/165) and I've also figured out how to bundle all my PAKE directly into Javascript using WASM (https://github.com/schollz/wasmcrypto/). I just need to re-write the relay so it uses websockets (for the initial PAKE + WebRTC offerer exchange) so its browser compatible, then it should be off and ready.

I'll be working in https://github.com/schollz/croc/tree/v7 if you want to follow along.

schollz avatar Nov 08 '19 23:11 schollz

webwormhole is a similar project that does use webrtc. I wonder how it compares in speed.

makew0rld avatar May 12 '20 19:05 makew0rld

any updates?

mishushakov avatar Sep 09 '20 17:09 mishushakov

I've been thinking about this.

A good route to go is to use webrtc like webwormhole. However, my tests show that webwormhole, between two terminals, is slower than croc (up to twice as slow), which I think is probably due to webrtc. I don't want to have a performance hit to support browsers.

An alternative method would be to add a new relay server that relays encrypted messages between a websocket client (i.e. a browser) and the relay server. The websocket relay essentially exists to convert the websocket messages to tcp packets. This way, any two partners can connect (browser to browser, terminal to browser, or terminal to terminal) using the same base relay.

Doing the latter method is not too hard, basically porting croc to wasm and transfering data over websockets.

The problem with either method is that croc needs to seek in a file to write the receieved data (blocks of data are received out-of-order). Is this possible with javascript/wasm? I couldn't figure this out.

schollz avatar Sep 09 '20 17:09 schollz

@schollz Do you know if that is SCTP over UDP performance, or bad Pion performance?

I would love to pay down tech debt and make Pion faster :)

Sean-Der avatar Sep 09 '20 18:09 Sean-Der

@Sean-Der I made a mistake -compression was turned on for croc which aids transfer. I turned off compression and then croc was only ~20% faster. I think that speed difference is due to croc's multiplexing (which boosts speed a little but not linearly related to number of parallel transfers). I'm fairly confident I can get parallel transfers going with webrtc to be just as fast (or faster?).

I think the biggest roadblock is getting a browser to be able to write blocks of data into an arbitrary location in a file. I have no idea how to do that other than storing each block in memory and rearranging it later (which won't work if you send giant files).

schollz avatar Sep 09 '20 20:09 schollz

hello everyone!

magic wormhole has similar ideas: https://magic-wormhole.readthedocs.io/en/latest/file-transfer-protocol.html#future-extensions

i think WebRTC is "natural" for this type of project as it solves problems like peering and relaying at protocol layer great read: https://webrtcforthecurious.com

thanks

mishushakov avatar Sep 09 '20 21:09 mishushakov

maybe this will solve the problem with loading files https://github.com/jimmywarting/StreamSaver.js

But there is one obstacle - The RAM it can hold and the max blob size limitation StreamSaver.js takes a different approach. Instead of saving data in client-side storage or in memory you could now actually create a writable stream directly to the file system

mishushakov avatar Sep 09 '20 21:09 mishushakov

I just need to re-write the relay so it uses websockets (for the initial PAKE + WebRTC offerer exchange)

could you explain? why websockets though?

mishushakov avatar Sep 09 '20 22:09 mishushakov

I think the biggest roadblock is getting a browser to be able to write blocks of data into an arbitrary location in a file. I have no idea how to do that other than storing each block in memory and rearranging it later (which won't work if you send giant files).

Not really. You could just have a small window buffer, which would sequentially scan over the file. If a block gets delayed, the window is held until the block arrives to maintain sequential flushing. The receiver's response would include information about which blocks from the window are missing.

hollmmax avatar Feb 18 '21 00:02 hollmmax

hi, as i gave up trying to make croc work somehow between peers on a 4G mobile network, i've been looking for webrtc p2p file sharing solutions. The idea of using webrtc as a croc relay looks like a natural evolution to me. Came upon these FOSS projects that might actually help implementing webrtc inside croc, as they use websockets for signaling as was raised here. https://github.com/subins2000/p2pt#how-does-it-work- https://github.com/subins2000/WebDrop

ihubgit avatar Apr 26 '21 13:04 ihubgit

@ihubgit https://github.com/saljam/webwormhole might be helpful. Open Source, Pure Go and has a web client as well

Sean-Der avatar Apr 26 '21 14:04 Sean-Der

ok, but advantage of the former is that it doesn't rely on a central signaling server and webwormhole's cryptos are still experimental. Looks like it's still a bit too in the early stages for me...

ihubgit avatar Apr 26 '21 16:04 ihubgit

How about something like gole (https://github.com/shawwwn/Gole)?

joepjoosten avatar Dec 29 '21 12:12 joepjoosten

I don't know how much more effort it would be to mantain, but webrtc could be made as an optional protocol instead of tcp... just to enable a transfer with no relay (current relay for croc should become a STUN/TURN server too). The use case I have in mind would be sender and receiver in the same LAN or very close geographically, and this would reduce the transfer time, and the load on the signaling server.

gitanovic avatar Mar 31 '22 13:03 gitanovic

Stale issue message

github-actions[bot] avatar Apr 05 '24 12:04 github-actions[bot]