akkadotnet / akka.net

Canonical actor model implementation for .NET with local + distributed actors in C# and F#.
http://getakka.net
Other
4.69k stars 1.04k forks source link

Akka.Mesh Transport #4688

Open Zetanova opened 3 years ago

Zetanova commented 3 years ago

I am investigating the possibility to implement a transport adapter for mesh networking. Feedback or ideas are welcome

What I come up with is: 1) Native support for ICE for p2p and NAT traversal https://tools.ietf.org/html/rfc8445

2) Cryptokey Routing like in wireguard/noise https://www.wireguard.com/protocol/

3) NSec as alloc free cryptokit https://github.com/ektrah/nsec

4) if UDP is used, some kind of native packet framing and packet sorting and packet-loss recover

5*) Maybe some kind of support to open a TURN/Proxy to connect to services like an DB on the remote private network

As transport address example would be: "akka.mesh://system@TrMvSoP4jYQlY6RIzBgbssQqY3vxI2Pi+y71lOWWXX0=:2552/user/myactor"

Nodes would be addressed by there pubKey and the endpoint would be transparent to akka It would be done like in wireguard, tinc, tor and lighting

With the help of ICE, It would be possible to discover the best route to other nodes or relay traffic over nodes and most of all travers NAT routers.

eaba commented 3 years ago

@Zetanova this will be nice.....I have long wished for working with with https://github.com/cjdelisle/cjdns, but having the same implemented with Akka.net will be a huge good news!

Zetanova commented 3 years ago

@eaba I am half done.

Status

Crypto routing like wireguard is working (unit tested) Anti-Reply detection without bit-shifting is working (unit tested)

Routing

Peer discovery and routing is resolved: If a node wants to connect to a mesh-address with unknown physical endpoint, it we send a small handshake_init + ICE-exchange to connected peers for relay. The flooding algo is used for now and because it is only a one-way handshakeinit, it will work well, don't think that we need more then that. https://en.wikipedia.org/wiki/Flooding(computer_networking)

Peers will always connect to each other (NAT traversal) and try to detect the best path (ICE) and could failover between endpoints (roaming) This will work for Clusters/Kubernetes and poor akka.remote nodes/clients

The only option that will not work from the start is as following: if all nodes are behind a NAT without a single global reachable remote node address for this we would need native STUN/TURN support and a global reachable STUN/TURN server like https://github.com/coturn/coturn running (like in VoIP)

Work in progress

I am currently defining the packet data in proto3 for features like in RUDP, ICE, Compression, ECN-detection, PLPMTUD

I will not implement everything from the start, but the data protocol should at least define it.

I believe that deflate or brotli for compression will have no benefit. But i found the zstd lib: https://facebook.github.io/zstd/ c# wraper: https://github.com/ImpromptuNinjas/ZStd It has dictionary support and dictionaries can be trained and retrained. But they should be a bit bigger 32kb-256KB to compress small data of ~1KB very well

@Aaronontheweb Don't know if the transport layer should support compression or maybe a separate higher layer or a transport-adapter. The problem is the size of the dictionary and how to transfer it "on demand" Best would be to load it from a side-channel ... not over the transport

My plan is that the peers will negotiate the known compression and needed dictionaries, but dont transfer the dictionary data itself. Only if we find some kind of diff operation of a retrained-dictionary it could be viable to transfer it.

Zetanova commented 3 years ago

Status Update

A version with basic features is now working. I will refactor, add more debug logging and unit tests.

It is standalone from akka.net and I will create a separate repo and an akka.net transport plugin repo for it. I need to think about a good name/namespace for it.

Its basically a hybrid of Wireguard+OnionRouting+P2P system only in application layer It requires no system rights/config beside to open at least one UDP-port.

After some integration and load tests, I will finish the rest of the features like compression, flow-control and the rest

Aaronontheweb commented 3 years ago

Sounds interesting!

Zetanova commented 3 years ago

I can only work in 1-2 weeks more on it Some Test Setup is missing to verify stability and NAT traversal

The projected is started here: https://github.com/Zetanova/PNet.Mesh