Skip to content

Commit a1dedff

Browse files
committed
Fix StreamPriorityKey::cmp implementation so it doesn't violate Rust's Ord trait contract while keeping the intended round-robin behavior.
1 parent 86a79a7 commit a1dedff

File tree

4 files changed

+201
-108
lines changed

4 files changed

+201
-108
lines changed

quiche/src/h3/mod.rs

Lines changed: 10 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3825,33 +3825,30 @@ mod tests {
38253825
more_frames: true,
38263826
};
38273827
assert_eq!(ev, ev_headers);
3828+
assert_eq!(s.poll_server(), Ok((0, Event::Data)));
3829+
assert_eq!(s.recv_body_server(0, &mut recv_buf), Ok(body.len()));
3830+
assert_eq!(s.poll_client(), Err(Error::Done));
3831+
assert_eq!(s.recv_body_server(0, &mut recv_buf), Ok(body.len()));
3832+
assert_eq!(s.poll_server(), Ok((0, Event::Finished)));
38283833

38293834
let (_, ev) = s.poll_server().unwrap();
38303835
let ev_headers = Event::Headers {
38313836
list: reqs[1].clone(),
38323837
more_frames: true,
38333838
};
38343839
assert_eq!(ev, ev_headers);
3840+
assert_eq!(s.poll_server(), Ok((4, Event::Data)));
3841+
assert_eq!(s.recv_body_server(4, &mut recv_buf), Ok(body.len()));
3842+
assert_eq!(s.poll_client(), Err(Error::Done));
3843+
assert_eq!(s.recv_body_server(4, &mut recv_buf), Ok(body.len()));
3844+
assert_eq!(s.poll_server(), Ok((4, Event::Finished)));
38353845

38363846
let (_, ev) = s.poll_server().unwrap();
38373847
let ev_headers = Event::Headers {
38383848
list: reqs[2].clone(),
38393849
more_frames: true,
38403850
};
38413851
assert_eq!(ev, ev_headers);
3842-
3843-
assert_eq!(s.poll_server(), Ok((0, Event::Data)));
3844-
assert_eq!(s.recv_body_server(0, &mut recv_buf), Ok(body.len()));
3845-
assert_eq!(s.poll_client(), Err(Error::Done));
3846-
assert_eq!(s.recv_body_server(0, &mut recv_buf), Ok(body.len()));
3847-
assert_eq!(s.poll_server(), Ok((0, Event::Finished)));
3848-
3849-
assert_eq!(s.poll_server(), Ok((4, Event::Data)));
3850-
assert_eq!(s.recv_body_server(4, &mut recv_buf), Ok(body.len()));
3851-
assert_eq!(s.poll_client(), Err(Error::Done));
3852-
assert_eq!(s.recv_body_server(4, &mut recv_buf), Ok(body.len()));
3853-
assert_eq!(s.poll_server(), Ok((4, Event::Finished)));
3854-
38553852
assert_eq!(s.poll_server(), Ok((8, Event::Data)));
38563853
assert_eq!(s.recv_body_server(8, &mut recv_buf), Ok(body.len()));
38573854
assert_eq!(s.poll_client(), Err(Error::Done));

quiche/src/lib.rs

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -429,8 +429,6 @@ use crate::recovery::OnLossDetectionTimeoutOutcome;
429429
use crate::recovery::RecoveryOps;
430430
use crate::recovery::ReleaseDecision;
431431

432-
use crate::stream::StreamPriorityKey;
433-
434432
/// The current QUIC wire version.
435433
pub const PROTOCOL_VERSION: u32 = PROTOCOL_VERSION_V1;
436434

@@ -4947,14 +4945,14 @@ impl<F: BufFactory> Connection<F> {
49474945
}
49484946

49494947
let priority_key = Arc::clone(&stream.priority_key);
4948+
49504949
// If the stream is no longer flushable, remove it from the queue
49514950
if !stream.is_flushable() {
49524951
self.streams.remove_flushable(&priority_key);
49534952
} else if stream.incremental {
4954-
// Shuffle the incremental stream to the back of the
4955-
// queue.
4956-
self.streams.remove_flushable(&priority_key);
4957-
self.streams.insert_flushable(&priority_key);
4953+
// Cycle the incremental stream to the back of the queue
4954+
// for round-robin scheduling.
4955+
self.streams.cycle_flushable(stream_id);
49584956
}
49594957

49604958
#[cfg(feature = "fuzzing")]
@@ -5685,15 +5683,21 @@ impl<F: BufFactory> Connection<F> {
56855683
stream.urgency = urgency;
56865684
stream.incremental = incremental;
56875685

5688-
let new_priority_key = Arc::new(StreamPriorityKey {
5689-
urgency: stream.urgency,
5690-
incremental: stream.incremental,
5686+
let old_priority_key = Arc::clone(&stream.priority_key);
5687+
5688+
let sequence = self.streams.next_sequence();
5689+
5690+
let stream = self.streams.get_mut(stream_id).unwrap();
5691+
5692+
let new_priority_key = Arc::new(stream::StreamPriorityKey {
5693+
urgency,
5694+
incremental,
56915695
id: stream_id,
5696+
sequence,
56925697
..Default::default()
56935698
});
56945699

5695-
let old_priority_key =
5696-
std::mem::replace(&mut stream.priority_key, new_priority_key.clone());
5700+
stream.priority_key = Arc::clone(&new_priority_key);
56975701

56985702
self.streams
56995703
.update_priority(&old_priority_key, &new_priority_key);

0 commit comments

Comments
 (0)