github.com/sagernet/quic-go@v0.43.1-beta.1/internal/wire/ack_frame.go (about)

     1  package wire
     2  
     3  import (
     4  	"bytes"
     5  	"errors"
     6  	"sort"
     7  	"time"
     8  
     9  	"github.com/sagernet/quic-go/internal/protocol"
    10  	"github.com/sagernet/quic-go/internal/utils"
    11  	"github.com/sagernet/quic-go/quicvarint"
    12  )
    13  
    14  var errInvalidAckRanges = errors.New("AckFrame: ACK frame contains invalid ACK ranges")
    15  
    16  // An AckFrame is an ACK frame
    17  type AckFrame struct {
    18  	AckRanges []AckRange // has to be ordered. The highest ACK range goes first, the lowest ACK range goes last
    19  	DelayTime time.Duration
    20  
    21  	ECT0, ECT1, ECNCE uint64
    22  }
    23  
    24  // parseAckFrame reads an ACK frame
    25  func parseAckFrame(frame *AckFrame, r *bytes.Reader, typ uint64, ackDelayExponent uint8, _ protocol.Version) error {
    26  	ecn := typ == ackECNFrameType
    27  
    28  	la, err := quicvarint.Read(r)
    29  	if err != nil {
    30  		return err
    31  	}
    32  	largestAcked := protocol.PacketNumber(la)
    33  	delay, err := quicvarint.Read(r)
    34  	if err != nil {
    35  		return err
    36  	}
    37  
    38  	delayTime := time.Duration(delay*1<<ackDelayExponent) * time.Microsecond
    39  	if delayTime < 0 {
    40  		// If the delay time overflows, set it to the maximum encode-able value.
    41  		delayTime = utils.InfDuration
    42  	}
    43  	frame.DelayTime = delayTime
    44  
    45  	numBlocks, err := quicvarint.Read(r)
    46  	if err != nil {
    47  		return err
    48  	}
    49  
    50  	// read the first ACK range
    51  	ab, err := quicvarint.Read(r)
    52  	if err != nil {
    53  		return err
    54  	}
    55  	ackBlock := protocol.PacketNumber(ab)
    56  	if ackBlock > largestAcked {
    57  		return errors.New("invalid first ACK range")
    58  	}
    59  	smallest := largestAcked - ackBlock
    60  	frame.AckRanges = append(frame.AckRanges, AckRange{Smallest: smallest, Largest: largestAcked})
    61  
    62  	// read all the other ACK ranges
    63  	for i := uint64(0); i < numBlocks; i++ {
    64  		g, err := quicvarint.Read(r)
    65  		if err != nil {
    66  			return err
    67  		}
    68  		gap := protocol.PacketNumber(g)
    69  		if smallest < gap+2 {
    70  			return errInvalidAckRanges
    71  		}
    72  		largest := smallest - gap - 2
    73  
    74  		ab, err := quicvarint.Read(r)
    75  		if err != nil {
    76  			return err
    77  		}
    78  		ackBlock := protocol.PacketNumber(ab)
    79  
    80  		if ackBlock > largest {
    81  			return errInvalidAckRanges
    82  		}
    83  		smallest = largest - ackBlock
    84  		frame.AckRanges = append(frame.AckRanges, AckRange{Smallest: smallest, Largest: largest})
    85  	}
    86  
    87  	if !frame.validateAckRanges() {
    88  		return errInvalidAckRanges
    89  	}
    90  
    91  	if ecn {
    92  		ect0, err := quicvarint.Read(r)
    93  		if err != nil {
    94  			return err
    95  		}
    96  		frame.ECT0 = ect0
    97  		ect1, err := quicvarint.Read(r)
    98  		if err != nil {
    99  			return err
   100  		}
   101  		frame.ECT1 = ect1
   102  		ecnce, err := quicvarint.Read(r)
   103  		if err != nil {
   104  			return err
   105  		}
   106  		frame.ECNCE = ecnce
   107  	}
   108  
   109  	return nil
   110  }
   111  
   112  // Append appends an ACK frame.
   113  func (f *AckFrame) Append(b []byte, _ protocol.Version) ([]byte, error) {
   114  	hasECN := f.ECT0 > 0 || f.ECT1 > 0 || f.ECNCE > 0
   115  	if hasECN {
   116  		b = append(b, ackECNFrameType)
   117  	} else {
   118  		b = append(b, ackFrameType)
   119  	}
   120  	b = quicvarint.Append(b, uint64(f.LargestAcked()))
   121  	b = quicvarint.Append(b, encodeAckDelay(f.DelayTime))
   122  
   123  	numRanges := f.numEncodableAckRanges()
   124  	b = quicvarint.Append(b, uint64(numRanges-1))
   125  
   126  	// write the first range
   127  	_, firstRange := f.encodeAckRange(0)
   128  	b = quicvarint.Append(b, firstRange)
   129  
   130  	// write all the other range
   131  	for i := 1; i < numRanges; i++ {
   132  		gap, len := f.encodeAckRange(i)
   133  		b = quicvarint.Append(b, gap)
   134  		b = quicvarint.Append(b, len)
   135  	}
   136  
   137  	if hasECN {
   138  		b = quicvarint.Append(b, f.ECT0)
   139  		b = quicvarint.Append(b, f.ECT1)
   140  		b = quicvarint.Append(b, f.ECNCE)
   141  	}
   142  	return b, nil
   143  }
   144  
   145  // Length of a written frame
   146  func (f *AckFrame) Length(_ protocol.Version) protocol.ByteCount {
   147  	largestAcked := f.AckRanges[0].Largest
   148  	numRanges := f.numEncodableAckRanges()
   149  
   150  	length := 1 + quicvarint.Len(uint64(largestAcked)) + quicvarint.Len(encodeAckDelay(f.DelayTime))
   151  
   152  	length += quicvarint.Len(uint64(numRanges - 1))
   153  	lowestInFirstRange := f.AckRanges[0].Smallest
   154  	length += quicvarint.Len(uint64(largestAcked - lowestInFirstRange))
   155  
   156  	for i := 1; i < numRanges; i++ {
   157  		gap, len := f.encodeAckRange(i)
   158  		length += quicvarint.Len(gap)
   159  		length += quicvarint.Len(len)
   160  	}
   161  	if f.ECT0 > 0 || f.ECT1 > 0 || f.ECNCE > 0 {
   162  		length += quicvarint.Len(f.ECT0)
   163  		length += quicvarint.Len(f.ECT1)
   164  		length += quicvarint.Len(f.ECNCE)
   165  	}
   166  	return protocol.ByteCount(length)
   167  }
   168  
   169  // gets the number of ACK ranges that can be encoded
   170  // such that the resulting frame is smaller than the maximum ACK frame size
   171  func (f *AckFrame) numEncodableAckRanges() int {
   172  	length := 1 + quicvarint.Len(uint64(f.LargestAcked())) + quicvarint.Len(encodeAckDelay(f.DelayTime))
   173  	length += 2 // assume that the number of ranges will consume 2 bytes
   174  	for i := 1; i < len(f.AckRanges); i++ {
   175  		gap, len := f.encodeAckRange(i)
   176  		rangeLen := quicvarint.Len(gap) + quicvarint.Len(len)
   177  		if protocol.ByteCount(length+rangeLen) > protocol.MaxAckFrameSize {
   178  			// Writing range i would exceed the MaxAckFrameSize.
   179  			// So encode one range less than that.
   180  			return i - 1
   181  		}
   182  		length += rangeLen
   183  	}
   184  	return len(f.AckRanges)
   185  }
   186  
   187  func (f *AckFrame) encodeAckRange(i int) (uint64 /* gap */, uint64 /* length */) {
   188  	if i == 0 {
   189  		return 0, uint64(f.AckRanges[0].Largest - f.AckRanges[0].Smallest)
   190  	}
   191  	return uint64(f.AckRanges[i-1].Smallest - f.AckRanges[i].Largest - 2),
   192  		uint64(f.AckRanges[i].Largest - f.AckRanges[i].Smallest)
   193  }
   194  
   195  // HasMissingRanges returns if this frame reports any missing packets
   196  func (f *AckFrame) HasMissingRanges() bool {
   197  	return len(f.AckRanges) > 1
   198  }
   199  
   200  func (f *AckFrame) validateAckRanges() bool {
   201  	if len(f.AckRanges) == 0 {
   202  		return false
   203  	}
   204  
   205  	// check the validity of every single ACK range
   206  	for _, ackRange := range f.AckRanges {
   207  		if ackRange.Smallest > ackRange.Largest {
   208  			return false
   209  		}
   210  	}
   211  
   212  	// check the consistency for ACK with multiple NACK ranges
   213  	for i, ackRange := range f.AckRanges {
   214  		if i == 0 {
   215  			continue
   216  		}
   217  		lastAckRange := f.AckRanges[i-1]
   218  		if lastAckRange.Smallest <= ackRange.Smallest {
   219  			return false
   220  		}
   221  		if lastAckRange.Smallest <= ackRange.Largest+1 {
   222  			return false
   223  		}
   224  	}
   225  
   226  	return true
   227  }
   228  
   229  // LargestAcked is the largest acked packet number
   230  func (f *AckFrame) LargestAcked() protocol.PacketNumber {
   231  	return f.AckRanges[0].Largest
   232  }
   233  
   234  // LowestAcked is the lowest acked packet number
   235  func (f *AckFrame) LowestAcked() protocol.PacketNumber {
   236  	return f.AckRanges[len(f.AckRanges)-1].Smallest
   237  }
   238  
   239  // AcksPacket determines if this ACK frame acks a certain packet number
   240  func (f *AckFrame) AcksPacket(p protocol.PacketNumber) bool {
   241  	if p < f.LowestAcked() || p > f.LargestAcked() {
   242  		return false
   243  	}
   244  
   245  	i := sort.Search(len(f.AckRanges), func(i int) bool {
   246  		return p >= f.AckRanges[i].Smallest
   247  	})
   248  	// i will always be < len(f.AckRanges), since we checked above that p is not bigger than the largest acked
   249  	return p <= f.AckRanges[i].Largest
   250  }
   251  
   252  func (f *AckFrame) Reset() {
   253  	f.DelayTime = 0
   254  	f.ECT0 = 0
   255  	f.ECT1 = 0
   256  	f.ECNCE = 0
   257  	for _, r := range f.AckRanges {
   258  		r.Largest = 0
   259  		r.Smallest = 0
   260  	}
   261  	f.AckRanges = f.AckRanges[:0]
   262  }
   263  
   264  func encodeAckDelay(delay time.Duration) uint64 {
   265  	return uint64(delay.Nanoseconds() / (1000 * (1 << protocol.AckDelayExponent)))
   266  }