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

Messaging layer #71

Open
DavidHuie opened this issue Jun 8, 2018 · 6 comments
Open

Messaging layer #71

DavidHuie opened this issue Jun 8, 2018 · 6 comments

Comments

@DavidHuie
Copy link

DavidHuie commented Jun 8, 2018

This issue is aimed at getting discussion started around designing a messaging layer for libp2p. The messaging layer is for encapsulating unreliable transports, like UDP, along with other use cases.

Specifically, I want to use IPFS in order to provide p2p networking for VPN traffic, which is usually implemented over UDP. It is possible to use other transports, although wasteful since TCP is usually also implemented within the networking stack the VPN encapsulates.

We discussed this a bit in ipfs/kubo#3994

From @magik6k:

There are some problems with supporting udp properly:

  • Need to track connections if we want 2-way communication (this isn't that hard, maybe slightly harder if one wants this to be any fast)
  • Libp2p** operates on streams, udp is message oriented. There are 2 ways to solve this:
  • wrap udp packets into messages (basically size+data piped into stream)
    • IMO the wrong way to do this
  • give libp2p the concept of messages
    • There are some plans for message oriented (+unreliable) transports/muxers
      • Can't find any specific issue
    • This would be ideal for udp
    • Also, useful in other parts of libp2p.

cc: @whyrusleeping @magik6k @lgierth

@whyrusleeping
Copy link
Contributor

also cc @Stebalien @diasdavid @bigs @mgoelzer @miyazono

This is a pretty big thing that could have a significant impact on the overall performance of protocols implemented on top of libp2p.

Within message based systems, the main 'choice' to make it reliable vs unreliable. The nice thing though, is that the interfaces shouldnt change between the two, meaning we could bootstrap the interfaces for packet based communications on top of tcp (many ipfs protocols are really just sending messages around), then add in the option later for 'unreliable' backends.

The other thing to consider, is transport security. Libp2p requires that all communications are encrypted peer to peer, so we need a workable encryption scheme (and method for negotiating this, really). Wireguard should work, and we've been meaning to investigate that.

@magik6k
Copy link

magik6k commented Jun 11, 2018

One thing to note with wireguard is that is would require us to switch to ed25519 keys (which afaik is something we want to do anyway, so there is yet another reason to do that)

https://www.wireguard.com/protocol/#key-exchange-and-data-packets

@DavidHuie
Copy link
Author

Wireguard is implemented as a Linux kernel space module, so using it plainly would break libp2p's multi-platform ability. Would we just be using its transport protocol?

It's funny that you guys bring that up, because my VPN project creates a Wireguard mesh network using IPFS for the p2p networking layer. If secure messages were already provided by IPFS, the VPN layer becomes much simpler.

@whyrusleeping
Copy link
Contributor

@DavidHuie wireguard is just a protocol. There is a go implementation IIRC, and we would likely just use that to wrap an 'unencrypted packet transport'. should work just fine cross platform.

On specific platforms would could have optimizations using kernel modules though.

@ghost
Copy link

ghost commented Jun 20, 2018

The recently merged transports changes (libp2p/go-libp2p#297 ❤️) have made packet/message stuff significantly easier to reason about. Packet mode can be just another feature of a transport. The transport can support it natively (e.g. UDP or Ethernet), or can gain it by getting passed an upgrader which puts packets into frames on a stream.

The ReadFrom/WriteTo functions should probably live on the Conn interface? After all we do have to shake crypto-hands before doing anything, so it makes sense to represent this state as a connection (also means less stuff to add of course.)

An important thing that we have yet to design is the packet-mode equivalent of multistream - something that lets us negotiate protocols and multiplex them into a single packet connection. There's a very old draft branch of multigram here: https://github.com/multiformats/multigram/tree/draft1

@DavidHuie wireguard is just a protocol. There is a go implementation IIRC, and we would likely just use that to wrap an 'unencrypted packet transport'. should work just fine cross platform.

Yes there's in fact implementations in Rust and JS too. I have only looked at the Go impl, it's pretty badly coupled to the networking and CLI parts, but with a bit of refactoring it looks perfectly usable to me. (/me LOVES wireguard)

@patrickmn
Copy link

I'd like to raise another hand for WireGuard. It's very well designed. Linus Torvalds recently called it a "work of art" (compared to OpenVPN and IPSec). And yeah, the kernel mode aspect is a bit tricky, but as @whyrusleeping noted, there are a indeed a few userspace implementations in early development.

I found this thread because I was looking at secio and I was wondering if anyone had tried to implement a middleware using the Noise Protocol Framework, the framework that underlies WireGuard, Signal, WhatsApp, and, apparently, Lightning. I couldn't find any and am trying to decide if I should take a stab at implementing them.

Great intro by its author, Trevor Perrin: https://www.youtube.com/watch?v=3gipxdJ22iM

There are Noise libraries in Go, Rust and JS/Wasm.

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

No branches or pull requests

4 participants