- commit
- a505aa3aa10f58ccf6c8b09ec9f359b66e5e4f74
- parent
- 8d1c8eabf67cc190c6f4c8f7d8662bdb2fc364a2
- author
- Dami <dami.etoile@gmail.com>
| M | crates/ | 78 | +++++++++++++++++++++++++----- |
@@ -2785,23 +2785,31 @@ struct Negotiated {
27852785 pointer_surface_dimensions: Option<PointerSurfaceDimensions>,27862786 }27872787 2788-async fn read_expected_input_ack(2789- recv: &mut iroh::endpoint::RecvStream,2788+async fn read_expected_input_ack<R>(2789+ recv: &mut R,27902790 timeout_seconds: u64,27912791 expected_sequence: u64,2792-) -> Result<sigil_protocol::InputAck> {2793- let input_ack = tokio::time::timeout(2794- Duration::from_secs(timeout_seconds.min(5)),2795- read_input_ack(recv),2796- )2792+) -> Result<sigil_protocol::InputAck>2793+where2794+ R: tokio::io::AsyncRead + Unpin,2795+{2796+ let input_ack = tokio::time::timeout(Duration::from_secs(timeout_seconds.min(5)), async {2797+ loop {2798+ let input_ack = read_input_ack(recv)2799+ .await?2800+ .context("host closed before input acknowledgment")?;2801+ ensure!(2802+ input_ack.sequence <= expected_sequence,2803+ "unexpected input acknowledgment sequence {}; expected at most {expected_sequence}",2804+ input_ack.sequence2805+ );2806+ if input_ack.sequence == expected_sequence {2807+ break Ok(input_ack);2808+ }2809+ }2810+ })27972811 .await2798- .context("timed out waiting for input acknowledgment")??2799- .context("host closed before input acknowledgment")?;2800- ensure!(2801- input_ack.sequence == expected_sequence,2802- "unexpected input acknowledgment sequence {}; expected {expected_sequence}",2803- input_ack.sequence2804- );2812+ .context("timed out waiting for input acknowledgment")??;28052813 Ok(input_ack)28062814 }28072815 @@ -2809,6 +2817,48 @@ async fn read_expected_input_ack(
28092817 mod tests {28102818 use super::*;28112819 2820+ 2821+ async fn expected_input_ack_skips_older_feedback_under_one_deadline() {2822+ let (mut sender, mut receiver) = tokio::io::duplex(512);2823+ for sequence in [0, 0, 1] {2824+ sigil_protocol::write_input_ack(2825+ &mut sender,2826+ &sigil_protocol::InputAck {2827+ sequence,2828+ pointer_position: None,2829+ pointer_visible: Some(false),2830+ },2831+ )2832+ .await2833+ .unwrap();2834+ }2835+2836+ let input_ack = read_expected_input_ack(&mut receiver, 1, 1).await.unwrap();2837+2838+ assert_eq!(input_ack.sequence, 1);2839+ }2840+2841+ 2842+ async fn expected_input_ack_rejects_future_feedback() {2843+ let (mut sender, mut receiver) = tokio::io::duplex(256);2844+ sigil_protocol::write_input_ack(2845+ &mut sender,2846+ &sigil_protocol::InputAck {2847+ sequence: 2,2848+ pointer_position: None,2849+ pointer_visible: Some(false),2850+ },2851+ )2852+ .await2853+ .unwrap();2854+2855+ let error = read_expected_input_ack(&mut receiver, 1, 1)2856+ .await2857+ .unwrap_err();2858+2859+ assert!(error.to_string().contains("expected at most 1"));2860+ }2861+28122862 28132863 fn feedback_report_is_complete_and_keeps_the_observed_sequence() {28142864 let report = complete_feedback_report(7, MediaFeedbackFlags::NONE, 42);