golang.org/x/net@v0.25.1-0.20240516223405-c87a5b62e243/quic/rtt_test.go (about) 1 // Copyright 2023 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 //go:build go1.21 6 7 package quic 8 9 import ( 10 "testing" 11 "time" 12 ) 13 14 func TestRTTMinRTT(t *testing.T) { 15 var ( 16 handshakeConfirmed = false 17 ackDelay = 0 * time.Millisecond 18 maxAckDelay = 25 * time.Millisecond 19 now = time.Date(2000, 1, 1, 0, 0, 0, 0, time.UTC) 20 ) 21 rtt := &rttState{} 22 rtt.init() 23 24 // "min_rtt MUST be set to the latest_rtt on the first RTT sample." 25 // https://www.rfc-editor.org/rfc/rfc9002.html#section-5.2-2 26 rtt.updateSample(now, handshakeConfirmed, initialSpace, 10*time.Millisecond, ackDelay, maxAckDelay) 27 if got, want := rtt.latestRTT, 10*time.Millisecond; got != want { 28 t.Errorf("on first sample: latest_rtt = %v, want %v", got, want) 29 } 30 if got, want := rtt.minRTT, 10*time.Millisecond; got != want { 31 t.Errorf("on first sample: min_rtt = %v, want %v", got, want) 32 } 33 34 // "min_rtt MUST be set to the lesser of min_rtt and latest_rtt [...] 35 // on all other samples." 36 rtt.updateSample(now, handshakeConfirmed, initialSpace, 20*time.Millisecond, ackDelay, maxAckDelay) 37 if got, want := rtt.latestRTT, 20*time.Millisecond; got != want { 38 t.Errorf("on increasing sample: latest_rtt = %v, want %v", got, want) 39 } 40 if got, want := rtt.minRTT, 10*time.Millisecond; got != want { 41 t.Errorf("on increasing sample: min_rtt = %v, want %v (no change)", got, want) 42 } 43 44 rtt.updateSample(now, handshakeConfirmed, initialSpace, 5*time.Millisecond, ackDelay, maxAckDelay) 45 if got, want := rtt.latestRTT, 5*time.Millisecond; got != want { 46 t.Errorf("on new minimum: latest_rtt = %v, want %v", got, want) 47 } 48 if got, want := rtt.minRTT, 5*time.Millisecond; got != want { 49 t.Errorf("on new minimum: min_rtt = %v, want %v", got, want) 50 } 51 52 // "Endpoints SHOULD set the min_rtt to the newest RTT sample 53 // after persistent congestion is established." 54 // https://www.rfc-editor.org/rfc/rfc9002.html#section-5.2-5 55 rtt.updateSample(now, handshakeConfirmed, initialSpace, 15*time.Millisecond, ackDelay, maxAckDelay) 56 if got, want := rtt.latestRTT, 15*time.Millisecond; got != want { 57 t.Errorf("on increasing sample: latest_rtt = %v, want %v", got, want) 58 } 59 if got, want := rtt.minRTT, 5*time.Millisecond; got != want { 60 t.Errorf("on increasing sample: min_rtt = %v, want %v (no change)", got, want) 61 } 62 rtt.establishPersistentCongestion() 63 if got, want := rtt.minRTT, 15*time.Millisecond; got != want { 64 t.Errorf("after persistent congestion: min_rtt = %v, want %v", got, want) 65 } 66 } 67 68 func TestRTTInitialRTT(t *testing.T) { 69 var ( 70 handshakeConfirmed = false 71 ackDelay = 0 * time.Millisecond 72 maxAckDelay = 25 * time.Millisecond 73 now = time.Date(2000, 1, 1, 0, 0, 0, 0, time.UTC) 74 ) 75 rtt := &rttState{} 76 rtt.init() 77 78 // "When no previous RTT is available, 79 // the initial RTT SHOULD be set to 333 milliseconds." 80 // https://www.rfc-editor.org/rfc/rfc9002#section-6.2.2-1 81 if got, want := rtt.smoothedRTT, 333*time.Millisecond; got != want { 82 t.Errorf("initial smoothed_rtt = %v, want %v", got, want) 83 } 84 if got, want := rtt.rttvar, 333*time.Millisecond/2; got != want { 85 t.Errorf("initial rttvar = %v, want %v", got, want) 86 } 87 88 rtt.updateSample(now, handshakeConfirmed, initialSpace, 10*time.Millisecond, ackDelay, maxAckDelay) 89 smoothedRTT := 10 * time.Millisecond 90 if got, want := rtt.smoothedRTT, smoothedRTT; got != want { 91 t.Errorf("after first rtt sample of 10ms, smoothed_rtt = %v, want %v", got, want) 92 } 93 rttvar := 5 * time.Millisecond 94 if got, want := rtt.rttvar, rttvar; got != want { 95 t.Errorf("after first rtt sample of 10ms, rttvar = %v, want %v", got, want) 96 } 97 98 // "[...] MAY ignore the acknowledgment delay for Initial packets [...]" 99 // https://www.rfc-editor.org/rfc/rfc9002#section-5.3-7.1 100 ackDelay = 1 * time.Millisecond 101 rtt.updateSample(now, handshakeConfirmed, initialSpace, 10*time.Millisecond, ackDelay, maxAckDelay) 102 adjustedRTT := 10 * time.Millisecond 103 smoothedRTT = (7*smoothedRTT + adjustedRTT) / 8 104 if got, want := rtt.smoothedRTT, smoothedRTT; got != want { 105 t.Errorf("smoothed_rtt = %v, want %v", got, want) 106 } 107 rttvarSample := abs(smoothedRTT - adjustedRTT) 108 rttvar = (3*rttvar + rttvarSample) / 4 109 if got, want := rtt.rttvar, rttvar; got != want { 110 t.Errorf("rttvar = %v, want %v", got, want) 111 } 112 113 // "[...] SHOULD ignore the peer's max_ack_delay until the handshake is confirmed [...]" 114 // https://www.rfc-editor.org/rfc/rfc9002#section-5.3-7.2 115 ackDelay = 30 * time.Millisecond 116 maxAckDelay = 25 * time.Millisecond 117 rtt.updateSample(now, handshakeConfirmed, handshakeSpace, 40*time.Millisecond, ackDelay, maxAckDelay) 118 adjustedRTT = 10 * time.Millisecond // latest_rtt (40ms) - ack_delay (30ms) 119 smoothedRTT = (7*smoothedRTT + adjustedRTT) / 8 120 if got, want := rtt.smoothedRTT, smoothedRTT; got != want { 121 t.Errorf("smoothed_rtt = %v, want %v", got, want) 122 } 123 rttvarSample = abs(smoothedRTT - adjustedRTT) 124 rttvar = (3*rttvar + rttvarSample) / 4 125 if got, want := rtt.rttvar, rttvar; got != want { 126 t.Errorf("rttvar = %v, want %v", got, want) 127 } 128 129 // "[...] MUST use the lesser of the acknowledgment delay and 130 // the peer's max_ack_delay after the handshake is confirmed [...]" 131 // https://www.rfc-editor.org/rfc/rfc9002#section-5.3-7.3 132 ackDelay = 30 * time.Millisecond 133 maxAckDelay = 25 * time.Millisecond 134 handshakeConfirmed = true 135 rtt.updateSample(now, handshakeConfirmed, handshakeSpace, 40*time.Millisecond, ackDelay, maxAckDelay) 136 adjustedRTT = 15 * time.Millisecond // latest_rtt (40ms) - max_ack_delay (25ms) 137 rttvarSample = abs(smoothedRTT - adjustedRTT) 138 rttvar = (3*rttvar + rttvarSample) / 4 139 if got, want := rtt.rttvar, rttvar; got != want { 140 t.Errorf("rttvar = %v, want %v", got, want) 141 } 142 smoothedRTT = (7*smoothedRTT + adjustedRTT) / 8 143 if got, want := rtt.smoothedRTT, smoothedRTT; got != want { 144 t.Errorf("smoothed_rtt = %v, want %v", got, want) 145 } 146 147 // "[...] MUST NOT subtract the acknowledgment delay from 148 // the RTT sample if the resulting value is smaller than the min_rtt." 149 // https://www.rfc-editor.org/rfc/rfc9002#section-5.3-7.4 150 ackDelay = 25 * time.Millisecond 151 maxAckDelay = 25 * time.Millisecond 152 handshakeConfirmed = true 153 rtt.updateSample(now, handshakeConfirmed, handshakeSpace, 30*time.Millisecond, ackDelay, maxAckDelay) 154 if got, want := rtt.minRTT, 10*time.Millisecond; got != want { 155 t.Errorf("min_rtt = %v, want %v", got, want) 156 } 157 // latest_rtt (30ms) - ack_delay (25ms) = 5ms, which is less than min_rtt (10ms) 158 adjustedRTT = 30 * time.Millisecond // latest_rtt 159 rttvarSample = abs(smoothedRTT - adjustedRTT) 160 rttvar = (3*rttvar + rttvarSample) / 4 161 if got, want := rtt.rttvar, rttvar; got != want { 162 t.Errorf("rttvar = %v, want %v", got, want) 163 } 164 smoothedRTT = (7*smoothedRTT + adjustedRTT) / 8 165 if got, want := rtt.smoothedRTT, smoothedRTT; got != want { 166 t.Errorf("smoothed_rtt = %v, want %v", got, want) 167 } 168 }