rust-libp2p icon indicating copy to clipboard operation
rust-libp2p copied to clipboard

feat: WebTransport on top QUIC transport

Open dgarus opened this issue 1 year ago • 8 comments

related to #2993

@thomaseizinger Hi! There were so many changes in the master branch, so it was easier for me to create a new PR from scratch. I tried to consider all your previous comments and our discussions.

Here are the main points:

Instead of rolling certificates, I'd suggest (something like) the following:

Give our users a simple API to generate and parse certificates
Allow the user to pass in a list of certificates in the QUIC config, explicitly for WebTransport
For the QUIC functionality, we can generate one similarly to how we do it currently
When the user calls listen_on for webtransport, we validate the certificates have a valid date range (the webtransport spec requires +/- 14 days I think)
Whilst not super convenient, this allows users to externally manage certificates until we can generate them deterministically. 
What is important is that we give users some way of restarting a libp2p-node and retain the certificate. 
WebTransport is of no use if the certificate hashes change constantly.

I would like to avoid interacting with the file system as much as possible. My suggestion would be:

- libp2p::webtransport::Transport::new takes a list of certificates (of type libp2p::webtransport::Certificate)
- libp2p::webtransport::Certificate::generate allows users generate a new certificate with certain parameters (validity date etc)
- libp2p::webtransport::Certificate::{parse,to_bytes} allow users to serialize and deserialize certificates

For simplicity, I made a single cert.

Let's consider the following scenario:

User calls listen_on for /quic-v1
User calls listen_on for /webtransport using the same port
Another peer attempts to connect using the /webtransport address
The incoming connection will be picked up by one of the two listeners. 
Until we inspect the Connecting struct, we don't actually know whether it is a QUIC or a WebTransport connection.

So I think what we need to do is:

At most have 1 Listener for a given socket address
The listener needs to be one of 3 modes:
- Only QUIC
- Only WT
- Both
When we receive a listen_on for a socket with an existing listener, we need to update its mode
For incoming connections, we need to inspect it whether it is a QUIC or 
WT connection and check whether the listener supports whatever is incoming. If yes, upgrade it accordingly.

dgarus avatar Aug 20 '24 13:08 dgarus

@jxs Hello! Please review this PR as well. This is a draft, but before cleaning it would be great to know what you think. Thanks!

dgarus avatar Aug 20 '24 13:08 dgarus

Thank you @dgarus ! I hope to give this a review soon.

thomaseizinger avatar Aug 23 '24 22:08 thomaseizinger

@thomaseizinger Thank you so much for your efforts! Currently, I’m stuck with an integration test writing. The problem is what can i use as a webtransport client? I'm looking at transports/webtransport-websys/src/transport.rs. What do you think this is a good idea using webtransport-websys to test webtransport transport?

dgarus avatar Sep 04 '24 08:09 dgarus

@thomaseizinger Thank you so much for your efforts! Currently, I’m stuck with an integration test writing. The problem is what can i use as a webtransport client? I'm looking at transports/webtransport-websys/src/transport.rs. What do you think this is a good idea using webtransport-websys to test webtransport transport?

You should get some basic coverage by adding webtransport here: https://github.com/libp2p/rust-libp2p/blob/3837e33cd4c40ae703138e6aed6f6c9d52928a80/interop-tests/native-ping-version.json#L4

thomaseizinger avatar Sep 09 '24 15:09 thomaseizinger

Some first comments. I like that in this approach the webtransport is integrated in the existing quic crate and that we can to support both on one listener!

Sorry of some of my comments have already been discussed in previous iterations on the PR.

Hi! I tried fixing compilation problems, but unfortunately couldn't. So I decided to ask h3 for release.

dgarus avatar Mar 11 '25 09:03 dgarus

@elenaf9 Good day! @jxs told me you're planning to removeasync-std feature from quic. If this is the case, I could do it to make 'quic' a bit simpler and then continue with 'webtransport'. I don't think it takes much time. What do you think?

dgarus avatar Mar 18 '25 08:03 dgarus

@elenaf9 Good day! @jxs told me you're planning to removeasync-std feature from quic. If this is the case, I could do it to make 'quic' a bit simpler and then continue with 'webtransport'. I don't think it takes much time. What do you think?

Yes, we are planning to remove support for async_std for all of rust-libp2p. However, we would first just deprecate async_std support, and then only in a second release completely remove it. So I am not sure how much of the code we can simplify right now. Does the existing async_std support complicate much of your work in webtransport?

Also related: https://github.com/libp2p/rust-libp2p/issues/3515#issuecomment-2734256901

elenaf9 avatar Mar 18 '25 18:03 elenaf9

@elenaf9 Good day! @jxs told me you're planning to removeasync-std feature from quic. If this is the case, I could do it to make 'quic' a bit simpler and then continue with 'webtransport'. I don't think it takes much time. What do you think?

Yes, we are planning to remove support for async_std for all of rust-libp2p. However, we would first just deprecate async_std support, and then only in a second release completely remove it. So I am not sure how much of the code we can simplify right now. Does the existing async_std support complicate much of your work in webtransport?

Also related: #3515 (comment)

Ok, I got it, you're right.

Does the existing async_std support complicate much of your work in webtransport?

No, just a bit less code base, that is all.

dgarus avatar Mar 19 '25 08:03 dgarus

@elenaf9 Hello! I apologize for the delay. There is one thing I'd like to talk about regarding ConnectingMode::Mixed. When I was trying to implement some logic for this mode, it became unclear to me how we could differentiate between quic and webtransport connections in this mode. Another question is whether it is a real scenario where one listener should act as both a quic listener and a webtransport listener at the same time. I propose removing this mode. In this case, one transport instance could listen to several addresses, but each address would be for a specific protocol. What do you think?

dgarus avatar Jun 21 '25 10:06 dgarus