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  }