From 295de00a80fc2367fd20b93bad5a933cc5c6ae23 Mon Sep 17 00:00:00 2001 From: Floris Bruynooghe Date: Tue, 24 Feb 2026 12:19:01 +0100 Subject: [PATCH] wip --- quinn-proto/src/connection/mod.rs | 38 +++++++++++++++++++++++-------- 1 file changed, 29 insertions(+), 9 deletions(-) diff --git a/quinn-proto/src/connection/mod.rs b/quinn-proto/src/connection/mod.rs index 627908de4..a8e5d789c 100644 --- a/quinn-proto/src/connection/mod.rs +++ b/quinn-proto/src/connection/mod.rs @@ -1636,13 +1636,7 @@ impl Connection { }; } - self.populate_packet( - now, - space_id, - path_id, - scheduling_info.get(path_id).unwrap(), - &mut builder, - ); + self.populate_packet(now, space_id, path_id, scheduling_info, &mut builder); // ACK-only packets should only be sent when explicitly allowed. If we write them due to // any other reason, there is a bug which leads to one component announcing write @@ -5599,9 +5593,11 @@ impl Connection { now: Instant, space_id: SpaceId, path_id: PathId, - scheduling_info: &PathSchedulingInfo, + scheduling_info: BTreeMap, builder: &mut PacketBuilder<'a, 'b>, ) { + let this_path = scheduling_info.get(&path_id).unwrap(); + debug_assert!(this_path.has_cids, "must have CIDs to populate packet"); let pn = builder.packet_number; let is_multipath_negotiated = self.is_multipath_negotiated(); let space_has_keys = self.crypto_state.has_keys(space_id.encryption_level()); @@ -6940,12 +6936,36 @@ struct PathSchedulingInfo { /// Whether the path is abandoned. /// /// Note that a path that is abandoned but still has CIDs can still send a packet. After - /// sending that packet the CIDs have to be considered retired as well. + /// sending that packet the CIDs have to be considered retired as well and + /// [`Self::has_cids`] should turn `false`. abandoned: bool, /// The status of the path. status: PathStatus, } +fn should_send_data(all: &BTreeMap, current: PathId) -> bool { + // To send SpaceKind::Data we want a path: + // - with CIDs + // - validated + // - not abandoned + // - status-available unless there is no such path + let this = all.get(¤t).unwrap(); + if !this.has_cids || !this.validated || this.abandoned { + return false; + } + if this.status == PathStatus::Available { + return true; + } + !data_space_available(all) +} + +/// Whether there is any path that can send SpaceKind::Data with PathStatus::Available +fn data_space_available(all: &BTreeMap) -> bool { + all.values() + .filter(|info| info.has_cids && info.validated && !info.abandoned) + .any(|info| info.status == PathStatus::Available) +} + #[derive(Debug, Copy, Clone, PartialEq, Eq)] enum PathBlocked { No,