ipfs / kubo

An IPFS implementation in Go
https://docs.ipfs.tech/how-to/command-line-quick-start/
Other
15.93k stars 2.98k forks source link

`ipfs p2p` feedback thread #3994

Open whyrusleeping opened 7 years ago

whyrusleeping commented 7 years ago

For everyone trying out the ipfs p2p command, please add any and all feedback here, this includes (but is not limited to) bugs, opinions, interface critiques, potential usecases, and feature requests.

To enable the command, you will need to run: ipfs config --json Experimental.Libp2pStreamMounting true And restart your daemon.

Basic usage of ipfs p2p is as follows:

First, open up a p2p listener on one ipfs node: p2p listener open p2p-test /ip4/127.0.0.1/tcp/10101 This will create a libp2p protocol handler for a protocol named p2p-test and then open up a tcp socket locally on port 10101. Your application can now connect to that port to interact with the service.

On the other ipfs node, connect to the listener on node A ipfsi 1 p2p stream dial $NODE_A_PEERID p2p-test /ip4/127.0.0.1/tcp/10102 Now the ipfs nodes are connected to eachother. This command also created another tcp socket for the other end of your application to connect to. Once the other end connects to that socket, both sides of your application should be able to communicate, with their traffic being routed through libp2p.

The easiest way to try this out is with netcat.

by @magik6k: The feature is getting refactored in some breaking ways. For updated guide see https://github.com/ipfs/go-ipfs/blob/4bafbf1cdef7d6d0041154ee03efb02f2ef0685b/docs/experimental-features.md#ipfs-p2p.

What changed: https://github.com/ipfs/go-ipfs/issues/3994#issuecomment-394159058

magik6k commented 7 years ago

What I noticed missing from one of the earlier PRs is the ability to tell to which peer connected to a listener. Earlier PRs had a switch that caused ipfs to send <PeerID>\n at the beginning of each incoming stream. This should be pretty simple to implement.

ReisenB commented 7 years ago

Is this planned to be accessible through the browser with js-ipfs-api?

whyrusleeping commented 7 years ago

Unfortunately no, you could set up the listeners from the browser, but you couldn't actually connect to it since you can't dial TCP connections there. Unless... @Magik6k could you specify a /ws multiaddr for the listeners?

On Wed, Jun 28, 2017, 05:22 ReisenB notifications@github.com wrote:

Is this planned to be accessible through the browser with js-ipfs-api?

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/ipfs/go-ipfs/issues/3994#issuecomment-311605346, or mute the thread https://github.com/notifications/unsubscribe-auth/ABL4HDTg_Rqp6Rg4nUp69-AhryuOL3O2ks5sIhs8gaJpZM4N-zsb .

magik6k commented 7 years ago

I'd need to look into how websockets are currently handled in go-ipfs. For dialing this should be relatively simple to do, though listen mode would probably have to use some sort of stream muxer that has js implementation. This should fit quite well into the existing code.

jdgcs commented 6 years ago

No opening port 10101, is that right?

liu@nas:~/ipfs/go-ipfs % ./ipfs p2p listener open p2p-test /ip4/127.0.0.1/tcp/10101

{"Address":"/ip4/127.0.0.1/tcp/10101","Protocol":"/p2p/p2p-test"}

liu@nas:~/ipfs/go-ipfs % ./ipfs p2p listener ls

/ip4/127.0.0.1/tcp/10101 /p2p/p2p-test

liu@nas:~/ipfs/go-ipfs % netstat -an | grep 10101

liu@nas:~/ipfs/go-ipfs %

magik6k commented 6 years ago

This creates listening libp2p handler and when p2p connection is incoming it(ipfs daemon) then opens a tcp connection to a given address and proxies the data. This seems counterintutive at first, but it allows for transparent connection proxying over libp2p

origama commented 6 years ago

It would be nice to be able to set the listeners in the config file, so that the daemon could create them at booting time. It makes sense especially if you run IPFS as an init/systemd/docker unit.

magik6k commented 6 years ago

I don't think using config for that is a good idea. What may work is extracting whole ipfs p2p into a separate program as it doesn't really fit ipfs (imo), this program could then talk to ipfs daemon and reuse its libp2p instance or be standalone.

origama commented 6 years ago

And adding up to my previous comment, I noticed a different behavior between the listener and the streamer.

Considering the case in which you start a listener for the protocol ipfs-test on peerA attached to the local port 80, and then you start a streamer on peerB to connect to peerA[ipfs-test] and listening on his local port 8080.

Now, with this setup, no matter if the streamer will disconnect or if the service on port 80 on peerA will die, the listener will still be up and running.

The streamer instead dies after whatever client running on peerB disconnects from port 8080.

Maybe it's expected, but it would be nice to have the streamer keep listening for more than one connection, or at least having a parameter (like a sort of nc -k), and maybe a config entry for this too.

magik6k commented 6 years ago

https://github.com/ipfs/go-ipfs/pull/4929 includes api-breaking changes, it will likely be released with the new version of go-ipfs.

EDIT: This changed a bit while the PR was open, this is the current version:

For updated how-to see https://github.com/ipfs/go-ipfs/blob/b84c386124441c1ecf261d7c4dbbc72112632299/docs/experimental-features.md#ipfs-p2p

What changes:

DavidHuie commented 6 years ago

@magik6k what's stopping ipfs p2p from supporting UDP?

magik6k commented 6 years ago

With #4929 you will be able to pass streams to udp services. You still won't be able to listen for udp connections as local listener uses go-multiaddr-net.Listen directly, and it only supports listening on tcp now.

There are some problems with supporting udp properly:

DavidHuie commented 6 years ago

@magik6k Is that something that you guys are open to having the community implement?

I'm designing a system that uses IPFS to create a peer-to-peer VPN. All of the VPN protocols I'm considering use UDP since TCP is implemented at a higher level networking stack.

DavidHuie commented 6 years ago

Also, net.Conn in Go implements UDP connections as streams, so it wouldn't be a terrible way to implement that...

whyrusleeping commented 6 years ago

@DavidHuie We're definitely open to having the community help there. It's something that will be tricky to get right, adding a message oriented layer to libp2p won't be trivial. If you want to get the ball rolling, open an issue in libp2p/libp2p about it, describe use cases, and tag people. We can start to brainstorm thoughts there.

I know that @lgierth was planning on working on that soon, he's out on vacation for another week or so. When he gets back maybe you two can work on pushing that?

Stebalien commented 5 years ago

The refactor has been merged (massive thanks to @magik6k for keeping with this). Go pull master and try it out.

Mikaela commented 5 years ago

Is it possible (or planned) to use this feature as a reverse proxy?

I am thinking of https://github.com/FruitieX/teleirc/issues/262 which is a Telegram/IRC relaybot and it includes HTTP server for Telegram file uploads / multimedia. I guess using it that way would lose a lot of advatages of the bot directly supporting IPFS though, unless the reverse proxy could add content by itself and the gateways cached or deduplicated it behind the scenes even if the filename kept changing.

magik6k commented 5 years ago

It is possible to use this as a reverse proxy, but it will just pass the stream without really caring what's inside.

We also have a separate http proxy feature - https://github.com/ipfs/go-ipfs/blob/master/docs/experimental-features.md#p2p-http-proxy, it doesn't handle caching either, but (with some special header magic) it should be possible to implementet this.

bojidar-bg commented 9 months ago

Not sure if this issue is still the place for bugs and feedback on ipfs p2p, but using it for a project, I was surprised that half-closing a forwarded TCP socket closes the whole stream. Don't have a minimal example lying around anymore, but from what I managed to intuit, this piece of code tears down the whole connection as soon as either half of the socket is closed, e.g. with Go's TCPConn.CloseWrite.

Also, from experimentation, it seems that p2p does not support local-to-local connections (when passing the local peer's address as a target address), which makes quick testing setups needlessly convoluted.