github.com/quic-go/quic-go@v0.44.0/internal/wire/ack_frame.go (about)

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