-
Notifications
You must be signed in to change notification settings - Fork 79
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
move datagram to separate crate #199
Open
Ruben2424
wants to merge
10
commits into
hyperium:master
Choose a base branch
from
Ruben2424:h3-datagrams
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from 7 commits
Commits
Show all changes
10 commits
Select commit
Hold shift + click to select a range
7b84faa
move datagram to separate crate
Ruben2424 2e67426
add to dev-dependencies
Ruben2424 e3a15b9
Merge branch 'Main' into h3-datagrams
Ruben2424 419c860
fix merge
Ruben2424 61aa6ca
cleanup
Ruben2424 dc8e0c2
remove todo comment
Ruben2424 cbb7ae7
cleanup
Ruben2424 d2fcc35
Merge branch 'Main' into h3-datagrams
Ruben2424 21ba7d1
make feature for datagram in h3-quinn
Ruben2424 3998a11
Merge branch 'Main' into h3-datagrams
Ruben2424 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -3,6 +3,7 @@ members = [ | |
"h3", | ||
"h3-quinn", | ||
"h3-webtransport", | ||
"h3-datagram", | ||
|
||
# Internal | ||
"examples", | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
[package] | ||
name = "h3-datagram" | ||
version = "0.0.1" | ||
edition = "2021" | ||
|
||
[dependencies] | ||
#h3 = { path = "../h3" } | ||
bytes = "1.4" | ||
pin-project-lite = { version = "0.2", default-features = false } | ||
|
||
[dependencies.h3] | ||
version = "0.0.6" | ||
path = "../h3" | ||
features = ["i-implement-a-third-party-backend-and-opt-into-breaking-changes"] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
# H3 Datagram | ||
|
||
this crate provides an implementation of the [h3-datagram](https://datatracker.ietf.org/doc/html/rfc9297) spec that works with the h3 crate. | ||
|
||
## Usage | ||
As stated in the [rfc](https://datatracker.ietf.org/doc/html/rfc9297#abstract) this is intended to be used for protocol extensions like [Web-Transport](https://datatracker.ietf.org/doc/draft-ietf-webtrans-http3/) and not directly by applications. | ||
|
||
> HTTP Datagrams and the Capsule Protocol are intended for use by HTTP extensions, not applications. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
use bytes::{Buf, Bytes}; | ||
use h3::{error::Code, proto::varint::VarInt, quic::StreamId, Error}; | ||
|
||
/// HTTP datagram frames | ||
/// See: <https://www.rfc-editor.org/rfc/rfc9297#section-2.1> | ||
pub struct Datagram<B = Bytes> { | ||
/// Stream id divided by 4 | ||
stream_id: StreamId, | ||
/// The data contained in the datagram | ||
payload: B, | ||
} | ||
|
||
impl<B> Datagram<B> | ||
where | ||
B: Buf, | ||
{ | ||
/// Creates a new datagram frame | ||
pub fn new(stream_id: StreamId, payload: B) -> Self { | ||
assert!( | ||
stream_id.into_inner() % 4 == 0, | ||
"StreamId is not divisible by 4" | ||
); | ||
Self { stream_id, payload } | ||
} | ||
|
||
/// Decodes a datagram frame from the QUIC datagram | ||
pub fn decode(mut buf: B) -> Result<Self, Error> { | ||
let q_stream_id = VarInt::decode(&mut buf) | ||
.map_err(|_| Code::H3_DATAGRAM_ERROR.with_cause("Malformed datagram frame"))?; | ||
|
||
//= https://www.rfc-editor.org/rfc/rfc9297#section-2.1 | ||
// Quarter Stream ID: A variable-length integer that contains the value of the client-initiated bidirectional | ||
// stream that this datagram is associated with divided by four (the division by four stems | ||
// from the fact that HTTP requests are sent on client-initiated bidirectional streams, | ||
// which have stream IDs that are divisible by four). The largest legal QUIC stream ID | ||
// value is 262-1, so the largest legal value of the Quarter Stream ID field is 260-1. | ||
// Receipt of an HTTP/3 Datagram that includes a larger value MUST be treated as an HTTP/3 | ||
// connection error of type H3_DATAGRAM_ERROR (0x33). | ||
let stream_id = StreamId::try_from(u64::from(q_stream_id) * 4) | ||
.map_err(|_| Code::H3_DATAGRAM_ERROR.with_cause("Invalid stream id"))?; | ||
|
||
let payload = buf; | ||
|
||
Ok(Self { stream_id, payload }) | ||
} | ||
|
||
#[inline] | ||
/// Returns the associated stream id of the datagram | ||
pub fn stream_id(&self) -> StreamId { | ||
self.stream_id | ||
} | ||
|
||
#[inline] | ||
/// Returns the datagram payload | ||
pub fn payload(&self) -> &B { | ||
&self.payload | ||
} | ||
|
||
/// Encode the datagram to wire format | ||
pub fn encode<D: bytes::BufMut>(self, buf: &mut D) { | ||
(VarInt::from(self.stream_id) / 4).encode(buf); | ||
buf.put(self.payload); | ||
} | ||
|
||
/// Returns the datagram payload | ||
pub fn into_payload(self) -> B { | ||
self.payload | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
//! Traits which define the user API for datagrams. | ||
//! These traits are implemented for the client and server types in the `h3` crate. | ||
|
||
use bytes::Buf; | ||
use h3::{ | ||
quic::{self, StreamId}, | ||
Error, | ||
}; | ||
|
||
use crate::server::ReadDatagram; | ||
|
||
pub trait HandleDatagramsExt<C, B> | ||
where | ||
B: Buf, | ||
C: quic::Connection<B>, | ||
{ | ||
/// Sends a datagram | ||
fn send_datagram(&mut self, stream_id: StreamId, data: B) -> Result<(), Error>; | ||
/// Reads an incoming datagram | ||
fn read_datagram(&mut self) -> ReadDatagram<C, B>; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
pub mod datagram; | ||
pub mod datagram_traits; | ||
pub mod quic_traits; | ||
pub mod server; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
//! QUIC Transport traits | ||
//! | ||
//! This module includes traits and types meant to allow being generic over any | ||
//! QUIC implementation. | ||
|
||
use core::task; | ||
use std::{error::Error, task::Poll}; | ||
|
||
use bytes::Buf; | ||
|
||
use crate::datagram::Datagram; | ||
|
||
/// Extends the `Connection` trait for sending datagrams | ||
/// | ||
/// See: <https://www.rfc-editor.org/rfc/rfc9297> | ||
pub trait SendDatagramExt<B: Buf> { | ||
/// The error type that can occur when sending a datagram | ||
type Error: Into<Box<dyn Error>>; | ||
|
||
/// Send a datagram | ||
fn send_datagram(&mut self, data: Datagram<B>) -> Result<(), Self::Error>; | ||
} | ||
|
||
/// Extends the `Connection` trait for receiving datagrams | ||
/// | ||
/// See: <https://www.rfc-editor.org/rfc/rfc9297> | ||
pub trait RecvDatagramExt { | ||
/// The type of `Buf` for *raw* datagrams (without the stream_id decoded) | ||
type Buf: Buf; | ||
/// The error type that can occur when receiving a datagram | ||
type Error: Into<Box<dyn Error>>; | ||
|
||
/// Poll the connection for incoming datagrams. | ||
fn poll_accept_datagram( | ||
&mut self, | ||
cx: &mut task::Context<'_>, | ||
) -> Poll<Result<Option<Self::Buf>, Self::Error>>; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
//! server API | ||
|
||
use std::{ | ||
future::Future, | ||
marker::PhantomData, | ||
task::{ready, Context, Poll}, | ||
}; | ||
|
||
use bytes::Buf; | ||
use h3::{ | ||
quic::{self, StreamId}, | ||
server::Connection, | ||
Error, | ||
}; | ||
use pin_project_lite::pin_project; | ||
|
||
use crate::{ | ||
datagram::Datagram, | ||
datagram_traits::HandleDatagramsExt, | ||
quic_traits::{self, RecvDatagramExt, SendDatagramExt}, | ||
}; | ||
|
||
impl<B, C> HandleDatagramsExt<C, B> for Connection<C, B> | ||
where | ||
B: Buf, | ||
C: quic::Connection<B> + SendDatagramExt<B> + RecvDatagramExt, | ||
<C as quic_traits::RecvDatagramExt>::Error: h3::quic::Error + 'static, | ||
<C as quic_traits::SendDatagramExt<B>>::Error: h3::quic::Error + 'static, | ||
{ | ||
/// Sends a datagram | ||
fn send_datagram(&mut self, stream_id: StreamId, data: B) -> Result<(), Error> { | ||
self.inner | ||
.conn | ||
.send_datagram(Datagram::new(stream_id, data))?; | ||
Ok(()) | ||
} | ||
|
||
/// Reads an incoming datagram | ||
fn read_datagram(&mut self) -> ReadDatagram<C, B> { | ||
ReadDatagram { | ||
conn: self, | ||
_marker: PhantomData, | ||
} | ||
} | ||
} | ||
|
||
pin_project! { | ||
/// Future for [`Connection::read_datagram`] | ||
pub struct ReadDatagram<'a, C, B> | ||
where | ||
C: quic::Connection<B>, | ||
B: Buf, | ||
{ | ||
conn: &'a mut Connection<C, B>, | ||
_marker: PhantomData<B>, | ||
} | ||
} | ||
|
||
impl<'a, C, B> Future for ReadDatagram<'a, C, B> | ||
where | ||
C: quic::Connection<B> + RecvDatagramExt, | ||
<C as quic_traits::RecvDatagramExt>::Error: h3::quic::Error + 'static, | ||
B: Buf, | ||
{ | ||
type Output = Result<Option<Datagram<C::Buf>>, Error>; | ||
|
||
fn poll(mut self: std::pin::Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> { | ||
match ready!(self.conn.inner.conn.poll_accept_datagram(cx))? { | ||
Some(v) => Poll::Ready(Ok(Some(Datagram::decode(v)?))), | ||
None => Poll::Ready(Ok(None)), | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wondering, should it be optional? Is there enough code in here that people would benefit if they didn't need to compile it?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Changed it.