Skip to content

Commit

Permalink
Merge branch 'main' into quic-address-discovery
Browse files Browse the repository at this point in the history
  • Loading branch information
divagant-martian authored Nov 21, 2024
2 parents b0f0a30 + a4c886c commit eaa83bc
Show file tree
Hide file tree
Showing 27 changed files with 180 additions and 100 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/codecov.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ jobs:
- uses: taiki-e/install-action@cargo-llvm-cov
- run: cargo llvm-cov --all-features --workspace --lcov --output-path lcov.info
- name: Upload coverage to Codecov
uses: codecov/codecov-action@v4
uses: codecov/codecov-action@v5
with:
token: ${{ secrets.CODECOV_TOKEN }}
files: lcov.info
Expand Down
28 changes: 23 additions & 5 deletions .github/workflows/rust.yml
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,28 @@ jobs:
cargo build --all-targets && cargo test && cargo test --manifest-path fuzz/Cargo.toml && cargo test -p quinn-udp --benches
test-solaris:
name: test on solaris
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: test on Solaris
uses: vmactions/solaris-vm@v1
with:
release: "11.4-gcc"
usesh: true
mem: 4096
copyback: false
prepare: |
source <(curl -s https://raw.githubusercontent.com/psumbera/solaris-rust/refs/heads/main/sh.rust-web-install)
echo "~~~~ rustc --version ~~~~"
rustc --version
echo "~~~~ Solaris-version ~~~~"
uname -a
run: |
export PATH=$HOME/.rust_solaris/bin:$PATH
cargo build --all-targets && cargo test && cargo test --manifest-path fuzz/Cargo.toml && cargo test -p quinn-udp --benches
test:
strategy:
matrix:
Expand Down Expand Up @@ -121,11 +143,6 @@ jobs:

- name: Install cargo binstall
uses: cargo-bins/cargo-binstall@main

# We need to downgrade cc to version 1.1.31 for ring Wasm compilation to work.
# See the upstream issue https://github.com/rust-lang/cc-rs/issues/1275
- name: Use working `cc` version 1.1.31
run: cargo update -p cc --precise 1.1.31

- name: build wasm32 tests (quinn-proto)
run: cargo test -p quinn-proto --target wasm32-unknown-unknown --no-run
Expand All @@ -146,6 +163,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
# Note that we must also update the README when changing the MSRV
- uses: dtolnay/[email protected]
- uses: Swatinem/rust-cache@v2
- run: cargo check --lib --all-features -p quinn-udp -p quinn-proto -p quinn
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ The project was founded by [Dirkjan Ochtman](https://github.com/djc) and
[rustls][rustls] and [*ring*][ring]
- Application-layer datagrams for small, unreliable messages
- Future-based async API
- Minimum supported Rust version of 1.66
- Minimum supported Rust version of 1.70

## Overview

Expand Down
2 changes: 1 addition & 1 deletion deny.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ allow = [
"MIT",
"MPL-2.0",
"OpenSSL",
"Unicode-DFS-2016",
"Unicode-3.0",
]
private = { ignore = true }

Expand Down
2 changes: 1 addition & 1 deletion perf/src/bin/perf_client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -308,7 +308,7 @@ async fn request(

let send_stream_stats = stream_stats.new_sender(&send, upload);

const DATA: [u8; 1024 * 1024] = [42; 1024 * 1024];
static DATA: [u8; 1024 * 1024] = [42; 1024 * 1024];
while upload > 0 {
let chunk_len = upload.min(DATA.len() as u64);
send.write_chunk(Bytes::from_static(&DATA[..chunk_len as usize]))
Expand Down
2 changes: 1 addition & 1 deletion perf/src/bin/perf_server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -215,7 +215,7 @@ async fn drain_stream(mut stream: quinn::RecvStream) -> Result<()> {
}

async fn respond(mut bytes: u64, mut stream: quinn::SendStream) -> Result<()> {
const DATA: [u8; 1024 * 1024] = [42; 1024 * 1024];
static DATA: [u8; 1024 * 1024] = [42; 1024 * 1024];

while bytes > 0 {
let chunk_len = bytes.min(DATA.len() as u64);
Expand Down
9 changes: 5 additions & 4 deletions quinn-proto/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "quinn-proto"
version = "0.11.9"
version = "0.11.10"
edition.workspace = true
rust-version.workspace = true
license.workspace = true
Expand All @@ -10,9 +10,6 @@ keywords.workspace = true
categories.workspace = true
workspace = ".."

[package.metadata.docs.rs]
all-features = true

[features]
default = ["rustls-ring", "log"]
aws-lc-rs = ["dep:aws-lc-rs", "aws-lc-rs?/aws-lc-sys", "aws-lc-rs?/prebuilt-nasm"]
Expand Down Expand Up @@ -66,3 +63,7 @@ wasm-bindgen-test = { workspace = true }
[lints.rust]
# https://rust-fuzz.github.io/book/cargo-fuzz/guide.html#cfgfuzzing
unexpected_cfgs = { level = "warn", check-cfg = ['cfg(fuzzing)'] }

[package.metadata.docs.rs]
# all non-default features except fips (cannot build on docs.rs environment)
features = ["rustls-aws-lc-rs", "rustls-ring", "platform-verifier", "log", "rustls-log"]
4 changes: 1 addition & 3 deletions quinn-proto/src/connection/ack_frequency.rs
Original file line number Diff line number Diff line change
Expand Up @@ -121,9 +121,7 @@ impl AckFrequencyState {
) -> Result<bool, TransportError> {
if self
.last_ack_frequency_frame
.map_or(false, |highest_sequence_nr| {
frame.sequence.into_inner() <= highest_sequence_nr
})
.is_some_and(|highest_sequence_nr| frame.sequence.into_inner() <= highest_sequence_nr)
{
return Ok(false);
}
Expand Down
42 changes: 28 additions & 14 deletions quinn-proto/src/connection/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ use crate::{
token::ResetToken,
transport_parameters::TransportParameters,
Dir, Duration, EndpointConfig, Frame, Instant, Side, StreamId, Transmit, TransportError,
TransportErrorCode, VarInt, MAX_CID_SIZE, MAX_STREAM_COUNT, MIN_INITIAL_SIZE,
TransportErrorCode, VarInt, INITIAL_MTU, MAX_CID_SIZE, MAX_STREAM_COUNT, MIN_INITIAL_SIZE,
TIMER_GRANULARITY,
};

Expand Down Expand Up @@ -700,13 +700,21 @@ impl Connection {
// waste large amounts of bandwidth. The exact threshold is a bit arbitrary
// and might benefit from further tuning, though there's no universally
// optimal value.
//
// Additionally, if this datagram is a loss probe and `segment_size` is
// larger than `INITIAL_MTU`, then padding it to `segment_size` to continue
// the GSO batch would risk failure to recover from a reduction in path
// MTU. Loss probes are the only packets for which we might grow
// `buf_capacity` by less than `segment_size`.
const MAX_PADDING: usize = 16;
let packet_len_unpadded = cmp::max(builder.min_size, buf.len())
- datagram_start
+ builder.tag_len;
if packet_len_unpadded + MAX_PADDING < segment_size {
if packet_len_unpadded + MAX_PADDING < segment_size
|| datagram_start + segment_size > buf_capacity
{
trace!(
"GSO truncated by demand for {} padding bytes",
"GSO truncated by demand for {} padding bytes or loss probe",
segment_size - packet_len_unpadded
);
builder_storage = Some(builder);
Expand Down Expand Up @@ -749,7 +757,17 @@ impl Connection {
}

// Allocate space for another datagram
buf_capacity += segment_size;
let next_datagram_size_limit = match self.spaces[space_id].loss_probes {
0 => segment_size,
_ => {
self.spaces[space_id].loss_probes -= 1;
// Clamp the datagram to at most the minimum MTU to ensure that loss probes
// can get through and enable recovery even if the path MTU has shrank
// unexpectedly.
usize::from(INITIAL_MTU)
}
};
buf_capacity += next_datagram_size_limit;
if buf.capacity() < buf_capacity {
// We reserve the maximum space for sending `max_datagrams` upfront
// to avoid any reallocations if more datagrams have to be appended later on.
Expand Down Expand Up @@ -963,14 +981,10 @@ impl Connection {
// Send MTU probe if necessary
if buf.is_empty() && self.state.is_established() {
let space_id = SpaceId::Data;
let probe_size = match self
let probe_size = self
.path
.mtud
.poll_transmit(now, self.packet_number_filter.peek(&self.spaces[space_id]))
{
Some(next_probe_size) => next_probe_size,
None => return None,
};
.poll_transmit(now, self.packet_number_filter.peek(&self.spaces[space_id]))?;

let buf_capacity = probe_size as usize;
buf.reserve(buf_capacity);
Expand Down Expand Up @@ -1645,7 +1659,7 @@ impl Connection {
None if self
.path
.first_packet_after_rtt_sample
.map_or(false, |x| x < (pn_space, packet)) =>
.is_some_and(|x| x < (pn_space, packet)) =>
{
persistent_congestion_start = Some(info.time_sent);
}
Expand Down Expand Up @@ -2220,7 +2234,7 @@ impl Connection {
let _guard = span.enter();

let is_duplicate = |n| self.spaces[packet.header.space()].dedup.insert(n);
if number.map_or(false, is_duplicate) {
if number.is_some_and(is_duplicate) {
debug!("discarding possible duplicate packet");
return;
} else if self.state.is_handshake() && packet.header.is_short() {
Expand Down Expand Up @@ -3640,13 +3654,13 @@ impl Connection {
|| self
.prev_path
.as_ref()
.map_or(false, |(_, x)| x.challenge_pending)
.is_some_and(|(_, x)| x.challenge_pending)
|| !self.path_responses.is_empty()
|| self
.datagrams
.outgoing
.front()
.map_or(false, |x| x.size(true) <= max_size)
.is_some_and(|x| x.size(true) <= max_size)
}

/// Update counters to account for a packet becoming acknowledged, lost, or abandoned
Expand Down
2 changes: 1 addition & 1 deletion quinn-proto/src/connection/mtud.rs
Original file line number Diff line number Diff line change
Expand Up @@ -417,7 +417,7 @@ impl BlackHoleDetector {
let end_last_burst = self
.current_loss_burst
.as_ref()
.map_or(false, |current| pn - current.latest_non_probe != 1);
.is_some_and(|current| pn - current.latest_non_probe != 1);

if end_last_burst {
self.finish_loss_burst();
Expand Down
13 changes: 2 additions & 11 deletions quinn-proto/src/connection/packet_builder.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
use std::cmp;

use bytes::Bytes;
use rand::Rng;
use tracing::{trace, trace_span};
Expand All @@ -8,7 +6,7 @@ use super::{spaces::SentPacket, Connection, SentFrames};
use crate::{
frame::{self, Close},
packet::{Header, InitialHeader, LongType, PacketNumber, PartialEncode, SpaceId, FIXED_BIT},
ConnectionId, Instant, TransportError, TransportErrorCode, INITIAL_MTU,
ConnectionId, Instant, TransportError, TransportErrorCode,
};

pub(super) struct PacketBuilder {
Expand Down Expand Up @@ -38,7 +36,7 @@ impl PacketBuilder {
space_id: SpaceId,
dst_cid: ConnectionId,
buffer: &mut Vec<u8>,
mut buffer_capacity: usize,
buffer_capacity: usize,
datagram_start: usize,
ack_eliciting: bool,
conn: &mut Connection,
Expand Down Expand Up @@ -79,13 +77,6 @@ impl PacketBuilder {
}

let space = &mut conn.spaces[space_id];

if space.loss_probes != 0 {
space.loss_probes -= 1;
// Clamp the packet size to at most the minimum MTU to ensure that loss probes can get
// through and enable recovery even if the path MTU has shrank unexpectedly.
buffer_capacity = cmp::min(buffer_capacity, datagram_start + usize::from(INITIAL_MTU));
}
let exact_number = match space_id {
SpaceId::Data => conn.packet_number_filter.allocate(&mut conn.rng, space),
_ => space.get_tx_number(),
Expand Down
2 changes: 1 addition & 1 deletion quinn-proto/src/connection/packet_crypto.rs
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ pub(super) fn decrypt_packet_body(

if crypto_update {
// Validate incoming key update
if number <= rx_packet || prev_crypto.map_or(false, |x| x.update_unacked) {
if number <= rx_packet || prev_crypto.is_some_and(|x| x.update_unacked) {
return Err(Some(TransportError::KEY_UPDATE_ERROR("")));
}
}
Expand Down
4 changes: 2 additions & 2 deletions quinn-proto/src/connection/spaces.rs
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ impl PacketSpace {

/// Queue data for a tail loss probe (or anti-amplification deadlock prevention) packet
///
/// Probes are sent similarly to normal packets when an expect ACK has not arrived. We never
/// Probes are sent similarly to normal packets when an expected ACK has not arrived. We never
/// deem a packet lost until we receive an ACK that should have included it, but if a trailing
/// run of packets (or their ACKs) are lost, this might not happen in a timely fashion. We send
/// probe packets to force an ACK, and exempt them from congestion control to prevent a deadlock
Expand Down Expand Up @@ -856,7 +856,7 @@ impl PacketNumberFilter {
if space_id == SpaceId::Data
&& self
.prev_skipped_packet_number
.map_or(false, |x| range.contains(&x))
.is_some_and(|x| range.contains(&x))
{
return Err(TransportError::PROTOCOL_VIOLATION("unsent packet acked"));
}
Expand Down
4 changes: 2 additions & 2 deletions quinn-proto/src/connection/streams/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -396,7 +396,7 @@ impl StreamsState {
self.send
.get(&stream.id)
.and_then(|s| s.as_ref())
.map_or(false, |s| !s.is_reset())
.is_some_and(|s| !s.is_reset())
})
}

Expand All @@ -406,7 +406,7 @@ impl StreamsState {
.get(&id)
.and_then(|s| s.as_ref())
.and_then(|s| s.as_open_recv())
.map_or(false, |s| s.can_send_flow_control())
.is_some_and(|s| s.can_send_flow_control())
}

pub(in crate::connection) fn write_control_frames(
Expand Down
2 changes: 1 addition & 1 deletion quinn-proto/src/connection/timer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,6 @@ impl TimerTable {
}

pub(super) fn is_expired(&self, timer: Timer, after: Instant) -> bool {
self.data[timer as usize].map_or(false, |x| x <= after)
self.data[timer as usize].is_some_and(|x| x <= after)
}
}
Loading

0 comments on commit eaa83bc

Please sign in to comment.