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

Return an error if the path is not permanent #1698

Merged
merged 5 commits into from
Mar 13, 2024
Merged
Show file tree
Hide file tree
Changes from 2 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
7 changes: 7 additions & 0 deletions neqo-transport/src/connection/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1937,6 +1937,13 @@ impl Connection {
};

let path = close.path().borrow();
// In some error cases, we will not be able to make a new, permanent path.
// For example, if we run out of connection IDs and the error results from
// a packet on a new path, we avoid sending (and the privacy risk) rather
// than reuse a connection ID.
if path.is_temporary() {
return Err(Error::InternalError);
}
let (_, mut builder) = Self::build_packet_header(
&path,
cspace,
Expand Down
41 changes: 41 additions & 0 deletions neqo-transport/src/connection/tests/migration.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

use std::{
cell::RefCell,
mem,
net::{IpAddr, Ipv6Addr, SocketAddr},
rc::Rc,
time::{Duration, Instant},
Expand Down Expand Up @@ -950,3 +951,43 @@ fn retire_prior_to_migration_success() {
assert_ne!(get_cid(&dgram), original_cid);
assert_ne!(get_cid(&dgram), probe_cid);
}

struct GarbageWriter {}

impl crate::connection::test_internal::FrameWriter for GarbageWriter {
fn write_frames(&mut self, builder: &mut PacketBuilder) {
builder.encode_varint(u32::MAX);
}
}

/// Test the case that we run out of connection ID and receive an invalid frame
/// from a new path.
#[test]
fn error_on_new_path_with_no_connection_id() {
let mut client = default_client();
let mut server = default_server();
connect_force_idle(&mut client, &mut server);

let dgram = send_something(&mut server, now());
let dgram = change_path(&dgram, DEFAULT_ADDR_V4);
client.process_input(&dgram, now());

let cid_gen: Rc<RefCell<dyn ConnectionIdGenerator>> =
Rc::new(RefCell::new(CountingConnectionIdGenerator::default()));
server.test_frame_writer = Some(Box::new(RetireAll { cid_gen }));
let retire_all = send_something(&mut server, now());
server.test_frame_writer = None;

client.process_input(&retire_all, now());

server.test_frame_writer = Some(Box::new(GarbageWriter {}));
let garbage = send_something(&mut server, now());
server.test_frame_writer = None;

let dgram = change_path(&garbage, DEFAULT_ADDR_V4);
client.process_input(&dgram, now());

// See issue #1697. We had a crash when the client had a temporary path and
// process_output is called.
mem::drop(client.process_output(now()));
}
Loading