-
Notifications
You must be signed in to change notification settings - Fork 86
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
Request for Guidance: Implementing an Abstract Transport Layer to Support Both TCP/UDP and QUIC #277
Comments
BitTorrent doesn't work over QUIC, why would you want to add support for it? As for abstracting away transport, it already is for stream protocols (TCP, TCP over SOCKS5). It was done just for socks, but extending to support smth like QUIC should be very easy - all you need is implement connect(), AsyncRead and AsyncWrite. But the real benefit for rqbit would be to add support for uTP, but the current abstraction isn't enough for it - you need to implement congestion control and other parts of uTP. |
I think there are advantages in using QUIC μTP Does not natively include encryption. Typically relies on the application layer or external protocols like TLS for security. Congestion control algorithms are more advanced in QUIC. μTP Optimized for low latency in congested networks. Other p2p solutions are using QUIC like Iroh and lubp2p. |
We might try to support μTP too and have some benchmarks. |
@ikatson why is that? as μTP already supports that. |
I don't understand what rqbit (a torrent client!) has to do with QUIC. Sure you can add QUIC but what's the point if the bit torrent network doesn't support it? If it supported QUIC there would be a design doc (BEP) that would explain how does it integrate into existing network. |
@ikatson I think the original question was not formulated ok. We are working on https://github.com/radumarias/rfs and we want to use BitTorrent to sync files between our internal nodes. So our plan is to have a BitTorrent custom client + protocol to make the transfer over UDP, again, just between our internal nodes, this will not communicate with other BitTorrent clients. You mentioned above that QUIC would be easy to integrate, this is good for us then. |
Given uTP is in the BitTorrent protocol we would like to add it to rqbit because it will benefit to be able to communicate with other standard implementation clients which have this. And it will fallback to TCP with clients that don't support it. Nowadays most of the BitTorrent clients supports it. But can you tell us why it would be harder to add compared to QUIC and can you give us some guidance on how to add it? The support for QUIC we will add just in out internal fork just for internal use. We olan to extend that a bit more and use Iroh actually, not even QUIC directly, because Iroh has an internal DHT which we need because we need internal one in our case, we can't use public DHT and trackers as files need to remain private in our cluster. Another approach for us, which makes more sense now, is to first add support for uTP, as our initial goal was to have BitTorrent over UDP, we didn't know that uTP is actually in the protocol, if we did this would gave been out first approach, and we just use Iroh for DHT. |
I was wrong - it should be similar in effort. I glossed over BEP 29 (uTP) to double-check - in my memory it changed the operation of the BitTorrent protocol itself, so leaked from transport to application layer. But it doesn't seem to be the case. So as long as this transport can be made AsyncRead + AsyncWrite - the changes should be minimal. You just change this "connect() -> Box" to return smth different than it does, and none of the internals (which operate over bittorrent application layer) will need to be changed. |
thanks @ikatson . can we crate an issue here do add the support for uTP? |
of course @radumarias , feel free to create an issue and mention that you're planning to do it |
@anchalshivank please do that and work on it, thanks |
Hi guys we are using uTP as well for our protocol https://github.com/ethereum/utp @ikatson are you planning to build your own implementation? I think there would be value in building 1 very good implementation we could all use |
@KolbyML I wasn't planning to, unless it's simple. Which it isn't :D Your library says "This library is currently unstable, with known issues. Use at your own discretion." |
We are about to bring https://github.com/ethereum/trin into production this year so I would say our uTP implementation must become production ready as well. Currently my focus on The only known issue is a connection can only send a maximum of ~50 MB (conservatively speaking), which would be fixed if we implemented this todo https://github.com/ethereum/utp/blob/d894487d80a650bffd9e511fd9071b05c1ddb40d/src/sent.rs#L361 or in other words the library can only send a maximum of u16/2^16 packets a connection due to us not properly handling the ack window rolling over |
@KolbyML I was just trying to hack together a PoC of using your lib in librqbit, faced a couple challenges:
#1 is by far the more important one which makes it seemingly impossible to use in librqbit in its current state. But if UtpStream is blocked on reading, we can't write anything to it. Is there something I'm missing? |
@ikatson @KolbyML we have this implementation made by @anchalshivank https://github.com/anchalshivank/rfs-utp which we plan to integrate in the client and have it as a separate crate too.
We have this kind of impl https://github.com/anchalshivank/rfs-utp/blob/main/src/udp_stream.rs#L247 I guess we can address 1. too with our UtpStream, @anchalshivank could you please add your thoughts on this? The impl is functional and it's fully async, just we need to do some more tests and small changes, but @anchalshivank please comment more. Do you gyus think we should collaborate maybe in merging these two into a better impl and use that? |
We use uTP in a non-standard way as we don't use it directly on UDP, but instead tunnel it in another protocol which negotiates connections which gives us a connection_id to use. I don't think you are missing anything and we should resolve the issues you outlined. We use a different interface due to our different usecase, I am of the belief we should support the standard interface you need. We just haven't had someone use our library in a standard way yet so the api isn't fleshed out properly. We would love your feedback |
@radumarias that's cool, thanks for the update. I own no uTP libs, so I can't recommend solutions on merging. But from what it looks like the impl in "rfs-utp" suits librqbit better at least from the API surface. Inside however looks like it's using tokio::spawn and channels which might limit perf in theory. Time will tell. @anchalshivank @radumarias If your lib is ready to go, we can test that and add as an experimental optional feature. As Streams are core to (lib)rqbit, I wouldn't make it enabled by default until time shows it's stable and performant. And even then, I'm sure TCP will be faster, so I'd use uTP only as fallback if we can't connect at all over TCP to a peer. |
Our implementation is async as well, supporting I would be very interested in collaborating to build the best uTP implementation possible. The way I see it is 2 people working on 1 implementation is likely to be better then 2 people working on 2 separate implementations in terms of testing, performance, etc. |
If you guys (or all of us) are going to collab on making a standard uTP impl, I'd take inspiration from smth like smol-tcp. I'd also look at how the existing C++ impl in libtorrent (or whever it is) works to take some inspiration. But as you already have 2 working implementations with different tradeoffs, none of it might be relevant or applicable, so all up to you. |
@ikatson I I gree, we will investigate that, we also like smol crate, not sure about the relation to
@ikatson why do you expect TPC to be faster? because of tokio?
I fully agree, maybe it would be wise to have a call all of us, analyze both the impl and architect one better and then work together on that? What do you think? |
This sounds great, what messaging platform would work best to coordinate this call? |
created a telegram chat https://t.me/+IFCaztp_ImtkMWE0 |
Overview
I am interested in extending
rqbit
to support both TCP/UDP and QUIC as potential transport protocols. Currently,rqbit
operates over TCP/UDP, which aligns with the standard BitTorrent protocol, but adding QUIC support could bring several benefits:Goal
The goal is to introduce an abstract transport layer within
rqbit
that allows interchangeable use of TCP/UDP or QUIC. This would enablerqbit
to operate over traditional BitTorrent networks while also providing the option for a QUIC-based setup.Request for Guidance
Since I’m new to working with
rqbit
's codebase, I’d appreciate any guidance on how to approach this. Specifically:Key Components to Modify:
rqbit
are responsible for TCP/UDP handling?Recommended Approach for Abstraction:
Transport
) to define basic operations likeconnect
,send
,receive
, andclose
?rqbit
for handling multiple protocols that could be extended to support both TCP/UDP and QUIC?Potential Challenges:
rqbit
for non-standard transports like QUIC?Implementation of QUIC:
quinn
, or are there other options that might be better suited for integration withrqbit
?Additional Context
I believe this enhancement could make
rqbit
more adaptable to modern network environments, where QUIC is becoming increasingly common. However, I’d like to ensure I follow the best approach to keeprqbit
's structure clean and maintainable.The text was updated successfully, but these errors were encountered: