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 }