Skip to content

Introduce QUIC traits #3924

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

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,8 @@ nightly = []
level = "warn"
check-cfg = [
'cfg(hyper_unstable_tracing)',
'cfg(hyper_unstable_ffi)'
'cfg(hyper_unstable_ffi)',
'cfg(hyper_unstable_quic)',
]

[package.metadata.docs.rs]
Expand Down
4 changes: 4 additions & 0 deletions src/rt/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,10 @@ pub mod bounds;
mod io;
mod timer;

#[cfg(hyper_unstable_quic)]
#[cfg_attr(docsrs, doc(cfg(hyper_unstable_quic)))]
pub mod quic;

pub use self::io::{Read, ReadBuf, ReadBufCursor, Write};
pub use self::timer::{Sleep, Timer};

Expand Down
91 changes: 91 additions & 0 deletions src/rt/quic.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
//! Generic QUIC support

use std::pin::Pin;
use std::task::{Context, Poll};

use bytes::Buf;

// TODO: Should this be gated by an `http3` feature?

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes I have a feeling this should be gated by http3 feature because quic is apart of http3.


/// A QUIC connection.
pub trait Connection<B> {
/// Send streams that can be opened by this connection.
type SendStream: SendStream<B>;
/// Receive streams that can be accepted by this connection.
type RecvStream: RecvStream;
/// Bidirectional streams that can be opened or accepted by this connection.
type BidiStream: SendStream<B> + RecvStream;
/// Errors that may occur opening or accepting streams.
type Error;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

H3 needs some some more infomation on the error. Because of this the ConnectionErrorIncoming type was created.
https://github.com/hyperium/h3/blob/94cb13f74979f3a0b6c4f98c3711abac8eb0435a/h3/src/quic.rs#L20-L35

This can be done with a trait or a specific type like in h3 atm.

The InternalError variant allows h3 to react to errors happening inside of the trait implementations with a Connection error.
Also h3 reacts to some ApplicationErrors.


// Accepting streams

// Q: shorten to bidi?
/// Accept a bidirection stream.
fn poll_accept_bidirectional_stream(
self: Pin<&mut Self>,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pin here probably requires Q in the glue to be Boxed.
https://github.com/hyperium/hyper/pull/3925/files#diff-5d22d97a30a051ea5e00978de444e3df97844c87b4174d6256e601c85216b1b4R5.

It should be possible to change h3 so its traits can be Pin as well hyperium/h3#298

cx: &mut Context<'_>,
) -> Poll<Result<Option<Self::BidiStream>, Self::Error>>;

/// Accept a unidirectional receive stream.
fn poll_accept_recv_stream(
self: Pin<&mut Self>,
cx: &mut Context<'_>,
) -> Poll<Result<Option<Self::RecvStream>, Self::Error>>;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Option here and on poll_accept_bidirectional_stream is not necessary, as the peer can always create a new stream until the connection is closed. Then Err is returned.

In RecvStream::poll_data this is dfferent because streams can either be reset or EOS.


// Creating streams

// Q: shorten to bidi?
/// Open a bidirectional stream.
fn poll_open_bidirectional_stream(
self: Pin<&mut Self>,
cx: &mut Context<'_>,
) -> Poll<Result<Self::BidiStream, Self::Error>>;

/// Open a unidirectional send stream.
fn poll_open_send_stream(
self: Pin<&mut Self>,
cx: &mut Context<'_>,
) -> Poll<Result<Self::SendStream, Self::Error>>;
}

/// The send portion of a QUIC stream.
pub trait SendStream<B> {
/// Errors that may happen trying to send data.
type Error; // bounds?
/// Polls that the stream is ready to send more data.
// Q: Should this be Pin<&mut Self>?
fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>>;
/// Send data on the stream.
fn send_data(&mut self, data: B) -> Result<(), Self::Error>;
// fn poll_flush?
/// finish?
fn poll_finish(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>>;
/// Close the stream with an error code.
fn reset(&mut self, reset_code: u64);
}

/// The receive portion of a QUIC stream.
pub trait RecvStream {
/// Buffers of data that can be received.
type Buf: Buf;
/// Errors that may be received.
type Error; // bounds?

// Q: should this be Pin?
/// Poll for more data received from the remote on this stream.
fn poll_data(&mut self, cx: &mut Context<'_>) -> Poll<Result<Option<Self::Buf>, Self::Error>>;
/// Signal to the remote peer to stop sending data.
fn stop_sending(&mut self, error_code: u64);
}

/// An optional trait if a QUIC stream can be split into two sides.
pub trait BidiStream<B>: SendStream<B> + RecvStream {
/// The send side of a stream.
type SendStream: SendStream<B>;
/// The receive side of a stream.
type RecvStream: RecvStream;

/// Split this stream into two sides.
fn split(self) -> (Self::SendStream, Self::RecvStream);
}
Loading