From 17d93b0844aabcdc4f24fd1911b2094d42a2fcf4 Mon Sep 17 00:00:00 2001 From: Lars Eggert Date: Tue, 21 Nov 2023 17:43:10 +0200 Subject: [PATCH] Add TTL --- Cargo.toml | 5 ++- neqo-client/src/main.rs | 20 ++++++--- neqo-common/src/datagram.rs | 37 ++++++++++------ neqo-helper/src/lib.rs | 44 ++++++++++++++----- neqo-interop/src/main.rs | 32 +++++++++++--- neqo-server/src/main.rs | 31 ++++++++----- neqo-transport/src/connection/mod.rs | 2 +- neqo-transport/src/connection/tests/close.rs | 7 +-- .../src/connection/tests/handshake.rs | 9 ++-- .../src/connection/tests/migration.rs | 4 +- neqo-transport/src/connection/tests/vn.rs | 32 +++++--------- neqo-transport/src/path.rs | 11 +---- neqo-transport/src/server.rs | 4 +- neqo-transport/tests/conn_vectors.rs | 4 +- neqo-transport/tests/connection.rs | 2 - neqo-transport/tests/retry.rs | 23 +++------- neqo-transport/tests/server.rs | 33 +++----------- test-fixture/src/lib.rs | 4 +- 18 files changed, 159 insertions(+), 145 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 08ab196c2e..d6b63b2fc9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,4 +12,7 @@ members = [ ] [patch.crates-io] -nix = { git = "https://github.com/larseggert/nix.git", branch = "feat-tos" } +nix = { path = "./../nix" } +libc = { path = "./../libc" } +#libc = { git = "https://github.com/larseggert/libc.git", branch = "feat-ttl" } +#nix = { git = "https://github.com/larseggert/nix.git", branch = "feat-tos" } diff --git a/neqo-client/src/main.rs b/neqo-client/src/main.rs index 1d0b46601d..1fc1e87a86 100644 --- a/neqo-client/src/main.rs +++ b/neqo-client/src/main.rs @@ -14,6 +14,7 @@ use neqo_crypto::{ constants::{TLS_AES_128_GCM_SHA256, TLS_AES_256_GCM_SHA384, TLS_CHACHA20_POLY1305_SHA256}, init, AuthenticationStatus, Cipher, ResumptionToken, }; +use neqo_helper::{bind, emit_datagram, recv_datagram}; use neqo_http3::{ self, Error, Header, Http3Client, Http3ClientEvent, Http3Parameters, Http3State, Output, Priority, @@ -22,7 +23,6 @@ use neqo_transport::{ CongestionControlAlgorithm, Connection, ConnectionId, ConnectionParameters, EmptyConnectionIdGenerator, Error as TransportError, StreamId, StreamType, Version, }; -use neqo_helper::{bind, emit_datagram, recv_datagram}; use std::{ cell::RefCell, @@ -32,11 +32,12 @@ use std::{ fs::{create_dir_all, File, OpenOptions}, io::{self, ErrorKind, Write}, net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr, ToSocketAddrs, UdpSocket}, + os::fd::AsRawFd, path::PathBuf, process::exit, rc::Rc, str::FromStr, - time::{Duration, Instant}, os::fd::AsRawFd, + time::{Duration, Instant}, }; use structopt::StructOpt; @@ -415,7 +416,8 @@ fn process_loop( } let mut tos = 0; - match recv_datagram(socket.as_raw_fd(), &mut buf[..], &mut tos) { + let mut ttl = 0; + match recv_datagram(socket.as_raw_fd(), &mut buf[..], &mut tos, &mut ttl) { Err(ref err) if err.kind() == ErrorKind::WouldBlock || err.kind() == ErrorKind::Interrupted => {} Err(err) => { @@ -428,7 +430,8 @@ fn process_loop( continue; } if sz > 0 { - let d = Datagram::new(remote, *local_addr, tos, &buf[..sz]); + let d = + Datagram::new_with_tos_and_ttl(remote, *local_addr, tos, ttl, &buf[..sz]); client.process_input(d, Instant::now()); handler.maybe_key_update(client)?; } @@ -864,10 +867,11 @@ mod old { fs::File, io::{ErrorKind, Write}, net::{SocketAddr, UdpSocket}, + os::fd::AsRawFd, path::PathBuf, process::exit, rc::Rc, - time::Instant, os::fd::AsRawFd, + time::Instant, }; use neqo_helper::recv_datagram; @@ -1108,7 +1112,8 @@ mod old { } let mut tos = 0; - match recv_datagram(socket.as_raw_fd(), &mut buf[..], &mut tos) { + let mut ttl = 0; + match recv_datagram(socket.as_raw_fd(), &mut buf[..], &mut tos, &mut ttl) { Err(err) => { if err.kind() != ErrorKind::WouldBlock && err.kind() != ErrorKind::Interrupted { eprintln!("UDP error: {}", err); @@ -1121,7 +1126,8 @@ mod old { continue; } if sz > 0 { - let d = Datagram::new(addr, *local_addr, tos, &buf[..sz]); + let d = + Datagram::new_with_tos_and_ttl(addr, *local_addr, tos, ttl, &buf[..sz]); client.process_input(d, Instant::now()); handler.maybe_key_update(client)?; } diff --git a/neqo-common/src/datagram.rs b/neqo-common/src/datagram.rs index eb7ac66651..6aeeb61d59 100644 --- a/neqo-common/src/datagram.rs +++ b/neqo-common/src/datagram.rs @@ -20,12 +20,6 @@ pub enum IpTosEcn { EcnCe = 0b11, // CE (Congestion Experienced) [RFC3168] } -// impl From for u8 { -// fn from(ecn: IpTosEcn) -> Self { -// ecn as u8 -// } -// } - // DiffServ Codepoints, mapped to the upper six bits of the TOS field. // https://www.iana.org/assignments/dscp-registry/dscp-registry.xhtml // #[derive(Copy, Clone)] @@ -55,26 +49,38 @@ pub enum IpTosDscp { DscpLe = 0b0000_0100, // [RFC8622] } -// impl From for u8 { -// fn from(dscp: IpTosDscp) -> Self { -// (dscp as u8) << 2 -// } -// } - #[derive(PartialEq, Eq, Clone)] pub struct Datagram { src: SocketAddr, dst: SocketAddr, tos: u8, + ttl: u8, d: Vec, } impl Datagram { - pub fn new>>(src: SocketAddr, dst: SocketAddr, tos: u8, d: V) -> Self { + pub fn new>>(src: SocketAddr, dst: SocketAddr, d: V) -> Self { + Self { + src, + dst, + tos: IpTosEcn::EcnEct0 as u8, + ttl: 128, + d: d.into(), + } + } + + pub fn new_with_tos_and_ttl>>( + src: SocketAddr, + dst: SocketAddr, + tos: u8, + ttl: u8, + d: V, + ) -> Self { Self { src, dst, tos, + ttl, d: d.into(), } } @@ -93,6 +99,11 @@ impl Datagram { pub fn tos(&self) -> u8 { self.tos } + + #[must_use] + pub fn ttl(&self) -> u8 { + self.ttl + } } impl Deref for Datagram { diff --git a/neqo-helper/src/lib.rs b/neqo-helper/src/lib.rs index 27cb7dbfe6..f63040aa49 100644 --- a/neqo-helper/src/lib.rs +++ b/neqo-helper/src/lib.rs @@ -15,15 +15,18 @@ use nix::{ errno::Errno::{EAGAIN, EINTR}, sys::socket::{ recvmsg, sendmsg, setsockopt, - sockopt::{IpDontFrag, IpRecvTos, IpTos, Ipv6DontFrag, Ipv6RecvTClass, Ipv6TClass}, + sockopt::{ + IpDontFrag, IpRecvTos, IpRecvTtl, IpTos, IpTtl, Ipv6DontFrag, Ipv6HopLimit, + Ipv6RecvHopLimit, Ipv6RecvTClass, Ipv6TClass, + }, AddressFamily, ControlMessage, ControlMessageOwned, MsgFlags, SockaddrLike, SockaddrStorage, }, }; -use neqo_common::{qdebug, Datagram}; +use neqo_common::Datagram; -// Bind a UDPO socket and set some default socket options. +// Bind a UDP socket and set some default socket options. pub fn bind(local_addr: SocketAddr) -> io::Result { let socket = match UdpSocket::bind(local_addr) { Err(e) => { @@ -45,6 +48,13 @@ pub fn bind(local_addr: SocketAddr) -> io::Result { SocketAddr::V6(..) => setsockopt(&s, Ipv6RecvTClass, &true), }; assert!(res.is_ok()); + // Request IPv4 time-to-live (TTL) and IPv6 hop count + // information for all incoming packets. + let res = match local_addr { + SocketAddr::V4(..) => setsockopt(&s, IpRecvTtl, &true), + SocketAddr::V6(..) => setsockopt(&s, Ipv6RecvHopLimit, &true), + }; + assert!(res.is_ok()); s } }; @@ -58,14 +68,19 @@ fn to_sockaddr(addr: SocketAddr) -> SockaddrStorage { pub fn emit_datagram(fd: i32, d: Datagram) -> io::Result<()> { let iov = [IoSlice::new(&d[..])]; let tos = d.tos() as i32; - let cmsg = match d.destination() { + let ttl = d.ttl() as i32; + let cmsg_tos = match d.destination() { SocketAddr::V4(..) => ControlMessage::IpTos(&tos), SocketAddr::V6(..) => ControlMessage::Ipv6TClass(&tos), }; + let cmsg_ttl = match d.destination() { + SocketAddr::V4(..) => ControlMessage::IpTtl(&ttl), + SocketAddr::V6(..) => ControlMessage::Ipv6HopLimit(&ttl), + }; let sent = sendmsg( fd, &iov, - &[cmsg], + &[cmsg_tos, cmsg_ttl], MsgFlags::empty(), Some(&to_sockaddr(d.destination())), ) @@ -73,7 +88,6 @@ pub fn emit_datagram(fd: i32, d: Datagram) -> io::Result<()> { if sent != d.len() { eprintln!("Unable to send all {} bytes of datagram", d.len()); } - qdebug!("TX TOS {:#04x}", tos); Ok(()) } @@ -99,9 +113,14 @@ fn to_socket_addr(addr: &SockaddrStorage) -> SocketAddr { } } -pub fn recv_datagram(fd: i32, buf: &mut [u8], tos: &mut u8) -> io::Result<(usize, SocketAddr)> { +pub fn recv_datagram( + fd: i32, + buf: &mut [u8], + tos: &mut u8, + ttl: &mut u8, +) -> io::Result<(usize, SocketAddr)> { let mut iov = [IoSliceMut::new(buf)]; - let mut cmsg = cmsg_space!(IpTos, Ipv6TClass); + let mut cmsg = cmsg_space!(IpTos, Ipv6TClass, IpTtl, Ipv6HopLimit); let flags = MsgFlags::empty(); match recvmsg::(fd, &mut iov, Some(&mut cmsg), flags) { @@ -113,13 +132,14 @@ pub fn recv_datagram(fd: i32, buf: &mut [u8], tos: &mut u8) -> io::Result<(usize } Ok(res) => { for cmsg in res.cmsgs() { - *tos = match cmsg { - ControlMessageOwned::IpTos(t) => t, - ControlMessageOwned::Ipv6TClass(t) => t, + match cmsg { + ControlMessageOwned::IpTos(t) => *tos = t, + ControlMessageOwned::Ipv6TClass(t) => *tos = t, + ControlMessageOwned::IpTtl(t) => *ttl = t, + ControlMessageOwned::Ipv6HopLimit(t) => *ttl = t, _ => todo!(), }; } - qdebug!("RX TOS {:#04x}", tos); Ok((res.bytes, to_socket_addr(&res.address.unwrap()))) } } diff --git a/neqo-interop/src/main.rs b/neqo-interop/src/main.rs index 1284fe9f92..ad3385d5c6 100644 --- a/neqo-interop/src/main.rs +++ b/neqo-interop/src/main.rs @@ -132,7 +132,9 @@ fn process_loop( } let mut tos = 0; - let (sz, _) = match recv_datagram(nctx.socket.as_raw_fd(), &mut buf[..], &mut tos) { + let mut ttl = 0; + let (sz, _) = match recv_datagram(nctx.socket.as_raw_fd(), &mut buf[..], &mut tos, &mut ttl) + { Ok(sz) => sz, Err(e) => { return Err(String::from(match e.kind() { @@ -147,7 +149,13 @@ fn process_loop( continue; } if sz > 0 { - let received = Datagram::new(nctx.remote_addr, nctx.local_addr, tos, &buf[..sz]); + let received = Datagram::new_with_tos_and_ttl( + nctx.remote_addr, + nctx.local_addr, + tos, + ttl, + &buf[..sz], + ); client.process_input(received, Instant::now()); } } @@ -294,7 +302,9 @@ fn process_loop_h3( } let mut tos = 0; - let (sz, _) = match recv_datagram(nctx.socket.as_raw_fd(), &mut buf[..], &mut tos) { + let mut ttl = 0; + let (sz, _) = match recv_datagram(nctx.socket.as_raw_fd(), &mut buf[..], &mut tos, &mut ttl) + { Ok(sz) => sz, Err(e) => { return Err(String::from(match e.kind() { @@ -309,7 +319,13 @@ fn process_loop_h3( continue; } if sz > 0 { - let received = Datagram::new(nctx.remote_addr, nctx.local_addr, tos, &buf[..sz]); + let received = Datagram::new_with_tos_and_ttl( + nctx.remote_addr, + nctx.local_addr, + tos, + ttl, + &buf[..sz], + ); handler.h3.process_input(received, Instant::now()); } } @@ -682,7 +698,13 @@ impl Handler for VnHandler { fn rewrite_out(&mut self, d: &Datagram) -> Option { let mut payload = d[..].to_vec(); payload[1] = 0x1a; - Some(Datagram::new(d.source(), d.destination(), d.tos(), payload)) + Some(Datagram::new_with_tos_and_ttl( + d.source(), + d.destination(), + d.tos(), + d.ttl(), + payload, + )) } } diff --git a/neqo-server/src/main.rs b/neqo-server/src/main.rs index c204ecd7e0..5d194ff741 100644 --- a/neqo-server/src/main.rs +++ b/neqo-server/src/main.rs @@ -18,11 +18,12 @@ use std::{ io::Read, mem, net::{SocketAddr, ToSocketAddrs}, + os::fd::AsRawFd, path::PathBuf, process::exit, rc::Rc, str::FromStr, - time::{Duration, Instant}, os::fd::AsRawFd, + time::{Duration, Instant}, }; use mio::{net::UdpSocket, Events, Poll, PollOpt, Ready, Token}; @@ -35,6 +36,7 @@ use neqo_crypto::{ constants::{TLS_AES_128_GCM_SHA256, TLS_AES_256_GCM_SHA384, TLS_CHACHA20_POLY1305_SHA256}, generate_ech_keys, init_db, random, AntiReplay, Cipher, }; +use neqo_helper::{bind, emit_datagram, recv_datagram}; use neqo_http3::{ Error, Http3OrWebTransportStream, Http3Parameters, Http3Server, Http3ServerEvent, StreamId, }; @@ -42,7 +44,6 @@ use neqo_transport::{ server::ValidateAddress, tparams::PreferredAddress, CongestionControlAlgorithm, ConnectionParameters, Output, RandomConnectionIdGenerator, StreamType, Version, }; -use neqo_helper::{bind, emit_datagram, recv_datagram}; use crate::old_https::Http09Server; @@ -551,14 +552,16 @@ fn read_dgram( ) -> Result, io::Error> { let buf = &mut [0u8; 2048]; let mut tos = 0; - let (sz, remote_addr) = match recv_datagram(socket.as_raw_fd(), &mut buf[..], &mut tos) { - Err(ref err) if err.kind() == io::ErrorKind::WouldBlock => return Ok(None), - Err(err) => { - eprintln!("UDP recv error: {:?}", err); - return Err(err); - } - Ok(res) => res, - }; + let mut ttl = 0; + let (sz, remote_addr) = + match recv_datagram(socket.as_raw_fd(), &mut buf[..], &mut tos, &mut ttl) { + Err(ref err) if err.kind() == io::ErrorKind::WouldBlock => return Ok(None), + Err(err) => { + eprintln!("UDP recv error: {:?}", err); + return Err(err); + } + Ok(res) => res, + }; if sz == buf.len() { eprintln!("Might have received more than {} bytes", buf.len()); @@ -568,7 +571,13 @@ fn read_dgram( eprintln!("zero length datagram received?"); Ok(None) } else { - Ok(Some(Datagram::new(remote_addr, *local_address, tos, &buf[..sz]))) + Ok(Some(Datagram::new_with_tos_and_ttl( + remote_addr, + *local_address, + tos, + ttl, + &buf[..sz], + ))) } } diff --git a/neqo-transport/src/connection/mod.rs b/neqo-transport/src/connection/mod.rs index 00a4312767..abb7e590ad 100644 --- a/neqo-transport/src/connection/mod.rs +++ b/neqo-transport/src/connection/mod.rs @@ -1128,7 +1128,7 @@ impl Connection { /// part that we don't have keys for. fn save_datagram(&mut self, cspace: CryptoSpace, d: Datagram, remaining: usize, now: Instant) { let d = if remaining < d.len() { - Datagram::new(d.source(), d.destination(), d.tos(), &d[d.len() - remaining..]) + Datagram::new(d.source(), d.destination(), &d[d.len() - remaining..]) } else { d }; diff --git a/neqo-transport/src/connection/tests/close.rs b/neqo-transport/src/connection/tests/close.rs index bb0e3908ca..a9f1fafa25 100644 --- a/neqo-transport/src/connection/tests/close.rs +++ b/neqo-transport/src/connection/tests/close.rs @@ -9,7 +9,7 @@ use super::{connect, connect_force_idle, default_client, default_server, send_so use crate::tparams::{self, TransportParameter}; use crate::{AppError, ConnectionError, Error, ERROR_APPLICATION_CLOSE}; -use neqo_common::{Datagram, IpTosEcn}; +use neqo_common::Datagram; use std::time::Duration; use test_fixture::{self, addr, now}; @@ -201,9 +201,6 @@ fn stateless_reset_client() { .unwrap(); connect_force_idle(&mut client, &mut server); - client.process_input( - Datagram::new(addr(), addr(), IpTosEcn::EcnEct0 as u8, vec![77; 21]), - now(), - ); + client.process_input(Datagram::new(addr(), addr(), vec![77; 21]), now()); assert_draining(&client, &Error::StatelessReset); } diff --git a/neqo-transport/src/connection/tests/handshake.rs b/neqo-transport/src/connection/tests/handshake.rs index c4df77bba9..5083ee7dcb 100644 --- a/neqo-transport/src/connection/tests/handshake.rs +++ b/neqo-transport/src/connection/tests/handshake.rs @@ -20,7 +20,6 @@ use crate::{ ConnectionError, ConnectionParameters, EmptyConnectionIdGenerator, Error, StreamType, Version, }; -use neqo_common::IpTosEcn; use neqo_common::{event::Provider, qdebug, Datagram}; use neqo_crypto::{ constants::TLS_CHACHA20_POLY1305_SHA256, generate_ech_keys, AuthenticationStatus, @@ -616,7 +615,7 @@ fn corrupted_initial() { .find(|(_, &v)| v != 0) .unwrap(); corrupted[idx] ^= 0x76; - let dgram = Datagram::new(d.source(), d.destination(), d.tos(), corrupted); + let dgram = Datagram::new(d.source(), d.destination(), corrupted); server.process_input(dgram, now()); // The server should have received two packets, // the first should be dropped, the second saved. @@ -712,7 +711,7 @@ fn extra_initial_invalid_cid() { let mut copy = hs.to_vec(); assert_ne!(copy[5], 0); // The DCID should be non-zero length. copy[6] ^= 0xc4; - let dgram_copy = Datagram::new(hs.destination(), hs.source(), hs.tos(), copy); + let dgram_copy = Datagram::new(hs.destination(), hs.source(), copy); let nothing = client.process(Some(dgram_copy), now).dgram(); assert!(nothing.is_none()); } @@ -815,7 +814,7 @@ fn garbage_initial() { let mut corrupted = Vec::from(&initial[..initial.len() - 1]); corrupted.push(initial[initial.len() - 1] ^ 0xb7); corrupted.extend_from_slice(rest.as_ref().map_or(&[], |r| &r[..])); - let garbage = Datagram::new(addr(), addr(), IpTosEcn::EcnEct0 as u8, corrupted); + let garbage = Datagram::new(addr(), addr(), corrupted); assert_eq!(Output::None, server.process(Some(garbage), now())); } @@ -833,7 +832,6 @@ fn drop_initial_packet_from_wrong_address() { let dgram = Datagram::new( SocketAddr::new(IpAddr::V6(Ipv6Addr::new(0xfe80, 0, 0, 0, 0, 0, 0, 2)), 443), p.destination(), - IpTosEcn::EcnEct0 as u8, &p[..], ); @@ -860,7 +858,6 @@ fn drop_handshake_packet_from_wrong_address() { let dgram = Datagram::new( SocketAddr::new(IpAddr::V6(Ipv6Addr::new(0xfe80, 0, 0, 0, 0, 0, 0, 2)), 443), p.destination(), - IpTosEcn::EcnEct0 as u8, &p[..], ); diff --git a/neqo-transport/src/connection/tests/migration.rs b/neqo-transport/src/connection/tests/migration.rs index 64ed50ba5d..9d662da0b8 100644 --- a/neqo-transport/src/connection/tests/migration.rs +++ b/neqo-transport/src/connection/tests/migration.rs @@ -52,7 +52,7 @@ fn loopback() -> SocketAddr { } fn change_path(d: &Datagram, a: SocketAddr) -> Datagram { - Datagram::new(a, a, d.tos(), &d[..]) + Datagram::new(a, a, &d[..]) } fn new_port(a: SocketAddr) -> SocketAddr { @@ -61,7 +61,7 @@ fn new_port(a: SocketAddr) -> SocketAddr { } fn change_source_port(d: &Datagram) -> Datagram { - Datagram::new(new_port(d.source()), d.destination(), d.tos(), &d[..]) + Datagram::new(new_port(d.source()), d.destination(), &d[..]) } /// As these tests use a new path, that path often has a non-zero RTT. diff --git a/neqo-transport/src/connection/tests/vn.rs b/neqo-transport/src/connection/tests/vn.rs index 3ed0981b42..416128f74e 100644 --- a/neqo-transport/src/connection/tests/vn.rs +++ b/neqo-transport/src/connection/tests/vn.rs @@ -13,7 +13,7 @@ use crate::packet::PACKET_BIT_LONG; use crate::tparams::{self, TransportParameter}; use crate::{ConnectionParameters, Error, Version}; -use neqo_common::{event::Provider, Datagram, Decoder, Encoder, IpTosEcn}; +use neqo_common::{event::Provider, Datagram, Decoder, Encoder}; use std::mem; use std::time::Duration; use test_fixture::{self, addr, assertions, now}; @@ -30,12 +30,7 @@ fn unknown_version() { let mut unknown_version_packet = vec![0x80, 0x1a, 0x1a, 0x1a, 0x1a]; unknown_version_packet.resize(1200, 0x0); mem::drop(client.process( - Some(Datagram::new( - addr(), - addr(), - IpTosEcn::EcnEct0 as u8, - unknown_version_packet, - )), + Some(Datagram::new(addr(), addr(), unknown_version_packet)), now(), )); assert_eq!(1, client.stats().dropped_rx); @@ -50,12 +45,7 @@ fn server_receive_unknown_first_packet() { assert_eq!( server.process( - Some(Datagram::new( - addr(), - addr(), - IpTosEcn::EcnEct0 as u8, - unknown_version_packet, - )), + Some(Datagram::new(addr(), addr(), unknown_version_packet,)), now(), ), Output::None @@ -96,7 +86,7 @@ fn version_negotiation_current_version() { &[0x1a1a_1a1a, Version::default().wire_version()], ); - let dgram = Datagram::new(addr(), addr(), IpTosEcn::EcnEct0 as u8, vn); + let dgram = Datagram::new(addr(), addr(), vn); let delay = client.process(Some(dgram), now()).callback(); assert_eq!(delay, INITIAL_PTO); assert_eq!(*client.state(), State::WaitInitial); @@ -115,7 +105,7 @@ fn version_negotiation_version0() { let vn = create_vn(&initial_pkt, &[0, 0x1a1a_1a1a]); - let dgram = Datagram::new(addr(), addr(), IpTosEcn::EcnEct0 as u8, vn); + let dgram = Datagram::new(addr(), addr(), vn); let delay = client.process(Some(dgram), now()).callback(); assert_eq!(delay, INITIAL_PTO); assert_eq!(*client.state(), State::WaitInitial); @@ -134,7 +124,7 @@ fn version_negotiation_only_reserved() { let vn = create_vn(&initial_pkt, &[0x1a1a_1a1a, 0x2a2a_2a2a]); - let dgram = Datagram::new(addr(), addr(), IpTosEcn::EcnEct0 as u8, vn); + let dgram = Datagram::new(addr(), addr(), vn); assert_eq!(client.process(Some(dgram), now()), Output::None); match client.state() { State::Closed(err) => { @@ -156,7 +146,7 @@ fn version_negotiation_corrupted() { let vn = create_vn(&initial_pkt, &[0x1a1a_1a1a, 0x2a2a_2a2a]); - let dgram = Datagram::new(addr(), addr(), IpTosEcn::EcnEct0 as u8, &vn[..vn.len() - 1]); + let dgram = Datagram::new(addr(), addr(), &vn[..vn.len() - 1]); let delay = client.process(Some(dgram), now()).callback(); assert_eq!(delay, INITIAL_PTO); assert_eq!(*client.state(), State::WaitInitial); @@ -175,7 +165,7 @@ fn version_negotiation_empty() { let vn = create_vn(&initial_pkt, &[]); - let dgram = Datagram::new(addr(), addr(), IpTosEcn::EcnEct0 as u8, vn); + let dgram = Datagram::new(addr(), addr(), vn); let delay = client.process(Some(dgram), now()).callback(); assert_eq!(delay, INITIAL_PTO); assert_eq!(*client.state(), State::WaitInitial); @@ -193,7 +183,7 @@ fn version_negotiation_not_supported() { .to_vec(); let vn = create_vn(&initial_pkt, &[0x1a1a_1a1a, 0x2a2a_2a2a, 0xff00_0001]); - let dgram = Datagram::new(addr(), addr(), IpTosEcn::EcnEct0 as u8, vn); + let dgram = Datagram::new(addr(), addr(), vn); assert_eq!(client.process(Some(dgram), now()), Output::None); match client.state() { State::Closed(err) => { @@ -216,7 +206,7 @@ fn version_negotiation_bad_cid() { initial_pkt[6] ^= 0xc4; let vn = create_vn(&initial_pkt, &[0x1a1a_1a1a, 0x2a2a_2a2a, 0xff00_0001]); - let dgram = Datagram::new(addr(), addr(), IpTosEcn::EcnEct0 as u8, vn); + let dgram = Datagram::new(addr(), addr(), vn); let delay = client.process(Some(dgram), now()).callback(); assert_eq!(delay, INITIAL_PTO); assert_eq!(*client.state(), State::WaitInitial); @@ -321,7 +311,7 @@ fn version_negotiation_downgrade() { // Start the handshake and spoof a VN packet. let initial = client.process_output(now()).dgram().unwrap(); let vn = create_vn(&initial, &[DOWNGRADE.wire_version()]); - let dgram = Datagram::new(addr(), addr(), IpTosEcn::EcnEct0 as u8, vn); + let dgram = Datagram::new(addr(), addr(), vn); client.process_input(dgram, now()); connect_fail( diff --git a/neqo-transport/src/path.rs b/neqo-transport/src/path.rs index 3c045f2216..3a25a1bea9 100644 --- a/neqo-transport/src/path.rs +++ b/neqo-transport/src/path.rs @@ -29,9 +29,7 @@ use crate::stats::FrameStats; use crate::tracking::{PacketNumberSpace, SentPacket}; use crate::{Error, Res}; -use neqo_common::{ - hex, qdebug, qinfo, qlog::NeqoQlog, qtrace, Datagram, Encoder, IpTosEcn::EcnEct0, -}; +use neqo_common::{hex, qdebug, qinfo, qlog::NeqoQlog, qtrace, Datagram, Encoder}; use neqo_crypto::random; /// This is the MTU that we assume when using IPv6. @@ -530,10 +528,6 @@ pub struct Path { /// A path challenge was received and PATH_RESPONSE has not been sent. challenge: Option<[u8; 8]>, - /// The IPv4 type-of-service (TOS) or IPv6 traffic class (TC) value - /// to use for this path. - tos: u8, - /// The round trip time estimate for this path. rtt: RttEstimate, /// A packet sender for the path, which includes congestion control and a pacer. @@ -565,7 +559,6 @@ impl Path { Self { local, remote, - tos: EcnEct0 as u8, local_cid: None, remote_cid: None, primary: false, @@ -696,7 +689,7 @@ impl Path { /// Make a datagram. pub fn datagram>>(&self, payload: V) -> Datagram { - Datagram::new(self.local, self.remote, self.tos, payload) + Datagram::new(self.local, self.remote, payload) } /// Get local address as `SocketAddr` diff --git a/neqo-transport/src/server.rs b/neqo-transport/src/server.rs index d9d8965787..75cc6d42d8 100644 --- a/neqo-transport/src/server.rs +++ b/neqo-transport/src/server.rs @@ -347,7 +347,7 @@ impl Server { &initial.dst_cid, ); if let Ok(p) = packet { - let retry = Datagram::new(dgram.destination(), dgram.source(), dgram.tos(), p); + let retry = Datagram::new(dgram.destination(), dgram.source(), p); Some(retry) } else { qerror!([self], "unable to encode retry, dropping packet"); @@ -578,7 +578,7 @@ impl Server { packet.wire_version(), self.conn_params.get_versions().all(), ); - return Some(Datagram::new(dgram.destination(), dgram.source(), dgram.tos(), vn)); + return Some(Datagram::new(dgram.destination(), dgram.source(), vn)); } match packet.packet_type() { diff --git a/neqo-transport/tests/conn_vectors.rs b/neqo-transport/tests/conn_vectors.rs index 0635ecc8ff..83de136d91 100644 --- a/neqo-transport/tests/conn_vectors.rs +++ b/neqo-transport/tests/conn_vectors.rs @@ -8,7 +8,7 @@ #![deny(clippy::pedantic)] #![cfg(not(feature = "fuzzing"))] -use neqo_common::{Datagram, IpTosEcn}; +use neqo_common::Datagram; use neqo_transport::{ Connection, ConnectionParameters, RandomConnectionIdGenerator, State, Version, }; @@ -265,7 +265,7 @@ fn make_server(v: Version) -> Connection { fn process_client_initial(v: Version, packet: &[u8]) { let mut server = make_server(v); - let dgram = Datagram::new(addr(), addr(), IpTosEcn::EcnEct0 as u8, packet); + let dgram = Datagram::new(addr(), addr(), packet); assert_eq!(*server.state(), State::Init); let out = server.process(Some(dgram), now()); assert_eq!(*server.state(), State::Handshaking); diff --git a/neqo-transport/tests/connection.rs b/neqo-transport/tests/connection.rs index 049346150d..6dd3d263cd 100644 --- a/neqo-transport/tests/connection.rs +++ b/neqo-transport/tests/connection.rs @@ -38,7 +38,6 @@ fn truncate_long_packet() { let truncated = Datagram::new( dupe.source(), dupe.destination(), - dupe.tos(), &dupe[..(dupe.len() - tail)], ); let hs_probe = client.process(Some(truncated), now()).dgram(); @@ -108,7 +107,6 @@ fn reorder_server_initial() { let reordered = Datagram::new( server_initial.source(), server_initial.destination(), - server_initial.tos(), packet, ); diff --git a/neqo-transport/tests/retry.rs b/neqo-transport/tests/retry.rs index 3aa763b35b..51cc442ddd 100644 --- a/neqo-transport/tests/retry.rs +++ b/neqo-transport/tests/retry.rs @@ -14,7 +14,7 @@ use common::{ apply_header_protection, connected_server, decode_initial_header, default_server, generate_ticket, initial_aead_and_hp, remove_header_protection, }; -use neqo_common::{hex_with_len, qdebug, qtrace, Datagram, Encoder, Role, IpTosEcn}; +use neqo_common::{hex_with_len, qdebug, qtrace, Datagram, Encoder, Role}; use neqo_crypto::AuthenticationStatus; use neqo_transport::{server::ValidateAddress, ConnectionError, Error, State, StreamType}; use std::convert::TryFrom; @@ -150,7 +150,7 @@ fn retry_different_ip() { let dgram = dgram.unwrap(); let other_v4 = IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)); let other_addr = SocketAddr::new(other_v4, 443); - let from_other = Datagram::new(other_addr, dgram.destination(), dgram.tos(), &dgram[..]); + let from_other = Datagram::new(other_addr, dgram.destination(), &dgram[..]); let dgram = server.process(Some(from_other), now()).dgram(); assert!(dgram.is_none()); } @@ -171,12 +171,7 @@ fn new_token_different_ip() { // Now rewrite the source address. let d = dgram.unwrap(); let src = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), d.source().port()); - let dgram = Some(Datagram::new( - src, - d.destination(), - IpTosEcn::EcnEct0 as u8, - &d[..], - )); + let dgram = Some(Datagram::new(src, d.destination(), &d[..])); let dgram = server.process(dgram, now()).dgram(); // Retry assert!(dgram.is_some()); assertions::assert_retry(dgram.as_ref().unwrap()); @@ -201,12 +196,7 @@ fn new_token_expired() { let the_future = now() + Duration::from_secs(60 * 60 * 24 * 30); let d = dgram.unwrap(); let src = SocketAddr::new(d.source().ip(), d.source().port() + 1); - let dgram = Some(Datagram::new( - src, - d.destination(), - IpTosEcn::EcnEct0 as u8, - &d[..], - )); + let dgram = Some(Datagram::new(src, d.destination(), &d[..])); let dgram = server.process(dgram, the_future).dgram(); // Retry assert!(dgram.is_some()); assertions::assert_retry(dgram.as_ref().unwrap()); @@ -267,7 +257,7 @@ fn retry_bad_integrity() { let mut tweaked = retry.to_vec(); tweaked[retry.len() - 1] ^= 0x45; // damage the auth tag - let tweaked_packet = Datagram::new(retry.source(), retry.destination(), retry.tos(), tweaked); + let tweaked_packet = Datagram::new(retry.source(), retry.destination(), tweaked); // The client should ignore this packet. let dgram = client.process(Some(tweaked_packet), now()).dgram(); @@ -346,7 +336,7 @@ fn vn_after_retry() { encoder.encode_vec(1, &client.odcid().unwrap()[..]); encoder.encode_vec(1, &[]); encoder.encode_uint(4, 0x5a5a_6a6a_u64); - let vn = Datagram::new(addr(), addr(), IpTosEcn::EcnEct0 as u8, encoder); + let vn = Datagram::new(addr(), addr(), encoder); assert_ne!( client.process(Some(vn), now()).callback(), @@ -431,7 +421,6 @@ fn mitm_retry() { let new_datagram = Datagram::new( client_initial2.source(), client_initial2.destination(), - client_initial2.tos(), notoken_packet, ); qdebug!("passing modified Initial to the main server"); diff --git a/neqo-transport/tests/server.rs b/neqo-transport/tests/server.rs index e4197fc0ca..fe03b2df1d 100644 --- a/neqo-transport/tests/server.rs +++ b/neqo-transport/tests/server.rs @@ -14,7 +14,7 @@ use common::{ find_ticket, generate_ticket, initial_aead_and_hp, new_server, remove_header_protection, }; -use neqo_common::{qtrace, Datagram, Decoder, Encoder, Role, IpTosEcn}; +use neqo_common::{qtrace, Datagram, Decoder, Encoder, Role}; use neqo_crypto::{ generate_ech_keys, AllowZeroRtt, AuthenticationStatus, ZeroRttCheckResult, ZeroRttChecker, }; @@ -157,7 +157,6 @@ fn duplicate_initial_new_path() { let other = Datagram::new( SocketAddr::new(initial.source().ip(), initial.source().port() ^ 23), initial.destination(), - IpTosEcn::EcnEct0 as u8, &initial[..], ); @@ -232,12 +231,7 @@ fn drop_non_initial() { let mut bogus_data: Vec = header.into(); bogus_data.resize(1200, 66); - let bogus = Datagram::new( - test_fixture::addr(), - test_fixture::addr(), - IpTosEcn::EcnEct0 as u8, - bogus_data, - ); + let bogus = Datagram::new(test_fixture::addr(), test_fixture::addr(), bogus_data); assert!(server.process(Some(bogus), now()).dgram().is_none()); } @@ -256,12 +250,7 @@ fn drop_short_initial() { let mut bogus_data: Vec = header.into(); bogus_data.resize(1199, 66); - let bogus = Datagram::new( - test_fixture::addr(), - test_fixture::addr(), - IpTosEcn::EcnEct0 as u8, - bogus_data, - ); + let bogus = Datagram::new(test_fixture::addr(), test_fixture::addr(), bogus_data); assert!(server.process(Some(bogus), now()).dgram().is_none()); } @@ -378,12 +367,7 @@ fn new_token_different_port() { // Now rewrite the source port, which should not change that the token is OK. let d = dgram.unwrap(); let src = SocketAddr::new(d.source().ip(), d.source().port() + 1); - let dgram = Some(Datagram::new( - src, - d.destination(), - IpTosEcn::EcnEct0 as u8, - &d[..], - )); + let dgram = Some(Datagram::new(src, d.destination(), &d[..])); let dgram = server.process(dgram, now()).dgram(); // Retry assert!(dgram.is_some()); assertions::assert_initial(dgram.as_ref().unwrap(), false); @@ -438,7 +422,7 @@ fn bad_client_initial() { &mut ciphertext, (header_enc.len() - 1)..header_enc.len(), ); - let bad_dgram = Datagram::new(dgram.source(), dgram.destination(), dgram.tos(), ciphertext); + let bad_dgram = Datagram::new(dgram.source(), dgram.destination(), ciphertext); // The server should reject this. let response = server.process(Some(bad_dgram), now()); @@ -486,12 +470,7 @@ fn version_negotiation_ignored() { let dgram = client.process(None, now()).dgram().expect("a datagram"); let mut input = dgram.to_vec(); input[1] ^= 0x12; - let damaged = Datagram::new( - dgram.source(), - dgram.destination(), - dgram.tos(), - input.clone(), - ); + let damaged = Datagram::new(dgram.source(), dgram.destination(), input.clone()); let vn = server.process(Some(damaged), now()).dgram(); let mut dec = Decoder::from(&input[5..]); // Skip past version. diff --git a/test-fixture/src/lib.rs b/test-fixture/src/lib.rs index 1ba7df33d7..f0830415b4 100644 --- a/test-fixture/src/lib.rs +++ b/test-fixture/src/lib.rs @@ -319,7 +319,7 @@ fn split_packet(buf: &[u8]) -> (&[u8], Option<&[u8]>) { pub fn split_datagram(d: &Datagram) -> (Datagram, Option) { let (a, b) = split_packet(&d[..]); ( - Datagram::new(d.source(), d.destination(), d.tos(), a), - b.map(|b| Datagram::new(d.source(), d.destination(), d.tos(), b)), + Datagram::new(d.source(), d.destination(), a), + b.map(|b| Datagram::new(d.source(), d.destination(), b)), ) }