schollz / croc

Easily and securely send things from one computer to another :crocodile: :package:
https://schollz.com/software/croc6
MIT License
27.11k stars 1.09k forks source link

Peer-to-Peer (P2P) #481

Closed Snake883 closed 2 months ago

Snake883 commented 2 years ago

Is your feature request related to a problem? Please describe. Do not want to use a relay for Internet transfers. Don't want to use a public relay, don't want to pay somebody, don't want the complexity of setting up a private relay node.

Describe the solution you'd like Would like to use P2P rather than a public relay, or setting up a private relay.

schollz commented 2 years ago

https://github.com/schollz/croc#self-host-relay

Snake883 commented 2 years ago

Is it possible to transfer not using a relay?

In P2P, is there an advantage of using a relay if the relay is the same person as either the sender/receiver?

sawft99 commented 2 years ago

I don't see how this would be realistically doable. These are very different protocols and architectures. This would be like trying to make a torrent client into a web browser. If anything that's an unequal comparison since p2p and croc are more complex than just http and TCP.

P2P has an overlaying virtual network to connect people through the internet and firewalls. Croc acts as a relay with an architecture also on top of TCP in addition to crypto operations to accomplish a similar goal. The two couldn't be more different though.

The backbone of Croc relies on relays to facilitate its connections. While p2p is obviously used without any kind of relays. The only time a central server may come into play is if there is a tracker server. If you're trying to add p2p and end up using a tracker server as well then at that point why not just use one of the many torrent apps that are already made for that? This is trying to add functionality for something that is almost the opposite of croc entirely.

Croc fills a unique hole as it stands. Turning it into basically a torrent client and adding tracking servers is overly complex (IMO) and unnecessary since there are numerous long standing p2p clients that accomplish this.

But I could be wrong. Someone may completely redesign the app from almost the ground up and abandon all other issues and feature requests to do something that's already been done numerous times. Something that, if it were actually created, would be just stable enough in a 1.0 version to run while competing against other apps that have been flushed out over decades.

TudbuT commented 1 year ago

You might want to look at qft if you want a direct P2P transfer.

stefins commented 1 year ago

This is an interesting article about NAT traversal https://tailscale.com/blog/how-nat-traversal-works/ .

TheFiZi commented 1 year ago

I wonder if a compromise might work. What about having the option to configure the relay similar to how qft does things.

You can either run a full croc relay (the way it currently works) or a lite croc relay that only facilitates nat hole punching?

Or better yet, the relay tries hole punching first for a P2P connection and then falls back to how it works now?

It doesn't solve the "not wanting to run a relay" problem but it does potentially reduce load on relays and increase privacy when using the public relays since only connection metadata would be captured in P2P mode and absolutely nothing about the actual transfer.

Could also make it so if you've forwarded ports to your PC you can run croc in standalone p2p mode where you specify your listening port which is pretty much what qft appears to do. Requires more knowledge on the end users end to setup port forwarding correctly on their firewall though.

danielrode commented 1 year ago

Would libp2p be useful for this endeavor?

Katzenwerfer commented 1 year ago

Wonder if anything has been though about this. I have the feeling that it would save a lot on costs and bandwidth of hosting a relay.

k-aito commented 9 months ago

Hello,

I was talking with a few friends and one use that could be amazing is a way to support sending to multiple peoples. I think it's still 1 -> 1 right now.

I don't think it would be something really easy to implement but maybe... The easiest solution would be to use a torrent and public tracker but there will be some trouble about opening the right port that can be avoided with croc for now.

github-actions[bot] commented 5 months ago

Stale issue message

derhuerst commented 5 months ago

not stale!

github-actions[bot] commented 3 months ago

Stale issue message

derhuerst commented 3 months ago

still not stale!

schollz commented 2 months ago

@derhuerst why not?

schollz commented 2 months ago

I forked this repo to do experiments with peer-to-peer UDP nat hole punching.

it works.

however, it is so so slow. I can initially get speeds of about 2 MB/s but after about a minute it drops below 0.2 MB/s.

anyone can try my experiment:

# server with public ip PUBLICIP
git clone https://github.com/schollz/go-udp-holepunch && cd go-udp*
go build -v && ./hp s :9595

# client 1 (sender)
git clone https://github.com/schollz/go-udp-holepunch && cd go-udp*
go build -v && ./hp c PUBLICIP:9595 :4546 sender

# client 2 (receiver)
git clone https://github.com/schollz/go-udp-holepunch && cd go-udp*
go build -v && ./hp c PUBLICIP:9595 :4546 receiver

sure, the multiplexing tricks may work here to get more bandwidth. but the slow down after a minute is really concerning for any large file. it means that there would need to be tons of logic to possible close/reopen new fresh ports to reinstate a high-quality connection.

also the other huge concern is that in my experiment I'm sending random bytes at exactly 5 MB/sec but they are only received at (max) 2 MB/s, which means there is huge packet loss happening. so any solution using these methods would essentially have to provide TCP over UDP which basically means redundancy, which basically means that all the measurements from UDP hole punching experiments are likely much better than what can be achieved with TCP.