golang.org/x/net@v0.25.1-0.20240516223405-c87a5b62e243/quic/rtt.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 "time" 11 ) 12 13 type rttState struct { 14 minRTT time.Duration 15 latestRTT time.Duration 16 smoothedRTT time.Duration 17 rttvar time.Duration // RTT variation 18 firstSampleTime time.Time // time of first RTT sample 19 } 20 21 func (r *rttState) init() { 22 r.minRTT = -1 // -1 indicates the first sample has not been taken yet 23 24 // "[...] the initial RTT SHOULD be set to 333 milliseconds." 25 // https://www.rfc-editor.org/rfc/rfc9002.html#section-6.2.2-1 26 const initialRTT = 333 * time.Millisecond 27 28 // https://www.rfc-editor.org/rfc/rfc9002.html#section-5.3-12 29 r.smoothedRTT = initialRTT 30 r.rttvar = initialRTT / 2 31 } 32 33 func (r *rttState) establishPersistentCongestion() { 34 // "Endpoints SHOULD set the min_rtt to the newest RTT sample 35 // after persistent congestion is established." 36 // https://www.rfc-editor.org/rfc/rfc9002#section-5.2-5 37 r.minRTT = r.latestRTT 38 } 39 40 // updateRTTSample is called when we generate a new RTT sample. 41 // https://www.rfc-editor.org/rfc/rfc9002.html#section-5 42 func (r *rttState) updateSample(now time.Time, handshakeConfirmed bool, spaceID numberSpace, latestRTT, ackDelay, maxAckDelay time.Duration) { 43 r.latestRTT = latestRTT 44 45 if r.minRTT < 0 { 46 // First RTT sample. 47 // "min_rtt MUST be set to the latest_rtt on the first RTT sample." 48 // https://www.rfc-editor.org/rfc/rfc9002.html#section-5.2-2 49 r.minRTT = latestRTT 50 // https://www.rfc-editor.org/rfc/rfc9002.html#section-5.3-14 51 r.smoothedRTT = latestRTT 52 r.rttvar = latestRTT / 2 53 r.firstSampleTime = now 54 return 55 } 56 57 // "min_rtt MUST be set to the lesser of min_rtt and latest_rtt [...] 58 // on all other samples." 59 // https://www.rfc-editor.org/rfc/rfc9002.html#section-5.2-2 60 r.minRTT = min(r.minRTT, latestRTT) 61 62 // https://www.rfc-editor.org/rfc/rfc9002.html#section-5.3-16 63 if handshakeConfirmed { 64 ackDelay = min(ackDelay, maxAckDelay) 65 } 66 adjustedRTT := latestRTT - ackDelay 67 if adjustedRTT < r.minRTT { 68 adjustedRTT = latestRTT 69 } 70 rttvarSample := abs(r.smoothedRTT - adjustedRTT) 71 r.rttvar = (3*r.rttvar + rttvarSample) / 4 72 r.smoothedRTT = ((7 * r.smoothedRTT) + adjustedRTT) / 8 73 }