Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update to draft 32 #879

Merged
merged 5 commits into from
Oct 31, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ Quinn was created and is maintained by Dirkjan Ochtman and Benjamin Saunders.

## Status

- [x] QUIC draft 27 with TLS 1.3
- [x] QUIC draft 32 with TLS 1.3
- [x] Cryptographic handshake
- [x] Stream data w/ flow control and congestion control
- [x] Connection close
Expand Down
27 changes: 8 additions & 19 deletions quinn-proto/src/connection/mod.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
use std::{
cmp,
collections::{BTreeMap, VecDeque},
convert::TryInto,
fmt, io, mem,
net::SocketAddr,
sync::Arc,
Expand All @@ -20,6 +19,7 @@ use crate::{
crypto::{self, HeaderKey, KeyPair, Keys, PacketKey},
frame,
frame::{Close, Datagram, FrameStruct},
is_supported_version,
packet::{Header, LongType, Packet, PacketNumber, PartialDecode, PartialEncode, SpaceId},
range_set::RangeSet,
shared::{
Expand All @@ -29,7 +29,7 @@ use crate::{
transport_parameters::TransportParameters,
Dir, Frame, Side, StreamId, Transmit, TransportError, TransportErrorCode, VarInt,
LOC_CID_COUNT, MAX_STREAM_COUNT, MIN_INITIAL_SIZE, MIN_MTU, RESET_TOKEN_SIZE,
TIMER_GRANULARITY, VERSION,
TIMER_GRANULARITY,
};

mod assembler;
Expand Down Expand Up @@ -378,11 +378,11 @@ where

let mut buf = Vec::with_capacity(self.mtu as usize);
let mut coalesce = spaces.len() > 1;
let pad_space = if self.side.is_client() && spaces.first() == Some(&SpaceId::Initial) {
spaces.last().cloned()
} else {
None
};
let pad_space = spaces.last().cloned().filter(|_| {
self.side.is_client() && spaces.first() == Some(&SpaceId::Initial)
|| self.path.challenge.is_some()
|| self.path_response.is_some()
});

for space_id in spaces {
let buf_start = buf.len();
Expand Down Expand Up @@ -2092,11 +2092,7 @@ where
if self.total_authed_packets > 1 {
return Ok(());
}
if packet
.payload
.chunks(4)
.any(|chunk| u32::from_be_bytes(chunk.try_into().unwrap()) == VERSION)
{
if packet.payload.chunks(4).any(is_supported_version) {
return Ok(());
}
debug!("remote doesn't support our version");
Expand Down Expand Up @@ -2746,13 +2742,6 @@ where
"CID authentication failure",
));
}
if params.initial_max_streams_bidi.0 > MAX_STREAM_COUNT
|| params.initial_max_streams_uni.0 > MAX_STREAM_COUNT
{
return Err(TransportError::STREAM_LIMIT_ERROR(
"unrepresentable initial stream limit",
));
}

Ok(())
}
Expand Down
4 changes: 2 additions & 2 deletions quinn-proto/src/crypto/rustls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -378,7 +378,7 @@ impl crypto::PacketKey for PacketKey {
fn confidentiality_limit(&self) -> u64 {
let cipher = self.key.algorithm();
if cipher == &aead::AES_128_GCM || cipher == &aead::AES_256_GCM {
2u64.pow(25)
2u64.pow(23)
} else if cipher == &aead::CHACHA20_POLY1305 {
u64::MAX
} else {
Expand All @@ -389,7 +389,7 @@ impl crypto::PacketKey for PacketKey {
fn integrity_limit(&self) -> u64 {
let cipher = self.key.algorithm();
if cipher == &aead::AES_128_GCM || cipher == &aead::AES_256_GCM {
2u64.pow(54)
2u64.pow(52)
} else if cipher == &aead::CHACHA20_POLY1305 {
2u64.pow(36)
} else {
Expand Down
2 changes: 1 addition & 1 deletion quinn-proto/src/endpoint.rs
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,7 @@ where
} else {
buf.write::<u32>(0x0a1a_2a4a);
}
buf.write(VERSION); // supported version
buf.write(*VERSION.start()); // supported version
self.transmits.push_back(Transmit {
destination: remote,
ecn: None,
Expand Down
10 changes: 8 additions & 2 deletions quinn-proto/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
#![allow(clippy::cognitive_complexity)]
#![allow(clippy::too_many_arguments)]

use std::{fmt, net::SocketAddr, ops, time::Duration};
use std::{convert::TryInto, fmt, net::SocketAddr, ops, time::Duration};

mod cid_queue;
#[doc(hidden)]
Expand Down Expand Up @@ -116,8 +116,14 @@ pub mod fuzzing {
}
}
}

/// The QUIC protocol version implemented
const VERSION: u32 = 0xff00_001d;
const VERSION: std::ops::RangeInclusive<u32> = 0xff00_001d..=0xff00_0020;

/// Whether a 4-byte slice represents a supported version number
fn is_supported_version(x: &[u8]) -> bool {
VERSION.contains(&u32::from_be_bytes(x.try_into().unwrap()))
}

/// Whether an endpoint was the initiator of a connection
#[cfg_attr(feature = "arbitrary", derive(Arbitrary))]
Expand Down
8 changes: 4 additions & 4 deletions quinn-proto/src/packet.rs
Original file line number Diff line number Diff line change
Expand Up @@ -254,7 +254,7 @@ impl Header {
number,
} => {
w.write(u8::from(LongHeaderType::Initial) | number.tag());
w.write(VERSION);
w.write(*VERSION.start());
dst_cid.encode_long(w);
src_cid.encode_long(w);
w.write_var(token.len() as u64);
Expand All @@ -274,7 +274,7 @@ impl Header {
number,
} => {
w.write(u8::from(LongHeaderType::Standard(ty)) | number.tag());
w.write(VERSION);
w.write(*VERSION.start());
dst_cid.encode_long(w);
src_cid.encode_long(w);
w.write::<u16>(0); // Placeholder for payload length; see `set_payload_length`
Expand All @@ -290,7 +290,7 @@ impl Header {
ref src_cid,
} => {
w.write(u8::from(LongHeaderType::Retry));
w.write(VERSION);
w.write(*VERSION.start());
dst_cid.encode_long(w);
src_cid.encode_long(w);
PartialEncode {
Expand Down Expand Up @@ -528,7 +528,7 @@ impl PlainHeader {
});
}

if version != VERSION {
if !VERSION.contains(&version) {
return Err(PacketDecodeError::UnsupportedVersion {
src_cid,
dst_cid,
Expand Down
5 changes: 1 addition & 4 deletions quinn-proto/src/tests/mod.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
use std::{
convert::TryInto,
net::{Ipv4Addr, Ipv6Addr, SocketAddr},
sync::Arc,
time::{Duration, Instant},
Expand Down Expand Up @@ -39,9 +38,7 @@ fn version_negotiate_server() {
if let Some(Transmit { contents, .. }) = io {
assert_ne!(contents[0] & 0x80, 0);
assert_eq!(&contents[1..15], hex!("00000000 04 00000000 04 00000000"));
assert!(contents[15..]
.chunks(4)
.any(|x| u32::from_be_bytes(x.try_into().unwrap()) == VERSION));
assert!(contents[15..].chunks(4).any(is_supported_version));
}
assert_matches!(server.poll_transmit(), None);
}
Expand Down
4 changes: 3 additions & 1 deletion quinn-proto/src/transport_parameters.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ use crate::{
config::{EndpointConfig, ServerConfig, TransportConfig},
crypto,
shared::ConnectionId,
ResetToken, Side, TransportError, VarInt, MAX_CID_SIZE, RESET_TOKEN_SIZE,
ResetToken, Side, TransportError, VarInt, MAX_CID_SIZE, MAX_STREAM_COUNT, RESET_TOKEN_SIZE,
};

// Apply a given macro to a list of all the transport parameters having integer types, along with
Expand Down Expand Up @@ -406,6 +406,8 @@ impl TransportParameters {
|| params.max_ack_delay.0 >= 1 << 14
|| params.active_connection_id_limit.0 < 2
|| params.max_udp_payload_size.0 < 1200
|| params.initial_max_streams_bidi.0 > MAX_STREAM_COUNT
|| params.initial_max_streams_uni.0 > MAX_STREAM_COUNT
|| (side.is_server()
&& (params.stateless_reset_token.is_some() || params.preferred_address.is_some()))
{
Expand Down