зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1907267 - Update neqo to v0.8.1, r=mxinden
Differential Revision: https://phabricator.services.mozilla.com/D217271
This commit is contained in:
Родитель
e1510d1954
Коммит
fae8fa9ca1
|
@ -90,9 +90,9 @@ git = "https://github.com/mozilla/mp4parse-rust"
|
|||
rev = "a138e40ec1c603615873e524b5b22e11c0ec4820"
|
||||
replace-with = "vendored-sources"
|
||||
|
||||
[source."git+https://github.com/mozilla/neqo?tag=v0.7.9"]
|
||||
[source."git+https://github.com/mozilla/neqo?tag=v0.8.1"]
|
||||
git = "https://github.com/mozilla/neqo"
|
||||
tag = "v0.7.9"
|
||||
tag = "v0.8.1"
|
||||
replace-with = "vendored-sources"
|
||||
|
||||
[source."git+https://github.com/seanmonstar/warp?rev=9d081461ae1167eb321585ce424f4fef6cf0092b"]
|
||||
|
|
|
@ -4052,8 +4052,8 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "neqo-bin"
|
||||
version = "0.7.9"
|
||||
source = "git+https://github.com/mozilla/neqo?tag=v0.7.9#121fe683ae4b39a5b694f671abfd397cbd9b4322"
|
||||
version = "0.8.1"
|
||||
source = "git+https://github.com/mozilla/neqo?tag=v0.8.1#f0bffce01be53309a9cc93dc344141f57918cb3b"
|
||||
dependencies = [
|
||||
"clap",
|
||||
"clap-verbosity-flag",
|
||||
|
@ -4063,8 +4063,8 @@ dependencies = [
|
|||
"neqo-common",
|
||||
"neqo-crypto",
|
||||
"neqo-http3",
|
||||
"neqo-qpack",
|
||||
"neqo-transport",
|
||||
"neqo-udp",
|
||||
"qlog",
|
||||
"quinn-udp",
|
||||
"regex",
|
||||
|
@ -4074,8 +4074,8 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "neqo-common"
|
||||
version = "0.7.9"
|
||||
source = "git+https://github.com/mozilla/neqo?tag=v0.7.9#121fe683ae4b39a5b694f671abfd397cbd9b4322"
|
||||
version = "0.8.1"
|
||||
source = "git+https://github.com/mozilla/neqo?tag=v0.8.1#f0bffce01be53309a9cc93dc344141f57918cb3b"
|
||||
dependencies = [
|
||||
"enum-map",
|
||||
"env_logger",
|
||||
|
@ -4087,8 +4087,8 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "neqo-crypto"
|
||||
version = "0.7.9"
|
||||
source = "git+https://github.com/mozilla/neqo?tag=v0.7.9#121fe683ae4b39a5b694f671abfd397cbd9b4322"
|
||||
version = "0.8.1"
|
||||
source = "git+https://github.com/mozilla/neqo?tag=v0.8.1#f0bffce01be53309a9cc93dc344141f57918cb3b"
|
||||
dependencies = [
|
||||
"bindgen 0.69.4",
|
||||
"log",
|
||||
|
@ -4102,8 +4102,8 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "neqo-http3"
|
||||
version = "0.7.9"
|
||||
source = "git+https://github.com/mozilla/neqo?tag=v0.7.9#121fe683ae4b39a5b694f671abfd397cbd9b4322"
|
||||
version = "0.8.1"
|
||||
source = "git+https://github.com/mozilla/neqo?tag=v0.8.1#f0bffce01be53309a9cc93dc344141f57918cb3b"
|
||||
dependencies = [
|
||||
"enumset",
|
||||
"log",
|
||||
|
@ -4113,18 +4113,16 @@ dependencies = [
|
|||
"neqo-transport",
|
||||
"qlog",
|
||||
"sfv",
|
||||
"smallvec",
|
||||
"url",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "neqo-qpack"
|
||||
version = "0.7.9"
|
||||
source = "git+https://github.com/mozilla/neqo?tag=v0.7.9#121fe683ae4b39a5b694f671abfd397cbd9b4322"
|
||||
version = "0.8.1"
|
||||
source = "git+https://github.com/mozilla/neqo?tag=v0.8.1#f0bffce01be53309a9cc93dc344141f57918cb3b"
|
||||
dependencies = [
|
||||
"log",
|
||||
"neqo-common",
|
||||
"neqo-crypto",
|
||||
"neqo-transport",
|
||||
"qlog",
|
||||
"static_assertions",
|
||||
|
@ -4132,8 +4130,8 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "neqo-transport"
|
||||
version = "0.7.9"
|
||||
source = "git+https://github.com/mozilla/neqo?tag=v0.7.9#121fe683ae4b39a5b694f671abfd397cbd9b4322"
|
||||
version = "0.8.1"
|
||||
source = "git+https://github.com/mozilla/neqo?tag=v0.8.1#f0bffce01be53309a9cc93dc344141f57918cb3b"
|
||||
dependencies = [
|
||||
"enum-map",
|
||||
"indexmap 2.2.6",
|
||||
|
@ -4142,6 +4140,17 @@ dependencies = [
|
|||
"neqo-crypto",
|
||||
"qlog",
|
||||
"smallvec",
|
||||
"static_assertions",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "neqo-udp"
|
||||
version = "0.8.1"
|
||||
source = "git+https://github.com/mozilla/neqo?tag=v0.8.1#f0bffce01be53309a9cc93dc344141f57918cb3b"
|
||||
dependencies = [
|
||||
"log",
|
||||
"neqo-common",
|
||||
"quinn-udp",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
|
@ -9,10 +9,10 @@ license = "MPL-2.0"
|
|||
name = "neqo_glue"
|
||||
|
||||
[dependencies]
|
||||
neqo-http3 = { tag = "v0.7.9", git = "https://github.com/mozilla/neqo" }
|
||||
neqo-transport = { tag = "v0.7.9", git = "https://github.com/mozilla/neqo" }
|
||||
neqo-common = { tag = "v0.7.9", git = "https://github.com/mozilla/neqo" }
|
||||
neqo-qpack = { tag = "v0.7.9", git = "https://github.com/mozilla/neqo" }
|
||||
neqo-http3 = { tag = "v0.8.1", git = "https://github.com/mozilla/neqo" }
|
||||
neqo-transport = { tag = "v0.8.1", git = "https://github.com/mozilla/neqo" }
|
||||
neqo-common = { tag = "v0.8.1", git = "https://github.com/mozilla/neqo" }
|
||||
neqo-qpack = { tag = "v0.8.1", git = "https://github.com/mozilla/neqo" }
|
||||
nserror = { path = "../../../xpcom/rust/nserror" }
|
||||
nsstring = { path = "../../../xpcom/rust/nsstring" }
|
||||
xpcom = { path = "../../../xpcom/rust/xpcom" }
|
||||
|
@ -27,7 +27,7 @@ uuid = { version = "1.0", features = ["v4"] }
|
|||
winapi = {version = "0.3", features = ["ws2def"] }
|
||||
|
||||
[dependencies.neqo-crypto]
|
||||
tag = "v0.7.9"
|
||||
tag = "v0.8.1"
|
||||
git = "https://github.com/mozilla/neqo"
|
||||
default-features = false
|
||||
features = ["gecko"]
|
||||
|
|
|
@ -353,7 +353,6 @@ pub unsafe extern "C" fn neqo_http3conn_process_input(
|
|||
remote,
|
||||
conn.local_addr,
|
||||
IpTos::default(),
|
||||
None,
|
||||
(*packet).to_vec(),
|
||||
);
|
||||
conn.conn
|
||||
|
|
|
@ -6,11 +6,11 @@ edition = "2018"
|
|||
license = "MPL-2.0"
|
||||
|
||||
[dependencies]
|
||||
neqo-bin = { tag = "v0.7.9", git = "https://github.com/mozilla/neqo" }
|
||||
neqo-transport = { tag = "v0.7.9", git = "https://github.com/mozilla/neqo" }
|
||||
neqo-common = { tag = "v0.7.9", git = "https://github.com/mozilla/neqo" }
|
||||
neqo-http3 = { tag = "v0.7.9", git = "https://github.com/mozilla/neqo" }
|
||||
neqo-qpack = { tag = "v0.7.9", git = "https://github.com/mozilla/neqo" }
|
||||
neqo-bin = { tag = "v0.8.1", git = "https://github.com/mozilla/neqo" }
|
||||
neqo-transport = { tag = "v0.8.1", git = "https://github.com/mozilla/neqo" }
|
||||
neqo-common = { tag = "v0.8.1", git = "https://github.com/mozilla/neqo" }
|
||||
neqo-http3 = { tag = "v0.8.1", git = "https://github.com/mozilla/neqo" }
|
||||
neqo-qpack = { tag = "v0.8.1", git = "https://github.com/mozilla/neqo" }
|
||||
log = "0.4.0"
|
||||
base64 = "0.21"
|
||||
cfg-if = "1.0"
|
||||
|
@ -20,7 +20,7 @@ tokio = { version = "1", features = ["rt-multi-thread"] }
|
|||
mozilla-central-workspace-hack = { version = "0.1", features = ["http3server"], optional = true }
|
||||
|
||||
[dependencies.neqo-crypto]
|
||||
tag = "v0.7.9"
|
||||
tag = "v0.8.1"
|
||||
git = "https://github.com/mozilla/neqo"
|
||||
default-features = false
|
||||
features = ["gecko"]
|
||||
|
|
|
@ -14,7 +14,7 @@ use neqo_http3::{
|
|||
Error, Http3OrWebTransportStream, Http3Parameters, Http3Server, Http3ServerEvent,
|
||||
WebTransportRequest, WebTransportServerEvent, WebTransportSessionAcceptAction,
|
||||
};
|
||||
use neqo_transport::server::ActiveConnectionRef;
|
||||
use neqo_transport::server::ConnectionRef;
|
||||
use neqo_transport::{
|
||||
ConnectionEvent, ConnectionParameters, Output, RandomConnectionIdGenerator, StreamId,
|
||||
StreamType,
|
||||
|
@ -69,7 +69,7 @@ struct Http3TestServer {
|
|||
sessions_to_close: HashMap<Instant, Vec<WebTransportRequest>>,
|
||||
sessions_to_create_stream: Vec<(WebTransportRequest, StreamType, bool)>,
|
||||
webtransport_bidi_stream: HashSet<Http3OrWebTransportStream>,
|
||||
wt_unidi_conn_to_stream: HashMap<ActiveConnectionRef, Http3OrWebTransportStream>,
|
||||
wt_unidi_conn_to_stream: HashMap<ConnectionRef, Http3OrWebTransportStream>,
|
||||
wt_unidi_echo_back: HashMap<Http3OrWebTransportStream, Http3OrWebTransportStream>,
|
||||
received_datagram: Option<Vec<u8>>,
|
||||
}
|
||||
|
@ -96,7 +96,7 @@ impl Http3TestServer {
|
|||
}
|
||||
}
|
||||
|
||||
fn new_response(&mut self, mut stream: Http3OrWebTransportStream, mut data: Vec<u8>) {
|
||||
fn new_response(&mut self, stream: Http3OrWebTransportStream, mut data: Vec<u8>) {
|
||||
if data.len() == 0 {
|
||||
let _ = stream.stream_close_send();
|
||||
return;
|
||||
|
@ -115,7 +115,7 @@ impl Http3TestServer {
|
|||
}
|
||||
}
|
||||
|
||||
fn handle_stream_writable(&mut self, mut stream: Http3OrWebTransportStream) {
|
||||
fn handle_stream_writable(&mut self, stream: Http3OrWebTransportStream) {
|
||||
if let Some(data) = self.responses.get_mut(&stream) {
|
||||
match stream.send_data(&data) {
|
||||
Ok(sent) => {
|
||||
|
@ -151,8 +151,8 @@ impl Http3TestServer {
|
|||
return;
|
||||
}
|
||||
let tuple = self.sessions_to_create_stream.pop().unwrap();
|
||||
let mut session = tuple.0;
|
||||
let mut wt_server_stream = session.create_stream(tuple.1).unwrap();
|
||||
let session = tuple.0;
|
||||
let wt_server_stream = session.create_stream(tuple.1).unwrap();
|
||||
if tuple.1 == StreamType::UniDi {
|
||||
if tuple.2 {
|
||||
wt_server_stream.send_data(b"qwerty").unwrap();
|
||||
|
@ -207,7 +207,7 @@ impl HttpServer for Http3TestServer {
|
|||
qtrace!("Event: {:?}", event);
|
||||
match event {
|
||||
Http3ServerEvent::Headers {
|
||||
mut stream,
|
||||
stream,
|
||||
headers,
|
||||
fin,
|
||||
} => {
|
||||
|
@ -419,11 +419,7 @@ impl HttpServer for Http3TestServer {
|
|||
}
|
||||
}
|
||||
}
|
||||
Http3ServerEvent::Data {
|
||||
mut stream,
|
||||
data,
|
||||
fin,
|
||||
} => {
|
||||
Http3ServerEvent::Data { stream, data, fin } => {
|
||||
// echo bidirectional input back to client
|
||||
if self.webtransport_bidi_stream.contains(&stream) {
|
||||
if stream.handler.borrow().state().active() {
|
||||
|
@ -435,7 +431,7 @@ impl HttpServer for Http3TestServer {
|
|||
// echo unidirectional input to back to client
|
||||
// need to close or we hang
|
||||
if self.wt_unidi_echo_back.contains_key(&stream) {
|
||||
let mut echo_back = self.wt_unidi_echo_back.remove(&stream).unwrap();
|
||||
let echo_back = self.wt_unidi_echo_back.remove(&stream).unwrap();
|
||||
echo_back.send_data(&data).unwrap();
|
||||
echo_back.stream_close_send().unwrap();
|
||||
break;
|
||||
|
@ -479,7 +475,7 @@ impl HttpServer for Http3TestServer {
|
|||
);
|
||||
}
|
||||
Http3ServerEvent::WebTransport(WebTransportServerEvent::NewSession {
|
||||
mut session,
|
||||
session,
|
||||
headers,
|
||||
}) => {
|
||||
qdebug!(
|
||||
|
@ -647,7 +643,7 @@ impl HttpServer for Server {
|
|||
|
||||
fn process_events(&mut self, _now: Instant) {
|
||||
let active_conns = self.0.active_connections();
|
||||
for mut acr in active_conns {
|
||||
for acr in active_conns {
|
||||
loop {
|
||||
let event = match acr.borrow_mut().next_event() {
|
||||
None => break,
|
||||
|
@ -707,7 +703,7 @@ impl Http3ProxyServer {
|
|||
}
|
||||
|
||||
#[cfg(not(target_os = "android"))]
|
||||
fn new_response(&mut self, mut stream: Http3OrWebTransportStream, mut data: Vec<u8>) {
|
||||
fn new_response(&mut self, stream: Http3OrWebTransportStream, mut data: Vec<u8>) {
|
||||
if data.len() == 0 {
|
||||
let _ = stream.stream_close_send();
|
||||
return;
|
||||
|
@ -727,7 +723,7 @@ impl Http3ProxyServer {
|
|||
}
|
||||
}
|
||||
|
||||
fn handle_stream_writable(&mut self, mut stream: Http3OrWebTransportStream) {
|
||||
fn handle_stream_writable(&mut self, stream: Http3OrWebTransportStream) {
|
||||
if let Some(data) = self.responses.get_mut(&stream) {
|
||||
match stream.send_data(&data) {
|
||||
Ok(sent) => {
|
||||
|
@ -780,7 +776,7 @@ impl Http3ProxyServer {
|
|||
#[cfg(not(target_os = "android"))]
|
||||
fn fetch(
|
||||
&mut self,
|
||||
mut stream: Http3OrWebTransportStream,
|
||||
stream: Http3OrWebTransportStream,
|
||||
request_headers: &Vec<Header>,
|
||||
request_body: Vec<u8>,
|
||||
) {
|
||||
|
@ -872,7 +868,7 @@ impl Http3ProxyServer {
|
|||
Err(TryRecvError::Disconnected) => false,
|
||||
});
|
||||
while let Some(id) = data_to_send.keys().next().cloned() {
|
||||
let mut stream = self.stream_map.remove(&id).unwrap();
|
||||
let stream = self.stream_map.remove(&id).unwrap();
|
||||
let (header, data) = data_to_send.remove(&id).unwrap();
|
||||
qtrace!("response headers: {:?}", header);
|
||||
match stream.send_headers(&header) {
|
||||
|
@ -914,7 +910,7 @@ impl HttpServer for Http3ProxyServer {
|
|||
qtrace!("Event: {:?}", event);
|
||||
match event {
|
||||
Http3ServerEvent::Headers {
|
||||
mut stream,
|
||||
stream,
|
||||
headers,
|
||||
fin: _,
|
||||
} => {
|
||||
|
|
|
@ -1 +1 @@
|
|||
{"files":{"Cargo.toml":"8147570152018b0e613e3745cf0f48ceabc1977047d16744a9e88ea55b1dd431","benches/main.rs":"0835db58b265c529dcde6b208942b60e932ac0665e7f303cf60406ff9994dd45","src/bin/client.rs":"db77efd75dc0745b6dd983ab8fa3bc8f5f9111967f0d90d23cb19140a940246d","src/bin/server.rs":"2f7ab3c7a98117bd162e6fd07abef1d21791d1bb240db3aae61afa6ff72df83a","src/client/http09.rs":"b13eda497821c932f60a45af304e4d3769d76588edfe6f940ba6b8f87dc7f96c","src/client/http3.rs":"66a15d176b98528277c2158b4e6df2e52715312180222ad279809868b7aa0d2a","src/client/mod.rs":"bef0d7874dd6de84e3320d877ab098889037da1fe3610d82365f9e66c73d939c","src/lib.rs":"77d01388ea8bf076dca5b67c8003622868a0d37af5bbf9deb50d41c971eb579b","src/server/http09.rs":"e1834ae7ae15e00c25c07a4ff522a0efe8f6a97996983a2c35a4cbe4a746128d","src/server/http3.rs":"dc9f71f964574fae7e83c49184df8cd76f9c1c019ca8592941acf093b9393efc","src/server/mod.rs":"eeabaed415b7c9eebc9b3bae255963c1c3407ae5ef30abefc29e7d26f649219a","src/udp.rs":"d914b6cf1dda149202c0499182f646f38244376903ee109c829de58c1a12132c"},"package":null}
|
||||
{"files":{"Cargo.toml":"5c8f1c82accd7dbe47dd53838f165d72009d8718e98fce6bef4757d3c8836ab0","benches/main.rs":"5209cbf879c3e0672e5c2f6f60b70643c4a28fbecdc56c182d7437a2f91740dd","src/bin/client.rs":"db77efd75dc0745b6dd983ab8fa3bc8f5f9111967f0d90d23cb19140a940246d","src/bin/server.rs":"2f7ab3c7a98117bd162e6fd07abef1d21791d1bb240db3aae61afa6ff72df83a","src/client/http09.rs":"868a55062e864e7c290e345e3049afbd49796ec3655259a681457540efa3650f","src/client/http3.rs":"cf6dc5ec2cf8eeb673410f499daa15ec55ed64bf3d51da718659f284e7984f25","src/client/mod.rs":"3bf40a6dcc5fde24c823f55ee9d34a2e7d96d2d19980b234d3ec22e33771c14c","src/lib.rs":"e41fe10d5f45b4472ca97a8be531a6b959ec47f094cf2fad3f4f50954ce09046","src/server/http09.rs":"7b0b0459d2b71ecb1d4c93177304a8b7dc0a74dc4cb0a9875df18295ab04b271","src/server/http3.rs":"9d5361a724be1d0e234bbc4b3893a8830825e5886a24a40b96e3f87f35c7b968","src/server/mod.rs":"91f8cd6278c42eef20b6e16f3d903705073d741093bcdf161b58c01914aca2de","src/udp.rs":"74004ac193cca4b7f3f31ecedb975d901ae1e25a8644dc4deedbfbc97d4a2d17"},"package":null}
|
|
@ -13,10 +13,23 @@
|
|||
edition = "2021"
|
||||
rust-version = "1.76.0"
|
||||
name = "neqo-bin"
|
||||
version = "0.7.9"
|
||||
version = "0.8.1"
|
||||
authors = ["The Neqo Authors <necko@mozilla.com>"]
|
||||
description = "A basic QUIC HTTP/0.9 and HTTP/3 client and server."
|
||||
homepage = "https://github.com/mozilla/neqo/"
|
||||
readme = "../README.md"
|
||||
keywords = [
|
||||
"quic",
|
||||
"http3",
|
||||
"neqo",
|
||||
"mozilla",
|
||||
"ietf",
|
||||
"firefox",
|
||||
]
|
||||
categories = [
|
||||
"network-programming",
|
||||
"web-programming",
|
||||
]
|
||||
license = "MIT OR Apache-2.0"
|
||||
repository = "https://github.com/mozilla/neqo/"
|
||||
|
||||
|
@ -77,12 +90,12 @@ path = "./../neqo-crypto"
|
|||
[dependencies.neqo-http3]
|
||||
path = "./../neqo-http3"
|
||||
|
||||
[dependencies.neqo-qpack]
|
||||
path = "./../neqo-qpack"
|
||||
|
||||
[dependencies.neqo-transport]
|
||||
path = "./../neqo-transport"
|
||||
|
||||
[dependencies.neqo-udp]
|
||||
path = "./../neqo-udp"
|
||||
|
||||
[dependencies.qlog]
|
||||
version = "0.13"
|
||||
default-features = false
|
||||
|
@ -127,6 +140,17 @@ default-features = false
|
|||
[features]
|
||||
bench = []
|
||||
|
||||
[lints.clippy]
|
||||
multiple_crate_versions = "allow"
|
||||
|
||||
[lints.clippy.cargo]
|
||||
level = "warn"
|
||||
priority = -1
|
||||
|
||||
[lints.clippy.nursery]
|
||||
level = "warn"
|
||||
priority = -1
|
||||
|
||||
[lints.clippy.pedantic]
|
||||
level = "warn"
|
||||
priority = -1
|
||||
|
|
|
@ -68,6 +68,7 @@ fn transfer(c: &mut Criterion) {
|
|||
done_sender.send(()).unwrap();
|
||||
}
|
||||
|
||||
#[allow(clippy::redundant_pub_crate)] // Bug in clippy nursery? Not sure how this lint could fire here.
|
||||
fn spawn_server() -> tokio::sync::oneshot::Sender<()> {
|
||||
let (done_sender, mut done_receiver) = tokio::sync::oneshot::channel();
|
||||
std::thread::spawn(move || {
|
||||
|
@ -76,7 +77,7 @@ fn spawn_server() -> tokio::sync::oneshot::Sender<()> {
|
|||
tokio::select! {
|
||||
_ = &mut done_receiver => {}
|
||||
res = &mut server => panic!("expect server not to terminate: {res:?}"),
|
||||
}
|
||||
};
|
||||
});
|
||||
});
|
||||
done_sender
|
||||
|
|
|
@ -106,7 +106,7 @@ impl<'a> super::Handler for Handler<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
pub(crate) fn create_client(
|
||||
pub fn create_client(
|
||||
args: &Args,
|
||||
local_addr: SocketAddr,
|
||||
remote_addr: SocketAddr,
|
||||
|
@ -147,11 +147,9 @@ impl TryFrom<&State> for CloseState {
|
|||
|
||||
fn try_from(value: &State) -> Result<Self, Self::Error> {
|
||||
let (state, error) = match value {
|
||||
State::Closing { error, .. } | State::Draining { error, .. } => {
|
||||
(CloseState::Closing, error)
|
||||
}
|
||||
State::Closed(error) => (CloseState::Closed, error),
|
||||
_ => return Ok(CloseState::NotClosing),
|
||||
State::Closing { error, .. } | State::Draining { error, .. } => (Self::Closing, error),
|
||||
State::Closed(error) => (Self::Closed, error),
|
||||
_ => return Ok(Self::NotClosing),
|
||||
};
|
||||
|
||||
if error.is_error() {
|
||||
|
|
|
@ -29,7 +29,7 @@ use url::Url;
|
|||
|
||||
use super::{get_output_file, qlog_new, Args, CloseState, Res};
|
||||
|
||||
pub(crate) struct Handler<'a> {
|
||||
pub struct Handler<'a> {
|
||||
#[allow(
|
||||
unknown_lints,
|
||||
clippy::struct_field_names,
|
||||
|
@ -62,7 +62,7 @@ impl<'a> Handler<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
pub(crate) fn create_client(
|
||||
pub fn create_client(
|
||||
args: &Args,
|
||||
local_addr: SocketAddr,
|
||||
remote_addr: SocketAddr,
|
||||
|
@ -110,13 +110,13 @@ impl TryFrom<Http3State> for CloseState {
|
|||
|
||||
fn try_from(value: Http3State) -> Result<Self, Self::Error> {
|
||||
let (state, error) = match value {
|
||||
Http3State::Closing(error) => (CloseState::Closing, error),
|
||||
Http3State::Closed(error) => (CloseState::Closed, error),
|
||||
_ => return Ok(CloseState::NotClosing),
|
||||
Http3State::Closing(error) => (Self::Closing, error),
|
||||
Http3State::Closed(error) => (Self::Closed, error),
|
||||
_ => return Ok(Self::NotClosing),
|
||||
};
|
||||
|
||||
if error.is_error() {
|
||||
Err(error.clone())
|
||||
Err(error)
|
||||
} else {
|
||||
Ok(state)
|
||||
}
|
||||
|
@ -452,7 +452,7 @@ impl<'a> UrlHandler<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
fn done(&mut self) -> bool {
|
||||
fn done(&self) -> bool {
|
||||
self.stream_handlers.is_empty() && self.url_queue.is_empty()
|
||||
}
|
||||
|
||||
|
|
|
@ -4,6 +4,8 @@
|
|||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
#![allow(clippy::future_not_send)]
|
||||
|
||||
use std::{
|
||||
collections::{HashMap, VecDeque},
|
||||
fmt::{self, Display},
|
||||
|
@ -32,7 +34,7 @@ use qlog::{events::EventImportance, streamer::QlogStreamer};
|
|||
use tokio::time::Sleep;
|
||||
use url::{Origin, Url};
|
||||
|
||||
use crate::{udp, SharedArgs};
|
||||
use crate::SharedArgs;
|
||||
|
||||
mod http09;
|
||||
mod http3;
|
||||
|
@ -326,13 +328,13 @@ enum Ready {
|
|||
|
||||
// Wait for the socket to be readable or the timeout to fire.
|
||||
async fn ready(
|
||||
socket: &udp::Socket,
|
||||
socket: &crate::udp::Socket,
|
||||
mut timeout: Option<&mut Pin<Box<Sleep>>>,
|
||||
) -> Result<Ready, io::Error> {
|
||||
let socket_ready = Box::pin(socket.readable()).map_ok(|()| Ready::Socket);
|
||||
let timeout_ready = timeout
|
||||
.as_mut()
|
||||
.map_or(Either::Right(futures::future::pending()), Either::Left)
|
||||
.map_or_else(|| Either::Right(futures::future::pending()), Either::Left)
|
||||
.map(|()| Ok(Ready::Timeout));
|
||||
select(socket_ready, timeout_ready).await.factor_first().0
|
||||
}
|
||||
|
@ -367,7 +369,7 @@ trait Client {
|
|||
|
||||
struct Runner<'a, H: Handler> {
|
||||
local_addr: SocketAddr,
|
||||
socket: &'a mut udp::Socket,
|
||||
socket: &'a mut crate::udp::Socket,
|
||||
client: H::Client,
|
||||
handler: H,
|
||||
timeout: Option<Pin<Box<Sleep>>>,
|
||||
|
@ -531,7 +533,7 @@ pub async fn client(mut args: Args) -> Res<()> {
|
|||
SocketAddr::V6(..) => SocketAddr::new(IpAddr::V6(Ipv6Addr::from([0; 16])), 0),
|
||||
};
|
||||
|
||||
let mut socket = udp::Socket::bind(local_addr)?;
|
||||
let mut socket = crate::udp::Socket::bind(local_addr)?;
|
||||
let real_local = socket.local_addr().unwrap();
|
||||
qinfo!(
|
||||
"{} Client connecting: {:?} -> {:?}",
|
||||
|
|
|
@ -119,6 +119,10 @@ pub struct QuicParameters {
|
|||
/// Whether to disable pacing.
|
||||
pub no_pacing: bool,
|
||||
|
||||
#[arg(long)]
|
||||
/// Whether to disable path MTU discovery.
|
||||
pub no_pmtud: bool,
|
||||
|
||||
#[arg(name = "preferred-address-v4", long)]
|
||||
/// An IPv4 address for the server preferred address.
|
||||
pub preferred_address_v4: Option<String>,
|
||||
|
@ -138,6 +142,7 @@ impl Default for QuicParameters {
|
|||
idle_timeout: 30,
|
||||
congestion_control: CongestionControlAlgorithm::NewReno,
|
||||
no_pacing: false,
|
||||
no_pmtud: false,
|
||||
preferred_address_v4: None,
|
||||
preferred_address_v6: None,
|
||||
}
|
||||
|
@ -204,7 +209,8 @@ impl QuicParameters {
|
|||
.max_streams(StreamType::UniDi, self.max_streams_uni)
|
||||
.idle_timeout(Duration::from_secs(self.idle_timeout))
|
||||
.cc_algorithm(self.congestion_control)
|
||||
.pacing(!self.no_pacing);
|
||||
.pacing(!self.no_pacing)
|
||||
.pmtud(!self.no_pmtud);
|
||||
|
||||
if let Some(&first) = self.quic_version.first() {
|
||||
let all = if self.quic_version[1..].contains(&first) {
|
||||
|
|
|
@ -10,7 +10,7 @@ use neqo_common::{event::Provider, hex, qdebug, qerror, qinfo, qwarn, Datagram};
|
|||
use neqo_crypto::{generate_ech_keys, random, AllowZeroRtt, AntiReplay};
|
||||
use neqo_http3::Error;
|
||||
use neqo_transport::{
|
||||
server::{ActiveConnectionRef, Server, ValidateAddress},
|
||||
server::{ConnectionRef, Server, ValidateAddress},
|
||||
ConnectionEvent, ConnectionIdGenerator, Output, State, StreamId,
|
||||
};
|
||||
use regex::Regex;
|
||||
|
@ -47,7 +47,7 @@ impl HttpServer {
|
|||
args.shared.quic_parameters.get(&args.shared.alpn),
|
||||
)?;
|
||||
|
||||
server.set_ciphers(&args.get_ciphers());
|
||||
server.set_ciphers(args.get_ciphers());
|
||||
server.set_qlog_dir(args.shared.qlog_dir.clone());
|
||||
if args.retry {
|
||||
server.set_validation(ValidateAddress::Always);
|
||||
|
@ -75,12 +75,7 @@ impl HttpServer {
|
|||
})
|
||||
}
|
||||
|
||||
fn save_partial(
|
||||
&mut self,
|
||||
stream_id: StreamId,
|
||||
partial: Vec<u8>,
|
||||
conn: &mut ActiveConnectionRef,
|
||||
) {
|
||||
fn save_partial(&mut self, stream_id: StreamId, partial: Vec<u8>, conn: &ConnectionRef) {
|
||||
let url_dbg = String::from_utf8(partial.clone())
|
||||
.unwrap_or_else(|_| format!("<invalid UTF-8: {}>", hex(&partial)));
|
||||
if partial.len() < 4096 {
|
||||
|
@ -92,12 +87,7 @@ impl HttpServer {
|
|||
}
|
||||
}
|
||||
|
||||
fn write(
|
||||
&mut self,
|
||||
stream_id: StreamId,
|
||||
data: Option<Vec<u8>>,
|
||||
conn: &mut ActiveConnectionRef,
|
||||
) {
|
||||
fn write(&mut self, stream_id: StreamId, data: Option<Vec<u8>>, conn: &ConnectionRef) {
|
||||
let resp = data.unwrap_or_else(|| Vec::from(&b"404 That request was nonsense\r\n"[..]));
|
||||
if let Some(stream_state) = self.write_state.get_mut(&stream_id) {
|
||||
match stream_state.data_to_send {
|
||||
|
@ -120,7 +110,7 @@ impl HttpServer {
|
|||
}
|
||||
}
|
||||
|
||||
fn stream_readable(&mut self, stream_id: StreamId, conn: &mut ActiveConnectionRef) {
|
||||
fn stream_readable(&mut self, stream_id: StreamId, conn: &ConnectionRef) {
|
||||
if !stream_id.is_client_initiated() || !stream_id.is_bidi() {
|
||||
qdebug!("Stream {} not client-initiated bidi, ignoring", stream_id);
|
||||
return;
|
||||
|
@ -176,7 +166,7 @@ impl HttpServer {
|
|||
self.write(stream_id, resp, conn);
|
||||
}
|
||||
|
||||
fn stream_writable(&mut self, stream_id: StreamId, conn: &mut ActiveConnectionRef) {
|
||||
fn stream_writable(&mut self, stream_id: StreamId, conn: &ConnectionRef) {
|
||||
match self.write_state.get_mut(&stream_id) {
|
||||
None => {
|
||||
qwarn!("Unknown stream {stream_id}, ignoring event");
|
||||
|
@ -190,7 +180,6 @@ impl HttpServer {
|
|||
.unwrap();
|
||||
qdebug!("Wrote {}", sent);
|
||||
*offset += sent;
|
||||
self.server.add_to_waiting(conn);
|
||||
if *offset == data.len() {
|
||||
qinfo!("Sent {sent} on {stream_id}, closing");
|
||||
conn.borrow_mut().stream_close_send(stream_id).unwrap();
|
||||
|
@ -210,8 +199,11 @@ impl super::HttpServer for HttpServer {
|
|||
}
|
||||
|
||||
fn process_events(&mut self, now: Instant) {
|
||||
// `ActiveConnectionRef` `Hash` implementation doesn’t access any of the interior mutable
|
||||
// types.
|
||||
#[allow(clippy::mutable_key_type)]
|
||||
let active_conns = self.server.active_connections();
|
||||
for mut acr in active_conns {
|
||||
for acr in active_conns {
|
||||
loop {
|
||||
let event = match acr.borrow_mut().next_event() {
|
||||
None => break,
|
||||
|
@ -223,10 +215,10 @@ impl super::HttpServer for HttpServer {
|
|||
.insert(stream_id, HttpStreamState::default());
|
||||
}
|
||||
ConnectionEvent::RecvStreamReadable { stream_id } => {
|
||||
self.stream_readable(stream_id, &mut acr);
|
||||
self.stream_readable(stream_id, &acr);
|
||||
}
|
||||
ConnectionEvent::SendStreamWritable { stream_id } => {
|
||||
self.stream_writable(stream_id, &mut acr);
|
||||
self.stream_writable(stream_id, &acr);
|
||||
}
|
||||
ConnectionEvent::StateChange(State::Connected) => {
|
||||
acr.connection()
|
||||
|
|
|
@ -54,7 +54,7 @@ impl HttpServer {
|
|||
)
|
||||
.expect("We cannot make a server!");
|
||||
|
||||
server.set_ciphers(&args.get_ciphers());
|
||||
server.set_ciphers(args.get_ciphers());
|
||||
server.set_qlog_dir(args.shared.qlog_dir.clone());
|
||||
if args.retry {
|
||||
server.set_validation(ValidateAddress::Always);
|
||||
|
@ -91,7 +91,7 @@ impl super::HttpServer for HttpServer {
|
|||
while let Some(event) = self.server.next_event() {
|
||||
match event {
|
||||
Http3ServerEvent::Headers {
|
||||
mut stream,
|
||||
stream,
|
||||
headers,
|
||||
fin,
|
||||
} => {
|
||||
|
@ -138,17 +138,17 @@ impl super::HttpServer for HttpServer {
|
|||
Header::new("content-length", response.remaining.to_string()),
|
||||
])
|
||||
.unwrap();
|
||||
response.send(&mut stream);
|
||||
response.send(&stream);
|
||||
if response.done() {
|
||||
stream.stream_close_send().unwrap();
|
||||
} else {
|
||||
self.remaining_data.insert(stream.stream_id(), response);
|
||||
}
|
||||
}
|
||||
Http3ServerEvent::DataWritable { mut stream } => {
|
||||
Http3ServerEvent::DataWritable { stream } => {
|
||||
if self.posts.get_mut(&stream).is_none() {
|
||||
if let Some(remaining) = self.remaining_data.get_mut(&stream.stream_id()) {
|
||||
remaining.send(&mut stream);
|
||||
remaining.send(&stream);
|
||||
if remaining.done() {
|
||||
self.remaining_data.remove(&stream.stream_id());
|
||||
stream.stream_close_send().unwrap();
|
||||
|
@ -157,11 +157,7 @@ impl super::HttpServer for HttpServer {
|
|||
}
|
||||
}
|
||||
|
||||
Http3ServerEvent::Data {
|
||||
mut stream,
|
||||
data,
|
||||
fin,
|
||||
} => {
|
||||
Http3ServerEvent::Data { stream, data, fin } => {
|
||||
if let Some(received) = self.posts.get_mut(&stream) {
|
||||
*received += data.len();
|
||||
}
|
||||
|
@ -210,7 +206,7 @@ impl From<Vec<u8>> for ResponseData {
|
|||
}
|
||||
|
||||
impl ResponseData {
|
||||
fn repeat(buf: &'static [u8], total: usize) -> Self {
|
||||
const fn repeat(buf: &'static [u8], total: usize) -> Self {
|
||||
Self {
|
||||
data: Cow::Borrowed(buf),
|
||||
offset: 0,
|
||||
|
@ -218,7 +214,7 @@ impl ResponseData {
|
|||
}
|
||||
}
|
||||
|
||||
fn send(&mut self, stream: &mut Http3OrWebTransportStream) {
|
||||
fn send(&mut self, stream: &Http3OrWebTransportStream) {
|
||||
while self.remaining > 0 {
|
||||
let end = min(self.data.len(), self.offset + self.remaining);
|
||||
let slice = &self.data[self.offset..end];
|
||||
|
@ -238,7 +234,7 @@ impl ResponseData {
|
|||
}
|
||||
}
|
||||
|
||||
fn done(&self) -> bool {
|
||||
const fn done(&self) -> bool {
|
||||
self.remaining == 0
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,6 +4,8 @@
|
|||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
#![allow(clippy::future_not_send)]
|
||||
|
||||
use std::{
|
||||
cell::RefCell,
|
||||
fmt::{self, Display},
|
||||
|
@ -29,7 +31,7 @@ use neqo_crypto::{
|
|||
use neqo_transport::{Output, RandomConnectionIdGenerator, Version};
|
||||
use tokio::time::Sleep;
|
||||
|
||||
use crate::{udp, SharedArgs};
|
||||
use crate::SharedArgs;
|
||||
|
||||
const ANTI_REPLAY_WINDOW: Duration = Duration::from_secs(10);
|
||||
|
||||
|
@ -194,7 +196,7 @@ pub struct ServerRunner {
|
|||
now: Box<dyn Fn() -> Instant>,
|
||||
server: Box<dyn HttpServer>,
|
||||
timeout: Option<Pin<Box<Sleep>>>,
|
||||
sockets: Vec<(SocketAddr, udp::Socket)>,
|
||||
sockets: Vec<(SocketAddr, crate::udp::Socket)>,
|
||||
}
|
||||
|
||||
impl ServerRunner {
|
||||
|
@ -202,7 +204,7 @@ impl ServerRunner {
|
|||
pub fn new(
|
||||
now: Box<dyn Fn() -> Instant>,
|
||||
server: Box<dyn HttpServer>,
|
||||
sockets: Vec<(SocketAddr, udp::Socket)>,
|
||||
sockets: Vec<(SocketAddr, crate::udp::Socket)>,
|
||||
) -> Self {
|
||||
Self {
|
||||
now,
|
||||
|
@ -213,7 +215,7 @@ impl ServerRunner {
|
|||
}
|
||||
|
||||
/// Tries to find a socket, but then just falls back to sending from the first.
|
||||
fn find_socket(&mut self, addr: SocketAddr) -> &mut udp::Socket {
|
||||
fn find_socket(&mut self, addr: SocketAddr) -> &mut crate::udp::Socket {
|
||||
let ((_host, first_socket), rest) = self.sockets.split_first_mut().unwrap();
|
||||
rest.iter_mut()
|
||||
.map(|(_host, socket)| socket)
|
||||
|
@ -261,7 +263,7 @@ impl ServerRunner {
|
|||
let timeout_ready = self
|
||||
.timeout
|
||||
.as_mut()
|
||||
.map_or(Either::Right(futures::future::pending()), Either::Left)
|
||||
.map_or_else(|| Either::Right(futures::future::pending()), Either::Left)
|
||||
.map(|()| Ok(Ready::Timeout));
|
||||
select(sockets_ready, timeout_ready).await.factor_first().0
|
||||
}
|
||||
|
@ -363,7 +365,7 @@ pub async fn server(mut args: Args) -> Res<()> {
|
|||
let sockets = hosts
|
||||
.into_iter()
|
||||
.map(|host| {
|
||||
let socket = udp::Socket::bind(host)?;
|
||||
let socket = crate::udp::Socket::bind(host)?;
|
||||
let local_addr = socket.local_addr()?;
|
||||
qinfo!("Server waiting for connection on: {local_addr:?}");
|
||||
|
||||
|
|
|
@ -4,215 +4,67 @@
|
|||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
#![allow(clippy::missing_errors_doc)] // Functions simply delegate to tokio and quinn-udp.
|
||||
#![allow(clippy::missing_panics_doc)] // Functions simply delegate to tokio and quinn-udp.
|
||||
use std::{io, net::SocketAddr};
|
||||
|
||||
use std::{
|
||||
io::{self, IoSliceMut},
|
||||
net::{SocketAddr, ToSocketAddrs},
|
||||
slice,
|
||||
};
|
||||
use neqo_common::Datagram;
|
||||
|
||||
use neqo_common::{Datagram, IpTos};
|
||||
use quinn_udp::{EcnCodepoint, RecvMeta, Transmit, UdpSocketState};
|
||||
use tokio::io::Interest;
|
||||
|
||||
/// Socket receive buffer size.
|
||||
/// Ideally this would live in [`neqo-udp`]. [`neqo-udp`] is used in Firefox.
|
||||
/// Firefox uses `cargo vet`. [`tokio`] the dependency of [`neqo-udp`] is not
|
||||
/// audited as `safe-to-deploy`. `cargo vet` will require `safe-to-deploy` for
|
||||
/// [`tokio`] even when behind a feature flag.
|
||||
///
|
||||
/// Allows reading multiple datagrams in a single [`Socket::recv`] call.
|
||||
const RECV_BUF_SIZE: usize = u16::MAX as usize;
|
||||
|
||||
/// See <https://github.com/mozilla/cargo-vet/issues/626>.
|
||||
pub struct Socket {
|
||||
#[allow(unknown_lints)] // available with Rust v1.75
|
||||
#[allow(clippy::struct_field_names)]
|
||||
socket: tokio::net::UdpSocket,
|
||||
state: UdpSocketState,
|
||||
recv_buf: Vec<u8>,
|
||||
state: quinn_udp::UdpSocketState,
|
||||
inner: tokio::net::UdpSocket,
|
||||
}
|
||||
|
||||
impl Socket {
|
||||
/// Calls [`std::net::UdpSocket::bind`] and instantiates [`quinn_udp::UdpSocketState`].
|
||||
pub fn bind<A: ToSocketAddrs>(addr: A) -> Result<Self, io::Error> {
|
||||
/// Create a new [`Socket`] bound to the provided address, not managed externally.
|
||||
pub fn bind<A: std::net::ToSocketAddrs>(addr: A) -> Result<Self, io::Error> {
|
||||
let socket = std::net::UdpSocket::bind(addr)?;
|
||||
|
||||
Ok(Self {
|
||||
state: quinn_udp::UdpSocketState::new((&socket).into())?,
|
||||
socket: tokio::net::UdpSocket::from_std(socket)?,
|
||||
recv_buf: vec![0; RECV_BUF_SIZE],
|
||||
inner: tokio::net::UdpSocket::from_std(socket)?,
|
||||
})
|
||||
}
|
||||
|
||||
/// See [`tokio::net::UdpSocket::local_addr`].
|
||||
pub fn local_addr(&self) -> io::Result<SocketAddr> {
|
||||
self.socket.local_addr()
|
||||
self.inner.local_addr()
|
||||
}
|
||||
|
||||
/// See [`tokio::net::UdpSocket::writable`].
|
||||
pub async fn writable(&self) -> Result<(), io::Error> {
|
||||
self.socket.writable().await
|
||||
self.inner.writable().await
|
||||
}
|
||||
|
||||
/// See [`tokio::net::UdpSocket::readable`].
|
||||
pub async fn readable(&self) -> Result<(), io::Error> {
|
||||
self.socket.readable().await
|
||||
self.inner.readable().await
|
||||
}
|
||||
|
||||
/// Send the UDP datagram on the specified socket.
|
||||
/// Send a [`Datagram`] on the given [`Socket`].
|
||||
pub fn send(&self, d: &Datagram) -> io::Result<()> {
|
||||
let transmit = Transmit {
|
||||
destination: d.destination(),
|
||||
ecn: EcnCodepoint::from_bits(Into::<u8>::into(d.tos())),
|
||||
contents: d,
|
||||
segment_size: None,
|
||||
src_ip: None,
|
||||
};
|
||||
|
||||
self.socket.try_io(Interest::WRITABLE, || {
|
||||
self.state.send((&self.socket).into(), &transmit)
|
||||
})?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Receive a UDP datagram on the specified socket.
|
||||
pub fn recv(&mut self, local_address: &SocketAddr) -> Result<Vec<Datagram>, io::Error> {
|
||||
let mut meta = RecvMeta::default();
|
||||
|
||||
match self.socket.try_io(Interest::READABLE, || {
|
||||
self.state.recv(
|
||||
(&self.socket).into(),
|
||||
&mut [IoSliceMut::new(&mut self.recv_buf)],
|
||||
slice::from_mut(&mut meta),
|
||||
)
|
||||
}) {
|
||||
Ok(n) => {
|
||||
assert_eq!(n, 1, "only passed one slice");
|
||||
}
|
||||
Err(ref err)
|
||||
if err.kind() == io::ErrorKind::WouldBlock
|
||||
|| err.kind() == io::ErrorKind::Interrupted =>
|
||||
{
|
||||
return Ok(vec![])
|
||||
}
|
||||
Err(err) => {
|
||||
return Err(err);
|
||||
}
|
||||
};
|
||||
|
||||
if meta.len == 0 {
|
||||
eprintln!("zero length datagram received?");
|
||||
return Ok(vec![]);
|
||||
}
|
||||
if meta.len == self.recv_buf.len() {
|
||||
eprintln!(
|
||||
"Might have received more than {} bytes",
|
||||
self.recv_buf.len()
|
||||
);
|
||||
}
|
||||
|
||||
Ok(self.recv_buf[0..meta.len]
|
||||
.chunks(meta.stride.min(self.recv_buf.len()))
|
||||
.map(|d| {
|
||||
Datagram::new(
|
||||
meta.addr,
|
||||
*local_address,
|
||||
meta.ecn.map(|n| IpTos::from(n as u8)).unwrap_or_default(),
|
||||
None, // TODO: get the real TTL https://github.com/quinn-rs/quinn/issues/1749
|
||||
d,
|
||||
)
|
||||
self.inner.try_io(tokio::io::Interest::WRITABLE, || {
|
||||
neqo_udp::send_inner(&self.state, (&self.inner).into(), d)
|
||||
})
|
||||
}
|
||||
|
||||
/// Receive a batch of [`Datagram`]s on the given [`Socket`], each set with
|
||||
/// the provided local address.
|
||||
pub fn recv(&self, local_address: &SocketAddr) -> Result<Vec<Datagram>, io::Error> {
|
||||
self.inner
|
||||
.try_io(tokio::io::Interest::READABLE, || {
|
||||
neqo_udp::recv_inner(local_address, &self.state, (&self.inner).into())
|
||||
})
|
||||
.or_else(|e| {
|
||||
if e.kind() == io::ErrorKind::WouldBlock {
|
||||
Ok(vec![])
|
||||
} else {
|
||||
Err(e)
|
||||
}
|
||||
})
|
||||
.collect())
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use neqo_common::{IpTosDscp, IpTosEcn};
|
||||
|
||||
use super::*;
|
||||
|
||||
#[tokio::test]
|
||||
async fn datagram_tos() -> Result<(), io::Error> {
|
||||
let sender = Socket::bind("127.0.0.1:0")?;
|
||||
let receiver_addr: SocketAddr = "127.0.0.1:0".parse().unwrap();
|
||||
let mut receiver = Socket::bind(receiver_addr)?;
|
||||
|
||||
let datagram = Datagram::new(
|
||||
sender.local_addr()?,
|
||||
receiver.local_addr()?,
|
||||
IpTos::from((IpTosDscp::Le, IpTosEcn::Ect1)),
|
||||
None,
|
||||
"Hello, world!".as_bytes().to_vec(),
|
||||
);
|
||||
|
||||
sender.writable().await?;
|
||||
sender.send(&datagram)?;
|
||||
|
||||
receiver.readable().await?;
|
||||
let received_datagram = receiver
|
||||
.recv(&receiver_addr)
|
||||
.expect("receive to succeed")
|
||||
.into_iter()
|
||||
.next()
|
||||
.expect("receive to yield datagram");
|
||||
|
||||
// Assert that the ECN is correct.
|
||||
assert_eq!(
|
||||
IpTosEcn::from(datagram.tos()),
|
||||
IpTosEcn::from(received_datagram.tos())
|
||||
);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Expect [`Socket::recv`] to handle multiple [`Datagram`]s on GRO read.
|
||||
#[tokio::test]
|
||||
#[cfg_attr(not(any(target_os = "linux", target_os = "windows")), ignore)]
|
||||
async fn many_datagrams_through_gro() -> Result<(), io::Error> {
|
||||
const SEGMENT_SIZE: usize = 128;
|
||||
|
||||
let sender = Socket::bind("127.0.0.1:0")?;
|
||||
let receiver_addr: SocketAddr = "127.0.0.1:0".parse().unwrap();
|
||||
let mut receiver = Socket::bind(receiver_addr)?;
|
||||
|
||||
// `neqo_common::udp::Socket::send` does not yet
|
||||
// (https://github.com/mozilla/neqo/issues/1693) support GSO. Use
|
||||
// `quinn_udp` directly.
|
||||
let max_gso_segments = sender.state.max_gso_segments();
|
||||
let msg = vec![0xAB; SEGMENT_SIZE * max_gso_segments];
|
||||
let transmit = Transmit {
|
||||
destination: receiver.local_addr()?,
|
||||
ecn: EcnCodepoint::from_bits(Into::<u8>::into(IpTos::from((
|
||||
IpTosDscp::Le,
|
||||
IpTosEcn::Ect1,
|
||||
)))),
|
||||
contents: &msg,
|
||||
segment_size: Some(SEGMENT_SIZE),
|
||||
src_ip: None,
|
||||
};
|
||||
sender.writable().await?;
|
||||
sender.socket.try_io(Interest::WRITABLE, || {
|
||||
sender.state.send((&sender.socket).into(), &transmit)
|
||||
})?;
|
||||
|
||||
// Allow for one GSO sendmmsg to result in multiple GRO recvmmsg.
|
||||
let mut num_received = 0;
|
||||
while num_received < max_gso_segments {
|
||||
receiver.readable().await?;
|
||||
receiver
|
||||
.recv(&receiver_addr)
|
||||
.expect("receive to succeed")
|
||||
.into_iter()
|
||||
.for_each(|d| {
|
||||
assert_eq!(
|
||||
SEGMENT_SIZE,
|
||||
d.len(),
|
||||
"Expect received datagrams to have same length as sent datagrams."
|
||||
);
|
||||
num_received += 1;
|
||||
});
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1 +1 @@
|
|||
{"files":{"Cargo.toml":"444cb61aa7dc0c89b6c60574f3bf4661ec74c1cf88ddb87bba3ad98c5a84b932","build.rs":"306b2f909a25ae38daf5404a4e128d2a94e8975b70870864c2a71cafec9717c7","src/codec.rs":"fd239f75d374db6ff744211344c82bcd19ecf753e07410e1fe37732bbb81dfe9","src/datagram.rs":"56b4c1001c6bfb9394e4b3f968e2e17f55db774510ea576b91e127a6b32300d0","src/event.rs":"106ca6c4afb107fa49a1bc72f5eb4ae95f4baa1ba19736aa38c8ba973774c160","src/fuzz.rs":"1ca74a34bdc97fedecf8a63c4a13cc487d1b2212398fb76f67792c822002138d","src/header.rs":"467b947f78bfe354d8bb51e8df0c2be69e75a45e2be688d81f0d268aa77c89ef","src/hrtime.rs":"112dc758e65301b8a7a508b125d3d61063180d432bffaec566a050d4f907ab18","src/incrdecoder.rs":"577c32b9ace51f2daaf940be6d0c391c4f55cd42ef6848c68c1ffc970d8c57b5","src/lib.rs":"a8efb2d2c098575ad28069d9da1be450784adf1fecb9e4a9cf30928e70092e49","src/log.rs":"6ed99e15707c4256ae793011ed2f4b33aa81fed70205aaf5f8d3cd11ad451cf0","src/qlog.rs":"9b081f32bf158fd340300693acc97fe0554b617ae664eba86e4d3572e2b1e16e","src/tos.rs":"087cd9b12a2510f05605e755d85c07179817c22670fe1b5d6db987357f77b38e","tests/log.rs":"a11e21fb570258ca93bb40e3923817d381e1e605accbc3aed1df5a0a9918b41d"},"package":null}
|
||||
{"files":{"Cargo.toml":"6474d7f764179fabd82c4b8f7b8ea95c7a538035adb968301a077613478c664e","build.rs":"306b2f909a25ae38daf5404a4e128d2a94e8975b70870864c2a71cafec9717c7","src/codec.rs":"30a5045a351dc4eee960d8ffc8ec275f1806d70f3805cd8bdbcfe63dee0cc0b1","src/datagram.rs":"2acecfcbecfbb767ea920e3b22388e67b31fcda776cae5b2d7ecbc67dd9febf7","src/event.rs":"106ca6c4afb107fa49a1bc72f5eb4ae95f4baa1ba19736aa38c8ba973774c160","src/fuzz.rs":"1ca74a34bdc97fedecf8a63c4a13cc487d1b2212398fb76f67792c822002138d","src/header.rs":"480a7848466249a78acddbf0bc0b4a096189abc14a89ad1a0943be571add2c2b","src/hrtime.rs":"9c60f13ae9429a9ddb318502b52eba2225e1dbd77637442a0048fb4b0f7acccd","src/incrdecoder.rs":"5c45034e61e75c76d2bca8b075c3e7a3cdd8af8c82b67c76283a2b08ab11846b","src/lib.rs":"2381fc00127a7eaf2265c3a13dc1e1d5843e048f3a8a1c97f1e6621c038de380","src/log.rs":"6ed99e15707c4256ae793011ed2f4b33aa81fed70205aaf5f8d3cd11ad451cf0","src/qlog.rs":"1cee4ff3bc9bf735a1bb913e1515ef240a70326a34c56a6ce89de02bc9f3459c","src/tos.rs":"28fd9acfce06f68ac6691efd2609618850182f77ef3717ce2db07bfac19a9396","tests/log.rs":"a11e21fb570258ca93bb40e3923817d381e1e605accbc3aed1df5a0a9918b41d"},"package":null}
|
|
@ -13,9 +13,23 @@
|
|||
edition = "2021"
|
||||
rust-version = "1.76.0"
|
||||
name = "neqo-common"
|
||||
version = "0.7.9"
|
||||
version = "0.8.1"
|
||||
authors = ["The Neqo Authors <necko@mozilla.com>"]
|
||||
description = "Neqo, the Mozilla implementation of QUIC in Rust."
|
||||
homepage = "https://github.com/mozilla/neqo/"
|
||||
readme = "../README.md"
|
||||
keywords = [
|
||||
"quic",
|
||||
"http3",
|
||||
"neqo",
|
||||
"mozilla",
|
||||
"ietf",
|
||||
"firefox",
|
||||
]
|
||||
categories = [
|
||||
"network-programming",
|
||||
"web-programming",
|
||||
]
|
||||
license = "MIT OR Apache-2.0"
|
||||
repository = "https://github.com/mozilla/neqo/"
|
||||
|
||||
|
@ -49,11 +63,6 @@ version = "0.3"
|
|||
features = ["formatting"]
|
||||
default-features = false
|
||||
|
||||
[dev-dependencies.criterion]
|
||||
version = "0.5"
|
||||
features = ["html_reports"]
|
||||
default-features = false
|
||||
|
||||
[dev-dependencies.test-fixture]
|
||||
path = "../test-fixture"
|
||||
|
||||
|
@ -65,6 +74,17 @@ ci = []
|
|||
version = "0.3"
|
||||
features = ["timeapi"]
|
||||
|
||||
[lints.clippy]
|
||||
multiple_crate_versions = "allow"
|
||||
|
||||
[lints.clippy.cargo]
|
||||
level = "warn"
|
||||
priority = -1
|
||||
|
||||
[lints.clippy.nursery]
|
||||
level = "warn"
|
||||
priority = -1
|
||||
|
||||
[lints.clippy.pedantic]
|
||||
level = "warn"
|
||||
priority = -1
|
||||
|
|
|
@ -17,19 +17,19 @@ pub struct Decoder<'a> {
|
|||
impl<'a> Decoder<'a> {
|
||||
/// Make a new view of the provided slice.
|
||||
#[must_use]
|
||||
pub fn new(buf: &[u8]) -> Decoder {
|
||||
pub const fn new(buf: &[u8]) -> Decoder {
|
||||
Decoder { buf, offset: 0 }
|
||||
}
|
||||
|
||||
/// Get the number of bytes remaining until the end.
|
||||
#[must_use]
|
||||
pub fn remaining(&self) -> usize {
|
||||
pub const fn remaining(&self) -> usize {
|
||||
self.buf.len() - self.offset
|
||||
}
|
||||
|
||||
/// The number of bytes from the underlying slice that have been decoded.
|
||||
#[must_use]
|
||||
pub fn offset(&self) -> usize {
|
||||
pub const fn offset(&self) -> usize {
|
||||
self.offset
|
||||
}
|
||||
|
||||
|
@ -73,7 +73,8 @@ impl<'a> Decoder<'a> {
|
|||
}
|
||||
|
||||
/// Provides the next byte without moving the read position.
|
||||
pub fn peek_byte(&mut self) -> Option<u8> {
|
||||
#[must_use]
|
||||
pub const fn peek_byte(&self) -> Option<u8> {
|
||||
if self.remaining() < 1 {
|
||||
None
|
||||
} else {
|
||||
|
@ -170,7 +171,7 @@ impl<'a> Debug for Decoder<'a> {
|
|||
|
||||
impl<'a> From<&'a [u8]> for Decoder<'a> {
|
||||
#[must_use]
|
||||
fn from(buf: &'a [u8]) -> Decoder<'a> {
|
||||
fn from(buf: &'a [u8]) -> Self {
|
||||
Decoder::new(buf)
|
||||
}
|
||||
}
|
||||
|
@ -180,7 +181,7 @@ where
|
|||
T: AsRef<[u8]>,
|
||||
{
|
||||
#[must_use]
|
||||
fn from(buf: &'a T) -> Decoder<'a> {
|
||||
fn from(buf: &'a T) -> Self {
|
||||
Decoder::new(buf.as_ref())
|
||||
}
|
||||
}
|
||||
|
@ -632,7 +633,7 @@ mod tests {
|
|||
|
||||
#[test]
|
||||
#[should_panic(expected = "Varint value too large")]
|
||||
fn encoded_length_oob() {
|
||||
const fn encoded_length_oob() {
|
||||
_ = Encoder::varint_len(1 << 62);
|
||||
}
|
||||
|
||||
|
|
|
@ -13,47 +13,34 @@ pub struct Datagram {
|
|||
src: SocketAddr,
|
||||
dst: SocketAddr,
|
||||
tos: IpTos,
|
||||
ttl: Option<u8>,
|
||||
d: Vec<u8>,
|
||||
}
|
||||
|
||||
impl Datagram {
|
||||
pub fn new<V: Into<Vec<u8>>>(
|
||||
src: SocketAddr,
|
||||
dst: SocketAddr,
|
||||
tos: IpTos,
|
||||
ttl: Option<u8>,
|
||||
d: V,
|
||||
) -> Self {
|
||||
pub fn new<V: Into<Vec<u8>>>(src: SocketAddr, dst: SocketAddr, tos: IpTos, d: V) -> Self {
|
||||
Self {
|
||||
src,
|
||||
dst,
|
||||
tos,
|
||||
ttl,
|
||||
d: d.into(),
|
||||
}
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn source(&self) -> SocketAddr {
|
||||
pub const fn source(&self) -> SocketAddr {
|
||||
self.src
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn destination(&self) -> SocketAddr {
|
||||
pub const fn destination(&self) -> SocketAddr {
|
||||
self.dst
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn tos(&self) -> IpTos {
|
||||
pub const fn tos(&self) -> IpTos {
|
||||
self.tos
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn ttl(&self) -> Option<u8> {
|
||||
self.ttl
|
||||
}
|
||||
|
||||
pub fn set_tos(&mut self, tos: IpTos) {
|
||||
self.tos = tos;
|
||||
}
|
||||
|
@ -71,9 +58,8 @@ impl std::fmt::Debug for Datagram {
|
|||
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||
write!(
|
||||
f,
|
||||
"Datagram {:?} TTL {:?} {:?}->{:?}: {}",
|
||||
"Datagram {:?} {:?}->{:?}: {}",
|
||||
self.tos,
|
||||
self.ttl,
|
||||
self.src,
|
||||
self.dst,
|
||||
hex_with_len(&self.d)
|
||||
|
@ -89,6 +75,6 @@ fn fmt_datagram() {
|
|||
let d = datagram([0; 1].to_vec());
|
||||
assert_eq!(
|
||||
&format!("{d:?}"),
|
||||
"Datagram IpTos(Cs0, Ect0) TTL Some(128) [fe80::1]:443->[fe80::1]:443: [1]: 00"
|
||||
"Datagram IpTos(Cs0, Ect0) [fe80::1]:443->[fe80::1]:443: [1]: 00"
|
||||
);
|
||||
}
|
||||
|
|
|
@ -13,8 +13,8 @@ pub struct Header {
|
|||
impl Header {
|
||||
pub fn new<N, V>(name: N, value: V) -> Self
|
||||
where
|
||||
N: Into<String> + ?Sized,
|
||||
V: Into<String> + ?Sized,
|
||||
N: Into<String>,
|
||||
V: Into<String>,
|
||||
{
|
||||
Self {
|
||||
name: name.into(),
|
||||
|
|
|
@ -22,8 +22,8 @@ use winapi::um::timeapi::{timeBeginPeriod, timeEndPeriod};
|
|||
struct Period(u8);
|
||||
|
||||
impl Period {
|
||||
const MAX: Period = Period(16);
|
||||
const MIN: Period = Period(1);
|
||||
const MAX: Self = Self(16);
|
||||
const MIN: Self = Self(1);
|
||||
|
||||
#[cfg(windows)]
|
||||
fn as_uint(self) -> UINT {
|
||||
|
@ -63,8 +63,9 @@ impl PeriodSet {
|
|||
|
||||
fn remove(&mut self, p: Period) {
|
||||
if p != Period::MAX {
|
||||
debug_assert_ne!(*self.idx(p), 0);
|
||||
*self.idx(p) -= 1;
|
||||
let p = self.idx(p);
|
||||
debug_assert_ne!(*p, 0);
|
||||
*p -= 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -219,7 +220,7 @@ pub struct Handle {
|
|||
impl Handle {
|
||||
const HISTORY: usize = 8;
|
||||
|
||||
fn new(hrt: Rc<RefCell<Time>>, active: Period) -> Self {
|
||||
const fn new(hrt: Rc<RefCell<Time>>, active: Period) -> Self {
|
||||
Self {
|
||||
hrt,
|
||||
active,
|
||||
|
@ -287,6 +288,7 @@ impl Time {
|
|||
}
|
||||
|
||||
#[allow(clippy::unused_self)] // Only on some platforms is it unused.
|
||||
#[allow(clippy::missing_const_for_fn)] // Only const on some platforms where the function is empty.
|
||||
fn start(&self) {
|
||||
#[cfg(target_os = "macos")]
|
||||
{
|
||||
|
@ -306,6 +308,7 @@ impl Time {
|
|||
}
|
||||
|
||||
#[allow(clippy::unused_self)] // Only on some platforms is it unused.
|
||||
#[allow(clippy::missing_const_for_fn)] // Only const on some platforms where the function is empty.
|
||||
fn stop(&self) {
|
||||
#[cfg(windows)]
|
||||
{
|
||||
|
@ -344,7 +347,7 @@ impl Time {
|
|||
HR_TIME.with(|r| {
|
||||
let mut b = r.borrow_mut();
|
||||
let hrt = b.upgrade().unwrap_or_else(|| {
|
||||
let hrt = Rc::new(RefCell::new(Time::new()));
|
||||
let hrt = Rc::new(RefCell::new(Self::new()));
|
||||
*b = Rc::downgrade(&hrt);
|
||||
hrt
|
||||
});
|
||||
|
|
|
@ -39,8 +39,10 @@ impl IncrementalDecoderUint {
|
|||
None
|
||||
}
|
||||
} else {
|
||||
let (v, remaining) = match dv.decode_byte() {
|
||||
Some(b) => (
|
||||
let (v, remaining) = dv.decode_byte().map_or_else(
|
||||
|| unreachable!(),
|
||||
|b| {
|
||||
(
|
||||
u64::from(b & 0x3f),
|
||||
match b >> 6 {
|
||||
0 => 0,
|
||||
|
@ -49,9 +51,9 @@ impl IncrementalDecoderUint {
|
|||
3 => 7,
|
||||
_ => unreachable!(),
|
||||
},
|
||||
),
|
||||
None => unreachable!(),
|
||||
};
|
||||
)
|
||||
},
|
||||
);
|
||||
self.remaining = Some(remaining);
|
||||
self.v = v;
|
||||
if remaining == 0 {
|
||||
|
@ -63,7 +65,7 @@ impl IncrementalDecoderUint {
|
|||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn decoding_in_progress(&self) -> bool {
|
||||
pub const fn decoding_in_progress(&self) -> bool {
|
||||
self.remaining.is_some()
|
||||
}
|
||||
}
|
||||
|
@ -76,7 +78,7 @@ pub struct IncrementalDecoderBuffer {
|
|||
|
||||
impl IncrementalDecoderBuffer {
|
||||
#[must_use]
|
||||
pub fn new(n: usize) -> Self {
|
||||
pub const fn new(n: usize) -> Self {
|
||||
Self {
|
||||
v: Vec::new(),
|
||||
remaining: n,
|
||||
|
@ -84,7 +86,7 @@ impl IncrementalDecoderBuffer {
|
|||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn min_remaining(&self) -> usize {
|
||||
pub const fn min_remaining(&self) -> usize {
|
||||
self.remaining
|
||||
}
|
||||
|
||||
|
@ -124,7 +126,7 @@ impl IncrementalDecoderIgnore {
|
|||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn min_remaining(&self) -> usize {
|
||||
pub const fn min_remaining(&self) -> usize {
|
||||
self.remaining
|
||||
}
|
||||
|
||||
|
|
|
@ -90,7 +90,7 @@ pub enum Role {
|
|||
|
||||
impl Role {
|
||||
#[must_use]
|
||||
pub fn remote(self) -> Self {
|
||||
pub const fn remote(self) -> Self {
|
||||
match self {
|
||||
Self::Client => Self::Server,
|
||||
Self::Server => Self::Client,
|
||||
|
|
|
@ -60,7 +60,7 @@ impl NeqoQlog {
|
|||
}
|
||||
|
||||
/// If logging enabled, closure may generate an event to be logged.
|
||||
pub fn add_event<F>(&mut self, f: F)
|
||||
pub fn add_event<F>(&self, f: F)
|
||||
where
|
||||
F: FnOnce() -> Option<qlog::events::Event>,
|
||||
{
|
||||
|
@ -73,7 +73,7 @@ impl NeqoQlog {
|
|||
}
|
||||
|
||||
/// If logging enabled, closure may generate an event to be logged.
|
||||
pub fn add_event_data<F>(&mut self, f: F)
|
||||
pub fn add_event_data<F>(&self, f: F)
|
||||
where
|
||||
F: FnOnce() -> Option<qlog::events::EventData>,
|
||||
{
|
||||
|
@ -87,7 +87,7 @@ impl NeqoQlog {
|
|||
|
||||
/// If logging enabled, closure is given the Qlog stream to write events and
|
||||
/// frames to.
|
||||
pub fn add_event_with_stream<F>(&mut self, f: F)
|
||||
pub fn add_event_with_stream<F>(&self, f: F)
|
||||
where
|
||||
F: FnOnce(&mut QlogStreamer) -> Result<(), qlog::Error>,
|
||||
{
|
||||
|
@ -174,7 +174,7 @@ mod test {
|
|||
|
||||
#[test]
|
||||
fn add_event() {
|
||||
let (mut log, contents) = test_fixture::new_neqo_qlog();
|
||||
let (log, contents) = test_fixture::new_neqo_qlog();
|
||||
log.add_event(|| Some(Event::with_time(1.1, EV_DATA)));
|
||||
assert_eq!(
|
||||
contents.to_string(),
|
||||
|
|
|
@ -30,17 +30,17 @@ pub enum IpTosEcn {
|
|||
|
||||
impl From<IpTosEcn> for u8 {
|
||||
fn from(v: IpTosEcn) -> Self {
|
||||
v as u8
|
||||
v as Self
|
||||
}
|
||||
}
|
||||
|
||||
impl From<u8> for IpTosEcn {
|
||||
fn from(v: u8) -> Self {
|
||||
match v & 0b0000_0011 {
|
||||
0b00 => IpTosEcn::NotEct,
|
||||
0b01 => IpTosEcn::Ect1,
|
||||
0b10 => IpTosEcn::Ect0,
|
||||
0b11 => IpTosEcn::Ce,
|
||||
0b00 => Self::NotEct,
|
||||
0b01 => Self::Ect1,
|
||||
0b10 => Self::Ect0,
|
||||
0b11 => Self::Ce,
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
|
@ -48,16 +48,16 @@ impl From<u8> for IpTosEcn {
|
|||
|
||||
impl From<IpTos> for IpTosEcn {
|
||||
fn from(v: IpTos) -> Self {
|
||||
IpTosEcn::from(u8::from(v))
|
||||
Self::from(u8::from(v))
|
||||
}
|
||||
}
|
||||
|
||||
impl IpTosEcn {
|
||||
#[must_use]
|
||||
pub fn is_ecn_marked(&self) -> bool {
|
||||
pub const fn is_ecn_marked(&self) -> bool {
|
||||
match self {
|
||||
IpTosEcn::Ect0 | IpTosEcn::Ect1 | IpTosEcn::Ce => true,
|
||||
IpTosEcn::NotEct => false,
|
||||
Self::Ect0 | Self::Ect1 | Self::Ce => true,
|
||||
Self::NotEct => false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -140,36 +140,36 @@ pub enum IpTosDscp {
|
|||
|
||||
impl From<IpTosDscp> for u8 {
|
||||
fn from(v: IpTosDscp) -> Self {
|
||||
v as u8
|
||||
v as Self
|
||||
}
|
||||
}
|
||||
|
||||
impl From<u8> for IpTosDscp {
|
||||
fn from(v: u8) -> Self {
|
||||
match v & 0b1111_1100 {
|
||||
0b0000_0000 => IpTosDscp::Cs0,
|
||||
0b0010_0000 => IpTosDscp::Cs1,
|
||||
0b0100_0000 => IpTosDscp::Cs2,
|
||||
0b0110_0000 => IpTosDscp::Cs3,
|
||||
0b1000_0000 => IpTosDscp::Cs4,
|
||||
0b1010_0000 => IpTosDscp::Cs5,
|
||||
0b1100_0000 => IpTosDscp::Cs6,
|
||||
0b1110_0000 => IpTosDscp::Cs7,
|
||||
0b0010_1000 => IpTosDscp::Af11,
|
||||
0b0011_0000 => IpTosDscp::Af12,
|
||||
0b0011_1000 => IpTosDscp::Af13,
|
||||
0b0100_1000 => IpTosDscp::Af21,
|
||||
0b0101_0000 => IpTosDscp::Af22,
|
||||
0b0101_1000 => IpTosDscp::Af23,
|
||||
0b0110_1000 => IpTosDscp::Af31,
|
||||
0b0111_0000 => IpTosDscp::Af32,
|
||||
0b0111_1000 => IpTosDscp::Af33,
|
||||
0b1000_1000 => IpTosDscp::Af41,
|
||||
0b1001_0000 => IpTosDscp::Af42,
|
||||
0b1001_1000 => IpTosDscp::Af43,
|
||||
0b1011_1000 => IpTosDscp::Ef,
|
||||
0b1011_0000 => IpTosDscp::VoiceAdmit,
|
||||
0b0000_0100 => IpTosDscp::Le,
|
||||
0b0000_0000 => Self::Cs0,
|
||||
0b0010_0000 => Self::Cs1,
|
||||
0b0100_0000 => Self::Cs2,
|
||||
0b0110_0000 => Self::Cs3,
|
||||
0b1000_0000 => Self::Cs4,
|
||||
0b1010_0000 => Self::Cs5,
|
||||
0b1100_0000 => Self::Cs6,
|
||||
0b1110_0000 => Self::Cs7,
|
||||
0b0010_1000 => Self::Af11,
|
||||
0b0011_0000 => Self::Af12,
|
||||
0b0011_1000 => Self::Af13,
|
||||
0b0100_1000 => Self::Af21,
|
||||
0b0101_0000 => Self::Af22,
|
||||
0b0101_1000 => Self::Af23,
|
||||
0b0110_1000 => Self::Af31,
|
||||
0b0111_0000 => Self::Af32,
|
||||
0b0111_1000 => Self::Af33,
|
||||
0b1000_1000 => Self::Af41,
|
||||
0b1001_0000 => Self::Af42,
|
||||
0b1001_1000 => Self::Af43,
|
||||
0b1011_1000 => Self::Ef,
|
||||
0b1011_0000 => Self::VoiceAdmit,
|
||||
0b0000_0100 => Self::Le,
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
|
@ -177,7 +177,7 @@ impl From<u8> for IpTosDscp {
|
|||
|
||||
impl From<IpTos> for IpTosDscp {
|
||||
fn from(v: IpTos) -> Self {
|
||||
IpTosDscp::from(u8::from(v))
|
||||
Self::from(u8::from(v))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1 +1 @@
|
|||
{"files":{"Cargo.toml":"fa915d4cac0a051c77107dd6f74514915fe2924fe3eecaad10e995062767fbbb","bindings/bindings.toml":"56921b753535f899b8095df3e8af04b1dc2213c4808dfb39734a3c554454d01d","bindings/nspr_err.h":"2d5205d017b536c2d838bcf9bc4ec79f96dd50e7bb9b73892328781f1ee6629d","bindings/nspr_error.h":"e41c03c77b8c22046f8618832c9569fbcc7b26d8b9bbc35eea7168f35e346889","bindings/nspr_io.h":"085b289849ef0e77f88512a27b4d9bdc28252bd4d39c6a17303204e46ef45f72","bindings/nspr_time.h":"2e637fd338a5cf0fd3fb0070a47f474a34c2a7f4447f31b6875f5a9928d0a261","bindings/nss_ciphers.h":"95ec6344a607558b3c5ba8510f463b6295f3a2fb3f538a01410531045a5f62d1","bindings/nss_init.h":"ef49045063782fb612aff459172cc6a89340f15005808608ade5320ca9974310","bindings/nss_p11.h":"0b81e64fe6db49b2ecff94edd850be111ef99ec11220e88ceb1c67be90143a78","bindings/nss_secerr.h":"713e8368bdae5159af7893cfa517dabfe5103cede051dee9c9557c850a2defc6","bindings/nss_ssl.h":"af222fb957b989e392e762fa2125c82608a0053aff4fb97e556691646c88c335","bindings/nss_sslerr.h":"24b97f092183d8486f774cdaef5030d0249221c78343570d83a4ee5b594210ae","bindings/nss_sslopt.h":"b7807eb7abdad14db6ad7bc51048a46b065a0ea65a4508c95a12ce90e59d1eea","build.rs":"6c3e94359395cce5cb29bc0063ff930ffcd7edd50c040cb459acce6c80aa4ef4","min_version.txt":"7e98f86c69cddb4f65cf96a6de1f4297e3ce224a4c4628609e29042b6c4dcfb9","src/aead.rs":"fc42bc20b84d2e5ccfd56271ae2d2db082e55586ea2926470c102da177f22296","src/aead_null.rs":"3a553f21126c9ca0116c2be81e5a777011b33c159fd88c4f384614bbdb06bb2e","src/agent.rs":"0ef7b488480d12c01a122050e82809bc784443ef6277d75fce21d706fbf5eaaf","src/agentio.rs":"415f70b95312d3ee6d74ba6f28094246101ab6d535aa9df880c38d8bb5a9279e","src/auth.rs":"ced1a18f691894984244088020ea25dc1ee678603317f0c7dfc8b8842fa750b4","src/cert.rs":"8942cb3ce25a61f92b6ffc30fb286052ed6f56eeda3be12fd46ea76ceba6c1cf","src/constants.rs":"f5c779db128a8b0607841ca18c376971017eb327e102e5e6959a7d8effe4b3a6","src/ech.rs":"9d322fcc01c0886f1dfe9bb6273cb9f88a746452ac9a802761b1816a05930c1f","src/err.rs":"ae979f334604aba89640c4491262641910033f0bd790d58671f649f5039b291c","src/exp.rs":"cec59d61fc95914f9703d2fb6490a8507af993c9db710dde894f2f8fd38123c7","src/ext.rs":"cbf7d9f5ecabf4b8c9efd6c334637ab1596ec5266d38ab8d2d6ceae305283deb","src/hkdf.rs":"ef32f20e30a9bd7f094199536d19c87c4231b7fbbe4a9c54c70e84ca9c6575be","src/hp.rs":"644f1bed67f1c6189a67c8d02ab3358aaa7f63af4b913dd7395becbc01a84291","src/lib.rs":"1f2c171e76f353c99cebe66f9812d3021ab2914eb015fed6a07409b7cfa426e6","src/min_version.rs":"89b7ef6f9d2301db4f689f4d963b58375d577f705b92003a804048441e00cfd1","src/p11.rs":"704c5f164c4f195c8051c5bf1e69a912c34b613a8cf6bed5f577dc5674eea34e","src/prio.rs":"e5e169296c0ac69919c59fb6c1f8bd6bf079452eaa13d75da0edd41d435d3f6f","src/replay.rs":"96b7af8eff9e14313e79303092018b12e8834f780c96b8e247c497fdc680c696","src/result.rs":"0587cbb6aace71a7f9765ef7c01dcd9f73a49dcc6331e1d8fe4de2aef6ca65b6","src/secrets.rs":"4ffaa66f25df47dadf042063bff5953effa7bf2f4920cafe827757d6a659cb58","src/selfencrypt.rs":"b7cc1c896c7661c37461fc3a8bcbfdf2589433b907fa5f968ae4f6907704b441","src/ssl.rs":"c83baa5518b81dd06f2e4072ea3c2d666ccdeb8b1ff6e3746eea9f1af47023a6","src/time.rs":"c71a01ff8aa2c0e97fb16ad620df4ed6b7cc1819ff93f46634e2f1c9551627ec","tests/aead.rs":"e36ae77802df1ea6d17cfd1bd2178a3706089577d6fd1554ca86e748b8b235b9","tests/agent.rs":"824735f88e487a3748200844e9481e81a72163ad74d82faa9aa16594d9b9bb25","tests/ext.rs":"1b047d23d9b224ad06eb65d8f3a7b351e263774e404c79bbcbe8f43790e29c18","tests/handshake.rs":"e892a2839b31414be16e96cdf3b1a65978716094700c1a4989229f7edbf578a0","tests/hkdf.rs":"1d2098dc8398395864baf13e4886cfd1da6d36118727c3b264f457ee3da6b048","tests/hp.rs":"b24fec53771c169be788772532d2617a5349196cf87d6444dc74214f7c73e92c","tests/init.rs":"616313cb38eac44b8c71a1d23a52a7d7b4c7c07d4c20dc9ea6600c3317f92613","tests/selfencrypt.rs":"8d10840b41629bf449a6b3a551377315e8a05ca26c6b041548748196652c5909"},"package":null}
|
||||
{"files":{"Cargo.toml":"c666fb16006b6fab5594d6631e107b4faedc360f737e838e775cbe64c1b6e1e5","bindings/bindings.toml":"56921b753535f899b8095df3e8af04b1dc2213c4808dfb39734a3c554454d01d","bindings/nspr_err.h":"2d5205d017b536c2d838bcf9bc4ec79f96dd50e7bb9b73892328781f1ee6629d","bindings/nspr_error.h":"e41c03c77b8c22046f8618832c9569fbcc7b26d8b9bbc35eea7168f35e346889","bindings/nspr_io.h":"085b289849ef0e77f88512a27b4d9bdc28252bd4d39c6a17303204e46ef45f72","bindings/nspr_time.h":"2e637fd338a5cf0fd3fb0070a47f474a34c2a7f4447f31b6875f5a9928d0a261","bindings/nss_ciphers.h":"95ec6344a607558b3c5ba8510f463b6295f3a2fb3f538a01410531045a5f62d1","bindings/nss_init.h":"ef49045063782fb612aff459172cc6a89340f15005808608ade5320ca9974310","bindings/nss_p11.h":"0b81e64fe6db49b2ecff94edd850be111ef99ec11220e88ceb1c67be90143a78","bindings/nss_secerr.h":"713e8368bdae5159af7893cfa517dabfe5103cede051dee9c9557c850a2defc6","bindings/nss_ssl.h":"af222fb957b989e392e762fa2125c82608a0053aff4fb97e556691646c88c335","bindings/nss_sslerr.h":"24b97f092183d8486f774cdaef5030d0249221c78343570d83a4ee5b594210ae","bindings/nss_sslopt.h":"b7807eb7abdad14db6ad7bc51048a46b065a0ea65a4508c95a12ce90e59d1eea","build.rs":"51cfa35860a4c1a0f16e3fc2e2540b02cd9bdf1598f0ca65b74cf4c02fca5be3","min_version.txt":"7e98f86c69cddb4f65cf96a6de1f4297e3ce224a4c4628609e29042b6c4dcfb9","src/aead.rs":"8fc9307ad6ca9651bfaf29cc2bc5144c5c573be90ef7e0e11405a04256f8e077","src/aead_null.rs":"81163fafef59bd2800bd0a078d53d0f05ee114f0e22165717823a5ff1cb908af","src/agent.rs":"51acad973ae4ab01de056bf7df2e884003fbeffb7c93eaf838019160b4bf8427","src/agentio.rs":"f7d5105845fa9fc9d1bfbd9bfeefd4fb10986e8bdf760d442cb2be230de6575e","src/auth.rs":"ced1a18f691894984244088020ea25dc1ee678603317f0c7dfc8b8842fa750b4","src/cert.rs":"0ea1f458342fe1f1f4a300dd85783bd47539bac3bc05d52ee9c23191e3f59488","src/constants.rs":"f5c779db128a8b0607841ca18c376971017eb327e102e5e6959a7d8effe4b3a6","src/ech.rs":"9d322fcc01c0886f1dfe9bb6273cb9f88a746452ac9a802761b1816a05930c1f","src/err.rs":"6fcceee509fd8f6b321745f962f2de957b10ceb1f408a93657a23f63b4ab72d2","src/exp.rs":"d953873e87430b1c84d4a83c8eb3815041f5585b210bbaf59ae2c4d0057f5edd","src/ext.rs":"cbf7d9f5ecabf4b8c9efd6c334637ab1596ec5266d38ab8d2d6ceae305283deb","src/hkdf.rs":"8745ba761be821c1819cedf6dfd91f8b3148c6718053a4a74f33eb50c7d0cc40","src/hp.rs":"a169745d505a233f52abed09576d76d0e803205c929b74e83ba4e66dc14105fa","src/lib.rs":"1f2c171e76f353c99cebe66f9812d3021ab2914eb015fed6a07409b7cfa426e6","src/min_version.rs":"c6e1f98b9f56db0622ac38c1be131c55acf4a0f09ed0d6283f4d6308e2d1301a","src/p11.rs":"32606dc2c8f861d4bc4b17b7dfb178049f1e64fe330d7624070d8a1d08dd675f","src/prio.rs":"e5e169296c0ac69919c59fb6c1f8bd6bf079452eaa13d75da0edd41d435d3f6f","src/replay.rs":"96b7af8eff9e14313e79303092018b12e8834f780c96b8e247c497fdc680c696","src/result.rs":"0587cbb6aace71a7f9765ef7c01dcd9f73a49dcc6331e1d8fe4de2aef6ca65b6","src/secrets.rs":"4ffaa66f25df47dadf042063bff5953effa7bf2f4920cafe827757d6a659cb58","src/selfencrypt.rs":"018c2dacabd3e463fdadd5707715b23c26c261c4c7d86e66c62f0acec986cad9","src/ssl.rs":"170933713f82511eff2846da18f7e651e12a4ed95281aee0df85d11634c1ea97","src/time.rs":"6e239ea1e4c54fae8df02cf847a8dfdbf5beff421596c34a1f297513e4d87453","tests/aead.rs":"e36ae77802df1ea6d17cfd1bd2178a3706089577d6fd1554ca86e748b8b235b9","tests/agent.rs":"824735f88e487a3748200844e9481e81a72163ad74d82faa9aa16594d9b9bb25","tests/ext.rs":"57af4e2df211fa8afdb73125d4344ef5c70c1ea4579107c3e6f5746308ee3e7b","tests/handshake.rs":"538c9241c4e3a65d4e66be70ec8faa02cb7ddc2b43362cb051fbb83b9c213a51","tests/hkdf.rs":"1d2098dc8398395864baf13e4886cfd1da6d36118727c3b264f457ee3da6b048","tests/hp.rs":"ccda23018dac70b3ff3742afcb0fbae0735be9aeb36644a4ae2b1d7c9126801c","tests/init.rs":"3e15150c4b324c06ca5e8935618e4008da53dc0ef4b69325d150831e87dc0b63","tests/selfencrypt.rs":"8d10840b41629bf449a6b3a551377315e8a05ca26c6b041548748196652c5909"},"package":null}
|
|
@ -13,9 +13,23 @@
|
|||
edition = "2021"
|
||||
rust-version = "1.76.0"
|
||||
name = "neqo-crypto"
|
||||
version = "0.7.9"
|
||||
version = "0.8.1"
|
||||
authors = ["The Neqo Authors <necko@mozilla.com>"]
|
||||
description = "Neqo, the Mozilla implementation of QUIC in Rust."
|
||||
homepage = "https://github.com/mozilla/neqo/"
|
||||
readme = "../README.md"
|
||||
keywords = [
|
||||
"quic",
|
||||
"http3",
|
||||
"neqo",
|
||||
"mozilla",
|
||||
"ietf",
|
||||
"firefox",
|
||||
]
|
||||
categories = [
|
||||
"network-programming",
|
||||
"web-programming",
|
||||
]
|
||||
license = "MIT OR Apache-2.0"
|
||||
repository = "https://github.com/mozilla/neqo/"
|
||||
|
||||
|
@ -63,6 +77,17 @@ disable-encryption = []
|
|||
disable-random = []
|
||||
gecko = ["mozbuild"]
|
||||
|
||||
[lints.clippy]
|
||||
multiple_crate_versions = "allow"
|
||||
|
||||
[lints.clippy.cargo]
|
||||
level = "warn"
|
||||
priority = -1
|
||||
|
||||
[lints.clippy.nursery]
|
||||
level = "warn"
|
||||
priority = -1
|
||||
|
||||
[lints.clippy.pedantic]
|
||||
level = "warn"
|
||||
priority = -1
|
||||
|
|
|
@ -103,10 +103,10 @@ fn get_bash() -> PathBuf {
|
|||
|
||||
// When running under MOZILLABUILD, we need to make sure not to invoke
|
||||
// another instance of bash that might be sitting around (like WSL).
|
||||
match env::var("MOZILLABUILD") {
|
||||
Ok(d) => PathBuf::from(d).join("msys").join("bin").join("bash.exe"),
|
||||
Err(_) => PathBuf::from("bash"),
|
||||
}
|
||||
env::var("MOZILLABUILD").map_or_else(
|
||||
|_| PathBuf::from("bash"),
|
||||
|d| PathBuf::from(d).join("msys").join("bin").join("bash.exe"),
|
||||
)
|
||||
}
|
||||
|
||||
fn build_nss(dir: PathBuf) {
|
||||
|
|
|
@ -70,7 +70,7 @@ impl RealAead {
|
|||
|
||||
#[must_use]
|
||||
#[allow(clippy::unused_self)]
|
||||
pub fn expansion(&self) -> usize {
|
||||
pub const fn expansion(&self) -> usize {
|
||||
16
|
||||
}
|
||||
|
||||
|
|
|
@ -18,12 +18,17 @@ pub struct AeadNull {}
|
|||
|
||||
impl AeadNull {
|
||||
#[allow(clippy::missing_errors_doc)]
|
||||
pub fn new(_version: Version, _cipher: Cipher, _secret: &SymKey, _prefix: &str) -> Res<Self> {
|
||||
pub const fn new(
|
||||
_version: Version,
|
||||
_cipher: Cipher,
|
||||
_secret: &SymKey,
|
||||
_prefix: &str,
|
||||
) -> Res<Self> {
|
||||
Ok(Self {})
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn expansion(&self) -> usize {
|
||||
pub const fn expansion(&self) -> usize {
|
||||
AEAD_NULL_TAG.len()
|
||||
}
|
||||
|
||||
|
|
|
@ -60,17 +60,17 @@ pub enum HandshakeState {
|
|||
|
||||
impl HandshakeState {
|
||||
#[must_use]
|
||||
pub fn is_connected(&self) -> bool {
|
||||
pub const fn is_connected(&self) -> bool {
|
||||
matches!(self, Self::Complete(_))
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn is_final(&self) -> bool {
|
||||
pub const fn is_final(&self) -> bool {
|
||||
matches!(self, Self::Complete(_) | Self::Failed(_))
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn authentication_needed(&self) -> bool {
|
||||
pub const fn authentication_needed(&self) -> bool {
|
||||
matches!(
|
||||
self,
|
||||
Self::AuthenticationPending | Self::EchFallbackAuthenticationPending(_)
|
||||
|
@ -154,7 +154,7 @@ impl SecretAgentPreInfo {
|
|||
);
|
||||
|
||||
#[must_use]
|
||||
pub fn early_data(&self) -> bool {
|
||||
pub const fn early_data(&self) -> bool {
|
||||
self.info.canSendEarlyData != 0
|
||||
}
|
||||
|
||||
|
@ -168,7 +168,7 @@ impl SecretAgentPreInfo {
|
|||
|
||||
/// Was ECH accepted.
|
||||
#[must_use]
|
||||
pub fn ech_accepted(&self) -> Option<bool> {
|
||||
pub const fn ech_accepted(&self) -> Option<bool> {
|
||||
if self.info.valuesSet & ssl::ssl_preinfo_ech == 0 {
|
||||
None
|
||||
} else {
|
||||
|
@ -198,7 +198,7 @@ impl SecretAgentPreInfo {
|
|||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn alpn(&self) -> Option<&String> {
|
||||
pub const fn alpn(&self) -> Option<&String> {
|
||||
self.alpn.as_ref()
|
||||
}
|
||||
}
|
||||
|
@ -238,35 +238,35 @@ impl SecretAgentInfo {
|
|||
})
|
||||
}
|
||||
#[must_use]
|
||||
pub fn version(&self) -> Version {
|
||||
pub const fn version(&self) -> Version {
|
||||
self.version
|
||||
}
|
||||
#[must_use]
|
||||
pub fn cipher_suite(&self) -> Cipher {
|
||||
pub const fn cipher_suite(&self) -> Cipher {
|
||||
self.cipher
|
||||
}
|
||||
#[must_use]
|
||||
pub fn key_exchange(&self) -> Group {
|
||||
pub const fn key_exchange(&self) -> Group {
|
||||
self.group
|
||||
}
|
||||
#[must_use]
|
||||
pub fn resumed(&self) -> bool {
|
||||
pub const fn resumed(&self) -> bool {
|
||||
self.resumed
|
||||
}
|
||||
#[must_use]
|
||||
pub fn early_data_accepted(&self) -> bool {
|
||||
pub const fn early_data_accepted(&self) -> bool {
|
||||
self.early_data
|
||||
}
|
||||
#[must_use]
|
||||
pub fn ech_accepted(&self) -> bool {
|
||||
pub const fn ech_accepted(&self) -> bool {
|
||||
self.ech_accepted
|
||||
}
|
||||
#[must_use]
|
||||
pub fn alpn(&self) -> Option<&String> {
|
||||
pub const fn alpn(&self) -> Option<&String> {
|
||||
self.alpn.as_ref()
|
||||
}
|
||||
#[must_use]
|
||||
pub fn signature_scheme(&self) -> SignatureScheme {
|
||||
pub const fn signature_scheme(&self) -> SignatureScheme {
|
||||
self.signature_scheme
|
||||
}
|
||||
}
|
||||
|
@ -343,6 +343,7 @@ impl SecretAgent {
|
|||
Ok(fd)
|
||||
}
|
||||
|
||||
#[allow(clippy::missing_const_for_fn)]
|
||||
unsafe extern "C" fn auth_complete_hook(
|
||||
arg: *mut c_void,
|
||||
_fd: *mut ssl::PRFileDesc,
|
||||
|
@ -482,7 +483,7 @@ impl SecretAgent {
|
|||
/// # Errors
|
||||
///
|
||||
/// Returns an error if the option or option value is invalid; i.e., never.
|
||||
pub fn set_option(&mut self, opt: ssl::Opt, value: bool) -> Res<()> {
|
||||
pub fn set_option(&self, opt: ssl::Opt, value: bool) -> Res<()> {
|
||||
opt.set(self.fd, value)
|
||||
}
|
||||
|
||||
|
@ -491,7 +492,7 @@ impl SecretAgent {
|
|||
/// # Errors
|
||||
///
|
||||
/// See `set_option`.
|
||||
pub fn enable_0rtt(&mut self) -> Res<()> {
|
||||
pub fn enable_0rtt(&self) -> Res<()> {
|
||||
self.set_option(ssl::Opt::EarlyData, true)
|
||||
}
|
||||
|
||||
|
@ -500,7 +501,7 @@ impl SecretAgent {
|
|||
/// # Errors
|
||||
///
|
||||
/// See `set_option`.
|
||||
pub fn disable_end_of_early_data(&mut self) -> Res<()> {
|
||||
pub fn disable_end_of_early_data(&self) -> Res<()> {
|
||||
self.set_option(ssl::Opt::SuppressEndOfEarlyData, true)
|
||||
}
|
||||
|
||||
|
@ -597,7 +598,7 @@ impl SecretAgent {
|
|||
///
|
||||
/// Calling this function returns None until the connection is complete.
|
||||
#[must_use]
|
||||
pub fn info(&self) -> Option<&SecretAgentInfo> {
|
||||
pub const fn info(&self) -> Option<&SecretAgentInfo> {
|
||||
match self.state {
|
||||
HandshakeState::Complete(ref info) => Some(info),
|
||||
_ => None,
|
||||
|
@ -753,7 +754,7 @@ impl SecretAgent {
|
|||
if self.fd.is_null() {
|
||||
return;
|
||||
}
|
||||
if let Some(true) = self.raw {
|
||||
if self.raw == Some(true) {
|
||||
// Need to hold the record list in scope until the close is done.
|
||||
let _records = self.setup_raw().expect("Can only close");
|
||||
unsafe { prio::PR_Close(self.fd.cast()) };
|
||||
|
@ -768,7 +769,7 @@ impl SecretAgent {
|
|||
|
||||
/// State returns the status of the handshake.
|
||||
#[must_use]
|
||||
pub fn state(&self) -> &HandshakeState {
|
||||
pub const fn state(&self) -> &HandshakeState {
|
||||
&self.state
|
||||
}
|
||||
|
||||
|
@ -817,7 +818,7 @@ impl AsRef<[u8]> for ResumptionToken {
|
|||
|
||||
impl ResumptionToken {
|
||||
#[must_use]
|
||||
pub fn new(token: Vec<u8>, expiration_time: Instant) -> Self {
|
||||
pub const fn new(token: Vec<u8>, expiration_time: Instant) -> Self {
|
||||
Self {
|
||||
token,
|
||||
expiration_time,
|
||||
|
@ -825,7 +826,7 @@ impl ResumptionToken {
|
|||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn expiration_time(&self) -> Instant {
|
||||
pub const fn expiration_time(&self) -> Instant {
|
||||
self.expiration_time
|
||||
}
|
||||
}
|
||||
|
|
|
@ -209,7 +209,7 @@ pub struct AgentIo {
|
|||
}
|
||||
|
||||
impl AgentIo {
|
||||
pub fn new() -> Self {
|
||||
pub const fn new() -> Self {
|
||||
Self {
|
||||
input: AgentIoInput {
|
||||
input: null(),
|
||||
|
@ -280,10 +280,9 @@ unsafe extern "C" fn agent_recv(
|
|||
return PR_FAILURE;
|
||||
}
|
||||
if let Ok(a) = usize::try_from(amount) {
|
||||
match io.input.read_input(buf.cast(), a) {
|
||||
Ok(v) => prio::PRInt32::try_from(v).unwrap_or(PR_FAILURE),
|
||||
Err(_) => PR_FAILURE,
|
||||
}
|
||||
io.input.read_input(buf.cast(), a).map_or(PR_FAILURE, |v| {
|
||||
prio::PRInt32::try_from(v).unwrap_or(PR_FAILURE)
|
||||
})
|
||||
} else {
|
||||
PR_FAILURE
|
||||
}
|
||||
|
@ -295,12 +294,10 @@ unsafe extern "C" fn agent_write(
|
|||
amount: prio::PRInt32,
|
||||
) -> PrStatus {
|
||||
let io = AgentIo::borrow(&mut fd);
|
||||
if let Ok(a) = usize::try_from(amount) {
|
||||
usize::try_from(amount).map_or(PR_FAILURE, |a| {
|
||||
io.save_output(buf.cast(), a);
|
||||
amount
|
||||
} else {
|
||||
PR_FAILURE
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
unsafe extern "C" fn agent_send(
|
||||
|
@ -315,12 +312,10 @@ unsafe extern "C" fn agent_send(
|
|||
if flags != 0 {
|
||||
return PR_FAILURE;
|
||||
}
|
||||
if let Ok(a) = usize::try_from(amount) {
|
||||
usize::try_from(amount).map_or(PR_FAILURE, |a| {
|
||||
io.save_output(buf.cast(), a);
|
||||
amount
|
||||
} else {
|
||||
PR_FAILURE
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
unsafe extern "C" fn agent_available(mut fd: PrFd) -> prio::PRInt32 {
|
||||
|
|
|
@ -60,18 +60,14 @@ fn stapled_ocsp_responses(fd: *mut PRFileDesc) -> Option<Vec<Vec<u8>>> {
|
|||
|
||||
fn signed_cert_timestamp(fd: *mut PRFileDesc) -> Option<Vec<u8>> {
|
||||
let sct_nss = unsafe { SSL_PeerSignedCertTimestamps(fd) };
|
||||
match NonNull::new(sct_nss as *mut SECItem) {
|
||||
Some(sct_ptr) => {
|
||||
NonNull::new(sct_nss as *mut SECItem).map(|sct_ptr| {
|
||||
if unsafe { sct_ptr.as_ref().len == 0 || sct_ptr.as_ref().data.is_null() } {
|
||||
Some(Vec::new())
|
||||
Vec::new()
|
||||
} else {
|
||||
let sct_slice =
|
||||
unsafe { null_safe_slice(sct_ptr.as_ref().data, sct_ptr.as_ref().len) };
|
||||
Some(sct_slice.to_owned())
|
||||
}
|
||||
}
|
||||
None => None,
|
||||
let sct_slice = unsafe { null_safe_slice(sct_ptr.as_ref().data, sct_ptr.as_ref().len) };
|
||||
sct_slice.to_owned()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
impl CertificateInfo {
|
||||
|
@ -106,11 +102,13 @@ impl<'a> Iterator for &'a mut CertificateInfo {
|
|||
}
|
||||
|
||||
impl CertificateInfo {
|
||||
pub fn stapled_ocsp_responses(&mut self) -> &Option<Vec<Vec<u8>>> {
|
||||
#[must_use]
|
||||
pub const fn stapled_ocsp_responses(&self) -> &Option<Vec<Vec<u8>>> {
|
||||
&self.stapled_ocsp_responses
|
||||
}
|
||||
|
||||
pub fn signed_cert_timestamp(&mut self) -> &Option<Vec<u8>> {
|
||||
#[must_use]
|
||||
pub const fn signed_cert_timestamp(&self) -> &Option<Vec<u8>> {
|
||||
&self.signed_cert_timestamp
|
||||
}
|
||||
}
|
||||
|
|
|
@ -151,7 +151,7 @@ pub fn secstatus_to_res(rv: SECStatus) -> Res<()> {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn is_blocked(result: &Res<()>) -> bool {
|
||||
pub const fn is_blocked(result: &Res<()>) -> bool {
|
||||
match result {
|
||||
Err(Error::NssError { code, .. }) => *code == nspr::PR_WOULD_BLOCK_ERROR,
|
||||
_ => false,
|
||||
|
|
|
@ -9,7 +9,9 @@ macro_rules! experimental_api {
|
|||
( $n:ident ( $( $a:ident : $t:ty ),* $(,)? ) ) => {
|
||||
#[allow(non_snake_case)]
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub(crate) unsafe fn $n ( $( $a : $t ),* ) -> Result<(), $crate::err::Error> {
|
||||
#[allow(clippy::missing_safety_doc)]
|
||||
#[allow(clippy::missing_errors_doc)]
|
||||
pub unsafe fn $n ( $( $a : $t ),* ) -> Result<(), $crate::err::Error> {
|
||||
const EXP_FUNCTION: &str = stringify!($n);
|
||||
let n = ::std::ffi::CString::new(EXP_FUNCTION)?;
|
||||
let f = $crate::ssl::SSL_GetExperimentalAPI(n.as_ptr());
|
||||
|
|
|
@ -103,10 +103,7 @@ pub fn extract(
|
|||
ikm: &SymKey,
|
||||
) -> Res<SymKey> {
|
||||
let mut prk: *mut PK11SymKey = null_mut();
|
||||
let salt_ptr: *mut PK11SymKey = match salt {
|
||||
Some(s) => **s,
|
||||
None => null_mut(),
|
||||
};
|
||||
let salt_ptr: *mut PK11SymKey = salt.map_or(null_mut(), |s| **s);
|
||||
unsafe { SSL_HkdfExtract(version, cipher, salt_ptr, **ikm, &mut prk) }?;
|
||||
SymKey::from_ptr(prk)
|
||||
}
|
||||
|
|
|
@ -57,7 +57,7 @@ impl Debug for HpKey {
|
|||
}
|
||||
|
||||
impl HpKey {
|
||||
const SAMPLE_SIZE: usize = 16;
|
||||
pub const SAMPLE_SIZE: usize = 16;
|
||||
|
||||
/// QUIC-specific API for extracting a header-protection key.
|
||||
///
|
||||
|
@ -124,14 +124,7 @@ impl HpKey {
|
|||
Ok(res)
|
||||
}
|
||||
|
||||
/// Get the sample size, which is also the output size.
|
||||
#[must_use]
|
||||
#[allow(clippy::unused_self)] // To maintain an API contract.
|
||||
pub fn sample_size(&self) -> usize {
|
||||
Self::SAMPLE_SIZE
|
||||
}
|
||||
|
||||
fn block_size(&self) -> usize {
|
||||
const fn block_size(&self) -> usize {
|
||||
match self {
|
||||
Self::Aes(_) => 16,
|
||||
Self::Chacha(_) => 64,
|
||||
|
@ -148,8 +141,9 @@ impl HpKey {
|
|||
/// # Panics
|
||||
///
|
||||
/// When the mechanism for our key is not supported.
|
||||
pub fn mask(&self, sample: &[u8]) -> Res<Vec<u8>> {
|
||||
let mut output = vec![0_u8; self.block_size()];
|
||||
/// Or when the sample provided is not at least `self.sample_size()` bytes.
|
||||
pub fn mask(&self, sample: &[u8]) -> Res<[u8; Self::SAMPLE_SIZE]> {
|
||||
let mut output = [0; Self::SAMPLE_SIZE];
|
||||
|
||||
match self {
|
||||
Self::Aes(context) => {
|
||||
|
@ -164,7 +158,7 @@ impl HpKey {
|
|||
c_int::try_from(Self::SAMPLE_SIZE).unwrap(),
|
||||
)
|
||||
})?;
|
||||
assert_eq!(usize::try_from(output_len).unwrap(), output.len());
|
||||
debug_assert_eq!(usize::try_from(output_len).unwrap(), output.len());
|
||||
Ok(output)
|
||||
}
|
||||
|
||||
|
@ -185,11 +179,11 @@ impl HpKey {
|
|||
output[..].as_mut_ptr(),
|
||||
&mut output_len,
|
||||
c_uint::try_from(output.len())?,
|
||||
output[..].as_ptr(),
|
||||
c_uint::try_from(output.len())?,
|
||||
[0; Self::SAMPLE_SIZE].as_ptr(),
|
||||
c_uint::try_from(Self::SAMPLE_SIZE)?,
|
||||
)
|
||||
})?;
|
||||
assert_eq!(usize::try_from(output_len).unwrap(), output.len());
|
||||
debug_assert_eq!(usize::try_from(output_len).unwrap(), output.len());
|
||||
Ok(output)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,4 +6,4 @@
|
|||
|
||||
/// The minimum version of NSS that is required by this version of neqo.
|
||||
/// Note that the string may contain whitespace at the beginning and/or end.
|
||||
pub(crate) const MINIMUM_NSS_VERSION: &str = include_str!("../min_version.txt");
|
||||
pub const MINIMUM_NSS_VERSION: &str = include_str!("../min_version.txt");
|
||||
|
|
|
@ -187,7 +187,7 @@ scoped_ptr!(Slot, PK11SlotInfo, PK11_FreeSlot);
|
|||
impl Slot {
|
||||
pub fn internal() -> Res<Self> {
|
||||
let p = unsafe { PK11_GetInternalSlot() };
|
||||
Slot::from_ptr(p)
|
||||
Self::from_ptr(p)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -267,7 +267,7 @@ impl Item {
|
|||
}
|
||||
|
||||
/// Make an empty `SECItem` for passing as a mutable `SECItem*` argument.
|
||||
pub fn make_empty() -> SECItem {
|
||||
pub const fn make_empty() -> SECItem {
|
||||
SECItem {
|
||||
type_: SECItemType::siBuffer,
|
||||
data: null_mut(),
|
||||
|
@ -328,8 +328,8 @@ impl RandomCache {
|
|||
const SIZE: usize = 256;
|
||||
const CUTOFF: usize = 32;
|
||||
|
||||
fn new() -> Self {
|
||||
RandomCache {
|
||||
const fn new() -> Self {
|
||||
Self {
|
||||
cache: [0; Self::SIZE],
|
||||
used: Self::SIZE,
|
||||
}
|
||||
|
@ -361,7 +361,7 @@ impl RandomCache {
|
|||
/// When `size` is too large or NSS fails.
|
||||
#[must_use]
|
||||
pub fn random<const N: usize>() -> [u8; N] {
|
||||
thread_local!(static CACHE: RefCell<RandomCache> = RefCell::new(RandomCache::new()));
|
||||
thread_local!(static CACHE: RefCell<RandomCache> = const { RefCell::new(RandomCache::new()) });
|
||||
|
||||
let buf = [0; N];
|
||||
if N <= RandomCache::CUTOFF {
|
||||
|
|
|
@ -108,7 +108,7 @@ impl SelfEncrypt {
|
|||
Ok(output)
|
||||
}
|
||||
|
||||
fn select_key(&self, kid: u8) -> Option<&SymKey> {
|
||||
const fn select_key(&self, kid: u8) -> Option<&SymKey> {
|
||||
if kid == self.key_id {
|
||||
Some(&self.key)
|
||||
} else {
|
||||
|
|
|
@ -56,7 +56,8 @@ pub enum Opt {
|
|||
impl Opt {
|
||||
// Cast is safe here because SSLOptions are within the i32 range
|
||||
#[allow(clippy::cast_possible_wrap)]
|
||||
pub(crate) fn as_int(self) -> PRInt32 {
|
||||
#[must_use]
|
||||
pub const fn as_int(self) -> PRInt32 {
|
||||
let i = match self {
|
||||
Self::Locking => SSLOption::SSL_NO_LOCKS,
|
||||
Self::Tickets => SSLOption::SSL_ENABLE_SESSION_TICKETS,
|
||||
|
|
|
@ -74,7 +74,7 @@ fn get_base() -> &'static TimeZero {
|
|||
})
|
||||
}
|
||||
|
||||
pub(crate) fn init() {
|
||||
pub fn init() {
|
||||
_ = get_base();
|
||||
}
|
||||
|
||||
|
@ -123,21 +123,20 @@ impl TryInto<PRTime> for Time {
|
|||
fn try_into(self) -> Res<PRTime> {
|
||||
let base = get_base();
|
||||
|
||||
if let Some(delta) = self.t.checked_duration_since(base.instant) {
|
||||
if let Ok(d) = PRTime::try_from(delta.as_micros()) {
|
||||
d.checked_add(base.prtime).ok_or(Error::TimeTravelError)
|
||||
} else {
|
||||
Err(Error::TimeTravelError)
|
||||
}
|
||||
} else {
|
||||
self.t.checked_duration_since(base.instant).map_or_else(
|
||||
|| {
|
||||
// Try to go backwards from the base time.
|
||||
let backwards = base.instant - self.t; // infallible
|
||||
if let Ok(d) = PRTime::try_from(backwards.as_micros()) {
|
||||
PRTime::try_from(backwards.as_micros()).map_or(Err(Error::TimeTravelError), |d| {
|
||||
base.prtime.checked_sub(d).ok_or(Error::TimeTravelError)
|
||||
} else {
|
||||
Err(Error::TimeTravelError)
|
||||
}
|
||||
}
|
||||
})
|
||||
},
|
||||
|delta| {
|
||||
PRTime::try_from(delta.as_micros()).map_or(Err(Error::TimeTravelError), |d| {
|
||||
d.checked_add(base.prtime).ok_or(Error::TimeTravelError)
|
||||
})
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -207,7 +206,7 @@ impl TimeHolder {
|
|||
|
||||
impl Default for TimeHolder {
|
||||
fn default() -> Self {
|
||||
TimeHolder { t: Box::pin(0) }
|
||||
Self { t: Box::pin(0) }
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -43,8 +43,7 @@ struct SimpleExtensionHandler {
|
|||
}
|
||||
|
||||
impl SimpleExtensionHandler {
|
||||
#[allow(dead_code)]
|
||||
pub fn negotiated(&self) -> bool {
|
||||
pub const fn negotiated(&self) -> bool {
|
||||
self.written && self.handled
|
||||
}
|
||||
}
|
||||
|
|
|
@ -113,12 +113,8 @@ impl ZeroRttChecker for PermissiveZeroRttChecker {
|
|||
}
|
||||
}
|
||||
|
||||
fn zero_rtt_setup(
|
||||
mode: Resumption,
|
||||
client: &mut Client,
|
||||
server: &mut Server,
|
||||
) -> Option<AntiReplay> {
|
||||
if let Resumption::WithZeroRtt = mode {
|
||||
fn zero_rtt_setup(mode: Resumption, client: &Client, server: &mut Server) -> Option<AntiReplay> {
|
||||
if matches!(mode, Resumption::WithZeroRtt) {
|
||||
client.enable_0rtt().expect("should enable 0-RTT on client");
|
||||
|
||||
let anti_replay = anti_replay();
|
||||
|
@ -141,7 +137,7 @@ pub fn resumption_setup(mode: Resumption) -> (Option<AntiReplay>, ResumptionToke
|
|||
|
||||
let mut client = Client::new("server.example", true).expect("should create client");
|
||||
let mut server = Server::new(&["key"]).expect("should create server");
|
||||
let anti_replay = zero_rtt_setup(mode, &mut client, &mut server);
|
||||
let anti_replay = zero_rtt_setup(mode, &client, &mut server);
|
||||
|
||||
connect(&mut client, &mut server);
|
||||
|
||||
|
|
|
@ -61,10 +61,7 @@ fn aes256() {
|
|||
fn chacha20_ctr() {
|
||||
const EXPECTED: &[u8] = &[
|
||||
0x34, 0x11, 0xb3, 0x53, 0x02, 0x0b, 0x16, 0xda, 0x0a, 0x85, 0x5a, 0x52, 0x0d, 0x06, 0x07,
|
||||
0x1f, 0x4a, 0xb1, 0xaf, 0xf7, 0x83, 0xa8, 0xf0, 0x29, 0xc3, 0x19, 0xef, 0x57, 0x48, 0xe7,
|
||||
0x8e, 0x3e, 0x11, 0x91, 0xe1, 0xd5, 0x92, 0x8f, 0x61, 0x6d, 0x3f, 0x3d, 0x76, 0xb5, 0x29,
|
||||
0xf1, 0x62, 0x2f, 0x1e, 0xad, 0xdd, 0x23, 0x59, 0x45, 0xac, 0xd2, 0x19, 0x8a, 0xb4, 0x1f,
|
||||
0x2f, 0x52, 0x46, 0x89,
|
||||
0x1f,
|
||||
];
|
||||
|
||||
hp_test(TLS_CHACHA20_POLY1305_SHA256, EXPECTED);
|
||||
|
|
|
@ -30,17 +30,6 @@ fn init_nodb() {
|
|||
}
|
||||
}
|
||||
|
||||
#[cfg(nss_nodb)]
|
||||
#[test]
|
||||
fn init_twice_nodb() {
|
||||
unsafe {
|
||||
nss::NSS_NoDB_Init(std::ptr::null());
|
||||
assert_ne!(nss::NSS_IsInitialized(), 0);
|
||||
}
|
||||
// Now do it again
|
||||
init_nodb();
|
||||
}
|
||||
|
||||
#[cfg(not(nss_nodb))]
|
||||
#[test]
|
||||
fn init_withdb() {
|
||||
|
@ -50,27 +39,3 @@ fn init_withdb() {
|
|||
assert_ne!(nss::NSS_IsInitialized(), 0);
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(nss_nodb))]
|
||||
#[test]
|
||||
fn init_twice_withdb() {
|
||||
use std::{ffi::CString, path::PathBuf};
|
||||
|
||||
let empty = CString::new("").unwrap();
|
||||
let path: PathBuf = ::test_fixture::NSS_DB_PATH.into();
|
||||
assert!(path.is_dir());
|
||||
let pathstr = path.to_str().unwrap();
|
||||
let dircstr = CString::new(pathstr).unwrap();
|
||||
unsafe {
|
||||
nss::NSS_Initialize(
|
||||
dircstr.as_ptr(),
|
||||
empty.as_ptr(),
|
||||
empty.as_ptr(),
|
||||
nss::SECMOD_DB.as_ptr().cast(),
|
||||
nss::NSS_INIT_READONLY,
|
||||
);
|
||||
assert_ne!(nss::NSS_IsInitialized(), 0);
|
||||
}
|
||||
// Now do it again
|
||||
init_withdb();
|
||||
}
|
||||
|
|
|
@ -1 +1 @@
|
|||
{"files":{"Cargo.toml":"b2c055251c5dcf2682152a328999042295463202d011ed2a43491ad3b15f8654","src/buffered_send_stream.rs":"0e8ad3f443a33e213d55ba26a1ff266692c9087a1627c9b3d10c5025dee550ac","src/client_events.rs":"77fedca72ce54956eaba3fb7103085d196a631b764662584ea2629224c5c234e","src/conn_params.rs":"224a8ea6ef632930a7788a1cabf47ce69ad41bd4bc8dcf3053fbd998fdb38e82","src/connection.rs":"f5f49dd72170f7e42c180b738ff8bddae92fd0c71acc5a08736e298bf53483e7","src/connection_client.rs":"eb623c56641414b89b91387cc8ca4ed1544565fa44301577dc90ee5ad8b392b0","src/connection_server.rs":"de5a6cb42b8c4dc08fb1f626f681b45cd22435892b11e6053b61a5401490db94","src/control_stream_local.rs":"ae52e3286f1686ca1265e7de841392addd42616db02799bb967a59feb6039cb5","src/control_stream_remote.rs":"59eb4041e366d92f9f294e8446755caa5e91fd943bba7b79b726698ba13be248","src/features/extended_connect/mod.rs":"3b02f6b18627f3855465a81b1d9b285e6f13839e75a8a6db648ed9082908d7f0","src/features/extended_connect/tests/mod.rs":"fd6aee37243713e80fc526552f21f0222338cec9890409b6575a2a637b17ec1f","src/features/extended_connect/tests/webtransport/datagrams.rs":"4c85a90afb753ce588e3fdeb773669bc49c013aebc28912340359eb01b74fd70","src/features/extended_connect/tests/webtransport/mod.rs":"cdb8de335293249525c73b52b49b44752425eaf0183182b4102d89494a5e5a52","src/features/extended_connect/tests/webtransport/negotiation.rs":"a8940b99e21a6b29fef2fc32f3dce05d12de8b09079dfdc0502c13e4582dbdb6","src/features/extended_connect/tests/webtransport/sessions.rs":"de3d836f666c2bec31e70b33bdc2669572cabbe17df2225db7282613a224a364","src/features/extended_connect/tests/webtransport/streams.rs":"8b3c34cac1b2171252a4bb53d420ac2098549a20309c327bf56e2e9ba9e33538","src/features/extended_connect/webtransport_session.rs":"198391dfe008732840d7050a6e5fcc1f52ec2a2b28641e392ca9ad7d8ddd97af","src/features/extended_connect/webtransport_streams.rs":"5d7507aaf6a819d266fbea9b7a415c8324329df0f6936d9045b73e17a5b844ee","src/features/mod.rs":"925aae4427ad82e4d019354802b223d53db5e5585d4a940f5417a24a9503d7ee","src/frames/hframe.rs":"56c36ac597504f28c73cf2370acd82104f8c7a7b9ffc0f6d222378abc524482d","src/frames/mod.rs":"7d0a46ca147336d14781edb8dbee8b03c2e4bcd6646f5473a9d93d31fe73fecb","src/frames/reader.rs":"e07ee9de74bc499c10afcda592fefd9a7eef3381c045aa14f6596d67313546ca","src/frames/tests/hframe.rs":"01ec74eb3eb25d95042aa0263f9267f89535e6b7b8c1161fab4ba9ee5352d4a7","src/frames/tests/mod.rs":"0610609b316767a6a022837d32ee0452e37ea296fde37e51bec87e7c77e923a3","src/frames/tests/reader.rs":"2bfadc7afbc41bff9f5f930b31550259a8a92484d35f6c5d8dd8fd9acfb88f5b","src/frames/tests/wtframe.rs":"589ebe1e62ce4da63b37b7d22cde7ba572ddbf29336fdcdbbcd0a745f79dacd8","src/frames/wtframe.rs":"1d9d0256ace2ba7262343ed035df795f21a4d45065792d3fd45b3391b6916b2f","src/headers_checks.rs":"be0f0109298dcc3a40350b7c0950076ddfe20617d195b305e3ffc8582557ab18","src/lib.rs":"4f908a021222bcc79b9d569bc3759a493379a20b47dfa228fddf51600bf6e446","src/priority.rs":"f3b77c208962e44a4e2d13138c6998b703d40e7bcf8f73ea84d8ef5b556e0aee","src/push_controller.rs":"13bccf2834ae19109504cf695a5948c3b2d03fd101bc032a92bb77a033423854","src/qlog.rs":"2debd75c7ea103c95ff79e44412f1408c3e496e324976100c55d5a833912b6c3","src/qpack_decoder_receiver.rs":"c927dfc3e58c71d282210ba79280f6f03e789733bc3bedc247e68bab516b9e9e","src/qpack_encoder_receiver.rs":"d0ac03cc111b6e1c555a8654d3234116f2b135b5b040edac23cefe2d640beba9","src/recv_message.rs":"7ac8d4057ba53874e4edfc62cd25ad5d3f0b10aaac5bf6e156103c3bc44e18cc","src/request_target.rs":"6041a69a0a74969ec08bc164509c055e9bad99f53bbeb16c0aa17d108dd68b8c","src/send_message.rs":"a16496e00a8ee9a69f20d97cf75c01230039eb8261b6b917d82238a42cb99bbe","src/server.rs":"ad477c0792a1e75d982215f4ad35a2dcb6dc82fc817093026670b675dd15dd21","src/server_connection_events.rs":"12d353ca6301467f6d475dde3b789951a5716c89ddd7dbf1383efef8082361f3","src/server_events.rs":"d7c845355a74ddee42047dc65fe394ef3a7625702beac3be75830002f4940f21","src/settings.rs":"476b154b5eea4c8d69a4a790fee3e527cef4d375df1cfb5eed04ec56406fe15a","src/stream_type_reader.rs":"7a7226b7911d69f7e00ec4987c2a32a5e8a33463203398cbee1e6645d2691478","tests/httpconn.rs":"a7137c37fe1003c9a3ba057b10cad4d8de1441100a24bad128345cfed69fb5b7","tests/priority.rs":"364754507873298612ad12e8d1d106d26d993712142d0be4cbf056da5338854c","tests/send_message.rs":"b5435045b16429d9e626ea94a8f10e2937e1a5a878af0035763a4f5ec09bf53c","tests/webtransport.rs":"25794305017ff58e57dc3c3b9b078e5bfc1814ea82a521b7b7156228e613c092"},"package":null}
|
||||
{"files":{"Cargo.toml":"173c2046a37c37c60d1a72799c3df3b278a76883caff7126ebf133849a4281c0","src/buffered_send_stream.rs":"dfb248c66ea65418b0c7798c2ecaa3ed70ef1af818ef58d53ef742b3445077b7","src/client_events.rs":"77fedca72ce54956eaba3fb7103085d196a631b764662584ea2629224c5c234e","src/conn_params.rs":"7f0df52bceda1923aef2b7c5c64a532f49ea083ea45e3dcd5bd4b03031b89643","src/connection.rs":"4a56ee7b7643f718318f138fd3d5235795cb0be9d2ae073959b43c2096b01b41","src/connection_client.rs":"8917faadc002d1ce35caec163422944fded670be4d6c5aad4cfe521a70a4dd52","src/connection_server.rs":"02fda7595a33c57d0b3ccede51a1e7a8c9073e1ec107ca1b56c56f1728db2318","src/control_stream_local.rs":"20917762c7e7c1112c56abf1cbaf0ad7f0eab97d8db9a3b10ff524315a235670","src/control_stream_remote.rs":"babad4b42274ea32936aa6a11fcb910d5d4a17c00db26cffd60545358207db86","src/features/extended_connect/mod.rs":"1def634e4d3547cc273fd862f3b22bbd22e94e03a402d1e2672c4b6b5061cd5e","src/features/extended_connect/tests/mod.rs":"fd6aee37243713e80fc526552f21f0222338cec9890409b6575a2a637b17ec1f","src/features/extended_connect/tests/webtransport/datagrams.rs":"51d6f3828c44b438eb1776e8dcce531af520f28bc0d715807d3f53a0eaa071d1","src/features/extended_connect/tests/webtransport/mod.rs":"27f77213414089148e94067bfc54133945a971fd7ddd6936bbfeabb9badc7e67","src/features/extended_connect/tests/webtransport/negotiation.rs":"a22094dbaf0754d39ac8ac08fce1ae34ace108220b696c7d618567df56cddeec","src/features/extended_connect/tests/webtransport/sessions.rs":"cf8aa14087cc3ff42657d86ecacbd51bc182357fdcbd10f57d32784abb415a12","src/features/extended_connect/tests/webtransport/streams.rs":"4c136855292d5ba5169f41c18beea13e7f1e014a0acb13c565c872d3a80d6377","src/features/extended_connect/webtransport_session.rs":"da0b99092d8af8d4f7699c8d45e2e4057f4de38d6fa99e27e3a7feffa569374f","src/features/extended_connect/webtransport_streams.rs":"9855d77705acb7d21566333c4b297816e363be2ade14b8685fd1df4a4861cf74","src/features/mod.rs":"89056df3a868cb0037963c942fc27093cc16d84538ffca2d4759f9a6a6c74c7f","src/frames/hframe.rs":"72349bf4e9dd5c57dc5443bb9aa079887e2742dc08d77ea55567e3b09e0de4d8","src/frames/mod.rs":"0e6d49888d723b2c2c73df11020ceb88d9f062e9d4dc436eb38173e0b772d905","src/frames/reader.rs":"8c7ea836a466410bd3c98848b4852945ae30e1306f73290c401c686998bde16d","src/frames/tests/hframe.rs":"01ec74eb3eb25d95042aa0263f9267f89535e6b7b8c1161fab4ba9ee5352d4a7","src/frames/tests/mod.rs":"a07b99a7ebc0771630a7b360679a5b8d568bb5ad2f1ec92e7f5afe6644c6800e","src/frames/tests/reader.rs":"6c5aaa9bf6becaf1892fda5d6d42c5e650f65d1a1a0fb4ccba9f5a6618a77ced","src/frames/tests/wtframe.rs":"589ebe1e62ce4da63b37b7d22cde7ba572ddbf29336fdcdbbcd0a745f79dacd8","src/frames/wtframe.rs":"ad6dd63c54a0305c045cd983d5889ae86a5a1afe1e7c13e1c169de9af440759e","src/headers_checks.rs":"be0f0109298dcc3a40350b7c0950076ddfe20617d195b305e3ffc8582557ab18","src/lib.rs":"54e9f5e9d37dc9b6bd6d1390edd91b4041699035419bdf7d44f18173e6be51cb","src/priority.rs":"946307329f31819d969093406ae5448f7923343ccc112221ea6eedf86cf447dc","src/push_controller.rs":"53f72e8043505f85cba0f9c16b4a5ce14d6668b030d773067bc88b2a10bdd25b","src/qlog.rs":"db5f2dd6566d44b4f0541f75266b417b558c09e62141f056885cb8c66478a932","src/qpack_decoder_receiver.rs":"eb06c4be59da567fef70c20daa2c0f165c768131165479a210e69659f168b88f","src/qpack_encoder_receiver.rs":"831f3da9ec17966286786ba3f2c723395a132e65d6a33b4ec341fe7640c1a53d","src/recv_message.rs":"c3acf0544680f88ccd3500e6bea949c1bb43e2fb0a8922edc8f837d0166c89f8","src/request_target.rs":"9720b9f87d66a7c2301bba7de5a5a9300f547613a63153a4d35c7a7506a59b31","src/send_message.rs":"be4e9f64db2c25eb7176b84695e608e768115d62e615d389a33d26f7cd5b0c6c","src/server.rs":"ff1aa32155da19d37df1a9303abe0b0f641b6ff8ef45d76d7aab94eb78472475","src/server_connection_events.rs":"1396baab265a814045ccfe63d637a4fdc32a667b5eb2925fa4951f5c3078fb20","src/server_events.rs":"02fc8c0711efd758fb1ddee27d257c12ed35e2a989e7bf3de44bd662dc8234e3","src/settings.rs":"d0f8c546e70161422a029a40564b9e9b953fe671c60835196b16f3364779eaf9","src/stream_type_reader.rs":"89e1a625bc0b7d7ad9d9bd4d82ad1d330fe7f5115e2c4f4ee6790b20b2e9acec","tests/httpconn.rs":"b29f3b1f6214586c472b1302a5111fc9ae549161b7ef41cacece10c4837a3401","tests/priority.rs":"364754507873298612ad12e8d1d106d26d993712142d0be4cbf056da5338854c","tests/send_message.rs":"cdf7028eb64f8f3778c3bbb2a10e9482c4e995e9e1813143ccd83ec96b2d4b6a","tests/webtransport.rs":"02b81be0a20252a8bb0796b5287e426c1af5ddaf5a47d68aa9165393cba83c45"},"package":null}
|
|
@ -13,9 +13,23 @@
|
|||
edition = "2021"
|
||||
rust-version = "1.76.0"
|
||||
name = "neqo-http3"
|
||||
version = "0.7.9"
|
||||
version = "0.8.1"
|
||||
authors = ["The Neqo Authors <necko@mozilla.com>"]
|
||||
description = "Neqo, the Mozilla implementation of QUIC in Rust."
|
||||
homepage = "https://github.com/mozilla/neqo/"
|
||||
readme = "../README.md"
|
||||
keywords = [
|
||||
"quic",
|
||||
"http3",
|
||||
"neqo",
|
||||
"mozilla",
|
||||
"ietf",
|
||||
"firefox",
|
||||
]
|
||||
categories = [
|
||||
"network-programming",
|
||||
"web-programming",
|
||||
]
|
||||
license = "MIT OR Apache-2.0"
|
||||
repository = "https://github.com/mozilla/neqo/"
|
||||
|
||||
|
@ -50,10 +64,6 @@ default-features = false
|
|||
version = "0.9"
|
||||
default-features = false
|
||||
|
||||
[dependencies.smallvec]
|
||||
version = "1.11"
|
||||
default-features = false
|
||||
|
||||
[dependencies.url]
|
||||
version = "2.5"
|
||||
default-features = false
|
||||
|
@ -67,6 +77,17 @@ disable-encryption = [
|
|||
"neqo-crypto/disable-encryption",
|
||||
]
|
||||
|
||||
[lints.clippy]
|
||||
multiple_crate_versions = "allow"
|
||||
|
||||
[lints.clippy.cargo]
|
||||
level = "warn"
|
||||
priority = -1
|
||||
|
||||
[lints.clippy.nursery]
|
||||
level = "warn"
|
||||
priority = -1
|
||||
|
||||
[lints.clippy.pedantic]
|
||||
level = "warn"
|
||||
priority = -1
|
||||
|
|
|
@ -29,7 +29,7 @@ impl ::std::fmt::Display for BufferedStream {
|
|||
|
||||
impl BufferedStream {
|
||||
#[must_use]
|
||||
pub fn new(stream_id: StreamId) -> Self {
|
||||
pub const fn new(stream_id: StreamId) -> Self {
|
||||
Self::Initialized {
|
||||
stream_id,
|
||||
buf: Vec::new(),
|
||||
|
@ -113,7 +113,7 @@ impl BufferedStream {
|
|||
}
|
||||
|
||||
impl From<&BufferedStream> for Option<StreamId> {
|
||||
fn from(stream: &BufferedStream) -> Option<StreamId> {
|
||||
fn from(stream: &BufferedStream) -> Self {
|
||||
if let BufferedStream::Initialized { stream_id, .. } = stream {
|
||||
Some(*stream_id)
|
||||
} else {
|
||||
|
|
|
@ -43,7 +43,7 @@ impl Default for Http3Parameters {
|
|||
|
||||
impl Http3Parameters {
|
||||
#[must_use]
|
||||
pub fn get_connection_parameters(&self) -> &ConnectionParameters {
|
||||
pub const fn get_connection_parameters(&self) -> &ConnectionParameters {
|
||||
&self.conn_params
|
||||
}
|
||||
|
||||
|
@ -65,7 +65,7 @@ impl Http3Parameters {
|
|||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn get_max_table_size_encoder(&self) -> u64 {
|
||||
pub const fn get_max_table_size_encoder(&self) -> u64 {
|
||||
self.qpack_settings.max_table_size_encoder
|
||||
}
|
||||
|
||||
|
@ -81,56 +81,56 @@ impl Http3Parameters {
|
|||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn get_max_table_size_decoder(&self) -> u64 {
|
||||
pub const fn get_max_table_size_decoder(&self) -> u64 {
|
||||
self.qpack_settings.max_table_size_decoder
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn max_blocked_streams(mut self, max_blocked: u16) -> Self {
|
||||
pub const fn max_blocked_streams(mut self, max_blocked: u16) -> Self {
|
||||
self.qpack_settings.max_blocked_streams = max_blocked;
|
||||
self
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn get_max_blocked_streams(&self) -> u16 {
|
||||
pub const fn get_max_blocked_streams(&self) -> u16 {
|
||||
self.qpack_settings.max_blocked_streams
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn get_qpack_settings(&self) -> &QpackSettings {
|
||||
pub const fn get_qpack_settings(&self) -> &QpackSettings {
|
||||
&self.qpack_settings
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn max_concurrent_push_streams(mut self, max_push_streams: u64) -> Self {
|
||||
pub const fn max_concurrent_push_streams(mut self, max_push_streams: u64) -> Self {
|
||||
self.max_concurrent_push_streams = max_push_streams;
|
||||
self
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn get_max_concurrent_push_streams(&self) -> u64 {
|
||||
pub const fn get_max_concurrent_push_streams(&self) -> u64 {
|
||||
self.max_concurrent_push_streams
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn webtransport(mut self, webtransport: bool) -> Self {
|
||||
pub const fn webtransport(mut self, webtransport: bool) -> Self {
|
||||
self.webtransport = webtransport;
|
||||
self
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn get_webtransport(&self) -> bool {
|
||||
pub const fn get_webtransport(&self) -> bool {
|
||||
self.webtransport
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn http3_datagram(mut self, http3_datagram: bool) -> Self {
|
||||
pub const fn http3_datagram(mut self, http3_datagram: bool) -> Self {
|
||||
self.http3_datagram = http3_datagram;
|
||||
self
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn get_http3_datagram(&self) -> bool {
|
||||
pub const fn get_http3_datagram(&self) -> bool {
|
||||
self.http3_datagram
|
||||
}
|
||||
}
|
||||
|
|
|
@ -44,7 +44,7 @@ use crate::{
|
|||
SendStreamEvents,
|
||||
};
|
||||
|
||||
pub(crate) struct RequestDescription<'b, 't, T>
|
||||
pub struct RequestDescription<'b, 't, T>
|
||||
where
|
||||
T: AsRequestTarget<'t> + ?Sized + Debug,
|
||||
{
|
||||
|
@ -63,8 +63,8 @@ pub enum WebTransportSessionAcceptAction {
|
|||
impl ::std::fmt::Display for WebTransportSessionAcceptAction {
|
||||
fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
|
||||
match self {
|
||||
WebTransportSessionAcceptAction::Accept => f.write_str("Accept"),
|
||||
WebTransportSessionAcceptAction::Reject(_) => f.write_str("Reject"),
|
||||
Self::Accept => f.write_str("Accept"),
|
||||
Self::Reject(_) => f.write_str("Reject"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -101,11 +101,8 @@ pub enum Http3State {
|
|||
|
||||
impl Http3State {
|
||||
#[must_use]
|
||||
pub fn active(&self) -> bool {
|
||||
matches!(
|
||||
self,
|
||||
Http3State::Connected | Http3State::GoingAway(_) | Http3State::ZeroRtt
|
||||
)
|
||||
pub const fn active(&self) -> bool {
|
||||
matches!(self, Self::Connected | Self::GoingAway(_) | Self::ZeroRtt)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -200,8 +197,9 @@ are local or remote:
|
|||
- will be canceled if is an unknown stream type or
|
||||
- the connection will fail if it is unallowed stream type (receiveing HTTP request on the
|
||||
client-side).
|
||||
The output is handled in `handle_new_stream`, for control, qpack streams and partially
|
||||
`WebTransport` streams, otherwise the output is handled by `Http3Client` and `Http3ServerHandler`.
|
||||
|
||||
The output is handled in `handle_new_stream`, for control, qpack streams and partially
|
||||
`WebTransport` streams, otherwise the output is handled by `Http3Client` and `Http3ServerHandler`.
|
||||
|
||||
|
||||
### Receiving data
|
||||
|
@ -298,7 +296,7 @@ The call to function `receive` may produce `Http3ClientEvent::DataReadable`. Act
|
|||
data is done in the `read_data` function.
|
||||
*/
|
||||
#[derive(Debug)]
|
||||
pub(crate) struct Http3Connection {
|
||||
pub struct Http3Connection {
|
||||
role: Role,
|
||||
pub state: Http3State,
|
||||
local_params: Http3Parameters,
|
||||
|
@ -375,7 +373,7 @@ impl Http3Connection {
|
|||
HttpZeroRttChecker::save(&self.local_params)
|
||||
}
|
||||
|
||||
fn create_qpack_streams(&mut self, conn: &mut Connection) -> Res<()> {
|
||||
fn create_qpack_streams(&self, conn: &mut Connection) -> Res<()> {
|
||||
qdebug!([self], "create_qpack_streams.");
|
||||
self.qpack_encoder
|
||||
.borrow_mut()
|
||||
|
@ -507,6 +505,7 @@ impl Http3Connection {
|
|||
/// 1) a `Push(_)`, `Htttp` or `WebTransportStream(_)` stream
|
||||
/// 2) frames `MaxPushId`, `PriorityUpdateRequest`, `PriorityUpdateRequestPush` or `Goaway` must
|
||||
/// be handled by `Http3Client`/`Server`.
|
||||
///
|
||||
/// The function returns `ReceiveOutput`.
|
||||
pub fn handle_stream_readable(
|
||||
&mut self,
|
||||
|
@ -525,9 +524,9 @@ impl Http3Connection {
|
|||
self.handle_unblocked_streams(unblocked_streams, conn)?;
|
||||
Ok(ReceiveOutput::NoOutput)
|
||||
}
|
||||
ReceiveOutput::ControlFrames(mut control_frames) => {
|
||||
ReceiveOutput::ControlFrames(control_frames) => {
|
||||
let mut rest = Vec::new();
|
||||
for cf in control_frames.drain(..) {
|
||||
for cf in control_frames {
|
||||
if let Some(not_handled) = self.handle_control_frame(cf)? {
|
||||
rest.push(not_handled);
|
||||
}
|
||||
|
@ -780,6 +779,7 @@ impl Http3Connection {
|
|||
/// - an error occurred or
|
||||
/// - the stream is done, i.e. the second value in `output` tuple is true if the stream is done
|
||||
/// and can be removed from the `recv_streams`
|
||||
///
|
||||
/// How it is handling `output`:
|
||||
/// - if the stream is done, it removes the stream from `recv_streams`
|
||||
/// - if the stream is not done and there is no error, return `output` and the caller will
|
||||
|
@ -891,7 +891,7 @@ impl Http3Connection {
|
|||
where
|
||||
T: AsRequestTarget<'t> + ?Sized + Debug,
|
||||
{
|
||||
let final_headers = Http3Connection::create_fetch_headers(request)?;
|
||||
let final_headers = Self::create_fetch_headers(request)?;
|
||||
|
||||
let stream_type = if request.connect_type.is_some() {
|
||||
Http3StreamType::ExtendedConnect
|
||||
|
@ -1138,7 +1138,7 @@ impl Http3Connection {
|
|||
Box::new(extended_conn.clone()),
|
||||
);
|
||||
|
||||
let final_headers = Http3Connection::create_fetch_headers(&RequestDescription {
|
||||
let final_headers = Self::create_fetch_headers(&RequestDescription {
|
||||
method: "CONNECT",
|
||||
target,
|
||||
headers,
|
||||
|
@ -1425,7 +1425,7 @@ impl Http3Connection {
|
|||
}
|
||||
}
|
||||
|
||||
fn set_qpack_settings(&mut self, settings: &HSettings) -> Res<()> {
|
||||
fn set_qpack_settings(&self, settings: &HSettings) -> Res<()> {
|
||||
let mut qpe = self.qpack_encoder.borrow_mut();
|
||||
qpe.set_max_capacity(settings.get(HSettingType::MaxTableCapacity))?;
|
||||
qpe.set_max_blocked_streams(settings.get(HSettingType::BlockedStreams))?;
|
||||
|
@ -1534,14 +1534,12 @@ impl Http3Connection {
|
|||
}
|
||||
|
||||
fn recv_stream_is_critical(&self, stream_id: StreamId) -> bool {
|
||||
if let Some(r) = self.recv_streams.get(&stream_id) {
|
||||
self.recv_streams.get(&stream_id).map_or(false, |r| {
|
||||
matches!(
|
||||
r.stream_type(),
|
||||
Http3StreamType::Control | Http3StreamType::Encoder | Http3StreamType::Decoder
|
||||
)
|
||||
} else {
|
||||
false
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
fn send_stream_is_critical(&self, stream_id: StreamId) -> bool {
|
||||
|
@ -1630,7 +1628,7 @@ impl Http3Connection {
|
|||
stream
|
||||
}
|
||||
|
||||
pub fn webtransport_enabled(&self) -> bool {
|
||||
pub const fn webtransport_enabled(&self) -> bool {
|
||||
self.webtransport.enabled()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -52,7 +52,7 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
fn alpn_from_quic_version(version: Version) -> &'static str {
|
||||
const fn alpn_from_quic_version(version: Version) -> &'static str {
|
||||
match version {
|
||||
Version::Version2 | Version::Version1 => "h3",
|
||||
Version::Draft29 => "h3-29",
|
||||
|
@ -68,7 +68,7 @@ fn alpn_from_quic_version(version: Version) -> &'static str {
|
|||
/// [connection.rs](https://github.com/mozilla/neqo/blob/main/neqo-http3/src/connection.rs) which
|
||||
/// implements common behavior for the client-side and the server-side. `Http3Client` structure
|
||||
/// implements the public API and set of functions that differ between the client and the server.
|
||||
|
||||
///
|
||||
/// The API is used for:
|
||||
/// - create and close an endpoint:
|
||||
/// - [`Http3Client::new`]
|
||||
|
@ -353,7 +353,7 @@ impl Http3Client {
|
|||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn role(&self) -> Role {
|
||||
pub const fn role(&self) -> Role {
|
||||
self.conn.role()
|
||||
}
|
||||
|
||||
|
@ -973,7 +973,7 @@ impl Http3Client {
|
|||
}
|
||||
Err(e) => {
|
||||
qinfo!([self], "Connection error: {}.", e);
|
||||
self.close(now, e.code(), &format!("{e}"));
|
||||
self.close(now, e.code(), format!("{e}"));
|
||||
true
|
||||
}
|
||||
_ => false,
|
||||
|
@ -1262,7 +1262,7 @@ impl Http3Client {
|
|||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn webtransport_enabled(&self) -> bool {
|
||||
pub const fn webtransport_enabled(&self) -> bool {
|
||||
self.base_handler.webtransport_enabled()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -228,7 +228,7 @@ impl Http3ServerHandler {
|
|||
}
|
||||
|
||||
/// Take the next available event.
|
||||
pub(crate) fn next_event(&mut self) -> Option<Http3ServerConnEvent> {
|
||||
pub(crate) fn next_event(&self) -> Option<Http3ServerConnEvent> {
|
||||
self.events.next_event()
|
||||
}
|
||||
|
||||
|
@ -255,7 +255,7 @@ impl Http3ServerHandler {
|
|||
|
||||
fn close(&mut self, conn: &mut Connection, now: Instant, err: &Error) {
|
||||
qinfo!([self], "Connection error: {}.", err);
|
||||
conn.close(now, err.code(), &format!("{err}"));
|
||||
conn.close(now, err.code(), format!("{err}"));
|
||||
self.base_handler.close(err.code());
|
||||
self.events
|
||||
.connection_state_change(self.base_handler.state());
|
||||
|
|
|
@ -15,7 +15,7 @@ pub const HTTP3_UNI_STREAM_TYPE_CONTROL: u64 = 0x0;
|
|||
|
||||
/// The local control stream, responsible for encoding frames and sending them
|
||||
#[derive(Debug)]
|
||||
pub(crate) struct ControlStreamLocal {
|
||||
pub struct ControlStreamLocal {
|
||||
stream: BufferedStream,
|
||||
/// `stream_id`s of outstanding request streams
|
||||
outstanding_priority_update: VecDeque<StreamId>,
|
||||
|
|
|
@ -15,7 +15,7 @@ use crate::{
|
|||
/// The remote control stream is responsible only for reading frames. The frames are handled by
|
||||
/// `Http3Connection`.
|
||||
#[derive(Debug)]
|
||||
pub(crate) struct ControlStreamRemote {
|
||||
pub struct ControlStreamRemote {
|
||||
stream_id: StreamId,
|
||||
frame_reader: FrameReader,
|
||||
}
|
||||
|
|
|
@ -30,12 +30,12 @@ pub enum SessionCloseReason {
|
|||
}
|
||||
|
||||
impl From<CloseType> for SessionCloseReason {
|
||||
fn from(close_type: CloseType) -> SessionCloseReason {
|
||||
fn from(close_type: CloseType) -> Self {
|
||||
match close_type {
|
||||
CloseType::ResetApp(e) | CloseType::ResetRemote(e) | CloseType::LocalError(e) => {
|
||||
SessionCloseReason::Error(e)
|
||||
Self::Error(e)
|
||||
}
|
||||
CloseType::Done => SessionCloseReason::Clean {
|
||||
CloseType::Done => Self::Clean {
|
||||
error: 0,
|
||||
message: String::new(),
|
||||
},
|
||||
|
@ -70,13 +70,13 @@ pub(crate) enum ExtendedConnectType {
|
|||
impl ExtendedConnectType {
|
||||
#[must_use]
|
||||
#[allow(clippy::unused_self)] // This will change when we have more features using ExtendedConnectType.
|
||||
pub fn string(&self) -> &str {
|
||||
pub const fn string(&self) -> &str {
|
||||
"webtransport"
|
||||
}
|
||||
|
||||
#[allow(clippy::unused_self)] // This will change when we have more features using ExtendedConnectType.
|
||||
#[must_use]
|
||||
pub fn get_stream_type(self, session_id: StreamId) -> Http3StreamType {
|
||||
pub const fn get_stream_type(self, session_id: StreamId) -> Http3StreamType {
|
||||
Http3StreamType::WebTransport(session_id)
|
||||
}
|
||||
}
|
||||
|
@ -84,7 +84,7 @@ impl ExtendedConnectType {
|
|||
impl From<ExtendedConnectType> for HSettingType {
|
||||
fn from(_type: ExtendedConnectType) -> Self {
|
||||
// This will change when we have more features using ExtendedConnectType.
|
||||
HSettingType::EnableWebTransport
|
||||
Self::EnableWebTransport
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -110,7 +110,7 @@ impl ExtendedConnectFeature {
|
|||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn enabled(&self) -> bool {
|
||||
pub const fn enabled(&self) -> bool {
|
||||
self.feature_negotiation.enabled()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,7 +22,7 @@ fn no_datagrams() {
|
|||
Http3Parameters::default().webtransport(true),
|
||||
Http3Parameters::default().webtransport(true),
|
||||
);
|
||||
let mut wt_session = wt.create_wt_session();
|
||||
let wt_session = wt.create_wt_session();
|
||||
|
||||
assert_eq!(
|
||||
wt_session.max_datagram_size(),
|
||||
|
@ -47,7 +47,7 @@ fn no_datagrams() {
|
|||
wt.check_no_datagram_received_server();
|
||||
}
|
||||
|
||||
fn do_datagram_test(wt: &mut WtTest, wt_session: &mut WebTransportRequest) {
|
||||
fn do_datagram_test(wt: &mut WtTest, wt_session: &WebTransportRequest) {
|
||||
assert_eq!(
|
||||
wt_session.max_datagram_size(),
|
||||
Ok(DATAGRAM_SIZE
|
||||
|
@ -70,8 +70,8 @@ fn do_datagram_test(wt: &mut WtTest, wt_session: &mut WebTransportRequest) {
|
|||
#[test]
|
||||
fn datagrams() {
|
||||
let mut wt = WtTest::new();
|
||||
let mut wt_session = wt.create_wt_session();
|
||||
do_datagram_test(&mut wt, &mut wt_session);
|
||||
let wt_session = wt.create_wt_session();
|
||||
do_datagram_test(&mut wt, &wt_session);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -80,7 +80,7 @@ fn datagrams_server_only() {
|
|||
Http3Parameters::default().webtransport(true),
|
||||
wt_default_parameters(),
|
||||
);
|
||||
let mut wt_session = wt.create_wt_session();
|
||||
let wt_session = wt.create_wt_session();
|
||||
|
||||
assert_eq!(
|
||||
wt_session.max_datagram_size(),
|
||||
|
@ -109,7 +109,7 @@ fn datagrams_client_only() {
|
|||
wt_default_parameters(),
|
||||
Http3Parameters::default().webtransport(true),
|
||||
);
|
||||
let mut wt_session = wt.create_wt_session();
|
||||
let wt_session = wt.create_wt_session();
|
||||
|
||||
assert_eq!(
|
||||
wt_session.max_datagram_size(),
|
||||
|
@ -136,9 +136,9 @@ fn datagrams_client_only() {
|
|||
fn datagrams_multiple_session() {
|
||||
let mut wt = WtTest::new();
|
||||
|
||||
let mut wt_session1 = wt.create_wt_session();
|
||||
do_datagram_test(&mut wt, &mut wt_session1);
|
||||
let wt_session1 = wt.create_wt_session();
|
||||
do_datagram_test(&mut wt, &wt_session1);
|
||||
|
||||
let mut wt_session_2 = wt.create_wt_session();
|
||||
do_datagram_test(&mut wt, &mut wt_session_2);
|
||||
let wt_session_2 = wt.create_wt_session();
|
||||
do_datagram_test(&mut wt, &wt_session_2);
|
||||
}
|
||||
|
|
|
@ -12,7 +12,7 @@ use std::{cell::RefCell, rc::Rc, time::Duration};
|
|||
|
||||
use neqo_common::event::Provider;
|
||||
use neqo_crypto::AuthenticationStatus;
|
||||
use neqo_transport::{ConnectionParameters, StreamId, StreamType, MIN_INITIAL_PACKET_SIZE};
|
||||
use neqo_transport::{ConnectionParameters, Pmtud, StreamId, StreamType};
|
||||
use test_fixture::{
|
||||
anti_replay, fixture_init, now, CountingConnectionIdGenerator, DEFAULT_ADDR, DEFAULT_ALPN_H3,
|
||||
DEFAULT_KEYS, DEFAULT_SERVER_NAME,
|
||||
|
@ -25,7 +25,8 @@ use crate::{
|
|||
WebTransportServerEvent, WebTransportSessionAcceptAction,
|
||||
};
|
||||
|
||||
const DATAGRAM_SIZE: u64 = MIN_INITIAL_PACKET_SIZE as u64;
|
||||
// Leave space for large QUIC header.
|
||||
const DATAGRAM_SIZE: u64 = Pmtud::default_plpmtu(DEFAULT_ADDR.ip()) as u64 - 40;
|
||||
|
||||
pub fn wt_default_parameters() -> Http3Parameters {
|
||||
Http3Parameters::default()
|
||||
|
@ -144,7 +145,7 @@ impl WtTest {
|
|||
while let Some(event) = self.server.next_event() {
|
||||
match event {
|
||||
Http3ServerEvent::WebTransport(WebTransportServerEvent::NewSession {
|
||||
mut session,
|
||||
session,
|
||||
headers,
|
||||
}) => {
|
||||
assert!(
|
||||
|
@ -243,7 +244,7 @@ impl WtTest {
|
|||
let mut event_found = false;
|
||||
|
||||
while let Some(event) = self.client.next_event() {
|
||||
event_found = WtTest::session_closed_client(
|
||||
event_found = Self::session_closed_client(
|
||||
&event,
|
||||
wt_session_id,
|
||||
expected_reason,
|
||||
|
@ -256,7 +257,7 @@ impl WtTest {
|
|||
assert!(event_found);
|
||||
}
|
||||
|
||||
pub fn cancel_session_server(&mut self, wt_session: &mut WebTransportRequest) {
|
||||
pub fn cancel_session_server(&mut self, wt_session: &WebTransportRequest) {
|
||||
wt_session.cancel_fetch(Error::HttpNoError.code()).unwrap();
|
||||
self.exchange_packets();
|
||||
}
|
||||
|
@ -279,12 +280,12 @@ impl WtTest {
|
|||
}
|
||||
|
||||
pub fn check_session_closed_event_server(
|
||||
&mut self,
|
||||
wt_session: &mut WebTransportRequest,
|
||||
&self,
|
||||
wt_session: &WebTransportRequest,
|
||||
expected_reeason: &SessionCloseReason,
|
||||
) {
|
||||
let event = self.server.next_event().unwrap();
|
||||
assert!(WtTest::session_closed_server(
|
||||
assert!(Self::session_closed_server(
|
||||
&event,
|
||||
wt_session.stream_id(),
|
||||
expected_reeason
|
||||
|
@ -444,13 +445,13 @@ impl WtTest {
|
|||
}
|
||||
|
||||
fn create_wt_stream_server(
|
||||
wt_server_session: &mut WebTransportRequest,
|
||||
wt_server_session: &WebTransportRequest,
|
||||
stream_type: StreamType,
|
||||
) -> Http3OrWebTransportStream {
|
||||
wt_server_session.create_stream(stream_type).unwrap()
|
||||
}
|
||||
|
||||
fn send_data_server(&mut self, wt_stream: &mut Http3OrWebTransportStream, data: &[u8]) {
|
||||
fn send_data_server(&mut self, wt_stream: &Http3OrWebTransportStream, data: &[u8]) {
|
||||
assert_eq!(wt_stream.send_data(data).unwrap(), data.len());
|
||||
self.exchange_packets();
|
||||
}
|
||||
|
@ -494,26 +495,26 @@ impl WtTest {
|
|||
wt_stream.unwrap()
|
||||
}
|
||||
|
||||
fn close_stream_sending_server(&mut self, wt_stream: &mut Http3OrWebTransportStream) {
|
||||
fn close_stream_sending_server(&mut self, wt_stream: &Http3OrWebTransportStream) {
|
||||
wt_stream.stream_close_send().unwrap();
|
||||
self.exchange_packets();
|
||||
}
|
||||
|
||||
fn reset_stream_server(&mut self, wt_stream: &mut Http3OrWebTransportStream) {
|
||||
fn reset_stream_server(&mut self, wt_stream: &Http3OrWebTransportStream) {
|
||||
wt_stream
|
||||
.stream_reset_send(Error::HttpNoError.code())
|
||||
.unwrap();
|
||||
self.exchange_packets();
|
||||
}
|
||||
|
||||
fn stream_stop_sending_server(&mut self, wt_stream: &mut Http3OrWebTransportStream) {
|
||||
fn stream_stop_sending_server(&mut self, wt_stream: &Http3OrWebTransportStream) {
|
||||
wt_stream
|
||||
.stream_stop_sending(Error::HttpNoError.code())
|
||||
.unwrap();
|
||||
self.exchange_packets();
|
||||
}
|
||||
|
||||
fn receive_reset_server(&mut self, expected_stream_id: StreamId, expected_error: u64) {
|
||||
fn receive_reset_server(&self, expected_stream_id: StreamId, expected_error: u64) {
|
||||
let stream_reset = |e| {
|
||||
matches!(
|
||||
e,
|
||||
|
@ -526,7 +527,7 @@ impl WtTest {
|
|||
assert!(self.server.events().any(stream_reset));
|
||||
}
|
||||
|
||||
fn receive_stop_sending_server(&mut self, expected_stream_id: StreamId, expected_error: u64) {
|
||||
fn receive_stop_sending_server(&self, expected_stream_id: StreamId, expected_error: u64) {
|
||||
let stop_sending = |e| {
|
||||
matches!(
|
||||
e,
|
||||
|
@ -540,7 +541,7 @@ impl WtTest {
|
|||
}
|
||||
|
||||
fn check_events_after_closing_session_server(
|
||||
&mut self,
|
||||
&self,
|
||||
expected_reset_ids: &[StreamId],
|
||||
expected_error_stream_reset: Option<u64>,
|
||||
expected_stop_sending_ids: &[StreamId],
|
||||
|
@ -589,11 +590,7 @@ impl WtTest {
|
|||
.unwrap();
|
||||
}
|
||||
|
||||
pub fn session_close_frame_server(
|
||||
wt_session: &mut WebTransportRequest,
|
||||
error: u32,
|
||||
message: &str,
|
||||
) {
|
||||
pub fn session_close_frame_server(wt_session: &WebTransportRequest, error: u32, message: &str) {
|
||||
wt_session.close_session(error, message).unwrap();
|
||||
}
|
||||
|
||||
|
@ -623,7 +620,7 @@ impl WtTest {
|
|||
}
|
||||
|
||||
fn check_datagram_received_server(
|
||||
&mut self,
|
||||
&self,
|
||||
expected_session: &WebTransportRequest,
|
||||
expected_dgram: &[u8],
|
||||
) {
|
||||
|
@ -649,7 +646,7 @@ impl WtTest {
|
|||
assert!(!self.client.events().any(wt_datagram_event));
|
||||
}
|
||||
|
||||
fn check_no_datagram_received_server(&mut self) {
|
||||
fn check_no_datagram_received_server(&self) {
|
||||
let wt_datagram_event = |e| {
|
||||
matches!(
|
||||
e,
|
||||
|
|
|
@ -116,12 +116,9 @@ fn zero_rtt(
|
|||
client_resumed && server_resumed
|
||||
);
|
||||
|
||||
let mut early_data_accepted = true;
|
||||
// The only case we should not do 0-RTT is when webtransport was enabled
|
||||
// originally and is disabled afterwards.
|
||||
if server_org && !server_resumed {
|
||||
early_data_accepted = false;
|
||||
}
|
||||
let early_data_accepted = !server_org || server_resumed;
|
||||
assert_eq!(
|
||||
client.tls_info().unwrap().early_data_accepted(),
|
||||
early_data_accepted
|
||||
|
|
|
@ -46,11 +46,11 @@ fn wt_session_reject() {
|
|||
#[test]
|
||||
fn wt_session_close_client() {
|
||||
let mut wt = WtTest::new();
|
||||
let mut wt_session = wt.create_wt_session();
|
||||
let wt_session = wt.create_wt_session();
|
||||
|
||||
wt.cancel_session_client(wt_session.stream_id());
|
||||
wt.check_session_closed_event_server(
|
||||
&mut wt_session,
|
||||
&wt_session,
|
||||
&SessionCloseReason::Error(Error::HttpNoError.code()),
|
||||
);
|
||||
}
|
||||
|
@ -58,9 +58,9 @@ fn wt_session_close_client() {
|
|||
#[test]
|
||||
fn wt_session_close_server() {
|
||||
let mut wt = WtTest::new();
|
||||
let mut wt_session = wt.create_wt_session();
|
||||
let wt_session = wt.create_wt_session();
|
||||
|
||||
wt.cancel_session_server(&mut wt_session);
|
||||
wt.cancel_session_server(&wt_session);
|
||||
wt.check_session_closed_event_client(
|
||||
wt_session.stream_id(),
|
||||
&SessionCloseReason::Error(Error::HttpNoError.code()),
|
||||
|
@ -71,7 +71,7 @@ fn wt_session_close_server() {
|
|||
#[test]
|
||||
fn wt_session_close_server_close_send() {
|
||||
let mut wt = WtTest::new();
|
||||
let mut wt_session = wt.create_wt_session();
|
||||
let wt_session = wt.create_wt_session();
|
||||
|
||||
wt_session.stream_close_send().unwrap();
|
||||
wt.exchange_packets();
|
||||
|
@ -88,7 +88,7 @@ fn wt_session_close_server_close_send() {
|
|||
#[test]
|
||||
fn wt_session_close_server_stop_sending() {
|
||||
let mut wt = WtTest::new();
|
||||
let mut wt_session = wt.create_wt_session();
|
||||
let wt_session = wt.create_wt_session();
|
||||
|
||||
wt_session
|
||||
.stream_stop_sending(Error::HttpNoError.code())
|
||||
|
@ -104,7 +104,7 @@ fn wt_session_close_server_stop_sending() {
|
|||
#[test]
|
||||
fn wt_session_close_server_reset() {
|
||||
let mut wt = WtTest::new();
|
||||
let mut wt_session = wt.create_wt_session();
|
||||
let wt_session = wt.create_wt_session();
|
||||
|
||||
wt_session
|
||||
.stream_reset_send(Error::HttpNoError.code())
|
||||
|
@ -146,7 +146,7 @@ fn wt_session_response_with_1xx() {
|
|||
}
|
||||
}
|
||||
|
||||
let mut wt_server_session = wt_server_session.unwrap();
|
||||
let wt_server_session = wt_server_session.unwrap();
|
||||
|
||||
// Send interim response.
|
||||
wt_server_session
|
||||
|
@ -221,7 +221,7 @@ fn wt_session_respone_200_with_fin() {
|
|||
}
|
||||
}
|
||||
|
||||
let mut wt_server_session = wt_server_session.unwrap();
|
||||
let wt_server_session = wt_server_session.unwrap();
|
||||
wt_server_session
|
||||
.response(&WebTransportSessionAcceptAction::Accept)
|
||||
.unwrap();
|
||||
|
@ -254,13 +254,13 @@ fn wt_session_close_frame_client() {
|
|||
const ERROR_NUM: u32 = 23;
|
||||
const ERROR_MESSAGE: &str = "Something went wrong";
|
||||
let mut wt = WtTest::new();
|
||||
let mut wt_session = wt.create_wt_session();
|
||||
let wt_session = wt.create_wt_session();
|
||||
|
||||
wt.session_close_frame_client(wt_session.stream_id(), ERROR_NUM, ERROR_MESSAGE);
|
||||
wt.exchange_packets();
|
||||
|
||||
wt.check_session_closed_event_server(
|
||||
&mut wt_session,
|
||||
&wt_session,
|
||||
&SessionCloseReason::Clean {
|
||||
error: ERROR_NUM,
|
||||
message: ERROR_MESSAGE.to_string(),
|
||||
|
@ -273,9 +273,9 @@ fn wt_session_close_frame_server() {
|
|||
const ERROR_NUM: u32 = 23;
|
||||
const ERROR_MESSAGE: &str = "Something went wrong";
|
||||
let mut wt = WtTest::new();
|
||||
let mut wt_session = wt.create_wt_session();
|
||||
let wt_session = wt.create_wt_session();
|
||||
|
||||
WtTest::session_close_frame_server(&mut wt_session, ERROR_NUM, ERROR_MESSAGE);
|
||||
WtTest::session_close_frame_server(&wt_session, ERROR_NUM, ERROR_MESSAGE);
|
||||
wt.exchange_packets();
|
||||
|
||||
wt.check_session_closed_event_client(
|
||||
|
@ -295,7 +295,7 @@ fn wt_unknown_session_frame_client() {
|
|||
const ERROR_NUM: u32 = 23;
|
||||
const ERROR_MESSAGE: &str = "Something went wrong";
|
||||
let mut wt = WtTest::new();
|
||||
let mut wt_session = wt.create_wt_session();
|
||||
let wt_session = wt.create_wt_session();
|
||||
|
||||
// Send an unknown frame.
|
||||
let mut enc = Encoder::with_capacity(UNKNOWN_FRAME_LEN + 4);
|
||||
|
@ -307,8 +307,8 @@ fn wt_unknown_session_frame_client() {
|
|||
wt.exchange_packets();
|
||||
|
||||
// The session is still active
|
||||
let mut unidi_server = WtTest::create_wt_stream_server(&mut wt_session, StreamType::UniDi);
|
||||
wt.send_data_server(&mut unidi_server, BUF);
|
||||
let unidi_server = WtTest::create_wt_stream_server(&wt_session, StreamType::UniDi);
|
||||
wt.send_data_server(&unidi_server, BUF);
|
||||
wt.receive_data_client(unidi_server.stream_id(), true, BUF, false);
|
||||
|
||||
// Now close the session.
|
||||
|
@ -341,7 +341,7 @@ fn wt_unknown_session_frame_client() {
|
|||
#[test]
|
||||
fn wt_close_session_frame_broken_client() {
|
||||
let mut wt = WtTest::new();
|
||||
let mut wt_session = wt.create_wt_session();
|
||||
let wt_session = wt.create_wt_session();
|
||||
|
||||
// Send a incorrect CloseSession frame.
|
||||
let mut enc = Encoder::default();
|
||||
|
@ -363,7 +363,7 @@ fn wt_close_session_frame_broken_client() {
|
|||
&None,
|
||||
);
|
||||
wt.check_session_closed_event_server(
|
||||
&mut wt_session,
|
||||
&wt_session,
|
||||
&SessionCloseReason::Error(Error::HttpGeneralProtocolStream.code()),
|
||||
);
|
||||
|
||||
|
@ -372,7 +372,7 @@ fn wt_close_session_frame_broken_client() {
|
|||
assert_eq!(wt_session.state(), Http3State::Connected);
|
||||
}
|
||||
|
||||
fn receive_request(server: &mut Http3Server) -> Option<Http3OrWebTransportStream> {
|
||||
fn receive_request(server: &Http3Server) -> Option<Http3OrWebTransportStream> {
|
||||
while let Some(event) = server.next_event() {
|
||||
if let Http3ServerEvent::Headers { stream, .. } = event {
|
||||
return Some(stream);
|
||||
|
@ -394,7 +394,7 @@ fn wt_close_session_cannot_be_sent_at_once() {
|
|||
let server = default_http3_server(wt_default_parameters());
|
||||
let mut wt = WtTest::new_with(client, server);
|
||||
|
||||
let mut wt_session = wt.create_wt_session();
|
||||
let wt_session = wt.create_wt_session();
|
||||
|
||||
// Fill the flow control window using an unrelated http stream.
|
||||
let req_id = wt
|
||||
|
@ -409,7 +409,7 @@ fn wt_close_session_cannot_be_sent_at_once() {
|
|||
.unwrap();
|
||||
assert_eq!(req_id, 4);
|
||||
wt.exchange_packets();
|
||||
let mut req = receive_request(&mut wt.server).unwrap();
|
||||
let req = receive_request(&wt.server).unwrap();
|
||||
req.send_headers(&[
|
||||
Header::new(":status", "200"),
|
||||
Header::new("content-length", BUF.len().to_string()),
|
||||
|
@ -418,7 +418,7 @@ fn wt_close_session_cannot_be_sent_at_once() {
|
|||
req.send_data(BUF).unwrap();
|
||||
|
||||
// Now close the session.
|
||||
WtTest::session_close_frame_server(&mut wt_session, ERROR_NUM, ERROR_MESSAGE);
|
||||
WtTest::session_close_frame_server(&wt_session, ERROR_NUM, ERROR_MESSAGE);
|
||||
// server cannot create new streams.
|
||||
assert_eq!(
|
||||
wt_session.create_stream(StreamType::UniDi),
|
||||
|
|
|
@ -53,8 +53,8 @@ fn wt_client_stream_bidi() {
|
|||
let wt_session = wt.create_wt_session();
|
||||
let wt_client_stream = wt.create_wt_stream_client(wt_session.stream_id(), StreamType::BiDi);
|
||||
wt.send_data_client(wt_client_stream, BUF_CLIENT);
|
||||
let mut wt_server_stream = wt.receive_data_server(wt_client_stream, true, BUF_CLIENT, false);
|
||||
wt.send_data_server(&mut wt_server_stream, BUF_SERVER);
|
||||
let wt_server_stream = wt.receive_data_server(wt_client_stream, true, BUF_CLIENT, false);
|
||||
wt.send_data_server(&wt_server_stream, BUF_SERVER);
|
||||
wt.receive_data_client(wt_client_stream, false, BUF_SERVER, false);
|
||||
let send_stats = wt.send_stream_stats(wt_client_stream).unwrap();
|
||||
assert_eq!(send_stats.bytes_written(), BUF_CLIENT.len() as u64);
|
||||
|
@ -71,9 +71,9 @@ fn wt_server_stream_uni() {
|
|||
const BUF_SERVER: &[u8] = &[2; 30];
|
||||
|
||||
let mut wt = WtTest::new();
|
||||
let mut wt_session = wt.create_wt_session();
|
||||
let mut wt_server_stream = WtTest::create_wt_stream_server(&mut wt_session, StreamType::UniDi);
|
||||
wt.send_data_server(&mut wt_server_stream, BUF_SERVER);
|
||||
let wt_session = wt.create_wt_session();
|
||||
let wt_server_stream = WtTest::create_wt_stream_server(&wt_session, StreamType::UniDi);
|
||||
wt.send_data_server(&wt_server_stream, BUF_SERVER);
|
||||
wt.receive_data_client(wt_server_stream.stream_id(), true, BUF_SERVER, false);
|
||||
let send_stats = wt.send_stream_stats(wt_server_stream.stream_id());
|
||||
assert_eq!(send_stats.unwrap_err(), Error::InvalidStreamId);
|
||||
|
@ -89,9 +89,9 @@ fn wt_server_stream_bidi() {
|
|||
const BUF_SERVER: &[u8] = &[1; 20];
|
||||
|
||||
let mut wt = WtTest::new();
|
||||
let mut wt_session = wt.create_wt_session();
|
||||
let mut wt_server_stream = WtTest::create_wt_stream_server(&mut wt_session, StreamType::BiDi);
|
||||
wt.send_data_server(&mut wt_server_stream, BUF_SERVER);
|
||||
let wt_session = wt.create_wt_session();
|
||||
let wt_server_stream = WtTest::create_wt_stream_server(&wt_session, StreamType::BiDi);
|
||||
wt.send_data_server(&wt_server_stream, BUF_SERVER);
|
||||
wt.receive_data_client(wt_server_stream.stream_id(), true, BUF_SERVER, false);
|
||||
wt.send_data_client(wt_server_stream.stream_id(), BUF_CLIENT);
|
||||
mem::drop(wt.receive_data_server(wt_server_stream.stream_id(), false, BUF_CLIENT, false));
|
||||
|
@ -129,10 +129,10 @@ fn wt_client_stream_bidi_close() {
|
|||
wt.send_data_client(wt_client_stream, BUF_CLIENT);
|
||||
wt.close_stream_sending_client(wt_client_stream);
|
||||
|
||||
let mut wt_server_stream = wt.receive_data_server(wt_client_stream, true, BUF_CLIENT, true);
|
||||
let wt_server_stream = wt.receive_data_server(wt_client_stream, true, BUF_CLIENT, true);
|
||||
|
||||
wt.send_data_server(&mut wt_server_stream, BUF_SERVER);
|
||||
wt.close_stream_sending_server(&mut wt_server_stream);
|
||||
wt.send_data_server(&wt_server_stream, BUF_SERVER);
|
||||
wt.close_stream_sending_server(&wt_server_stream);
|
||||
wt.receive_data_client(wt_client_stream, false, BUF_SERVER, true);
|
||||
}
|
||||
|
||||
|
@ -141,10 +141,10 @@ fn wt_server_stream_uni_closed() {
|
|||
const BUF_SERVER: &[u8] = &[2; 30];
|
||||
|
||||
let mut wt = WtTest::new();
|
||||
let mut wt_session = wt.create_wt_session();
|
||||
let mut wt_server_stream = WtTest::create_wt_stream_server(&mut wt_session, StreamType::UniDi);
|
||||
wt.send_data_server(&mut wt_server_stream, BUF_SERVER);
|
||||
wt.close_stream_sending_server(&mut wt_server_stream);
|
||||
let wt_session = wt.create_wt_session();
|
||||
let wt_server_stream = WtTest::create_wt_stream_server(&wt_session, StreamType::UniDi);
|
||||
wt.send_data_server(&wt_server_stream, BUF_SERVER);
|
||||
wt.close_stream_sending_server(&wt_server_stream);
|
||||
wt.receive_data_client(wt_server_stream.stream_id(), true, BUF_SERVER, true);
|
||||
}
|
||||
|
||||
|
@ -154,10 +154,10 @@ fn wt_server_stream_bidi_close() {
|
|||
const BUF_SERVER: &[u8] = &[1; 20];
|
||||
|
||||
let mut wt = WtTest::new();
|
||||
let mut wt_session = wt.create_wt_session();
|
||||
let mut wt_server_stream = WtTest::create_wt_stream_server(&mut wt_session, StreamType::BiDi);
|
||||
wt.send_data_server(&mut wt_server_stream, BUF_SERVER);
|
||||
wt.close_stream_sending_server(&mut wt_server_stream);
|
||||
let wt_session = wt.create_wt_session();
|
||||
let wt_server_stream = WtTest::create_wt_stream_server(&wt_session, StreamType::BiDi);
|
||||
wt.send_data_server(&wt_server_stream, BUF_SERVER);
|
||||
wt.close_stream_sending_server(&wt_server_stream);
|
||||
wt.receive_data_client(wt_server_stream.stream_id(), true, BUF_SERVER, true);
|
||||
wt.send_data_client(wt_server_stream.stream_id(), BUF_CLIENT);
|
||||
wt.close_stream_sending_client(wt_server_stream.stream_id());
|
||||
|
@ -182,11 +182,11 @@ fn wt_server_stream_uni_reset() {
|
|||
const BUF_SERVER: &[u8] = &[2; 30];
|
||||
|
||||
let mut wt = WtTest::new();
|
||||
let mut wt_session = wt.create_wt_session();
|
||||
let mut wt_server_stream = WtTest::create_wt_stream_server(&mut wt_session, StreamType::UniDi);
|
||||
wt.send_data_server(&mut wt_server_stream, BUF_SERVER);
|
||||
let wt_session = wt.create_wt_session();
|
||||
let wt_server_stream = WtTest::create_wt_stream_server(&wt_session, StreamType::UniDi);
|
||||
wt.send_data_server(&wt_server_stream, BUF_SERVER);
|
||||
wt.receive_data_client(wt_server_stream.stream_id(), true, BUF_SERVER, false);
|
||||
wt.reset_stream_server(&mut wt_server_stream);
|
||||
wt.reset_stream_server(&wt_server_stream);
|
||||
wt.receive_reset_client(wt_server_stream.stream_id());
|
||||
}
|
||||
|
||||
|
@ -199,12 +199,12 @@ fn wt_client_stream_bidi_reset() {
|
|||
let wt_client_stream = wt.create_wt_stream_client(wt_session.stream_id(), StreamType::BiDi);
|
||||
|
||||
wt.send_data_client(wt_client_stream, BUF_CLIENT);
|
||||
let mut wt_server_stream = wt.receive_data_server(wt_client_stream, true, BUF_CLIENT, false);
|
||||
let wt_server_stream = wt.receive_data_server(wt_client_stream, true, BUF_CLIENT, false);
|
||||
|
||||
wt.reset_stream_client(wt_client_stream);
|
||||
wt.receive_reset_server(wt_server_stream.stream_id(), Error::HttpNoError.code());
|
||||
|
||||
wt.reset_stream_server(&mut wt_server_stream);
|
||||
wt.reset_stream_server(&wt_server_stream);
|
||||
wt.receive_reset_client(wt_client_stream);
|
||||
}
|
||||
|
||||
|
@ -213,15 +213,15 @@ fn wt_server_stream_bidi_reset() {
|
|||
const BUF_SERVER: &[u8] = &[1; 20];
|
||||
|
||||
let mut wt = WtTest::new();
|
||||
let mut wt_session = wt.create_wt_session();
|
||||
let mut wt_server_stream = WtTest::create_wt_stream_server(&mut wt_session, StreamType::BiDi);
|
||||
wt.send_data_server(&mut wt_server_stream, BUF_SERVER);
|
||||
let wt_session = wt.create_wt_session();
|
||||
let wt_server_stream = WtTest::create_wt_stream_server(&wt_session, StreamType::BiDi);
|
||||
wt.send_data_server(&wt_server_stream, BUF_SERVER);
|
||||
wt.receive_data_client(wt_server_stream.stream_id(), true, BUF_SERVER, false);
|
||||
|
||||
wt.reset_stream_client(wt_server_stream.stream_id());
|
||||
wt.receive_reset_server(wt_server_stream.stream_id(), Error::HttpNoError.code());
|
||||
|
||||
wt.reset_stream_server(&mut wt_server_stream);
|
||||
wt.reset_stream_server(&wt_server_stream);
|
||||
wt.receive_reset_client(wt_server_stream.stream_id());
|
||||
}
|
||||
|
||||
|
@ -233,8 +233,8 @@ fn wt_client_stream_uni_stop_sending() {
|
|||
let wt_session = wt.create_wt_session();
|
||||
let wt_stream = wt.create_wt_stream_client(wt_session.stream_id(), StreamType::UniDi);
|
||||
wt.send_data_client(wt_stream, BUF_CLIENT);
|
||||
let mut wt_server_stream = wt.receive_data_server(wt_stream, true, BUF_CLIENT, false);
|
||||
wt.stream_stop_sending_server(&mut wt_server_stream);
|
||||
let wt_server_stream = wt.receive_data_server(wt_stream, true, BUF_CLIENT, false);
|
||||
wt.stream_stop_sending_server(&wt_server_stream);
|
||||
wt.receive_stop_sending_client(wt_stream);
|
||||
}
|
||||
|
||||
|
@ -243,9 +243,9 @@ fn wt_server_stream_uni_stop_sending() {
|
|||
const BUF_SERVER: &[u8] = &[2; 30];
|
||||
|
||||
let mut wt = WtTest::new();
|
||||
let mut wt_session = wt.create_wt_session();
|
||||
let mut wt_server_stream = WtTest::create_wt_stream_server(&mut wt_session, StreamType::UniDi);
|
||||
wt.send_data_server(&mut wt_server_stream, BUF_SERVER);
|
||||
let wt_session = wt.create_wt_session();
|
||||
let wt_server_stream = WtTest::create_wt_stream_server(&wt_session, StreamType::UniDi);
|
||||
wt.send_data_server(&wt_server_stream, BUF_SERVER);
|
||||
wt.receive_data_client(wt_server_stream.stream_id(), true, BUF_SERVER, false);
|
||||
wt.stream_stop_sending_client(wt_server_stream.stream_id());
|
||||
wt.receive_stop_sending_server(wt_server_stream.stream_id(), Error::HttpNoError.code());
|
||||
|
@ -262,12 +262,12 @@ fn wt_client_stream_bidi_stop_sending() {
|
|||
|
||||
wt.send_data_client(wt_client_stream, BUF_CLIENT);
|
||||
|
||||
let mut wt_server_stream = wt.receive_data_server(wt_client_stream, true, BUF_CLIENT, false);
|
||||
let wt_server_stream = wt.receive_data_server(wt_client_stream, true, BUF_CLIENT, false);
|
||||
|
||||
wt.stream_stop_sending_client(wt_client_stream);
|
||||
|
||||
wt.receive_stop_sending_server(wt_server_stream.stream_id(), Error::HttpNoError.code());
|
||||
wt.stream_stop_sending_server(&mut wt_server_stream);
|
||||
wt.stream_stop_sending_server(&wt_server_stream);
|
||||
wt.receive_stop_sending_client(wt_server_stream.stream_id());
|
||||
}
|
||||
|
||||
|
@ -276,14 +276,14 @@ fn wt_server_stream_bidi_stop_sending() {
|
|||
const BUF_SERVER: &[u8] = &[1; 20];
|
||||
|
||||
let mut wt = WtTest::new();
|
||||
let mut wt_session = wt.create_wt_session();
|
||||
let mut wt_server_stream = WtTest::create_wt_stream_server(&mut wt_session, StreamType::BiDi);
|
||||
let wt_session = wt.create_wt_session();
|
||||
let wt_server_stream = WtTest::create_wt_stream_server(&wt_session, StreamType::BiDi);
|
||||
|
||||
wt.send_data_server(&mut wt_server_stream, BUF_SERVER);
|
||||
wt.send_data_server(&wt_server_stream, BUF_SERVER);
|
||||
wt.receive_data_client(wt_server_stream.stream_id(), true, BUF_SERVER, false);
|
||||
wt.stream_stop_sending_client(wt_server_stream.stream_id());
|
||||
wt.receive_stop_sending_server(wt_server_stream.stream_id(), Error::HttpNoError.code());
|
||||
wt.stream_stop_sending_server(&mut wt_server_stream);
|
||||
wt.stream_stop_sending_server(&wt_server_stream);
|
||||
wt.receive_stop_sending_client(wt_server_stream.stream_id());
|
||||
}
|
||||
|
||||
|
@ -414,8 +414,8 @@ fn wt_client_session_close_4() {
|
|||
let unidi_from_client = wt.create_wt_stream_client(wt_session.stream_id(), StreamType::UniDi);
|
||||
|
||||
wt.send_data_client(unidi_from_client, BUF);
|
||||
let mut unidi_from_client_s = wt.receive_data_server(unidi_from_client, true, BUF, false);
|
||||
wt.stream_stop_sending_server(&mut unidi_from_client_s);
|
||||
let unidi_from_client_s = wt.receive_data_server(unidi_from_client, true, BUF, false);
|
||||
wt.stream_stop_sending_server(&unidi_from_client_s);
|
||||
|
||||
wt.cancel_session_client(wt_session.stream_id());
|
||||
|
||||
|
@ -474,10 +474,10 @@ fn wt_client_session_close_6() {
|
|||
const BUF: &[u8] = &[0; 10];
|
||||
|
||||
let mut wt = WtTest::new();
|
||||
let mut wt_session = wt.create_wt_session();
|
||||
let wt_session = wt.create_wt_session();
|
||||
|
||||
let mut bidi_from_server = WtTest::create_wt_stream_server(&mut wt_session, StreamType::BiDi);
|
||||
wt.send_data_server(&mut bidi_from_server, BUF);
|
||||
let bidi_from_server = WtTest::create_wt_stream_server(&wt_session, StreamType::BiDi);
|
||||
wt.send_data_server(&bidi_from_server, BUF);
|
||||
wt.receive_data_client(bidi_from_server.stream_id(), true, BUF, false);
|
||||
|
||||
wt.cancel_session_client(wt_session.stream_id());
|
||||
|
@ -508,10 +508,10 @@ fn wt_client_session_close_7() {
|
|||
const BUF: &[u8] = &[0; 10];
|
||||
|
||||
let mut wt = WtTest::new();
|
||||
let mut wt_session = wt.create_wt_session();
|
||||
let wt_session = wt.create_wt_session();
|
||||
|
||||
let mut unidi_from_server = WtTest::create_wt_stream_server(&mut wt_session, StreamType::UniDi);
|
||||
wt.send_data_server(&mut unidi_from_server, BUF);
|
||||
let unidi_from_server = WtTest::create_wt_stream_server(&wt_session, StreamType::UniDi);
|
||||
wt.send_data_server(&unidi_from_server, BUF);
|
||||
wt.receive_data_client(unidi_from_server.stream_id(), true, BUF, false);
|
||||
|
||||
wt.cancel_session_client(wt_session.stream_id());
|
||||
|
@ -542,11 +542,11 @@ fn wt_client_session_close_8() {
|
|||
const BUF: &[u8] = &[0; 10];
|
||||
|
||||
let mut wt = WtTest::new();
|
||||
let mut wt_session = wt.create_wt_session();
|
||||
let wt_session = wt.create_wt_session();
|
||||
|
||||
let mut unidi_server = WtTest::create_wt_stream_server(&mut wt_session, StreamType::UniDi);
|
||||
wt.send_data_server(&mut unidi_server, BUF);
|
||||
wt.close_stream_sending_server(&mut unidi_server);
|
||||
let unidi_server = WtTest::create_wt_stream_server(&wt_session, StreamType::UniDi);
|
||||
wt.send_data_server(&unidi_server, BUF);
|
||||
wt.close_stream_sending_server(&unidi_server);
|
||||
wt.receive_data_client(unidi_server.stream_id(), true, BUF, true);
|
||||
|
||||
wt.cancel_session_client(wt_session.stream_id());
|
||||
|
@ -570,10 +570,10 @@ fn wt_client_session_close_9() {
|
|||
const BUF: &[u8] = &[0; 10];
|
||||
|
||||
let mut wt = WtTest::new();
|
||||
let mut wt_session = wt.create_wt_session();
|
||||
let wt_session = wt.create_wt_session();
|
||||
|
||||
let mut unidi_server = WtTest::create_wt_stream_server(&mut wt_session, StreamType::UniDi);
|
||||
wt.send_data_server(&mut unidi_server, BUF);
|
||||
let unidi_server = WtTest::create_wt_stream_server(&wt_session, StreamType::UniDi);
|
||||
wt.send_data_server(&unidi_server, BUF);
|
||||
wt.stream_stop_sending_client(unidi_server.stream_id());
|
||||
|
||||
wt.cancel_session_client(wt_session.stream_id());
|
||||
|
@ -597,11 +597,11 @@ fn wt_client_session_close_10() {
|
|||
const BUF: &[u8] = &[0; 10];
|
||||
|
||||
let mut wt = WtTest::new();
|
||||
let mut wt_session = wt.create_wt_session();
|
||||
let wt_session = wt.create_wt_session();
|
||||
|
||||
let mut unidi_server = WtTest::create_wt_stream_server(&mut wt_session, StreamType::UniDi);
|
||||
wt.send_data_server(&mut unidi_server, BUF);
|
||||
wt.close_stream_sending_server(&mut unidi_server);
|
||||
let unidi_server = WtTest::create_wt_stream_server(&wt_session, StreamType::UniDi);
|
||||
wt.send_data_server(&unidi_server, BUF);
|
||||
wt.close_stream_sending_server(&unidi_server);
|
||||
|
||||
wt.cancel_session_client(wt_session.stream_id());
|
||||
|
||||
|
@ -631,13 +631,13 @@ fn wt_client_session_close_11() {
|
|||
const BUF: &[u8] = &[0; 10];
|
||||
|
||||
let mut wt = WtTest::new();
|
||||
let mut wt_session = wt.create_wt_session();
|
||||
let wt_session = wt.create_wt_session();
|
||||
|
||||
let mut bidi_server = WtTest::create_wt_stream_server(&mut wt_session, StreamType::BiDi);
|
||||
wt.send_data_server(&mut bidi_server, BUF);
|
||||
wt.close_stream_sending_server(&mut bidi_server);
|
||||
let bidi_server = WtTest::create_wt_stream_server(&wt_session, StreamType::BiDi);
|
||||
wt.send_data_server(&bidi_server, BUF);
|
||||
wt.close_stream_sending_server(&bidi_server);
|
||||
wt.receive_data_client(bidi_server.stream_id(), true, BUF, true);
|
||||
wt.stream_stop_sending_server(&mut bidi_server);
|
||||
wt.stream_stop_sending_server(&bidi_server);
|
||||
wt.receive_stop_sending_client(bidi_server.stream_id());
|
||||
|
||||
wt.cancel_session_client(wt_session.stream_id());
|
||||
|
@ -661,12 +661,12 @@ fn wt_client_session_close_12() {
|
|||
const BUF: &[u8] = &[0; 10];
|
||||
|
||||
let mut wt = WtTest::new();
|
||||
let mut wt_session = wt.create_wt_session();
|
||||
let wt_session = wt.create_wt_session();
|
||||
|
||||
let mut bidi_server = WtTest::create_wt_stream_server(&mut wt_session, StreamType::BiDi);
|
||||
wt.send_data_server(&mut bidi_server, BUF);
|
||||
wt.close_stream_sending_server(&mut bidi_server);
|
||||
wt.stream_stop_sending_server(&mut bidi_server);
|
||||
let bidi_server = WtTest::create_wt_stream_server(&wt_session, StreamType::BiDi);
|
||||
wt.send_data_server(&bidi_server, BUF);
|
||||
wt.close_stream_sending_server(&bidi_server);
|
||||
wt.stream_stop_sending_server(&bidi_server);
|
||||
|
||||
wt.cancel_session_client(wt_session.stream_id());
|
||||
|
||||
|
@ -746,13 +746,13 @@ fn wt_client_session_server_close_1() {
|
|||
const BUF: &[u8] = &[0; 10];
|
||||
|
||||
let mut wt = WtTest::new();
|
||||
let mut wt_session = wt.create_wt_session();
|
||||
let wt_session = wt.create_wt_session();
|
||||
|
||||
let bidi_client = wt.create_wt_stream_client(wt_session.stream_id(), StreamType::BiDi);
|
||||
wt.send_data_client(bidi_client, BUF);
|
||||
std::mem::drop(wt.receive_data_server(bidi_client, true, BUF, false));
|
||||
|
||||
wt.cancel_session_server(&mut wt_session);
|
||||
wt.cancel_session_server(&wt_session);
|
||||
|
||||
wt.check_events_after_closing_session_client(
|
||||
&[bidi_client],
|
||||
|
@ -780,13 +780,13 @@ fn wt_client_session_server_close_2() {
|
|||
const BUF: &[u8] = &[0; 10];
|
||||
|
||||
let mut wt = WtTest::new();
|
||||
let mut wt_session = wt.create_wt_session();
|
||||
let wt_session = wt.create_wt_session();
|
||||
|
||||
let unidi_client = wt.create_wt_stream_client(wt_session.stream_id(), StreamType::UniDi);
|
||||
wt.send_data_client(unidi_client, BUF);
|
||||
std::mem::drop(wt.receive_data_server(unidi_client, true, BUF, false));
|
||||
|
||||
wt.cancel_session_server(&mut wt_session);
|
||||
wt.cancel_session_server(&wt_session);
|
||||
|
||||
wt.check_events_after_closing_session_client(
|
||||
&[],
|
||||
|
@ -814,15 +814,15 @@ fn wt_client_session_server_close_3() {
|
|||
const BUF: &[u8] = &[0; 10];
|
||||
|
||||
let mut wt = WtTest::new();
|
||||
let mut wt_session = wt.create_wt_session();
|
||||
let wt_session = wt.create_wt_session();
|
||||
|
||||
let unidi_client = wt.create_wt_stream_client(wt_session.stream_id(), StreamType::UniDi);
|
||||
wt.send_data_client(unidi_client, BUF);
|
||||
let mut unidi_client_s = wt.receive_data_server(unidi_client, true, BUF, false);
|
||||
wt.stream_stop_sending_server(&mut unidi_client_s);
|
||||
let unidi_client_s = wt.receive_data_server(unidi_client, true, BUF, false);
|
||||
wt.stream_stop_sending_server(&unidi_client_s);
|
||||
wt.receive_stop_sending_client(unidi_client);
|
||||
|
||||
wt.cancel_session_server(&mut wt_session);
|
||||
wt.cancel_session_server(&wt_session);
|
||||
|
||||
wt.check_events_after_closing_session_client(
|
||||
&[],
|
||||
|
@ -844,14 +844,14 @@ fn wt_client_session_server_close_4() {
|
|||
const BUF: &[u8] = &[0; 10];
|
||||
|
||||
let mut wt = WtTest::new();
|
||||
let mut wt_session = wt.create_wt_session();
|
||||
let wt_session = wt.create_wt_session();
|
||||
|
||||
let unidi_client = wt.create_wt_stream_client(wt_session.stream_id(), StreamType::UniDi);
|
||||
wt.send_data_client(unidi_client, BUF);
|
||||
let mut unidi_client_s = wt.receive_data_server(unidi_client, true, BUF, false);
|
||||
wt.stream_stop_sending_server(&mut unidi_client_s);
|
||||
let unidi_client_s = wt.receive_data_server(unidi_client, true, BUF, false);
|
||||
wt.stream_stop_sending_server(&unidi_client_s);
|
||||
|
||||
wt.cancel_session_server(&mut wt_session);
|
||||
wt.cancel_session_server(&wt_session);
|
||||
|
||||
wt.check_events_after_closing_session_client(
|
||||
&[],
|
||||
|
@ -873,13 +873,13 @@ fn wt_client_session_server_close_5() {
|
|||
const BUF: &[u8] = &[0; 10];
|
||||
|
||||
let mut wt = WtTest::new();
|
||||
let mut wt_session = wt.create_wt_session();
|
||||
let wt_session = wt.create_wt_session();
|
||||
|
||||
let mut bidi_server = WtTest::create_wt_stream_server(&mut wt_session, StreamType::BiDi);
|
||||
wt.send_data_server(&mut bidi_server, BUF);
|
||||
let bidi_server = WtTest::create_wt_stream_server(&wt_session, StreamType::BiDi);
|
||||
wt.send_data_server(&bidi_server, BUF);
|
||||
wt.receive_data_client(bidi_server.stream_id(), true, BUF, false);
|
||||
|
||||
wt.cancel_session_server(&mut wt_session);
|
||||
wt.cancel_session_server(&wt_session);
|
||||
|
||||
wt.check_events_after_closing_session_client(
|
||||
&[bidi_server.stream_id()],
|
||||
|
@ -907,13 +907,13 @@ fn wt_client_session_server_close_6() {
|
|||
const BUF: &[u8] = &[0; 10];
|
||||
|
||||
let mut wt = WtTest::new();
|
||||
let mut wt_session = wt.create_wt_session();
|
||||
let wt_session = wt.create_wt_session();
|
||||
|
||||
let mut unidi_server = WtTest::create_wt_stream_server(&mut wt_session, StreamType::UniDi);
|
||||
wt.send_data_server(&mut unidi_server, BUF);
|
||||
let unidi_server = WtTest::create_wt_stream_server(&wt_session, StreamType::UniDi);
|
||||
wt.send_data_server(&unidi_server, BUF);
|
||||
wt.receive_data_client(unidi_server.stream_id(), true, BUF, false);
|
||||
|
||||
wt.cancel_session_server(&mut wt_session);
|
||||
wt.cancel_session_server(&wt_session);
|
||||
|
||||
wt.check_events_after_closing_session_client(
|
||||
&[unidi_server.stream_id()],
|
||||
|
@ -940,14 +940,14 @@ fn wt_client_session_server_close_7() {
|
|||
const BUF: &[u8] = &[0; 10];
|
||||
|
||||
let mut wt = WtTest::new();
|
||||
let mut wt_session = wt.create_wt_session();
|
||||
let wt_session = wt.create_wt_session();
|
||||
|
||||
let mut unidi_server = WtTest::create_wt_stream_server(&mut wt_session, StreamType::UniDi);
|
||||
wt.send_data_server(&mut unidi_server, BUF);
|
||||
wt.close_stream_sending_server(&mut unidi_server);
|
||||
let unidi_server = WtTest::create_wt_stream_server(&wt_session, StreamType::UniDi);
|
||||
wt.send_data_server(&unidi_server, BUF);
|
||||
wt.close_stream_sending_server(&unidi_server);
|
||||
wt.receive_data_client(unidi_server.stream_id(), true, BUF, true);
|
||||
|
||||
wt.cancel_session_server(&mut wt_session);
|
||||
wt.cancel_session_server(&wt_session);
|
||||
|
||||
// Already close stream will not have a reset event.
|
||||
wt.check_events_after_closing_session_client(
|
||||
|
@ -970,13 +970,13 @@ fn wt_client_session_server_close_8() {
|
|||
const BUF: &[u8] = &[0; 10];
|
||||
|
||||
let mut wt = WtTest::new();
|
||||
let mut wt_session = wt.create_wt_session();
|
||||
let wt_session = wt.create_wt_session();
|
||||
|
||||
let mut unidi_server = WtTest::create_wt_stream_server(&mut wt_session, StreamType::UniDi);
|
||||
wt.send_data_server(&mut unidi_server, BUF);
|
||||
wt.close_stream_sending_server(&mut unidi_server);
|
||||
let unidi_server = WtTest::create_wt_stream_server(&wt_session, StreamType::UniDi);
|
||||
wt.send_data_server(&unidi_server, BUF);
|
||||
wt.close_stream_sending_server(&unidi_server);
|
||||
|
||||
wt.cancel_session_server(&mut wt_session);
|
||||
wt.cancel_session_server(&wt_session);
|
||||
|
||||
// The stream was only closed on the server side therefore it is cancelled on the client side.
|
||||
wt.check_events_after_closing_session_client(
|
||||
|
@ -999,16 +999,16 @@ fn wt_client_session_server_close_9() {
|
|||
const BUF: &[u8] = &[0; 10];
|
||||
|
||||
let mut wt = WtTest::new();
|
||||
let mut wt_session = wt.create_wt_session();
|
||||
let wt_session = wt.create_wt_session();
|
||||
|
||||
let mut bidi_server = WtTest::create_wt_stream_server(&mut wt_session, StreamType::BiDi);
|
||||
wt.send_data_server(&mut bidi_server, BUF);
|
||||
wt.close_stream_sending_server(&mut bidi_server);
|
||||
let bidi_server = WtTest::create_wt_stream_server(&wt_session, StreamType::BiDi);
|
||||
wt.send_data_server(&bidi_server, BUF);
|
||||
wt.close_stream_sending_server(&bidi_server);
|
||||
wt.receive_data_client(bidi_server.stream_id(), true, BUF, true);
|
||||
wt.stream_stop_sending_server(&mut bidi_server);
|
||||
wt.stream_stop_sending_server(&bidi_server);
|
||||
wt.receive_stop_sending_client(bidi_server.stream_id());
|
||||
|
||||
wt.cancel_session_server(&mut wt_session);
|
||||
wt.cancel_session_server(&wt_session);
|
||||
|
||||
// Already close stream will not have a reset event.
|
||||
wt.check_events_after_closing_session_client(
|
||||
|
@ -1031,14 +1031,14 @@ fn wt_client_session_server_close_10() {
|
|||
const BUF: &[u8] = &[0; 10];
|
||||
|
||||
let mut wt = WtTest::new();
|
||||
let mut wt_session = wt.create_wt_session();
|
||||
let wt_session = wt.create_wt_session();
|
||||
|
||||
let mut bidi_server = WtTest::create_wt_stream_server(&mut wt_session, StreamType::BiDi);
|
||||
wt.send_data_server(&mut bidi_server, BUF);
|
||||
wt.close_stream_sending_server(&mut bidi_server);
|
||||
wt.stream_stop_sending_server(&mut bidi_server);
|
||||
let bidi_server = WtTest::create_wt_stream_server(&wt_session, StreamType::BiDi);
|
||||
wt.send_data_server(&bidi_server, BUF);
|
||||
wt.close_stream_sending_server(&bidi_server);
|
||||
wt.stream_stop_sending_server(&bidi_server);
|
||||
|
||||
wt.cancel_session_server(&mut wt_session);
|
||||
wt.cancel_session_server(&wt_session);
|
||||
|
||||
wt.check_events_after_closing_session_client(
|
||||
&[bidi_server.stream_id()],
|
||||
|
@ -1060,7 +1060,7 @@ fn wt_client_session_server_close_11() {
|
|||
const BUF: &[u8] = &[0; 10];
|
||||
|
||||
let mut wt = WtTest::new();
|
||||
let mut wt_session = wt.create_wt_session();
|
||||
let wt_session = wt.create_wt_session();
|
||||
|
||||
let bidi_client_1 = wt.create_wt_stream_client(wt_session.stream_id(), StreamType::BiDi);
|
||||
wt.send_data_client(bidi_client_1, BUF);
|
||||
|
@ -1069,7 +1069,7 @@ fn wt_client_session_server_close_11() {
|
|||
wt.send_data_client(bidi_client_2, BUF);
|
||||
std::mem::drop(wt.receive_data_server(bidi_client_2, true, BUF, false));
|
||||
|
||||
wt.cancel_session_server(&mut wt_session);
|
||||
wt.cancel_session_server(&wt_session);
|
||||
|
||||
wt.check_events_after_closing_session_client(
|
||||
&[bidi_client_1, bidi_client_2],
|
||||
|
@ -1098,10 +1098,10 @@ fn wt_session_close_frame_and_streams_client() {
|
|||
const ERROR_NUM: u32 = 23;
|
||||
const ERROR_MESSAGE: &str = "Something went wrong";
|
||||
let mut wt = WtTest::new();
|
||||
let mut wt_session = wt.create_wt_session();
|
||||
let wt_session = wt.create_wt_session();
|
||||
|
||||
let mut unidi_server = WtTest::create_wt_stream_server(&mut wt_session, StreamType::UniDi);
|
||||
wt.send_data_server(&mut unidi_server, BUF);
|
||||
let unidi_server = WtTest::create_wt_stream_server(&wt_session, StreamType::UniDi);
|
||||
wt.send_data_server(&unidi_server, BUF);
|
||||
wt.exchange_packets();
|
||||
|
||||
wt.session_close_frame_client(wt_session.stream_id(), ERROR_NUM, ERROR_MESSAGE);
|
||||
|
|
|
@ -29,13 +29,13 @@ enum SessionState {
|
|||
}
|
||||
|
||||
impl SessionState {
|
||||
pub fn closing_state(&self) -> bool {
|
||||
pub const fn closing_state(&self) -> bool {
|
||||
matches!(self, Self::FinPending | Self::Done)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub(crate) struct WebTransportSession {
|
||||
pub struct WebTransportSession {
|
||||
control_stream_recv: Box<dyn RecvStream>,
|
||||
control_stream_send: Box<dyn SendStream>,
|
||||
stream_event_listener: Rc<RefCell<WebTransportSessionListener>>,
|
||||
|
@ -295,7 +295,7 @@ impl WebTransportSession {
|
|||
}
|
||||
|
||||
pub fn add_stream(&mut self, stream_id: StreamId) {
|
||||
if let SessionState::Active = self.state {
|
||||
if self.state == SessionState::Active {
|
||||
if stream_id.is_bidi() {
|
||||
self.send_streams.insert(stream_id);
|
||||
self.recv_streams.insert(stream_id);
|
||||
|
@ -324,7 +324,7 @@ impl WebTransportSession {
|
|||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn is_active(&self) -> bool {
|
||||
pub const fn is_active(&self) -> bool {
|
||||
matches!(self.state, SessionState::Active)
|
||||
}
|
||||
|
||||
|
@ -411,7 +411,7 @@ impl WebTransportSession {
|
|||
id: impl Into<DatagramTracking>,
|
||||
) -> Res<()> {
|
||||
qtrace!([self], "send_datagram state={:?}", self.state);
|
||||
if let SessionState::Active = self.state {
|
||||
if self.state == SessionState::Active {
|
||||
let mut dgram_data = Encoder::default();
|
||||
dgram_data.encode_varint(self.session_id.as_u64() / 4);
|
||||
dgram_data.encode(buf);
|
||||
|
@ -423,8 +423,8 @@ impl WebTransportSession {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
pub fn datagram(&mut self, datagram: Vec<u8>) {
|
||||
if let SessionState::Active = self.state {
|
||||
pub fn datagram(&self, datagram: Vec<u8>) {
|
||||
if self.state == SessionState::Active {
|
||||
self.events.new_datagram(self.session_id, datagram);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,7 +19,7 @@ pub const WEBTRANSPORT_UNI_STREAM: u64 = 0x54;
|
|||
pub const WEBTRANSPORT_STREAM: u64 = 0x41;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub(crate) struct WebTransportRecvStream {
|
||||
pub struct WebTransportRecvStream {
|
||||
stream_id: StreamId,
|
||||
events: Box<dyn RecvStreamEvents>,
|
||||
session: Rc<RefCell<WebTransportSession>>,
|
||||
|
@ -115,7 +115,7 @@ enum WebTransportSenderStreamState {
|
|||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub(crate) struct WebTransportSendStream {
|
||||
pub struct WebTransportSendStream {
|
||||
stream_id: StreamId,
|
||||
state: WebTransportSenderStreamState,
|
||||
events: Box<dyn SendStreamEvents>,
|
||||
|
|
|
@ -35,7 +35,7 @@ pub enum NegotiationState {
|
|||
|
||||
impl NegotiationState {
|
||||
#[must_use]
|
||||
pub fn new(enable: bool, feature_type: HSettingType) -> Self {
|
||||
pub const fn new(enable: bool, feature_type: HSettingType) -> Self {
|
||||
if enable {
|
||||
Self::Negotiating {
|
||||
feature_type,
|
||||
|
@ -81,12 +81,12 @@ impl NegotiationState {
|
|||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn enabled(&self) -> bool {
|
||||
pub const fn enabled(&self) -> bool {
|
||||
matches!(self, &Self::Negotiated)
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn locally_enabled(&self) -> bool {
|
||||
pub const fn locally_enabled(&self) -> bool {
|
||||
!matches!(self, &Self::Disabled)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,7 +12,7 @@ use neqo_transport::StreamId;
|
|||
|
||||
use crate::{frames::reader::FrameDecoder, settings::HSettings, Error, Priority, Res};
|
||||
|
||||
pub(crate) type HFrameType = u64;
|
||||
pub type HFrameType = u64;
|
||||
|
||||
pub const H3_FRAME_TYPE_DATA: HFrameType = 0x0;
|
||||
pub const H3_FRAME_TYPE_HEADERS: HFrameType = 0x1;
|
||||
|
@ -142,7 +142,7 @@ impl HFrame {
|
|||
}
|
||||
}
|
||||
|
||||
impl FrameDecoder<HFrame> for HFrame {
|
||||
impl FrameDecoder<Self> for HFrame {
|
||||
fn frame_type_allowed(frame_type: u64) -> Res<()> {
|
||||
if H3_RESERVED_FRAME_TYPES.contains(&frame_type) {
|
||||
return Err(Error::HttpFrameUnexpected);
|
||||
|
@ -150,17 +150,17 @@ impl FrameDecoder<HFrame> for HFrame {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
fn decode(frame_type: u64, frame_len: u64, data: Option<&[u8]>) -> Res<Option<HFrame>> {
|
||||
fn decode(frame_type: u64, frame_len: u64, data: Option<&[u8]>) -> Res<Option<Self>> {
|
||||
if frame_type == H3_FRAME_TYPE_DATA {
|
||||
Ok(Some(HFrame::Data { len: frame_len }))
|
||||
Ok(Some(Self::Data { len: frame_len }))
|
||||
} else if let Some(payload) = data {
|
||||
let mut dec = Decoder::from(payload);
|
||||
Ok(match frame_type {
|
||||
H3_FRAME_TYPE_DATA => unreachable!("DATA frame has been handled already."),
|
||||
H3_FRAME_TYPE_HEADERS => Some(HFrame::Headers {
|
||||
H3_FRAME_TYPE_HEADERS => Some(Self::Headers {
|
||||
header_block: dec.decode_remainder().to_vec(),
|
||||
}),
|
||||
H3_FRAME_TYPE_CANCEL_PUSH => Some(HFrame::CancelPush {
|
||||
H3_FRAME_TYPE_CANCEL_PUSH => Some(Self::CancelPush {
|
||||
push_id: dec.decode_varint().ok_or(Error::HttpFrame)?,
|
||||
}),
|
||||
H3_FRAME_TYPE_SETTINGS => {
|
||||
|
@ -172,16 +172,16 @@ impl FrameDecoder<HFrame> for HFrame {
|
|||
Error::HttpFrame
|
||||
}
|
||||
})?;
|
||||
Some(HFrame::Settings { settings })
|
||||
Some(Self::Settings { settings })
|
||||
}
|
||||
H3_FRAME_TYPE_PUSH_PROMISE => Some(HFrame::PushPromise {
|
||||
H3_FRAME_TYPE_PUSH_PROMISE => Some(Self::PushPromise {
|
||||
push_id: dec.decode_varint().ok_or(Error::HttpFrame)?,
|
||||
header_block: dec.decode_remainder().to_vec(),
|
||||
}),
|
||||
H3_FRAME_TYPE_GOAWAY => Some(HFrame::Goaway {
|
||||
H3_FRAME_TYPE_GOAWAY => Some(Self::Goaway {
|
||||
stream_id: StreamId::new(dec.decode_varint().ok_or(Error::HttpFrame)?),
|
||||
}),
|
||||
H3_FRAME_TYPE_MAX_PUSH_ID => Some(HFrame::MaxPushId {
|
||||
H3_FRAME_TYPE_MAX_PUSH_ID => Some(Self::MaxPushId {
|
||||
push_id: dec.decode_varint().ok_or(Error::HttpFrame)?,
|
||||
}),
|
||||
H3_FRAME_TYPE_PRIORITY_UPDATE_REQUEST | H3_FRAME_TYPE_PRIORITY_UPDATE_PUSH => {
|
||||
|
@ -189,12 +189,12 @@ impl FrameDecoder<HFrame> for HFrame {
|
|||
let priority = dec.decode_remainder();
|
||||
let priority = Priority::from_bytes(priority)?;
|
||||
if frame_type == H3_FRAME_TYPE_PRIORITY_UPDATE_REQUEST {
|
||||
Some(HFrame::PriorityUpdateRequest {
|
||||
Some(Self::PriorityUpdateRequest {
|
||||
element_id,
|
||||
priority,
|
||||
})
|
||||
} else {
|
||||
Some(HFrame::PriorityUpdatePush {
|
||||
Some(Self::PriorityUpdatePush {
|
||||
element_id,
|
||||
priority,
|
||||
})
|
||||
|
|
|
@ -4,18 +4,14 @@
|
|||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
pub(crate) mod hframe;
|
||||
pub(crate) mod reader;
|
||||
pub(crate) mod wtframe;
|
||||
pub mod hframe;
|
||||
pub mod reader;
|
||||
pub mod wtframe;
|
||||
|
||||
#[allow(unused_imports)]
|
||||
pub(crate) use hframe::{
|
||||
HFrame, H3_FRAME_TYPE_HEADERS, H3_FRAME_TYPE_SETTINGS, H3_RESERVED_FRAME_TYPES,
|
||||
};
|
||||
pub(crate) use reader::{
|
||||
FrameReader, StreamReaderConnectionWrapper, StreamReaderRecvStreamWrapper,
|
||||
};
|
||||
pub(crate) use wtframe::WebTransportFrame;
|
||||
pub use hframe::{HFrame, H3_FRAME_TYPE_HEADERS, H3_FRAME_TYPE_SETTINGS, H3_RESERVED_FRAME_TYPES};
|
||||
pub use reader::{FrameReader, StreamReaderConnectionWrapper, StreamReaderRecvStreamWrapper};
|
||||
pub use wtframe::WebTransportFrame;
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests;
|
||||
|
|
|
@ -18,7 +18,7 @@ use crate::{Error, RecvStream, Res};
|
|||
|
||||
const MAX_READ_SIZE: usize = 4096;
|
||||
|
||||
pub(crate) trait FrameDecoder<T> {
|
||||
pub trait FrameDecoder<T> {
|
||||
fn is_known_type(frame_type: u64) -> bool;
|
||||
/// # Errors
|
||||
///
|
||||
|
@ -33,7 +33,7 @@ pub(crate) trait FrameDecoder<T> {
|
|||
fn decode(frame_type: u64, frame_len: u64, data: Option<&[u8]>) -> Res<Option<T>>;
|
||||
}
|
||||
|
||||
pub(crate) trait StreamReader {
|
||||
pub trait StreamReader {
|
||||
/// # Errors
|
||||
///
|
||||
/// An error may happen while reading a stream, e.g. early close, protocol error, etc.
|
||||
|
@ -42,7 +42,7 @@ pub(crate) trait StreamReader {
|
|||
fn read_data(&mut self, buf: &mut [u8]) -> Res<(usize, bool)>;
|
||||
}
|
||||
|
||||
pub(crate) struct StreamReaderConnectionWrapper<'a> {
|
||||
pub struct StreamReaderConnectionWrapper<'a> {
|
||||
conn: &'a mut Connection,
|
||||
stream_id: StreamId,
|
||||
}
|
||||
|
@ -63,7 +63,7 @@ impl<'a> StreamReader for StreamReaderConnectionWrapper<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
pub(crate) struct StreamReaderRecvStreamWrapper<'a> {
|
||||
pub struct StreamReaderRecvStreamWrapper<'a> {
|
||||
recv_stream: &'a mut Box<dyn RecvStream>,
|
||||
conn: &'a mut Connection,
|
||||
}
|
||||
|
@ -93,7 +93,7 @@ enum FrameReaderState {
|
|||
|
||||
#[allow(clippy::module_name_repetitions)]
|
||||
#[derive(Debug)]
|
||||
pub(crate) struct FrameReader {
|
||||
pub struct FrameReader {
|
||||
state: FrameReaderState,
|
||||
frame_type: u64,
|
||||
frame_len: u64,
|
||||
|
@ -144,7 +144,7 @@ impl FrameReader {
|
|||
}
|
||||
}
|
||||
|
||||
fn decoding_in_progress(&self) -> bool {
|
||||
const fn decoding_in_progress(&self) -> bool {
|
||||
if let FrameReaderState::GetType { decoder } = &self.state {
|
||||
decoder.decoding_in_progress()
|
||||
} else {
|
||||
|
|
|
@ -16,7 +16,7 @@ use crate::frames::{
|
|||
};
|
||||
|
||||
#[allow(clippy::many_single_char_names)]
|
||||
pub(crate) fn enc_dec<T: FrameDecoder<T>>(d: &Encoder, st: &str, remaining: usize) -> T {
|
||||
pub fn enc_dec<T: FrameDecoder<T>>(d: &Encoder, st: &str, remaining: usize) -> T {
|
||||
// For data, headers and push_promise we do not read all bytes from the buffer
|
||||
let d2 = Encoder::from_hex(st);
|
||||
assert_eq!(d.as_ref(), &d2.as_ref()[..d.as_ref().len()]);
|
||||
|
|
|
@ -226,14 +226,14 @@ fn test_reading_frame<T: FrameDecoder<T> + PartialEq + Debug>(
|
|||
let mut fr = FrameReaderTest::new();
|
||||
|
||||
fr.conn_s.stream_send(fr.stream_id, buf).unwrap();
|
||||
if let FrameReadingTestSend::DataWithFin = test_to_send {
|
||||
if matches!(test_to_send, FrameReadingTestSend::DataWithFin) {
|
||||
fr.conn_s.stream_close_send(fr.stream_id).unwrap();
|
||||
}
|
||||
|
||||
let out = fr.conn_s.process(None, now());
|
||||
mem::drop(fr.conn_c.process(out.as_dgram_ref(), now()));
|
||||
|
||||
if let FrameReadingTestSend::DataThenFin = test_to_send {
|
||||
if matches!(test_to_send, FrameReadingTestSend::DataThenFin) {
|
||||
fr.conn_s.stream_close_send(fr.stream_id).unwrap();
|
||||
let out = fr.conn_s.process(None, now());
|
||||
mem::drop(fr.conn_c.process(out.as_dgram_ref(), now()));
|
||||
|
|
|
@ -8,7 +8,7 @@ use neqo_common::{Decoder, Encoder};
|
|||
|
||||
use crate::{frames::reader::FrameDecoder, Error, Res};
|
||||
|
||||
pub(crate) type WebTransportFrameType = u64;
|
||||
pub type WebTransportFrameType = u64;
|
||||
|
||||
const WT_FRAME_CLOSE_SESSION: WebTransportFrameType = 0x2843;
|
||||
const WT_FRAME_CLOSE_MAX_MESSAGE_SIZE: u64 = 1024;
|
||||
|
@ -21,19 +21,15 @@ pub enum WebTransportFrame {
|
|||
impl WebTransportFrame {
|
||||
pub fn encode(&self, enc: &mut Encoder) {
|
||||
enc.encode_varint(WT_FRAME_CLOSE_SESSION);
|
||||
let WebTransportFrame::CloseSession { error, message } = &self;
|
||||
let Self::CloseSession { error, message } = &self;
|
||||
enc.encode_varint(4 + message.len() as u64);
|
||||
enc.encode_uint(4, *error);
|
||||
enc.encode(message.as_bytes());
|
||||
}
|
||||
}
|
||||
|
||||
impl FrameDecoder<WebTransportFrame> for WebTransportFrame {
|
||||
fn decode(
|
||||
frame_type: u64,
|
||||
frame_len: u64,
|
||||
data: Option<&[u8]>,
|
||||
) -> Res<Option<WebTransportFrame>> {
|
||||
impl FrameDecoder<Self> for WebTransportFrame {
|
||||
fn decode(frame_type: u64, frame_len: u64, data: Option<&[u8]>) -> Res<Option<Self>> {
|
||||
if let Some(payload) = data {
|
||||
let mut dec = Decoder::from(payload);
|
||||
if frame_type == WT_FRAME_CLOSE_SESSION {
|
||||
|
@ -45,7 +41,7 @@ impl FrameDecoder<WebTransportFrame> for WebTransportFrame {
|
|||
let Ok(message) = String::from_utf8(dec.decode_remainder().to_vec()) else {
|
||||
return Err(Error::HttpMessageError);
|
||||
};
|
||||
Ok(Some(WebTransportFrame::CloseSession { error, message }))
|
||||
Ok(Some(Self::CloseSession { error, message }))
|
||||
} else {
|
||||
Ok(None)
|
||||
}
|
||||
|
|
|
@ -49,14 +49,14 @@ instead informs the application when processing needs to be triggered.
|
|||
The core functions for driving HTTP/3 sessions are:
|
||||
- __On the client-side__ :
|
||||
- [`process_output`](struct.Http3Client.html#method.process_output) used for producing UDP
|
||||
payload. If a payload is not produced this function returns a callback time, e.g. the time when
|
||||
[`process_output`](struct.Http3Client.html#method.process_output) should be called again.
|
||||
payload. If a payload is not produced this function returns a callback time, e.g. the time when
|
||||
[`process_output`](struct.Http3Client.html#method.process_output) should be called again.
|
||||
- [`process_input`](struct.Http3Client.html#method.process_input) used consuming UDP payload.
|
||||
- [`process`](struct.Http3Client.html#method.process) combines the 2 functions into one, i.e. it
|
||||
consumes UDP payload if available and produces some UDP payload to be sent or returns a
|
||||
callback time.
|
||||
consumes UDP payload if available and produces some UDP payload to be sent or returns a
|
||||
callback time.
|
||||
- __On the server-side__ only [`process`](struct.Http3Server.html#method.process) is
|
||||
available.
|
||||
available.
|
||||
|
||||
An example interaction with a socket:
|
||||
|
||||
|
@ -235,7 +235,7 @@ pub enum Error {
|
|||
|
||||
impl Error {
|
||||
#[must_use]
|
||||
pub fn code(&self) -> AppError {
|
||||
pub const fn code(&self) -> AppError {
|
||||
match self {
|
||||
Self::HttpNoError => 0x100,
|
||||
Self::HttpGeneralProtocol | Self::HttpGeneralProtocolStream | Self::InvalidHeader => {
|
||||
|
@ -263,7 +263,7 @@ impl Error {
|
|||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn connection_error(&self) -> bool {
|
||||
pub const fn connection_error(&self) -> bool {
|
||||
matches!(
|
||||
self,
|
||||
Self::HttpGeneralProtocol
|
||||
|
@ -281,7 +281,7 @@ impl Error {
|
|||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn stream_reset_error(&self) -> bool {
|
||||
pub const fn stream_reset_error(&self) -> bool {
|
||||
matches!(self, Self::HttpGeneralProtocolStream | Self::InvalidHeader)
|
||||
}
|
||||
|
||||
|
@ -289,15 +289,15 @@ impl Error {
|
|||
///
|
||||
/// On unexpected errors, in debug mode.
|
||||
#[must_use]
|
||||
pub fn map_stream_send_errors(err: &Error) -> Self {
|
||||
pub fn map_stream_send_errors(err: &Self) -> Self {
|
||||
match err {
|
||||
Self::TransportError(
|
||||
TransportError::InvalidStreamId | TransportError::FinalSizeError,
|
||||
) => Error::TransportStreamDoesNotExist,
|
||||
Self::TransportError(TransportError::InvalidInput) => Error::InvalidInput,
|
||||
) => Self::TransportStreamDoesNotExist,
|
||||
Self::TransportError(TransportError::InvalidInput) => Self::InvalidInput,
|
||||
_ => {
|
||||
debug_assert!(false, "Unexpected error");
|
||||
Error::TransportStreamDoesNotExist
|
||||
Self::TransportStreamDoesNotExist
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -308,11 +308,11 @@ impl Error {
|
|||
#[must_use]
|
||||
pub fn map_stream_create_errors(err: &TransportError) -> Self {
|
||||
match err {
|
||||
TransportError::ConnectionState => Error::Unavailable,
|
||||
TransportError::StreamLimitError => Error::StreamLimitError,
|
||||
TransportError::ConnectionState => Self::Unavailable,
|
||||
TransportError::StreamLimitError => Self::StreamLimitError,
|
||||
_ => {
|
||||
debug_assert!(false, "Unexpected error");
|
||||
Error::TransportStreamDoesNotExist
|
||||
Self::TransportStreamDoesNotExist
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -321,7 +321,7 @@ impl Error {
|
|||
///
|
||||
/// On unexpected errors, in debug mode.
|
||||
#[must_use]
|
||||
pub fn map_stream_recv_errors(err: &Error) -> Self {
|
||||
pub fn map_stream_recv_errors(err: &Self) -> Self {
|
||||
match err {
|
||||
Self::TransportError(TransportError::NoMoreData) => {
|
||||
debug_assert!(
|
||||
|
@ -334,14 +334,14 @@ impl Error {
|
|||
debug_assert!(false, "Unexpected error");
|
||||
}
|
||||
};
|
||||
Error::TransportStreamDoesNotExist
|
||||
Self::TransportStreamDoesNotExist
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn map_set_resumption_errors(err: &TransportError) -> Self {
|
||||
pub const fn map_set_resumption_errors(err: &TransportError) -> Self {
|
||||
match err {
|
||||
TransportError::ConnectionState => Error::InvalidState,
|
||||
_ => Error::InvalidResumptionToken,
|
||||
TransportError::ConnectionState => Self::InvalidState,
|
||||
_ => Self::InvalidResumptionToken,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -370,7 +370,7 @@ impl From<TransportError> for Error {
|
|||
impl From<QpackError> for Error {
|
||||
fn from(err: QpackError) -> Self {
|
||||
match err {
|
||||
QpackError::ClosedCriticalStream => Error::HttpClosedCriticalStream,
|
||||
QpackError::ClosedCriticalStream => Self::HttpClosedCriticalStream,
|
||||
e => Self::QpackError(e),
|
||||
}
|
||||
}
|
||||
|
@ -513,7 +513,7 @@ pub struct Http3StreamInfo {
|
|||
|
||||
impl Http3StreamInfo {
|
||||
#[must_use]
|
||||
pub fn new(stream_id: StreamId, stream_type: Http3StreamType) -> Self {
|
||||
pub const fn new(stream_id: StreamId, stream_type: Http3StreamType) -> Self {
|
||||
Self {
|
||||
stream_id,
|
||||
stream_type,
|
||||
|
@ -521,12 +521,12 @@ impl Http3StreamInfo {
|
|||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn stream_id(&self) -> StreamId {
|
||||
pub const fn stream_id(&self) -> StreamId {
|
||||
self.stream_id
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn session_id(&self) -> Option<StreamId> {
|
||||
pub const fn session_id(&self) -> Option<StreamId> {
|
||||
if let Http3StreamType::WebTransport(session) = self.stream_type {
|
||||
Some(session)
|
||||
} else {
|
||||
|
@ -640,7 +640,7 @@ enum CloseType {
|
|||
|
||||
impl CloseType {
|
||||
#[must_use]
|
||||
pub fn error(&self) -> Option<AppError> {
|
||||
pub const fn error(&self) -> Option<AppError> {
|
||||
match self {
|
||||
Self::ResetApp(error) | Self::ResetRemote(error) | Self::LocalError(error) => {
|
||||
Some(*error)
|
||||
|
@ -650,7 +650,7 @@ impl CloseType {
|
|||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn locally_initiated(&self) -> bool {
|
||||
matches!(self, CloseType::ResetApp(_))
|
||||
pub const fn locally_initiated(&self) -> bool {
|
||||
matches!(self, Self::ResetApp(_))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,7 +19,7 @@ pub struct Priority {
|
|||
|
||||
impl Default for Priority {
|
||||
fn default() -> Self {
|
||||
Priority {
|
||||
Self {
|
||||
urgency: 3,
|
||||
incremental: false,
|
||||
}
|
||||
|
@ -31,9 +31,9 @@ impl Priority {
|
|||
///
|
||||
/// If an invalid urgency (>7 is given)
|
||||
#[must_use]
|
||||
pub fn new(urgency: u8, incremental: bool) -> Priority {
|
||||
pub fn new(urgency: u8, incremental: bool) -> Self {
|
||||
assert!(urgency < 8);
|
||||
Priority {
|
||||
Self {
|
||||
urgency,
|
||||
incremental,
|
||||
}
|
||||
|
@ -43,7 +43,7 @@ impl Priority {
|
|||
#[must_use]
|
||||
pub fn header(self) -> Option<Header> {
|
||||
match self {
|
||||
Priority {
|
||||
Self {
|
||||
urgency: 3,
|
||||
incremental: false,
|
||||
} => None,
|
||||
|
@ -60,7 +60,7 @@ impl Priority {
|
|||
/// # Panics
|
||||
///
|
||||
/// Never, but the compiler is not smart enough to work that out.
|
||||
pub fn from_bytes(bytes: &[u8]) -> Res<Priority> {
|
||||
pub fn from_bytes(bytes: &[u8]) -> Res<Self> {
|
||||
let dict = Parser::parse_dictionary(bytes).map_err(|_| Error::HttpFrame)?;
|
||||
let urgency = match dict.get("u") {
|
||||
Some(ListEntry::Item(Item {
|
||||
|
@ -76,7 +76,7 @@ impl Priority {
|
|||
})) => *i,
|
||||
_ => false,
|
||||
};
|
||||
Ok(Priority {
|
||||
Ok(Self {
|
||||
urgency,
|
||||
incremental,
|
||||
})
|
||||
|
@ -86,19 +86,19 @@ impl Priority {
|
|||
impl fmt::Display for Priority {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
match self {
|
||||
Priority {
|
||||
Self {
|
||||
urgency: 3,
|
||||
incremental: false,
|
||||
} => Ok(()),
|
||||
Priority {
|
||||
Self {
|
||||
urgency: 3,
|
||||
incremental: true,
|
||||
} => write!(f, "i"),
|
||||
Priority {
|
||||
Self {
|
||||
urgency,
|
||||
incremental: false,
|
||||
} => write!(f, "u={urgency}"),
|
||||
Priority {
|
||||
Self {
|
||||
urgency,
|
||||
incremental: true,
|
||||
} => write!(f, "u={urgency},i"),
|
||||
|
@ -115,8 +115,8 @@ pub struct PriorityHandler {
|
|||
}
|
||||
|
||||
impl PriorityHandler {
|
||||
pub fn new(push_stream: bool, priority: Priority) -> PriorityHandler {
|
||||
PriorityHandler {
|
||||
pub const fn new(push_stream: bool, priority: Priority) -> Self {
|
||||
Self {
|
||||
push_stream,
|
||||
priority,
|
||||
last_send_priority: priority,
|
||||
|
|
|
@ -61,7 +61,7 @@ struct ActivePushStreams {
|
|||
}
|
||||
|
||||
impl ActivePushStreams {
|
||||
pub fn new() -> Self {
|
||||
pub const fn new() -> Self {
|
||||
Self {
|
||||
push_streams: VecDeque::new(),
|
||||
first_push_id: 0,
|
||||
|
@ -98,7 +98,7 @@ impl ActivePushStreams {
|
|||
None | Some(PushState::Closed) => None,
|
||||
Some(s) => {
|
||||
let res = mem::replace(s, PushState::Closed);
|
||||
while let Some(PushState::Closed) = self.push_streams.front() {
|
||||
while self.push_streams.front() == Some(&PushState::Closed) {
|
||||
self.push_streams.pop_front();
|
||||
self.first_push_id += 1;
|
||||
}
|
||||
|
@ -144,7 +144,7 @@ impl ActivePushStreams {
|
|||
/// `CANCEL_PUSH` frame. The difference is that `PushCanceled` will not
|
||||
/// be posted and a `CANCEL_PUSH` frame may be sent.
|
||||
#[derive(Debug)]
|
||||
pub(crate) struct PushController {
|
||||
pub struct PushController {
|
||||
max_concurent_push: u64,
|
||||
current_max_push_id: u64,
|
||||
// push_streams holds the states of push streams.
|
||||
|
@ -157,8 +157,8 @@ pub(crate) struct PushController {
|
|||
}
|
||||
|
||||
impl PushController {
|
||||
pub fn new(max_concurent_push: u64, conn_events: Http3ClientEvents) -> Self {
|
||||
PushController {
|
||||
pub const fn new(max_concurent_push: u64, conn_events: Http3ClientEvents) -> Self {
|
||||
Self {
|
||||
max_concurent_push,
|
||||
current_max_push_id: 0,
|
||||
push_streams: ActivePushStreams::new(),
|
||||
|
@ -245,12 +245,12 @@ impl PushController {
|
|||
|
||||
self.check_push_id(push_id)?;
|
||||
|
||||
match self.push_streams.get_mut(push_id) {
|
||||
None => {
|
||||
self.push_streams.get_mut(push_id).map_or_else(
|
||||
|| {
|
||||
qinfo!("Push has been closed already.");
|
||||
Ok(false)
|
||||
}
|
||||
Some(push_state) => match push_state {
|
||||
},
|
||||
|push_state| match push_state {
|
||||
PushState::Init => {
|
||||
*push_state = PushState::OnlyPushStream {
|
||||
stream_id,
|
||||
|
@ -273,10 +273,10 @@ impl PushController {
|
|||
Err(Error::HttpId)
|
||||
}
|
||||
},
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
fn check_push_id(&mut self, push_id: u64) -> Res<()> {
|
||||
fn check_push_id(&self, push_id: u64) -> Res<()> {
|
||||
// Check if push id is greater than what we allow.
|
||||
if push_id > self.current_max_push_id {
|
||||
qerror!("Push id is greater than current_max_push_id.");
|
||||
|
@ -431,7 +431,7 @@ impl PushController {
|
|||
self.push_streams.clear();
|
||||
}
|
||||
|
||||
pub fn can_receive_push(&self) -> bool {
|
||||
pub const fn can_receive_push(&self) -> bool {
|
||||
self.max_concurent_push > 0
|
||||
}
|
||||
|
||||
|
@ -459,13 +459,13 @@ impl PushController {
|
|||
/// `PushHeaderReady` and `PushDataReadable` events or to postpone them if
|
||||
/// a `push_promise` has not been yet received for the stream.
|
||||
#[derive(Debug)]
|
||||
pub(crate) struct RecvPushEvents {
|
||||
pub struct RecvPushEvents {
|
||||
push_id: u64,
|
||||
push_handler: Rc<RefCell<PushController>>,
|
||||
}
|
||||
|
||||
impl RecvPushEvents {
|
||||
pub fn new(push_id: u64, push_handler: Rc<RefCell<PushController>>) -> Self {
|
||||
pub const fn new(push_id: u64, push_handler: Rc<RefCell<PushController>>) -> Self {
|
||||
Self {
|
||||
push_id,
|
||||
push_handler,
|
||||
|
|
|
@ -10,7 +10,7 @@ use neqo_common::qlog::NeqoQlog;
|
|||
use neqo_transport::StreamId;
|
||||
use qlog::events::{DataRecipient, EventData};
|
||||
|
||||
pub fn h3_data_moved_up(qlog: &mut NeqoQlog, stream_id: StreamId, amount: usize) {
|
||||
pub fn h3_data_moved_up(qlog: &NeqoQlog, stream_id: StreamId, amount: usize) {
|
||||
qlog.add_event_data(|| {
|
||||
let ev_data = EventData::DataMoved(qlog::events::quic::DataMoved {
|
||||
stream_id: Some(stream_id.as_u64()),
|
||||
|
@ -25,7 +25,7 @@ pub fn h3_data_moved_up(qlog: &mut NeqoQlog, stream_id: StreamId, amount: usize)
|
|||
});
|
||||
}
|
||||
|
||||
pub fn h3_data_moved_down(qlog: &mut NeqoQlog, stream_id: StreamId, amount: usize) {
|
||||
pub fn h3_data_moved_down(qlog: &NeqoQlog, stream_id: StreamId, amount: usize) {
|
||||
qlog.add_event_data(|| {
|
||||
let ev_data = EventData::DataMoved(qlog::events::quic::DataMoved {
|
||||
stream_id: Some(stream_id.as_u64()),
|
||||
|
|
|
@ -12,13 +12,13 @@ use neqo_transport::{Connection, StreamId};
|
|||
use crate::{CloseType, Error, Http3StreamType, ReceiveOutput, RecvStream, Res, Stream};
|
||||
|
||||
#[derive(Debug)]
|
||||
pub(crate) struct DecoderRecvStream {
|
||||
pub struct DecoderRecvStream {
|
||||
stream_id: StreamId,
|
||||
decoder: Rc<RefCell<QPackDecoder>>,
|
||||
}
|
||||
|
||||
impl DecoderRecvStream {
|
||||
pub fn new(stream_id: StreamId, decoder: Rc<RefCell<QPackDecoder>>) -> Self {
|
||||
pub const fn new(stream_id: StreamId, decoder: Rc<RefCell<QPackDecoder>>) -> Self {
|
||||
Self { stream_id, decoder }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,13 +12,13 @@ use neqo_transport::{Connection, StreamId};
|
|||
use crate::{CloseType, Error, Http3StreamType, ReceiveOutput, RecvStream, Res, Stream};
|
||||
|
||||
#[derive(Debug)]
|
||||
pub(crate) struct EncoderRecvStream {
|
||||
pub struct EncoderRecvStream {
|
||||
stream_id: StreamId,
|
||||
encoder: Rc<RefCell<QPackEncoder>>,
|
||||
}
|
||||
|
||||
impl EncoderRecvStream {
|
||||
pub fn new(stream_id: StreamId, encoder: Rc<RefCell<QPackEncoder>>) -> Self {
|
||||
pub const fn new(stream_id: StreamId, encoder: Rc<RefCell<QPackEncoder>>) -> Self {
|
||||
Self { stream_id, encoder }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,7 +20,7 @@ use crate::{
|
|||
};
|
||||
|
||||
#[allow(clippy::module_name_repetitions)]
|
||||
pub(crate) struct RecvMessageInfo {
|
||||
pub struct RecvMessageInfo {
|
||||
pub message_type: MessageType,
|
||||
pub stream_type: Http3StreamType,
|
||||
pub stream_id: StreamId,
|
||||
|
@ -66,7 +66,7 @@ struct PushInfo {
|
|||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub(crate) struct RecvMessage {
|
||||
pub struct RecvMessage {
|
||||
state: RecvMessageState,
|
||||
message_type: MessageType,
|
||||
stream_type: Http3StreamType,
|
||||
|
@ -363,14 +363,14 @@ impl RecvMessage {
|
|||
.recv_closed(self.get_stream_info(), CloseType::Done);
|
||||
}
|
||||
|
||||
fn closing(&self) -> bool {
|
||||
const fn closing(&self) -> bool {
|
||||
matches!(
|
||||
self.state,
|
||||
RecvMessageState::ClosePending | RecvMessageState::Closed
|
||||
)
|
||||
}
|
||||
|
||||
fn get_stream_info(&self) -> Http3StreamInfo {
|
||||
const fn get_stream_info(&self) -> Http3StreamInfo {
|
||||
Http3StreamInfo::new(self.stream_id, Http3StreamType::Http)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -38,7 +38,7 @@ impl RequestTarget for RefRequestTarget<'_, '_, '_> {
|
|||
|
||||
impl<'s, 'a, 'p> RefRequestTarget<'s, 'a, 'p> {
|
||||
#[must_use]
|
||||
pub fn new(scheme: &'s str, authority: &'a str, path: &'p str) -> Self {
|
||||
pub const fn new(scheme: &'s str, authority: &'a str, path: &'p str) -> Self {
|
||||
Self {
|
||||
scheme,
|
||||
authority,
|
||||
|
|
|
@ -27,7 +27,7 @@ const MAX_DATA_HEADER_SIZE_5_LIMIT: usize = MAX_DATA_HEADER_SIZE_5 + 9; // 10737
|
|||
|
||||
/// A HTTP message, request and response, consists of headers, optional data and an optional
|
||||
/// trailer header block. This state machine does not reflect what was already sent to the
|
||||
/// transport layer but only reflect what has been supplied to the `SendMessage`.It is
|
||||
/// transport layer but only reflect what has been supplied to the `SendMessage`. It is
|
||||
/// represented by the following states:
|
||||
/// `WaitingForHeaders` - the headers have not been supplied yet. In this state only a
|
||||
/// request/response header can be added. When headers are supplied
|
||||
|
@ -42,7 +42,6 @@ const MAX_DATA_HEADER_SIZE_5_LIMIT: usize = MAX_DATA_HEADER_SIZE_5 + 9; // 10737
|
|||
/// supply only a fin.
|
||||
/// `Done` - in this state no more data or headers can be added. This state is entered when the
|
||||
/// message is closed.
|
||||
|
||||
#[derive(Debug, PartialEq)]
|
||||
enum MessageState {
|
||||
WaitingForHeaders,
|
||||
|
@ -103,7 +102,7 @@ impl MessageState {
|
|||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub(crate) struct SendMessage {
|
||||
pub struct SendMessage {
|
||||
state: MessageState,
|
||||
message_type: MessageType,
|
||||
stream_type: Http3StreamType,
|
||||
|
@ -314,7 +313,7 @@ impl SendStream for SendMessage {
|
|||
impl HttpSendStream for SendMessage {
|
||||
fn send_headers(&mut self, headers: &[Header], conn: &mut Connection) -> Res<()> {
|
||||
self.state.new_headers(headers, self.message_type)?;
|
||||
let buf = SendMessage::encode(
|
||||
let buf = Self::encode(
|
||||
&mut self.encoder.borrow_mut(),
|
||||
headers,
|
||||
conn,
|
||||
|
|
|
@ -17,7 +17,7 @@ use std::{
|
|||
use neqo_common::{qtrace, Datagram};
|
||||
use neqo_crypto::{AntiReplay, Cipher, PrivateKey, PublicKey, ZeroRttChecker};
|
||||
use neqo_transport::{
|
||||
server::{ActiveConnectionRef, Server, ValidateAddress},
|
||||
server::{ConnectionRef, Server, ValidateAddress},
|
||||
ConnectionIdGenerator, Output,
|
||||
};
|
||||
|
||||
|
@ -39,7 +39,7 @@ const MAX_EVENT_DATA_SIZE: usize = 1024;
|
|||
pub struct Http3Server {
|
||||
server: Server,
|
||||
http3_parameters: Http3Parameters,
|
||||
http3_handlers: HashMap<ActiveConnectionRef, HandlerRef>,
|
||||
http3_handlers: HashMap<ConnectionRef, HandlerRef>,
|
||||
events: Http3ServerEvents,
|
||||
}
|
||||
|
||||
|
@ -84,7 +84,7 @@ impl Http3Server {
|
|||
self.server.set_qlog_dir(dir);
|
||||
}
|
||||
|
||||
pub fn set_validation(&mut self, v: ValidateAddress) {
|
||||
pub fn set_validation(&self, v: ValidateAddress) {
|
||||
self.server.set_validation(v);
|
||||
}
|
||||
|
||||
|
@ -130,34 +130,24 @@ impl Http3Server {
|
|||
/// Process HTTP3 layer.
|
||||
fn process_http3(&mut self, now: Instant) {
|
||||
qtrace!([self], "Process http3 internal.");
|
||||
// `ActiveConnectionRef` `Hash` implementation doesn’t access any of the interior mutable
|
||||
// types.
|
||||
#[allow(clippy::mutable_key_type)]
|
||||
let mut active_conns = self.server.active_connections();
|
||||
active_conns.extend(
|
||||
self.http3_handlers
|
||||
.iter()
|
||||
.filter(|(_, handler)| handler.borrow_mut().should_be_processed())
|
||||
.map(|(c, _)| c)
|
||||
.cloned(),
|
||||
);
|
||||
|
||||
// We need to find connections that needs to be process on http3 level.
|
||||
let mut http3_active: Vec<ActiveConnectionRef> = self
|
||||
.http3_handlers
|
||||
.iter()
|
||||
.filter_map(|(conn, handler)| {
|
||||
if handler.borrow_mut().should_be_processed() && !active_conns.contains(conn) {
|
||||
Some(conn)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
.cloned()
|
||||
.collect();
|
||||
// For http_active connection we need to put them in neqo-transport's server
|
||||
// waiting queue.
|
||||
active_conns.append(&mut http3_active);
|
||||
active_conns.dedup();
|
||||
active_conns
|
||||
.iter()
|
||||
.for_each(|conn| self.server.add_to_waiting(conn));
|
||||
for mut conn in active_conns {
|
||||
self.process_events(&mut conn, now);
|
||||
for conn in active_conns {
|
||||
self.process_events(&conn, now);
|
||||
}
|
||||
}
|
||||
|
||||
fn process_events(&mut self, conn: &mut ActiveConnectionRef, now: Instant) {
|
||||
fn process_events(&mut self, conn: &ConnectionRef, now: Instant) {
|
||||
let mut remove = false;
|
||||
let http3_parameters = &self.http3_parameters;
|
||||
{
|
||||
|
@ -188,7 +178,7 @@ impl Http3Server {
|
|||
conn,
|
||||
handler,
|
||||
now,
|
||||
&mut self.events,
|
||||
&self.events,
|
||||
);
|
||||
}
|
||||
Http3ServerConnEvent::DataWritable { stream_info } => self
|
||||
|
@ -259,7 +249,7 @@ impl Http3Server {
|
|||
|
||||
/// Get all current events. Best used just in debug/testing code, use
|
||||
/// `next_event` instead.
|
||||
pub fn events(&mut self) -> impl Iterator<Item = Http3ServerEvent> {
|
||||
pub fn events(&self) -> impl Iterator<Item = Http3ServerEvent> {
|
||||
self.events.events()
|
||||
}
|
||||
|
||||
|
@ -272,17 +262,18 @@ impl Http3Server {
|
|||
/// Get events that indicate state changes on the connection. This method
|
||||
/// correctly handles cases where handling one event can obsolete
|
||||
/// previously-queued events, or cause new events to be generated.
|
||||
pub fn next_event(&mut self) -> Option<Http3ServerEvent> {
|
||||
#[must_use]
|
||||
pub fn next_event(&self) -> Option<Http3ServerEvent> {
|
||||
self.events.next_event()
|
||||
}
|
||||
}
|
||||
fn prepare_data(
|
||||
stream_info: Http3StreamInfo,
|
||||
handler_borrowed: &mut RefMut<Http3ServerHandler>,
|
||||
conn: &mut ActiveConnectionRef,
|
||||
conn: &ConnectionRef,
|
||||
handler: &HandlerRef,
|
||||
now: Instant,
|
||||
events: &mut Http3ServerEvents,
|
||||
events: &Http3ServerEvents,
|
||||
) {
|
||||
loop {
|
||||
let mut data = vec![0; MAX_EVENT_DATA_SIZE];
|
||||
|
@ -365,13 +356,13 @@ mod tests {
|
|||
create_server(http3params(DEFAULT_SETTINGS))
|
||||
}
|
||||
|
||||
fn assert_closed(hconn: &mut Http3Server, expected: &Error) {
|
||||
fn assert_closed(hconn: &Http3Server, expected: &Error) {
|
||||
let err = CloseReason::Application(expected.code());
|
||||
let closed = |e| matches!(e, Http3ServerEvent::StateChange{ state: Http3State::Closing(e) | Http3State::Closed(e), .. } if e == err);
|
||||
assert!(hconn.events().any(closed));
|
||||
}
|
||||
|
||||
fn assert_connected(hconn: &mut Http3Server) {
|
||||
fn assert_connected(hconn: &Http3Server) {
|
||||
let connected = |e| {
|
||||
matches!(
|
||||
e,
|
||||
|
@ -384,7 +375,7 @@ mod tests {
|
|||
assert!(hconn.events().any(connected));
|
||||
}
|
||||
|
||||
fn assert_not_closed(hconn: &mut Http3Server) {
|
||||
fn assert_not_closed(hconn: &Http3Server) {
|
||||
let closed = |e| {
|
||||
matches!(
|
||||
e,
|
||||
|
@ -595,7 +586,7 @@ mod tests {
|
|||
peer_conn.stream_close_send(control).unwrap();
|
||||
let out = peer_conn.process(None, now());
|
||||
hconn.process(out.as_dgram_ref(), now());
|
||||
assert_closed(&mut hconn, &Error::HttpClosedCriticalStream);
|
||||
assert_closed(&hconn, &Error::HttpClosedCriticalStream);
|
||||
}
|
||||
|
||||
// Server: test missing SETTINGS frame
|
||||
|
@ -610,7 +601,7 @@ mod tests {
|
|||
assert_eq!(sent, Ok(4));
|
||||
let out = neqo_trans_conn.process(None, now());
|
||||
hconn.process(out.as_dgram_ref(), now());
|
||||
assert_closed(&mut hconn, &Error::HttpMissingSettings);
|
||||
assert_closed(&hconn, &Error::HttpMissingSettings);
|
||||
}
|
||||
|
||||
// Server: receiving SETTINGS frame twice causes connection close
|
||||
|
@ -622,7 +613,7 @@ mod tests {
|
|||
peer_conn.control_send(&[0x4, 0x6, 0x1, 0x40, 0x64, 0x7, 0x40, 0x64]);
|
||||
let out = peer_conn.process(None, now());
|
||||
hconn.process(out.as_dgram_ref(), now());
|
||||
assert_closed(&mut hconn, &Error::HttpFrameUnexpected);
|
||||
assert_closed(&hconn, &Error::HttpFrameUnexpected);
|
||||
}
|
||||
|
||||
fn priority_update_check_id(stream_id: StreamId, valid: bool) {
|
||||
|
@ -639,9 +630,9 @@ mod tests {
|
|||
hconn.process(out.as_dgram_ref(), now());
|
||||
// check if the given connection got closed on invalid stream ids
|
||||
if valid {
|
||||
assert_not_closed(&mut hconn);
|
||||
assert_not_closed(&hconn);
|
||||
} else {
|
||||
assert_closed(&mut hconn, &Error::HttpId);
|
||||
assert_closed(&hconn, &Error::HttpId);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -680,7 +671,7 @@ mod tests {
|
|||
|
||||
let out = peer_conn.process(None, now());
|
||||
hconn.process(out.as_dgram_ref(), now());
|
||||
assert_closed(&mut hconn, &Error::HttpFrameUnexpected);
|
||||
assert_closed(&hconn, &Error::HttpFrameUnexpected);
|
||||
}
|
||||
|
||||
// send DATA frame on a control stream
|
||||
|
@ -732,7 +723,7 @@ mod tests {
|
|||
}
|
||||
}
|
||||
assert!(stop_sending_event_found);
|
||||
assert_not_closed(&mut hconn);
|
||||
assert_not_closed(&hconn);
|
||||
}
|
||||
|
||||
// Server: receiving a push stream on a server should cause WrongStreamDirection
|
||||
|
@ -746,7 +737,7 @@ mod tests {
|
|||
let out = peer_conn.process(None, now());
|
||||
let out = hconn.process(out.as_dgram_ref(), now());
|
||||
mem::drop(peer_conn.conn.process(out.as_dgram_ref(), now()));
|
||||
assert_closed(&mut hconn, &Error::HttpStreamCreation);
|
||||
assert_closed(&hconn, &Error::HttpStreamCreation);
|
||||
}
|
||||
|
||||
/// Test reading of a slowly streamed frame. bytes are received one by one
|
||||
|
@ -794,7 +785,7 @@ mod tests {
|
|||
let out = peer_conn.process(None, now());
|
||||
hconn.process(out.as_dgram_ref(), now());
|
||||
|
||||
assert_not_closed(&mut hconn);
|
||||
assert_not_closed(&hconn);
|
||||
|
||||
// Now test PushPromise
|
||||
sent = peer_conn.stream_send(control_stream, &[0x5]);
|
||||
|
@ -833,7 +824,7 @@ mod tests {
|
|||
hconn.process(out.as_dgram_ref(), now());
|
||||
|
||||
// PUSH_PROMISE on a control stream will cause an error
|
||||
assert_closed(&mut hconn, &Error::HttpFrameUnexpected);
|
||||
assert_closed(&hconn, &Error::HttpFrameUnexpected);
|
||||
}
|
||||
|
||||
// Test reading of a slowly streamed frame. bytes are received one by one
|
||||
|
@ -848,7 +839,7 @@ mod tests {
|
|||
let out = peer_conn.process(None, now());
|
||||
hconn.process(out.as_dgram_ref(), now());
|
||||
|
||||
assert_closed(&mut hconn, &Error::HttpFrame);
|
||||
assert_closed(&hconn, &Error::HttpFrame);
|
||||
}
|
||||
|
||||
const REQUEST_WITH_BODY: &[u8] = &[
|
||||
|
@ -910,11 +901,7 @@ mod tests {
|
|||
assert!(!fin);
|
||||
headers_frames += 1;
|
||||
}
|
||||
Http3ServerEvent::Data {
|
||||
mut stream,
|
||||
data,
|
||||
fin,
|
||||
} => {
|
||||
Http3ServerEvent::Data { stream, data, fin } => {
|
||||
assert_eq!(data, REQUEST_BODY);
|
||||
assert!(fin);
|
||||
stream
|
||||
|
@ -956,7 +943,7 @@ mod tests {
|
|||
while let Some(event) = hconn.next_event() {
|
||||
match event {
|
||||
Http3ServerEvent::Headers {
|
||||
mut stream,
|
||||
stream,
|
||||
headers,
|
||||
fin,
|
||||
} => {
|
||||
|
@ -1034,7 +1021,7 @@ mod tests {
|
|||
while let Some(event) = hconn.next_event() {
|
||||
match event {
|
||||
Http3ServerEvent::Headers {
|
||||
mut stream,
|
||||
stream,
|
||||
headers,
|
||||
fin,
|
||||
} => {
|
||||
|
@ -1092,7 +1079,7 @@ mod tests {
|
|||
.unwrap();
|
||||
let out = peer_conn.process(None, now());
|
||||
hconn.process(out.as_dgram_ref(), now());
|
||||
assert_closed(&mut hconn, &Error::HttpClosedCriticalStream);
|
||||
assert_closed(&hconn, &Error::HttpClosedCriticalStream);
|
||||
}
|
||||
|
||||
// Server: Test that the connection will be closed if the client side encoder stream
|
||||
|
@ -1105,7 +1092,7 @@ mod tests {
|
|||
.unwrap();
|
||||
let out = peer_conn.process(None, now());
|
||||
hconn.process(out.as_dgram_ref(), now());
|
||||
assert_closed(&mut hconn, &Error::HttpClosedCriticalStream);
|
||||
assert_closed(&hconn, &Error::HttpClosedCriticalStream);
|
||||
}
|
||||
|
||||
// Server: Test that the connection will be closed if the client side decoder stream
|
||||
|
@ -1118,7 +1105,7 @@ mod tests {
|
|||
.unwrap();
|
||||
let out = peer_conn.process(None, now());
|
||||
hconn.process(out.as_dgram_ref(), now());
|
||||
assert_closed(&mut hconn, &Error::HttpClosedCriticalStream);
|
||||
assert_closed(&hconn, &Error::HttpClosedCriticalStream);
|
||||
}
|
||||
|
||||
// Server: Test that the connection will be closed if the local control stream
|
||||
|
@ -1132,7 +1119,7 @@ mod tests {
|
|||
.unwrap();
|
||||
let out = peer_conn.process(None, now());
|
||||
hconn.process(out.as_dgram_ref(), now());
|
||||
assert_closed(&mut hconn, &Error::HttpClosedCriticalStream);
|
||||
assert_closed(&hconn, &Error::HttpClosedCriticalStream);
|
||||
}
|
||||
|
||||
// Server: Test that the connection will be closed if the server side encoder stream
|
||||
|
@ -1145,7 +1132,7 @@ mod tests {
|
|||
.unwrap();
|
||||
let out = peer_conn.process(None, now());
|
||||
hconn.process(out.as_dgram_ref(), now());
|
||||
assert_closed(&mut hconn, &Error::HttpClosedCriticalStream);
|
||||
assert_closed(&hconn, &Error::HttpClosedCriticalStream);
|
||||
}
|
||||
|
||||
// Server: Test that the connection will be closed if the server side decoder stream
|
||||
|
@ -1158,7 +1145,7 @@ mod tests {
|
|||
.unwrap();
|
||||
let out = peer_conn.process(None, now());
|
||||
hconn.process(out.as_dgram_ref(), now());
|
||||
assert_closed(&mut hconn, &Error::HttpClosedCriticalStream);
|
||||
assert_closed(&hconn, &Error::HttpClosedCriticalStream);
|
||||
}
|
||||
|
||||
/// Perform a handshake, then another with the token from the first.
|
||||
|
|
|
@ -16,7 +16,7 @@ use crate::{
|
|||
};
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, Clone)]
|
||||
pub(crate) enum Http3ServerConnEvent {
|
||||
pub enum Http3ServerConnEvent {
|
||||
/// Headers are ready.
|
||||
Headers {
|
||||
stream_info: Http3StreamInfo,
|
||||
|
@ -62,7 +62,7 @@ pub(crate) enum Http3ServerConnEvent {
|
|||
}
|
||||
|
||||
#[derive(Debug, Default, Clone)]
|
||||
pub(crate) struct Http3ServerConnEvents {
|
||||
pub struct Http3ServerConnEvents {
|
||||
events: Rc<RefCell<VecDeque<Http3ServerConnEvent>>>,
|
||||
}
|
||||
|
||||
|
|
|
@ -15,7 +15,7 @@ use std::{
|
|||
|
||||
use neqo_common::{qdebug, Encoder, Header};
|
||||
use neqo_transport::{
|
||||
server::ActiveConnectionRef, AppError, Connection, DatagramTracking, StreamId, StreamType,
|
||||
server::ConnectionRef, AppError, Connection, DatagramTracking, StreamId, StreamType,
|
||||
};
|
||||
|
||||
use crate::{
|
||||
|
@ -27,7 +27,7 @@ use crate::{
|
|||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct StreamHandler {
|
||||
pub conn: ActiveConnectionRef,
|
||||
pub conn: ConnectionRef,
|
||||
pub handler: Rc<RefCell<Http3ServerHandler>>,
|
||||
pub stream_info: Http3StreamInfo,
|
||||
}
|
||||
|
@ -43,7 +43,7 @@ impl std::hash::Hash for StreamHandler {
|
|||
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
|
||||
self.conn.hash(state);
|
||||
state.write_u64(self.stream_info.stream_id().as_u64());
|
||||
state.finish();
|
||||
_ = state.finish();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -56,7 +56,7 @@ impl PartialEq for StreamHandler {
|
|||
impl Eq for StreamHandler {}
|
||||
|
||||
impl StreamHandler {
|
||||
pub fn stream_id(&self) -> StreamId {
|
||||
pub const fn stream_id(&self) -> StreamId {
|
||||
self.stream_info.stream_id()
|
||||
}
|
||||
|
||||
|
@ -65,7 +65,7 @@ impl StreamHandler {
|
|||
/// # Errors
|
||||
///
|
||||
/// It may return `InvalidStreamId` if a stream does not exist anymore.
|
||||
pub fn send_headers(&mut self, headers: &[Header]) -> Res<()> {
|
||||
pub fn send_headers(&self, headers: &[Header]) -> Res<()> {
|
||||
self.handler.borrow_mut().send_headers(
|
||||
self.stream_id(),
|
||||
headers,
|
||||
|
@ -78,7 +78,7 @@ impl StreamHandler {
|
|||
/// # Errors
|
||||
///
|
||||
/// It may return `InvalidStreamId` if a stream does not exist anymore.
|
||||
pub fn send_data(&mut self, buf: &[u8]) -> Res<usize> {
|
||||
pub fn send_data(&self, buf: &[u8]) -> Res<usize> {
|
||||
self.handler
|
||||
.borrow_mut()
|
||||
.send_data(self.stream_id(), buf, &mut self.conn.borrow_mut())
|
||||
|
@ -91,7 +91,7 @@ impl StreamHandler {
|
|||
/// # Errors
|
||||
///
|
||||
/// It may return `InvalidStreamId` if a stream does not exist anymore.
|
||||
pub fn available(&mut self) -> Res<usize> {
|
||||
pub fn available(&self) -> Res<usize> {
|
||||
let stream_id = self.stream_id();
|
||||
let n = self.conn.borrow_mut().stream_avail_send_space(stream_id)?;
|
||||
Ok(n)
|
||||
|
@ -102,7 +102,7 @@ impl StreamHandler {
|
|||
/// # Errors
|
||||
///
|
||||
/// It may return `InvalidStreamId` if a stream does not exist anymore.
|
||||
pub fn stream_close_send(&mut self) -> Res<()> {
|
||||
pub fn stream_close_send(&self) -> Res<()> {
|
||||
self.handler
|
||||
.borrow_mut()
|
||||
.stream_close_send(self.stream_id(), &mut self.conn.borrow_mut())
|
||||
|
@ -113,7 +113,7 @@ impl StreamHandler {
|
|||
/// # Errors
|
||||
///
|
||||
/// It may return `InvalidStreamId` if a stream does not exist anymore.
|
||||
pub fn stream_stop_sending(&mut self, app_error: AppError) -> Res<()> {
|
||||
pub fn stream_stop_sending(&self, app_error: AppError) -> Res<()> {
|
||||
qdebug!(
|
||||
[self],
|
||||
"stop sending stream_id:{} error:{}.",
|
||||
|
@ -132,7 +132,7 @@ impl StreamHandler {
|
|||
/// # Errors
|
||||
///
|
||||
/// It may return `InvalidStreamId` if a stream does not exist anymore.
|
||||
pub fn stream_reset_send(&mut self, app_error: AppError) -> Res<()> {
|
||||
pub fn stream_reset_send(&self, app_error: AppError) -> Res<()> {
|
||||
qdebug!(
|
||||
[self],
|
||||
"reset send stream_id:{} error:{}.",
|
||||
|
@ -151,7 +151,7 @@ impl StreamHandler {
|
|||
/// # Errors
|
||||
///
|
||||
/// It may return `InvalidStreamId` if a stream does not exist anymore
|
||||
pub fn cancel_fetch(&mut self, app_error: AppError) -> Res<()> {
|
||||
pub fn cancel_fetch(&self, app_error: AppError) -> Res<()> {
|
||||
qdebug!([self], "reset error:{}.", app_error);
|
||||
self.handler.borrow_mut().cancel_fetch(
|
||||
self.stream_info.stream_id(),
|
||||
|
@ -173,8 +173,8 @@ impl ::std::fmt::Display for Http3OrWebTransportStream {
|
|||
}
|
||||
|
||||
impl Http3OrWebTransportStream {
|
||||
pub(crate) fn new(
|
||||
conn: ActiveConnectionRef,
|
||||
pub(crate) const fn new(
|
||||
conn: ConnectionRef,
|
||||
handler: Rc<RefCell<Http3ServerHandler>>,
|
||||
stream_info: Http3StreamInfo,
|
||||
) -> Self {
|
||||
|
@ -192,7 +192,7 @@ impl Http3OrWebTransportStream {
|
|||
/// # Errors
|
||||
///
|
||||
/// It may return `InvalidStreamId` if a stream does not exist anymore.
|
||||
pub fn send_headers(&mut self, headers: &[Header]) -> Res<()> {
|
||||
pub fn send_headers(&self, headers: &[Header]) -> Res<()> {
|
||||
self.stream_handler.send_headers(headers)
|
||||
}
|
||||
|
||||
|
@ -201,7 +201,7 @@ impl Http3OrWebTransportStream {
|
|||
/// # Errors
|
||||
///
|
||||
/// It may return `InvalidStreamId` if a stream does not exist anymore.
|
||||
pub fn send_data(&mut self, data: &[u8]) -> Res<usize> {
|
||||
pub fn send_data(&self, data: &[u8]) -> Res<usize> {
|
||||
qdebug!([self], "Set new response.");
|
||||
self.stream_handler.send_data(data)
|
||||
}
|
||||
|
@ -211,7 +211,7 @@ impl Http3OrWebTransportStream {
|
|||
/// # Errors
|
||||
///
|
||||
/// It may return `InvalidStreamId` if a stream does not exist anymore.
|
||||
pub fn stream_close_send(&mut self) -> Res<()> {
|
||||
pub fn stream_close_send(&self) -> Res<()> {
|
||||
qdebug!([self], "Set new response.");
|
||||
self.stream_handler.stream_close_send()
|
||||
}
|
||||
|
@ -234,7 +234,7 @@ impl DerefMut for Http3OrWebTransportStream {
|
|||
impl std::hash::Hash for Http3OrWebTransportStream {
|
||||
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
|
||||
self.stream_handler.hash(state);
|
||||
state.finish();
|
||||
_ = state.finish();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -258,8 +258,8 @@ impl ::std::fmt::Display for WebTransportRequest {
|
|||
}
|
||||
|
||||
impl WebTransportRequest {
|
||||
pub(crate) fn new(
|
||||
conn: ActiveConnectionRef,
|
||||
pub(crate) const fn new(
|
||||
conn: ConnectionRef,
|
||||
handler: Rc<RefCell<Http3ServerHandler>>,
|
||||
stream_id: StreamId,
|
||||
) -> Self {
|
||||
|
@ -282,7 +282,7 @@ impl WebTransportRequest {
|
|||
/// # Errors
|
||||
///
|
||||
/// It may return `InvalidStreamId` if a stream does not exist anymore.
|
||||
pub fn response(&mut self, accept: &WebTransportSessionAcceptAction) -> Res<()> {
|
||||
pub fn response(&self, accept: &WebTransportSessionAcceptAction) -> Res<()> {
|
||||
qdebug!([self], "Set a response for a WebTransport session.");
|
||||
self.stream_handler
|
||||
.handler
|
||||
|
@ -299,7 +299,7 @@ impl WebTransportRequest {
|
|||
/// It may return `InvalidStreamId` if a stream does not exist anymore.
|
||||
/// Also return an error if the stream was closed on the transport layer,
|
||||
/// but that information is not yet consumed on the http/3 layer.
|
||||
pub fn close_session(&mut self, error: u32, message: &str) -> Res<()> {
|
||||
pub fn close_session(&self, error: u32, message: &str) -> Res<()> {
|
||||
self.stream_handler
|
||||
.handler
|
||||
.borrow_mut()
|
||||
|
@ -312,7 +312,7 @@ impl WebTransportRequest {
|
|||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn stream_id(&self) -> StreamId {
|
||||
pub const fn stream_id(&self) -> StreamId {
|
||||
self.stream_handler.stream_id()
|
||||
}
|
||||
|
||||
|
@ -321,7 +321,7 @@ impl WebTransportRequest {
|
|||
/// # Errors
|
||||
///
|
||||
/// It may return `InvalidStreamId` if a stream does not exist anymore.
|
||||
pub fn create_stream(&mut self, stream_type: StreamType) -> Res<Http3OrWebTransportStream> {
|
||||
pub fn create_stream(&self, stream_type: StreamType) -> Res<Http3OrWebTransportStream> {
|
||||
let session_id = self.stream_handler.stream_id();
|
||||
let id = self
|
||||
.stream_handler
|
||||
|
@ -347,7 +347,7 @@ impl WebTransportRequest {
|
|||
/// It may return `InvalidStreamId` if a stream does not exist anymore.
|
||||
/// The function returns `TooMuchData` if the supply buffer is bigger than
|
||||
/// the allowed remote datagram size.
|
||||
pub fn send_datagram(&mut self, buf: &[u8], id: impl Into<DatagramTracking>) -> Res<()> {
|
||||
pub fn send_datagram(&self, buf: &[u8], id: impl Into<DatagramTracking>) -> Res<()> {
|
||||
let session_id = self.stream_handler.stream_id();
|
||||
self.stream_handler
|
||||
.handler
|
||||
|
@ -403,7 +403,7 @@ impl DerefMut for WebTransportRequest {
|
|||
impl std::hash::Hash for WebTransportRequest {
|
||||
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
|
||||
self.stream_handler.hash(state);
|
||||
state.finish();
|
||||
_ = state.finish();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -460,7 +460,7 @@ pub enum Http3ServerEvent {
|
|||
},
|
||||
/// When individual connection change state. It is only used for tests.
|
||||
StateChange {
|
||||
conn: ActiveConnectionRef,
|
||||
conn: ConnectionRef,
|
||||
state: Http3State,
|
||||
},
|
||||
PriorityUpdate {
|
||||
|
@ -510,14 +510,14 @@ impl Http3ServerEvents {
|
|||
}
|
||||
|
||||
/// Insert a `StateChange` event.
|
||||
pub(crate) fn connection_state_change(&self, conn: ActiveConnectionRef, state: Http3State) {
|
||||
pub(crate) fn connection_state_change(&self, conn: ConnectionRef, state: Http3State) {
|
||||
self.insert(Http3ServerEvent::StateChange { conn, state });
|
||||
}
|
||||
|
||||
/// Insert a `Data` event.
|
||||
pub(crate) fn data(
|
||||
&self,
|
||||
conn: ActiveConnectionRef,
|
||||
conn: ConnectionRef,
|
||||
handler: Rc<RefCell<Http3ServerHandler>>,
|
||||
stream_info: Http3StreamInfo,
|
||||
data: Vec<u8>,
|
||||
|
@ -532,7 +532,7 @@ impl Http3ServerEvents {
|
|||
|
||||
pub(crate) fn data_writable(
|
||||
&self,
|
||||
conn: ActiveConnectionRef,
|
||||
conn: ConnectionRef,
|
||||
handler: Rc<RefCell<Http3ServerHandler>>,
|
||||
stream_info: Http3StreamInfo,
|
||||
) {
|
||||
|
@ -543,7 +543,7 @@ impl Http3ServerEvents {
|
|||
|
||||
pub(crate) fn stream_reset(
|
||||
&self,
|
||||
conn: ActiveConnectionRef,
|
||||
conn: ConnectionRef,
|
||||
handler: Rc<RefCell<Http3ServerHandler>>,
|
||||
stream_info: Http3StreamInfo,
|
||||
error: AppError,
|
||||
|
@ -556,7 +556,7 @@ impl Http3ServerEvents {
|
|||
|
||||
pub(crate) fn stream_stop_sending(
|
||||
&self,
|
||||
conn: ActiveConnectionRef,
|
||||
conn: ConnectionRef,
|
||||
handler: Rc<RefCell<Http3ServerHandler>>,
|
||||
stream_info: Http3StreamInfo,
|
||||
error: AppError,
|
||||
|
|
|
@ -41,7 +41,7 @@ pub enum HSettingType {
|
|||
EnableH3Datagram,
|
||||
}
|
||||
|
||||
fn hsetting_default(setting_type: HSettingType) -> u64 {
|
||||
const fn hsetting_default(setting_type: HSettingType) -> u64 {
|
||||
match setting_type {
|
||||
HSettingType::MaxHeaderListSize => 1 << 62,
|
||||
HSettingType::MaxTableCapacity
|
||||
|
@ -59,7 +59,7 @@ pub struct HSetting {
|
|||
|
||||
impl HSetting {
|
||||
#[must_use]
|
||||
pub fn new(setting_type: HSettingType, value: u64) -> Self {
|
||||
pub const fn new(setting_type: HSettingType, value: u64) -> Self {
|
||||
Self {
|
||||
setting_type,
|
||||
value,
|
||||
|
@ -82,10 +82,10 @@ impl HSettings {
|
|||
|
||||
#[must_use]
|
||||
pub fn get(&self, setting: HSettingType) -> u64 {
|
||||
match self.settings.iter().find(|s| s.setting_type == setting) {
|
||||
Some(v) => v.value,
|
||||
None => hsetting_default(setting),
|
||||
}
|
||||
self.settings
|
||||
.iter()
|
||||
.find(|s| s.setting_type == setting)
|
||||
.map_or_else(|| hsetting_default(setting), |v| v.value)
|
||||
}
|
||||
|
||||
pub fn encode_frame_contents(&self, enc: &mut Encoder) {
|
||||
|
@ -226,7 +226,7 @@ pub struct HttpZeroRttChecker {
|
|||
impl HttpZeroRttChecker {
|
||||
/// Right now we only have QPACK settings, so that is all this takes.
|
||||
#[must_use]
|
||||
pub fn new(settings: Http3Parameters) -> Self {
|
||||
pub const fn new(settings: Http3Parameters) -> Self {
|
||||
Self { settings }
|
||||
}
|
||||
|
||||
|
|
|
@ -15,12 +15,12 @@ use crate::{
|
|||
Error, Http3StreamType, ReceiveOutput, RecvStream, Res, Stream,
|
||||
};
|
||||
|
||||
pub(crate) const HTTP3_UNI_STREAM_TYPE_PUSH: u64 = 0x1;
|
||||
pub(crate) const WEBTRANSPORT_UNI_STREAM: u64 = 0x54;
|
||||
pub(crate) const WEBTRANSPORT_STREAM: u64 = 0x41;
|
||||
pub const HTTP3_UNI_STREAM_TYPE_PUSH: u64 = 0x1;
|
||||
pub const WEBTRANSPORT_UNI_STREAM: u64 = 0x54;
|
||||
pub const WEBTRANSPORT_STREAM: u64 = 0x41;
|
||||
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
|
||||
pub(crate) enum NewStreamType {
|
||||
pub enum NewStreamType {
|
||||
Control,
|
||||
Decoder,
|
||||
Encoder,
|
||||
|
@ -39,31 +39,23 @@ impl NewStreamType {
|
|||
///
|
||||
/// Push streams received by the server are not allowed and this function will return
|
||||
/// `HttpStreamCreation` error.
|
||||
fn final_stream_type(
|
||||
const fn final_stream_type(
|
||||
stream_type: u64,
|
||||
trans_stream_type: StreamType,
|
||||
role: Role,
|
||||
) -> Res<Option<NewStreamType>> {
|
||||
) -> Res<Option<Self>> {
|
||||
match (stream_type, trans_stream_type, role) {
|
||||
(HTTP3_UNI_STREAM_TYPE_CONTROL, StreamType::UniDi, _) => {
|
||||
Ok(Some(NewStreamType::Control))
|
||||
}
|
||||
(QPACK_UNI_STREAM_TYPE_ENCODER, StreamType::UniDi, _) => {
|
||||
Ok(Some(NewStreamType::Decoder))
|
||||
}
|
||||
(QPACK_UNI_STREAM_TYPE_DECODER, StreamType::UniDi, _) => {
|
||||
Ok(Some(NewStreamType::Encoder))
|
||||
}
|
||||
(HTTP3_UNI_STREAM_TYPE_CONTROL, StreamType::UniDi, _) => Ok(Some(Self::Control)),
|
||||
(QPACK_UNI_STREAM_TYPE_ENCODER, StreamType::UniDi, _) => Ok(Some(Self::Decoder)),
|
||||
(QPACK_UNI_STREAM_TYPE_DECODER, StreamType::UniDi, _) => Ok(Some(Self::Encoder)),
|
||||
(HTTP3_UNI_STREAM_TYPE_PUSH, StreamType::UniDi, Role::Client)
|
||||
| (WEBTRANSPORT_UNI_STREAM, StreamType::UniDi, _)
|
||||
| (WEBTRANSPORT_STREAM, StreamType::BiDi, _) => Ok(None),
|
||||
(H3_FRAME_TYPE_HEADERS, StreamType::BiDi, Role::Server) => {
|
||||
Ok(Some(NewStreamType::Http))
|
||||
}
|
||||
(H3_FRAME_TYPE_HEADERS, StreamType::BiDi, Role::Server) => Ok(Some(Self::Http)),
|
||||
(_, StreamType::BiDi, Role::Server) => Err(Error::HttpFrame),
|
||||
(HTTP3_UNI_STREAM_TYPE_PUSH, StreamType::UniDi, Role::Server)
|
||||
| (_, StreamType::BiDi, Role::Client) => Err(Error::HttpStreamCreation),
|
||||
_ => Ok(Some(NewStreamType::Unknown)),
|
||||
_ => Ok(Some(Self::Unknown)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -76,7 +68,7 @@ impl NewStreamType {
|
|||
/// is identified by the type and `PushId`. After reading the type in the `ReadType` state,
|
||||
/// `NewStreamHeadReader` changes to `ReadId` state and from there to `Done` state
|
||||
#[derive(Debug)]
|
||||
pub(crate) enum NewStreamHeadReader {
|
||||
pub enum NewStreamHeadReader {
|
||||
ReadType {
|
||||
role: Role,
|
||||
reader: IncrementalDecoderUint,
|
||||
|
@ -92,7 +84,7 @@ pub(crate) enum NewStreamHeadReader {
|
|||
|
||||
impl NewStreamHeadReader {
|
||||
pub fn new(stream_id: StreamId, role: Role) -> Self {
|
||||
NewStreamHeadReader::ReadType {
|
||||
Self::ReadType {
|
||||
role,
|
||||
reader: IncrementalDecoderUint::default(),
|
||||
stream_id,
|
||||
|
@ -100,10 +92,10 @@ impl NewStreamHeadReader {
|
|||
}
|
||||
|
||||
fn read(&mut self, conn: &mut Connection) -> Res<(Option<u64>, bool)> {
|
||||
if let NewStreamHeadReader::ReadType {
|
||||
if let Self::ReadType {
|
||||
reader, stream_id, ..
|
||||
}
|
||||
| NewStreamHeadReader::ReadId {
|
||||
| Self::ReadId {
|
||||
reader, stream_id, ..
|
||||
} = self
|
||||
{
|
||||
|
@ -130,7 +122,7 @@ impl NewStreamHeadReader {
|
|||
let (output, fin) = self.read(conn)?;
|
||||
let Some(output) = output else {
|
||||
if fin {
|
||||
*self = NewStreamHeadReader::Done;
|
||||
*self = Self::Done;
|
||||
return Err(Error::HttpStreamCreation);
|
||||
}
|
||||
return Ok(None);
|
||||
|
@ -138,7 +130,7 @@ impl NewStreamHeadReader {
|
|||
|
||||
qtrace!("Decoded uint {}", output);
|
||||
match self {
|
||||
NewStreamHeadReader::ReadType {
|
||||
Self::ReadType {
|
||||
role, stream_id, ..
|
||||
} => {
|
||||
// final_stream_type may return:
|
||||
|
@ -152,21 +144,21 @@ impl NewStreamHeadReader {
|
|||
NewStreamType::final_stream_type(output, stream_id.stream_type(), *role);
|
||||
match (&final_type, fin) {
|
||||
(Err(_), _) => {
|
||||
*self = NewStreamHeadReader::Done;
|
||||
*self = Self::Done;
|
||||
return final_type;
|
||||
}
|
||||
(Ok(t), true) => {
|
||||
*self = NewStreamHeadReader::Done;
|
||||
*self = Self::Done;
|
||||
return Self::map_stream_fin(*t);
|
||||
}
|
||||
(Ok(Some(t)), false) => {
|
||||
qtrace!("Decoded stream type {:?}", *t);
|
||||
*self = NewStreamHeadReader::Done;
|
||||
*self = Self::Done;
|
||||
return final_type;
|
||||
}
|
||||
(Ok(None), false) => {
|
||||
// This is a push stream and it needs more data to be decoded.
|
||||
*self = NewStreamHeadReader::ReadId {
|
||||
*self = Self::ReadId {
|
||||
reader: IncrementalDecoderUint::default(),
|
||||
stream_id: *stream_id,
|
||||
stream_type: output,
|
||||
|
@ -174,9 +166,9 @@ impl NewStreamHeadReader {
|
|||
}
|
||||
}
|
||||
}
|
||||
NewStreamHeadReader::ReadId { stream_type, .. } => {
|
||||
Self::ReadId { stream_type, .. } => {
|
||||
let is_push = *stream_type == HTTP3_UNI_STREAM_TYPE_PUSH;
|
||||
*self = NewStreamHeadReader::Done;
|
||||
*self = Self::Done;
|
||||
qtrace!("New Stream stream push_id={}", output);
|
||||
if fin {
|
||||
return Err(Error::HttpGeneralProtocol);
|
||||
|
@ -187,7 +179,7 @@ impl NewStreamHeadReader {
|
|||
Ok(Some(NewStreamType::WebTransportStream(output)))
|
||||
};
|
||||
}
|
||||
NewStreamHeadReader::Done => {
|
||||
Self::Done => {
|
||||
unreachable!("Cannot be in state NewStreamHeadReader::Done");
|
||||
}
|
||||
}
|
||||
|
@ -208,8 +200,8 @@ impl NewStreamHeadReader {
|
|||
}
|
||||
}
|
||||
|
||||
fn done(&self) -> bool {
|
||||
matches!(self, NewStreamHeadReader::Done)
|
||||
const fn done(&self) -> bool {
|
||||
matches!(self, Self::Done)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -221,7 +213,7 @@ impl Stream for NewStreamHeadReader {
|
|||
|
||||
impl RecvStream for NewStreamHeadReader {
|
||||
fn reset(&mut self, _close_type: CloseType) -> Res<()> {
|
||||
*self = NewStreamHeadReader::Done;
|
||||
*self = Self::Done;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
|
|
@ -22,7 +22,7 @@ use test_fixture::*;
|
|||
|
||||
const RESPONSE_DATA: &[u8] = &[0x61, 0x62, 0x63];
|
||||
|
||||
fn receive_request(server: &mut Http3Server) -> Option<Http3OrWebTransportStream> {
|
||||
fn receive_request(server: &Http3Server) -> Option<Http3OrWebTransportStream> {
|
||||
while let Some(event) = server.next_event() {
|
||||
if let Http3ServerEvent::Headers {
|
||||
stream,
|
||||
|
@ -47,7 +47,7 @@ fn receive_request(server: &mut Http3Server) -> Option<Http3OrWebTransportStream
|
|||
None
|
||||
}
|
||||
|
||||
fn set_response(request: &mut Http3OrWebTransportStream) {
|
||||
fn set_response(request: &Http3OrWebTransportStream) {
|
||||
request
|
||||
.send_headers(&[
|
||||
Header::new(":status", "200"),
|
||||
|
@ -58,9 +58,9 @@ fn set_response(request: &mut Http3OrWebTransportStream) {
|
|||
request.stream_close_send().unwrap();
|
||||
}
|
||||
|
||||
fn process_server_events(server: &mut Http3Server) {
|
||||
let mut request = receive_request(server).unwrap();
|
||||
set_response(&mut request);
|
||||
fn process_server_events(server: &Http3Server) {
|
||||
let request = receive_request(server).unwrap();
|
||||
set_response(&request);
|
||||
}
|
||||
|
||||
fn process_client_events(conn: &mut Http3Client) {
|
||||
|
@ -192,7 +192,7 @@ fn test_fetch() {
|
|||
qtrace!("-----server");
|
||||
let out = hconn_s.process(out.as_dgram_ref(), now());
|
||||
mem::drop(hconn_c.process(out.as_dgram_ref(), now()));
|
||||
process_server_events(&mut hconn_s);
|
||||
process_server_events(&hconn_s);
|
||||
let out = hconn_s.process(None, now());
|
||||
|
||||
qtrace!("-----client");
|
||||
|
@ -221,8 +221,7 @@ fn test_103_response() {
|
|||
|
||||
let out = hconn_s.process(out.as_dgram_ref(), now());
|
||||
mem::drop(hconn_c.process(out.as_dgram_ref(), now()));
|
||||
let mut request = receive_request(&mut hconn_s).unwrap();
|
||||
|
||||
let request = receive_request(&hconn_s).unwrap();
|
||||
let info_headers = [
|
||||
Header::new(":status", "103"),
|
||||
Header::new("link", "</style.css>; rel=preload; as=style"),
|
||||
|
@ -240,7 +239,7 @@ fn test_103_response() {
|
|||
};
|
||||
assert!(hconn_c.events().any(info_headers_event));
|
||||
|
||||
set_response(&mut request);
|
||||
set_response(&request);
|
||||
let out = hconn_s.process(None, now());
|
||||
mem::drop(hconn_c.process(out.as_dgram_ref(), now()));
|
||||
process_client_events(&mut hconn_c);
|
||||
|
@ -273,7 +272,7 @@ fn test_data_writable_events_low_watermark() -> Result<(), Box<dyn std::error::E
|
|||
exchange_packets(&mut hconn_c, &mut hconn_s, None);
|
||||
|
||||
// Server receives GET and responds with headers.
|
||||
let mut request = receive_request(&mut hconn_s).unwrap();
|
||||
let request = receive_request(&hconn_s).unwrap();
|
||||
request.send_headers(&[Header::new(":status", "200")])?;
|
||||
|
||||
// Sending these headers clears the server's send stream buffer and thus
|
||||
|
@ -348,7 +347,7 @@ fn test_data_writable_events() {
|
|||
hconn_c.stream_close_send(req).unwrap();
|
||||
exchange_packets(&mut hconn_c, &mut hconn_s, None);
|
||||
|
||||
let mut request = receive_request(&mut hconn_s).unwrap();
|
||||
let request = receive_request(&hconn_s).unwrap();
|
||||
|
||||
request
|
||||
.send_headers(&[
|
||||
|
@ -484,10 +483,10 @@ fn zerortt() {
|
|||
}
|
||||
}
|
||||
assert!(zerortt_state_change);
|
||||
let mut request_stream = request_stream.unwrap();
|
||||
let request_stream = request_stream.unwrap();
|
||||
|
||||
// Send a response
|
||||
set_response(&mut request_stream);
|
||||
set_response(&request_stream);
|
||||
|
||||
// Receive the response
|
||||
exchange_packets(&mut hconn_c, &mut hconn_s, out.dgram());
|
||||
|
|
|
@ -37,7 +37,7 @@ fn exchange_packets(client: &mut Http3Client, server: &mut Http3Server) {
|
|||
}
|
||||
}
|
||||
|
||||
fn receive_request(server: &mut Http3Server) -> Option<Http3OrWebTransportStream> {
|
||||
fn receive_request(server: &Http3Server) -> Option<Http3OrWebTransportStream> {
|
||||
while let Some(event) = server.next_event() {
|
||||
if let Http3ServerEvent::Headers {
|
||||
stream,
|
||||
|
@ -61,18 +61,18 @@ fn receive_request(server: &mut Http3Server) -> Option<Http3OrWebTransportStream
|
|||
None
|
||||
}
|
||||
|
||||
fn send_trailers(request: &mut Http3OrWebTransportStream) -> Result<(), Error> {
|
||||
fn send_trailers(request: &Http3OrWebTransportStream) -> Result<(), Error> {
|
||||
request.send_headers(&[
|
||||
Header::new("something1", "something"),
|
||||
Header::new("something2", "3"),
|
||||
])
|
||||
}
|
||||
|
||||
fn send_informational_headers(request: &mut Http3OrWebTransportStream) -> Result<(), Error> {
|
||||
fn send_informational_headers(request: &Http3OrWebTransportStream) -> Result<(), Error> {
|
||||
request.send_headers(response_header_103())
|
||||
}
|
||||
|
||||
fn send_headers(request: &mut Http3OrWebTransportStream) -> Result<(), Error> {
|
||||
fn send_headers(request: &Http3OrWebTransportStream) -> Result<(), Error> {
|
||||
request.send_headers(&[
|
||||
Header::new(":status", "200"),
|
||||
Header::new("content-length", "3"),
|
||||
|
@ -158,17 +158,17 @@ fn connect_send_and_receive_request() -> (Http3Client, Http3Server, Http3OrWebTr
|
|||
hconn_c.stream_close_send(req).unwrap();
|
||||
exchange_packets(&mut hconn_c, &mut hconn_s);
|
||||
|
||||
let request = receive_request(&mut hconn_s).unwrap();
|
||||
let request = receive_request(&hconn_s).unwrap();
|
||||
|
||||
(hconn_c, hconn_s, request)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn response_trailers1() {
|
||||
let (mut hconn_c, mut hconn_s, mut request) = connect_send_and_receive_request();
|
||||
send_headers(&mut request).unwrap();
|
||||
let (mut hconn_c, mut hconn_s, request) = connect_send_and_receive_request();
|
||||
send_headers(&request).unwrap();
|
||||
request.send_data(RESPONSE_DATA).unwrap();
|
||||
send_trailers(&mut request).unwrap();
|
||||
send_trailers(&request).unwrap();
|
||||
request.stream_close_send().unwrap();
|
||||
exchange_packets(&mut hconn_c, &mut hconn_s);
|
||||
process_client_events(&mut hconn_c);
|
||||
|
@ -176,11 +176,11 @@ fn response_trailers1() {
|
|||
|
||||
#[test]
|
||||
fn response_trailers2() {
|
||||
let (mut hconn_c, mut hconn_s, mut request) = connect_send_and_receive_request();
|
||||
send_headers(&mut request).unwrap();
|
||||
let (mut hconn_c, mut hconn_s, request) = connect_send_and_receive_request();
|
||||
send_headers(&request).unwrap();
|
||||
request.send_data(RESPONSE_DATA).unwrap();
|
||||
exchange_packets(&mut hconn_c, &mut hconn_s);
|
||||
send_trailers(&mut request).unwrap();
|
||||
send_trailers(&request).unwrap();
|
||||
request.stream_close_send().unwrap();
|
||||
exchange_packets(&mut hconn_c, &mut hconn_s);
|
||||
process_client_events(&mut hconn_c);
|
||||
|
@ -188,11 +188,11 @@ fn response_trailers2() {
|
|||
|
||||
#[test]
|
||||
fn response_trailers3() {
|
||||
let (mut hconn_c, mut hconn_s, mut request) = connect_send_and_receive_request();
|
||||
send_headers(&mut request).unwrap();
|
||||
let (mut hconn_c, mut hconn_s, request) = connect_send_and_receive_request();
|
||||
send_headers(&request).unwrap();
|
||||
request.send_data(RESPONSE_DATA).unwrap();
|
||||
exchange_packets(&mut hconn_c, &mut hconn_s);
|
||||
send_trailers(&mut request).unwrap();
|
||||
send_trailers(&request).unwrap();
|
||||
exchange_packets(&mut hconn_c, &mut hconn_s);
|
||||
request.stream_close_send().unwrap();
|
||||
exchange_packets(&mut hconn_c, &mut hconn_s);
|
||||
|
@ -201,10 +201,10 @@ fn response_trailers3() {
|
|||
|
||||
#[test]
|
||||
fn response_trailers_no_data() {
|
||||
let (mut hconn_c, mut hconn_s, mut request) = connect_send_and_receive_request();
|
||||
let (mut hconn_c, mut hconn_s, request) = connect_send_and_receive_request();
|
||||
request.send_headers(response_header_no_data()).unwrap();
|
||||
exchange_packets(&mut hconn_c, &mut hconn_s);
|
||||
send_trailers(&mut request).unwrap();
|
||||
send_trailers(&request).unwrap();
|
||||
exchange_packets(&mut hconn_c, &mut hconn_s);
|
||||
request.stream_close_send().unwrap();
|
||||
exchange_packets(&mut hconn_c, &mut hconn_s);
|
||||
|
@ -213,14 +213,14 @@ fn response_trailers_no_data() {
|
|||
|
||||
#[test]
|
||||
fn multiple_response_trailers() {
|
||||
let (mut hconn_c, mut hconn_s, mut request) = connect_send_and_receive_request();
|
||||
send_headers(&mut request).unwrap();
|
||||
let (mut hconn_c, mut hconn_s, request) = connect_send_and_receive_request();
|
||||
send_headers(&request).unwrap();
|
||||
request.send_data(RESPONSE_DATA).unwrap();
|
||||
exchange_packets(&mut hconn_c, &mut hconn_s);
|
||||
send_trailers(&mut request).unwrap();
|
||||
send_trailers(&request).unwrap();
|
||||
exchange_packets(&mut hconn_c, &mut hconn_s);
|
||||
|
||||
assert_eq!(send_trailers(&mut request), Err(Error::InvalidInput));
|
||||
assert_eq!(send_trailers(&request), Err(Error::InvalidInput));
|
||||
|
||||
request.stream_close_send().unwrap();
|
||||
exchange_packets(&mut hconn_c, &mut hconn_s);
|
||||
|
@ -229,11 +229,11 @@ fn multiple_response_trailers() {
|
|||
|
||||
#[test]
|
||||
fn data_after_trailer() {
|
||||
let (mut hconn_c, mut hconn_s, mut request) = connect_send_and_receive_request();
|
||||
send_headers(&mut request).unwrap();
|
||||
let (mut hconn_c, mut hconn_s, request) = connect_send_and_receive_request();
|
||||
send_headers(&request).unwrap();
|
||||
request.send_data(RESPONSE_DATA).unwrap();
|
||||
exchange_packets(&mut hconn_c, &mut hconn_s);
|
||||
send_trailers(&mut request).unwrap();
|
||||
send_trailers(&request).unwrap();
|
||||
exchange_packets(&mut hconn_c, &mut hconn_s);
|
||||
|
||||
assert_eq!(request.send_data(RESPONSE_DATA), Err(Error::InvalidInput));
|
||||
|
@ -245,12 +245,12 @@ fn data_after_trailer() {
|
|||
|
||||
#[test]
|
||||
fn trailers_after_close() {
|
||||
let (mut hconn_c, mut hconn_s, mut request) = connect_send_and_receive_request();
|
||||
send_headers(&mut request).unwrap();
|
||||
let (mut hconn_c, mut hconn_s, request) = connect_send_and_receive_request();
|
||||
send_headers(&request).unwrap();
|
||||
request.send_data(RESPONSE_DATA).unwrap();
|
||||
request.stream_close_send().unwrap();
|
||||
|
||||
assert_eq!(send_trailers(&mut request), Err(Error::InvalidStreamId));
|
||||
assert_eq!(send_trailers(&request), Err(Error::InvalidStreamId));
|
||||
|
||||
exchange_packets(&mut hconn_c, &mut hconn_s);
|
||||
process_client_events(&mut hconn_c);
|
||||
|
@ -258,7 +258,7 @@ fn trailers_after_close() {
|
|||
|
||||
#[test]
|
||||
fn multiple_response_headers() {
|
||||
let (mut hconn_c, mut hconn_s, mut request) = connect_send_and_receive_request();
|
||||
let (mut hconn_c, mut hconn_s, request) = connect_send_and_receive_request();
|
||||
request.send_headers(response_header_no_data()).unwrap();
|
||||
|
||||
assert_eq!(
|
||||
|
@ -273,11 +273,11 @@ fn multiple_response_headers() {
|
|||
|
||||
#[test]
|
||||
fn informational_after_response_headers() {
|
||||
let (mut hconn_c, mut hconn_s, mut request) = connect_send_and_receive_request();
|
||||
let (mut hconn_c, mut hconn_s, request) = connect_send_and_receive_request();
|
||||
request.send_headers(response_header_no_data()).unwrap();
|
||||
|
||||
assert_eq!(
|
||||
send_informational_headers(&mut request),
|
||||
send_informational_headers(&request),
|
||||
Err(Error::InvalidHeader)
|
||||
);
|
||||
|
||||
|
@ -288,12 +288,12 @@ fn informational_after_response_headers() {
|
|||
|
||||
#[test]
|
||||
fn data_after_informational() {
|
||||
let (mut hconn_c, mut hconn_s, mut request) = connect_send_and_receive_request();
|
||||
send_informational_headers(&mut request).unwrap();
|
||||
let (mut hconn_c, mut hconn_s, request) = connect_send_and_receive_request();
|
||||
send_informational_headers(&request).unwrap();
|
||||
|
||||
assert_eq!(request.send_data(RESPONSE_DATA), Err(Error::InvalidInput));
|
||||
|
||||
send_headers(&mut request).unwrap();
|
||||
send_headers(&request).unwrap();
|
||||
request.send_data(RESPONSE_DATA).unwrap();
|
||||
request.stream_close_send().unwrap();
|
||||
exchange_packets(&mut hconn_c, &mut hconn_s);
|
||||
|
@ -302,8 +302,8 @@ fn data_after_informational() {
|
|||
|
||||
#[test]
|
||||
fn non_trailers_headers_after_data() {
|
||||
let (mut hconn_c, mut hconn_s, mut request) = connect_send_and_receive_request();
|
||||
send_headers(&mut request).unwrap();
|
||||
let (mut hconn_c, mut hconn_s, request) = connect_send_and_receive_request();
|
||||
send_headers(&request).unwrap();
|
||||
request.send_data(RESPONSE_DATA).unwrap();
|
||||
exchange_packets(&mut hconn_c, &mut hconn_s);
|
||||
|
||||
|
@ -319,10 +319,10 @@ fn non_trailers_headers_after_data() {
|
|||
|
||||
#[test]
|
||||
fn data_before_headers() {
|
||||
let (mut hconn_c, mut hconn_s, mut request) = connect_send_and_receive_request();
|
||||
let (mut hconn_c, mut hconn_s, request) = connect_send_and_receive_request();
|
||||
assert_eq!(request.send_data(RESPONSE_DATA), Err(Error::InvalidInput));
|
||||
|
||||
send_headers(&mut request).unwrap();
|
||||
send_headers(&request).unwrap();
|
||||
request.send_data(RESPONSE_DATA).unwrap();
|
||||
request.stream_close_send().unwrap();
|
||||
exchange_packets(&mut hconn_c, &mut hconn_s);
|
||||
|
|
|
@ -92,7 +92,7 @@ fn create_wt_session(client: &mut Http3Client, server: &mut Http3Server) -> WebT
|
|||
while let Some(event) = server.next_event() {
|
||||
match event {
|
||||
Http3ServerEvent::WebTransport(WebTransportServerEvent::NewSession {
|
||||
mut session,
|
||||
session,
|
||||
headers,
|
||||
}) => {
|
||||
assert!(
|
||||
|
@ -151,7 +151,7 @@ fn send_data_client(
|
|||
fn send_data_server(
|
||||
client: &mut Http3Client,
|
||||
server: &mut Http3Server,
|
||||
wt_stream: &mut Http3OrWebTransportStream,
|
||||
wt_stream: &Http3OrWebTransportStream,
|
||||
data: &[u8],
|
||||
) {
|
||||
assert_eq!(wt_stream.send_data(data).unwrap(), data.len());
|
||||
|
@ -254,7 +254,7 @@ fn wt_client_stream_bidi() {
|
|||
.webtransport_create_stream(wt_session.stream_id(), StreamType::BiDi)
|
||||
.unwrap();
|
||||
send_data_client(&mut client, &mut server, wt_client_stream, BUF_CLIENT);
|
||||
let mut wt_server_stream = receive_data_server(
|
||||
let wt_server_stream = receive_data_server(
|
||||
&mut client,
|
||||
&mut server,
|
||||
wt_client_stream,
|
||||
|
@ -262,7 +262,7 @@ fn wt_client_stream_bidi() {
|
|||
BUF_CLIENT,
|
||||
false,
|
||||
);
|
||||
send_data_server(&mut client, &mut server, &mut wt_server_stream, BUF_SERVER);
|
||||
send_data_server(&mut client, &mut server, &wt_server_stream, BUF_SERVER);
|
||||
receive_data_client(&mut client, wt_client_stream, false, BUF_SERVER, false);
|
||||
}
|
||||
|
||||
|
@ -271,9 +271,9 @@ fn wt_server_stream_uni() {
|
|||
const BUF_SERVER: &[u8] = &[2; 30];
|
||||
|
||||
let (mut client, mut server) = connect();
|
||||
let mut wt_session = create_wt_session(&mut client, &mut server);
|
||||
let mut wt_server_stream = wt_session.create_stream(StreamType::UniDi).unwrap();
|
||||
send_data_server(&mut client, &mut server, &mut wt_server_stream, BUF_SERVER);
|
||||
let wt_session = create_wt_session(&mut client, &mut server);
|
||||
let wt_server_stream = wt_session.create_stream(StreamType::UniDi).unwrap();
|
||||
send_data_server(&mut client, &mut server, &wt_server_stream, BUF_SERVER);
|
||||
receive_data_client(
|
||||
&mut client,
|
||||
wt_server_stream.stream_id(),
|
||||
|
@ -289,9 +289,9 @@ fn wt_server_stream_bidi() {
|
|||
const BUF_SERVER: &[u8] = &[1; 20];
|
||||
|
||||
let (mut client, mut server) = connect();
|
||||
let mut wt_session = create_wt_session(&mut client, &mut server);
|
||||
let mut wt_server_stream = wt_session.create_stream(StreamType::BiDi).unwrap();
|
||||
send_data_server(&mut client, &mut server, &mut wt_server_stream, BUF_SERVER);
|
||||
let wt_session = create_wt_session(&mut client, &mut server);
|
||||
let wt_server_stream = wt_session.create_stream(StreamType::BiDi).unwrap();
|
||||
send_data_server(&mut client, &mut server, &wt_server_stream, BUF_SERVER);
|
||||
receive_data_client(
|
||||
&mut client,
|
||||
wt_server_stream.stream_id(),
|
||||
|
|
|
@ -1 +1 @@
|
|||
{"files":{"Cargo.toml":"d139f2aa85c79512562bff7b664376089365cecd68b8ec9a6a4aa4b9495aa42d","src/decoder.rs":"0675444129e074e9d5d56f0d45d2eaed614c85e22cfe9f2d28cdee912c15b420","src/decoder_instructions.rs":"d991d70e51f079bc5b30d3982fd0176edfa9bb7ba14c17a20ec3eea878c56206","src/encoder.rs":"84649cbee81e050f55d7ea691ac871e072741abd8bbf96303eb2e98aa8ee0aea","src/encoder_instructions.rs":"86e3abbd9cf94332041326ac6cf806ed64623e3fd38dbc0385b1f63c37e73fd9","src/header_block.rs":"3925476df69b90d950594faadc5cb24c374d46de8c75a374a235f0d27323a7d8","src/huffman.rs":"71ec740426eee0abb6205104e504f5b97f525a76c4a5f5827b78034d28ce1876","src/huffman_decode_helper.rs":"9ce470e318b3664f58aa109bed483ab15bfd9e0b17d261ea2b609668a42a9d80","src/huffman_table.rs":"06fea766a6276ac56c7ee0326faed800a742c15fda1f33bf2513e6cc6a5e6d27","src/lib.rs":"fd673630b5ed64197851c9a9758685096d3c0aa04f4994290733a38057004ee6","src/prefix.rs":"fb4a9acbcf6fd3178f4474404cd3d3b131abca934f69fe14a9d744bc7e636dc5","src/qlog.rs":"e320007ea8309546b26f9c0019ab8722da80dbd38fa976233fd8ae19a0af637c","src/qpack_send_buf.rs":"755af90fe077b1bcca34a1a2a1bdce5ce601ea490b2ca3f1313e0107d13e67e2","src/reader.rs":"1581261741a0922b147a6975cc8b1a3503846f6dbfdb771d254760c298996982","src/static_table.rs":"fda9d5c6f38f94b0bf92d3afdf8432dce6e27e189736596e16727090c77b78ec","src/stats.rs":"624dfa3b40858c304097bb0ce5b1be1bb4d7916b1abfc222f1aa705907009730","src/table.rs":"ddf055a228bed575d640d9a06e19e1e9fd98a48e393a7d326f8254438fb94889"},"package":null}
|
||||
{"files":{"Cargo.toml":"5179aa8414e078471cfdc7318b7bb36161fef0f74939b7b871f7e451b18e772c","src/decoder.rs":"510f1b597e1b1a05aa8e835ca6cfa8ae8450cc81ea947edf3ee5568c378ee797","src/decoder_instructions.rs":"87cabf7b19e7c66736fb38b5c037d21d1b3c14a816f1a663c523a679cff1ef82","src/encoder.rs":"4453eca4dbdcf21e8b8c847c86ba1dc3455985d461efa024319da39719cde6be","src/encoder_instructions.rs":"e4bae7510f5bea691e8089581d26128a34b733a85d4277d9eb47f16838a01b5e","src/header_block.rs":"b89c508d85622716f9b82b951767c70b0ff1bda21aaeb66f9b4a59e2252ba9af","src/huffman.rs":"4bafbcb6db099e6c18c480d4d5eb98669957aed2102c4f1bdf8f0e928c723e65","src/huffman_decode_helper.rs":"9ce470e318b3664f58aa109bed483ab15bfd9e0b17d261ea2b609668a42a9d80","src/huffman_table.rs":"06fea766a6276ac56c7ee0326faed800a742c15fda1f33bf2513e6cc6a5e6d27","src/lib.rs":"f9bad0fe7643c618d034c4941ebd30ad5f6015b8b87b484b0ea79681d13d8b49","src/prefix.rs":"5ef50ae0cef68097a3061c9c38fb264e7a14a5658d35591687d1165a4219bc18","src/qlog.rs":"fbd96ef7d21db2bae19b8e379995544e8cf123e8e5129c1500ace2773acf5649","src/qpack_send_buf.rs":"e207e464b3063421b984ffb7eb4c7f90142e763e5f8c7e0d5aa1bd3614e9d6bd","src/reader.rs":"c23214ba190c7a59e416eaffac612ff8c2043c3a84e884fb10ae3bc112d884a5","src/static_table.rs":"6e5ec26e2b6bd63375d2d77e72748151d430d1629a8e497ec0d0ea21c078524a","src/stats.rs":"624dfa3b40858c304097bb0ce5b1be1bb4d7916b1abfc222f1aa705907009730","src/table.rs":"2d2c9e6070a1e90048a4ad7c8279f9e1ce7615b44d7d8145fb0f140e554f5ca2"},"package":null}
|
|
@ -13,12 +13,29 @@
|
|||
edition = "2021"
|
||||
rust-version = "1.76.0"
|
||||
name = "neqo-qpack"
|
||||
version = "0.7.9"
|
||||
version = "0.8.1"
|
||||
authors = ["The Neqo Authors <necko@mozilla.com>"]
|
||||
description = "Neqo, the Mozilla implementation of QUIC in Rust."
|
||||
homepage = "https://github.com/mozilla/neqo/"
|
||||
readme = "../README.md"
|
||||
keywords = [
|
||||
"quic",
|
||||
"http3",
|
||||
"neqo",
|
||||
"mozilla",
|
||||
"ietf",
|
||||
"firefox",
|
||||
]
|
||||
categories = [
|
||||
"network-programming",
|
||||
"web-programming",
|
||||
]
|
||||
license = "MIT OR Apache-2.0"
|
||||
repository = "https://github.com/mozilla/neqo/"
|
||||
|
||||
[package.metadata.cargo-machete]
|
||||
ignored = ["log"]
|
||||
|
||||
[lib]
|
||||
bench = false
|
||||
|
||||
|
@ -29,9 +46,6 @@ default-features = false
|
|||
[dependencies.neqo-common]
|
||||
path = "./../neqo-common"
|
||||
|
||||
[dependencies.neqo-crypto]
|
||||
path = "./../neqo-crypto"
|
||||
|
||||
[dependencies.neqo-transport]
|
||||
path = "./../neqo-transport"
|
||||
|
||||
|
@ -46,6 +60,17 @@ default-features = false
|
|||
[dev-dependencies.test-fixture]
|
||||
path = "../test-fixture"
|
||||
|
||||
[lints.clippy]
|
||||
multiple_crate_versions = "allow"
|
||||
|
||||
[lints.clippy.cargo]
|
||||
level = "warn"
|
||||
priority = -1
|
||||
|
||||
[lints.clippy.nursery]
|
||||
level = "warn"
|
||||
priority = -1
|
||||
|
||||
[lints.clippy.pedantic]
|
||||
level = "warn"
|
||||
priority = -1
|
||||
|
|
|
@ -58,12 +58,12 @@ impl QPackDecoder {
|
|||
}
|
||||
|
||||
#[must_use]
|
||||
fn capacity(&self) -> u64 {
|
||||
const fn capacity(&self) -> u64 {
|
||||
self.table.capacity()
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn get_max_table_size(&self) -> u64 {
|
||||
pub const fn get_max_table_size(&self) -> u64 {
|
||||
self.max_table_size
|
||||
}
|
||||
|
||||
|
@ -259,7 +259,7 @@ impl QPackDecoder {
|
|||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn local_stream_id(&self) -> Option<StreamId> {
|
||||
pub const fn local_stream_id(&self) -> Option<StreamId> {
|
||||
self.local_stream_id
|
||||
}
|
||||
|
||||
|
|
|
@ -76,7 +76,7 @@ impl ::std::fmt::Display for DecoderInstructionReader {
|
|||
}
|
||||
|
||||
impl DecoderInstructionReader {
|
||||
pub fn new() -> Self {
|
||||
pub const fn new() -> Self {
|
||||
Self {
|
||||
state: DecoderInstructionReaderState::ReadInstruction,
|
||||
instruction: DecoderInstruction::NoInstruction,
|
||||
|
|
|
@ -31,7 +31,7 @@ enum LocalStreamState {
|
|||
}
|
||||
|
||||
impl LocalStreamState {
|
||||
pub fn stream_id(&self) -> Option<StreamId> {
|
||||
pub const fn stream_id(&self) -> Option<StreamId> {
|
||||
match self {
|
||||
Self::NoStream => None,
|
||||
Self::Uninitialized(stream_id) | Self::Initialized(stream_id) => Some(*stream_id),
|
||||
|
@ -202,11 +202,7 @@ impl QPackEncoder {
|
|||
}
|
||||
}
|
||||
|
||||
fn call_instruction(
|
||||
&mut self,
|
||||
instruction: DecoderInstruction,
|
||||
qlog: &mut NeqoQlog,
|
||||
) -> Res<()> {
|
||||
fn call_instruction(&mut self, instruction: DecoderInstruction, qlog: &NeqoQlog) -> Res<()> {
|
||||
qdebug!([self], "call intruction {:?}", instruction);
|
||||
match instruction {
|
||||
DecoderInstruction::InsertCountIncrement { increment } => {
|
||||
|
@ -344,15 +340,14 @@ impl QPackEncoder {
|
|||
}
|
||||
|
||||
fn is_stream_blocker(&self, stream_id: StreamId) -> bool {
|
||||
if let Some(hb_list) = self.unacked_header_blocks.get(&stream_id) {
|
||||
self.unacked_header_blocks
|
||||
.get(&stream_id)
|
||||
.map_or(false, |hb_list| {
|
||||
debug_assert!(!hb_list.is_empty());
|
||||
match hb_list.iter().flatten().max() {
|
||||
Some(max_ref) => *max_ref >= self.table.get_acked_inserts_cnt(),
|
||||
None => false,
|
||||
}
|
||||
} else {
|
||||
false
|
||||
}
|
||||
hb_list.iter().flatten().max().map_or(false, |max_ref| {
|
||||
*max_ref >= self.table.get_acked_inserts_cnt()
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
/// Encodes headers
|
||||
|
@ -373,9 +368,7 @@ impl QPackEncoder {
|
|||
) -> HeaderEncoder {
|
||||
qdebug!([self], "encoding headers.");
|
||||
|
||||
let mut encoder_blocked = false;
|
||||
// Try to send capacity instructions if present.
|
||||
if self.send_encoder_updates(conn).is_err() {
|
||||
// This code doesn't try to deal with errors, it just tries
|
||||
// to write to the encoder stream AND if it can't uses
|
||||
// literal instructions.
|
||||
|
@ -385,8 +378,7 @@ impl QPackEncoder {
|
|||
// 3) `ClosedCriticalStream` - this is error that should close the HTTP/3 session.
|
||||
// The last 2 errors are ignored here and will be picked up
|
||||
// by the main loop.
|
||||
encoder_blocked = true;
|
||||
}
|
||||
let mut encoder_blocked = self.send_encoder_updates(conn).is_err();
|
||||
|
||||
let mut encoded_h =
|
||||
HeaderEncoder::new(self.table.base(), self.use_huffman, self.max_entries);
|
||||
|
@ -496,12 +488,12 @@ impl QPackEncoder {
|
|||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn local_stream_id(&self) -> Option<StreamId> {
|
||||
pub const fn local_stream_id(&self) -> Option<StreamId> {
|
||||
self.local_stream.stream_id()
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
fn blocked_stream_cnt(&self) -> u16 {
|
||||
const fn blocked_stream_cnt(&self) -> u16 {
|
||||
self.blocked_stream_cnt
|
||||
}
|
||||
}
|
||||
|
|
|
@ -122,7 +122,7 @@ impl ::std::fmt::Display for EncoderInstructionReader {
|
|||
}
|
||||
|
||||
impl EncoderInstructionReader {
|
||||
pub fn new() -> Self {
|
||||
pub const fn new() -> Self {
|
||||
Self {
|
||||
state: EncoderInstructionReaderState::ReadInstruction,
|
||||
instruction: DecodedEncoderInstruction::NoInstruction,
|
||||
|
|
|
@ -25,7 +25,7 @@ use crate::{
|
|||
Error, Res,
|
||||
};
|
||||
|
||||
#[derive(Default, Debug, PartialEq)]
|
||||
#[derive(Default, Debug, PartialEq, Eq)]
|
||||
pub struct HeaderEncoder {
|
||||
buf: QpackData,
|
||||
base: u64,
|
||||
|
@ -172,7 +172,7 @@ impl Deref for HeaderEncoder {
|
|||
}
|
||||
}
|
||||
|
||||
pub(crate) struct HeaderDecoder<'a> {
|
||||
pub struct HeaderDecoder<'a> {
|
||||
buf: ReceiverBufferWrapper<'a>,
|
||||
base: u64,
|
||||
req_insert_cnt: u64,
|
||||
|
@ -191,7 +191,7 @@ pub enum HeaderDecoderResult {
|
|||
}
|
||||
|
||||
impl<'a> HeaderDecoder<'a> {
|
||||
pub fn new(buf: &'a [u8]) -> Self {
|
||||
pub const fn new(buf: &'a [u8]) -> Self {
|
||||
Self {
|
||||
buf: ReceiverBufferWrapper::new(buf),
|
||||
base: 0,
|
||||
|
@ -278,7 +278,7 @@ impl<'a> HeaderDecoder<'a> {
|
|||
Ok(HeaderDecoderResult::Headers(h))
|
||||
}
|
||||
|
||||
pub fn get_req_insert_cnt(&self) -> u64 {
|
||||
pub const fn get_req_insert_cnt(&self) -> u64 {
|
||||
self.req_insert_cnt
|
||||
}
|
||||
|
||||
|
|
|
@ -17,7 +17,7 @@ struct BitReader<'a> {
|
|||
}
|
||||
|
||||
impl<'a> BitReader<'a> {
|
||||
pub fn new(input: &'a [u8]) -> Self {
|
||||
pub const fn new(input: &'a [u8]) -> Self {
|
||||
BitReader {
|
||||
input,
|
||||
offset: 0,
|
||||
|
@ -60,7 +60,7 @@ impl<'a> BitReader<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn has_more_data(&self) -> bool {
|
||||
pub const fn has_more_data(&self) -> bool {
|
||||
!self.input.is_empty() && (self.offset != self.input.len() || (self.current_bit != 0))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -64,7 +64,7 @@ pub enum Error {
|
|||
|
||||
impl Error {
|
||||
#[must_use]
|
||||
pub fn code(&self) -> neqo_transport::AppError {
|
||||
pub const fn code(&self) -> neqo_transport::AppError {
|
||||
match self {
|
||||
Self::DecompressionFailed => 0x200,
|
||||
Self::EncoderStream => 0x201,
|
||||
|
|
|
@ -33,15 +33,15 @@ impl Prefix {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn len(self) -> u8 {
|
||||
pub const fn len(self) -> u8 {
|
||||
self.len
|
||||
}
|
||||
|
||||
pub fn prefix(self) -> u8 {
|
||||
pub const fn prefix(self) -> u8 {
|
||||
self.prefix
|
||||
}
|
||||
|
||||
pub fn cmp_prefix(self, b: u8) -> bool {
|
||||
pub const fn cmp_prefix(self, b: u8) -> bool {
|
||||
(b & self.mask) == self.prefix
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,11 +12,7 @@ use qlog::events::{
|
|||
EventData, RawInfo,
|
||||
};
|
||||
|
||||
pub fn qpack_read_insert_count_increment_instruction(
|
||||
qlog: &mut NeqoQlog,
|
||||
increment: u64,
|
||||
data: &[u8],
|
||||
) {
|
||||
pub fn qpack_read_insert_count_increment_instruction(qlog: &NeqoQlog, increment: u64, data: &[u8]) {
|
||||
qlog.add_event_data(|| {
|
||||
let raw = RawInfo {
|
||||
length: Some(8),
|
||||
|
|
Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше
Загрузка…
Ссылка в новой задаче