golang.org/x/net@v0.25.1-0.20240516223405-c87a5b62e243/quic/conn_loss.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 "fmt"
    10  
    11  // handleAckOrLoss deals with the final fate of a packet we sent:
    12  // Either the peer acknowledges it, or we declare it lost.
    13  //
    14  // In order to handle packet loss, we must retain any information sent to the peer
    15  // until the peer has acknowledged it.
    16  //
    17  // When information is acknowledged, we can discard it.
    18  //
    19  // When information is lost, we mark it for retransmission.
    20  // See RFC 9000, Section 13.3 for a complete list of information which is retransmitted on loss.
    21  // https://www.rfc-editor.org/rfc/rfc9000#section-13.3
    22  func (c *Conn) handleAckOrLoss(space numberSpace, sent *sentPacket, fate packetFate) {
    23  	if fate == packetLost && c.logEnabled(QLogLevelPacket) {
    24  		c.logPacketLost(space, sent)
    25  	}
    26  
    27  	// The list of frames in a sent packet is marshaled into a buffer in the sentPacket
    28  	// by the packetWriter. Unmarshal that buffer here. This code must be kept in sync with
    29  	// packetWriter.append*.
    30  	//
    31  	// A sent packet meets its fate (acked or lost) only once, so it's okay to consume
    32  	// the sentPacket's buffer here.
    33  	for !sent.done() {
    34  		switch f := sent.next(); f {
    35  		default:
    36  			panic(fmt.Sprintf("BUG: unhandled acked/lost frame type %x", f))
    37  		case frameTypeAck:
    38  			// Unlike most information, loss of an ACK frame does not trigger
    39  			// retransmission. ACKs are sent in response to ack-eliciting packets,
    40  			// and always contain the latest information available.
    41  			//
    42  			// Acknowledgement of an ACK frame may allow us to discard information
    43  			// about older packets.
    44  			largest := packetNumber(sent.nextInt())
    45  			if fate == packetAcked {
    46  				c.acks[space].handleAck(largest)
    47  			}
    48  		case frameTypeCrypto:
    49  			start, end := sent.nextRange()
    50  			c.crypto[space].ackOrLoss(start, end, fate)
    51  		case frameTypeMaxData:
    52  			c.ackOrLossMaxData(sent.num, fate)
    53  		case frameTypeResetStream,
    54  			frameTypeStopSending,
    55  			frameTypeMaxStreamData,
    56  			frameTypeStreamDataBlocked:
    57  			id := streamID(sent.nextInt())
    58  			s := c.streamForID(id)
    59  			if s == nil {
    60  				continue
    61  			}
    62  			s.ackOrLoss(sent.num, f, fate)
    63  		case frameTypeStreamBase,
    64  			frameTypeStreamBase | streamFinBit:
    65  			id := streamID(sent.nextInt())
    66  			start, end := sent.nextRange()
    67  			s := c.streamForID(id)
    68  			if s == nil {
    69  				continue
    70  			}
    71  			fin := f&streamFinBit != 0
    72  			s.ackOrLossData(sent.num, start, end, fin, fate)
    73  		case frameTypeMaxStreamsBidi:
    74  			c.streams.remoteLimit[bidiStream].sendMax.ackLatestOrLoss(sent.num, fate)
    75  		case frameTypeMaxStreamsUni:
    76  			c.streams.remoteLimit[uniStream].sendMax.ackLatestOrLoss(sent.num, fate)
    77  		case frameTypeNewConnectionID:
    78  			seq := int64(sent.nextInt())
    79  			c.connIDState.ackOrLossNewConnectionID(sent.num, seq, fate)
    80  		case frameTypeRetireConnectionID:
    81  			seq := int64(sent.nextInt())
    82  			c.connIDState.ackOrLossRetireConnectionID(sent.num, seq, fate)
    83  		case frameTypeHandshakeDone:
    84  			c.handshakeConfirmed.ackOrLoss(sent.num, fate)
    85  		}
    86  	}
    87  }