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

KCP transport (reliable UDP) #193

Closed
ghost opened this issue May 14, 2017 · 14 comments
Closed

KCP transport (reliable UDP) #193

ghost opened this issue May 14, 2017 · 14 comments
Labels
help wanted Seeking public contribution on this issue need/community-input Needs input from the wider community

Comments

@ghost
Copy link

ghost commented May 14, 2017

Let's check it out:

https://github.com/xtaci/kcp-go

kcp-go is a Production-Grade Reliable-UDP library for golang.

It provides fast, ordered and error-checked delivery of streams over UDP packets, has been well tested with opensource project kcptun. Millions of devices(from low-end MIPS routers to high-end servers) are running with kcp-go at present, including applications like online games, live broadcasting, file synchronization and network acceleration.

  1. Optimized for Realtime Multiplayer Games, Audio/Video Streaming.
  2. Compatible with skywind3000's C version with language specific optimizations.
  3. Cache friendly and Memory optimized design, offers extremely High Performance core.
  4. Compatible with net.Conn and net.Listener, easy to use.
  5. FEC(Forward Error Correction) Support with Reed-Solomon Codes
  6. Packet level encryption support with AES, TEA, 3DES, Blowfish, Cast5, Salsa20, etc. in CFB mode.
  7. O(1) goroutines created for the entire server application, minimized goroutine context switch.

It's used by Lantern and Syncthing among others

@ghost ghost added need/community-input Needs input from the wider community help wanted Seeking public contribution on this issue labels May 14, 2017
@whyrusleeping
Copy link
Contributor

Yeah, i'd love to try this out. Should be fairly simple to plug it in

@whyrusleeping
Copy link
Contributor

They also have a multiplexer: https://github.com/xtaci/smux

@whyrusleeping
Copy link
Contributor

Easy enough to plug the muxer in, it passes our test suite too: https://github.com/whyrusleeping/go-smux-smux

@whyrusleeping
Copy link
Contributor

Only rough part of plugging kcp in seems to be that their net.Addr method isnt quite compliant, it just returns a udp addr. So i may have to fork it and change that

@daviddias
Copy link
Member

daviddias commented Aug 19, 2017

Oh wow, this looks sweet! https://github.com/xtaci/smux. I like this team, they modularize things! //cc @Stebalien

@Stebalien
Copy link
Member

Ooh nice! Personally, I wouldn't bother with KCP given that QUIC is around the corner (unless QUIC doesn't work out) but their SMUX library looks great and can be used over TCP.

@paralin
Copy link
Contributor

paralin commented Dec 28, 2017

I have finished my KCP transport implementation, it uses smux to basically build a mock-tcp connection. From my initial tests with even the default configs the performance is quite impressive.

https://github.com/paralin/go-libp2p-kcp

I replicated the echo example, with GRPC over the connection as a bonus (so, UDP[KCP[SMUX[GRPC]]]).

https://github.com/paralin/go-libp2p-grpc

@whyrusleeping
Copy link
Contributor

@paralin Hey! Great work there. A couple things:

  • Not sure why the smux package is used in the transport itself, we can have that separately as a muxer package. KCP is reliable on its own, right?
  • It would be really great to be able to dial out using the same socket we listen on. This would save a ton of file descriptors. As implemented, each dial would create a new socket. Not sure if kcp lets us do this, but we were able to with utp
  • We should start looking at using plugins to add transports to libp2p without having to rebuild ipfs.

@paralin
Copy link
Contributor

paralin commented Jan 1, 2018

@whyrusleeping Not sure why, but without smux in place libp2p wouldn't work at all over KCP. I suspected it was because: "Control messages like SYN/FIN/RST in TCP are not defined in KCP, you need some keepalive/heartbeat mechanism in the application-level." For this reason I believe we need some kind of SYN/ACK in the transport level, although we really shouldn't need it. I just haven't had a chance yet to write any tests to figure out the issue.

We can pass a PacketConn to KCP, so establishing a socket dialing out with SO_REUSE should be fine.

In terms of plugins this should be easy with the existing interfaces and the Go plugin mechanism.

@whyrusleeping
Copy link
Contributor

whyrusleeping commented Jan 1, 2018 via email

@whyrusleeping
Copy link
Contributor

@paralin Do you think you could take a look at adding a Libp2pTransportPlugin to ipfs?

Right now we just have IpldPlugins: https://github.com/ipfs/go-ipfs/blob/master/plugin/loader/initializer.go#L21
But we're working on adding a new set of plugins for turning logs into execution traces: ipfs/kubo#4506

The tricky part here is that we would likely have to have some global DefaultTransports array in libp2p that the plugin would append to, then the libp2p constructor would need to use those.

If you don't have time or don't want to, no worries, I figured I would ask here anyways, and someone else could pick it up :)

@paralin
Copy link
Contributor

paralin commented Jan 9, 2018

I'd be happy to, but I'm a bit busy at the moment so it'll be a little while.

@paralin
Copy link
Contributor

paralin commented Jan 17, 2018

@whyrusleeping Please have a look at paralin/go-libp2p-kcp#1 re/KCP integration with reusable UDP file descriptors (assuming the CC didn't send you a notification).

@Stebalien
Copy link
Member

(QUIC has shipped)

marten-seemann pushed a commit that referenced this issue Apr 21, 2022
don't expire backoffs until 2x backoff period
marten-seemann added a commit that referenced this issue Apr 22, 2022
compress qlogs when the QUIC connection is closed
marten-seemann added a commit that referenced this issue Aug 9, 2022
move AddrList to pstoremen, unexport it
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
help wanted Seeking public contribution on this issue need/community-input Needs input from the wider community
Projects
None yet
Development

No branches or pull requests

4 participants