Source file src/vendor/golang.org/x/net/quic/conn_send.go

     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  package quic
     6  
     7  import (
     8  	"crypto/tls"
     9  	"errors"
    10  	"time"
    11  )
    12  
    13  // maybeSend sends datagrams, if possible.
    14  //
    15  // If sending is blocked by pacing, it returns the next time
    16  // a datagram may be sent.
    17  //
    18  // If sending is blocked indefinitely, it returns the zero Time.
    19  func (c *Conn) maybeSend(now time.Time) (next time.Time) {
    20  	// Assumption: The congestion window is not underutilized.
    21  	// If congestion control, pacing, and anti-amplification all permit sending,
    22  	// but we have no packet to send, then we will declare the window underutilized.
    23  	underutilized := false
    24  	defer func() {
    25  		c.loss.cc.setUnderutilized(c.log, underutilized)
    26  	}()
    27  
    28  	// Send one datagram on each iteration of this loop,
    29  	// until we hit a limit or run out of data to send.
    30  	//
    31  	// For each number space where we have write keys,
    32  	// attempt to construct a packet in that space.
    33  	// If the packet contains no frames (we have no data in need of sending),
    34  	// abandon the packet.
    35  	//
    36  	// Speculatively constructing packets means we don't need
    37  	// separate code paths for "do we have data to send?" and
    38  	// "send the data" that need to be kept in sync.
    39  	for {
    40  		limit, next := c.loss.sendLimit(now)
    41  		if limit == ccBlocked {
    42  			// If anti-amplification blocks sending, then no packet can be sent.
    43  			return next
    44  		}
    45  		if !c.sendOK(now) {
    46  			return time.Time{}
    47  		}
    48  		// We may still send ACKs, even if congestion control or pacing limit sending.
    49  
    50  		// Prepare to write a datagram of at most maxSendSize bytes.
    51  		c.w.reset(c.loss.maxSendSize())
    52  
    53  		dstConnID, ok := c.connIDState.dstConnID()
    54  		if !ok {
    55  			// It is currently not possible for us to end up without a connection ID,
    56  			// but handle the case anyway.
    57  			return time.Time{}
    58  		}
    59  
    60  		// Initial packet.
    61  		pad := false
    62  		var sentInitial *sentPacket
    63  		if c.keysInitial.canWrite() {
    64  			pnumMaxAcked := c.loss.spaces[initialSpace].maxAcked
    65  			pnum := c.loss.nextNumber(initialSpace)
    66  			p := longPacket{
    67  				ptype:     packetTypeInitial,
    68  				version:   quicVersion1,
    69  				num:       pnum,
    70  				dstConnID: dstConnID,
    71  				srcConnID: c.connIDState.srcConnID(),
    72  				extra:     c.retryToken,
    73  			}
    74  			c.w.startProtectedLongHeaderPacket(pnumMaxAcked, p)
    75  			c.appendFrames(now, initialSpace, pnum, limit)
    76  			if logPackets {
    77  				logSentPacket(c, packetTypeInitial, pnum, p.srcConnID, p.dstConnID, c.w.payload())
    78  			}
    79  			if c.logEnabled(QLogLevelPacket) && len(c.w.payload()) > 0 {
    80  				c.logPacketSent(packetTypeInitial, pnum, p.srcConnID, p.dstConnID, c.w.packetLen(), c.w.payload())
    81  			}
    82  			sentInitial = c.w.finishProtectedLongHeaderPacket(pnumMaxAcked, c.keysInitial.w, p)
    83  			if sentInitial != nil {
    84  				// Client initial packets and ack-eliciting server initial packaets
    85  				// need to be sent in a datagram padded to at least 1200 bytes.
    86  				// We can't add the padding yet, however, since we may want to
    87  				// coalesce additional packets with this one.
    88  				if c.side == clientSide || sentInitial.ackEliciting {
    89  					pad = true
    90  				}
    91  			}
    92  		}
    93  
    94  		// Handshake packet.
    95  		if c.keysHandshake.canWrite() {
    96  			pnumMaxAcked := c.loss.spaces[handshakeSpace].maxAcked
    97  			pnum := c.loss.nextNumber(handshakeSpace)
    98  			p := longPacket{
    99  				ptype:     packetTypeHandshake,
   100  				version:   quicVersion1,
   101  				num:       pnum,
   102  				dstConnID: dstConnID,
   103  				srcConnID: c.connIDState.srcConnID(),
   104  			}
   105  			c.w.startProtectedLongHeaderPacket(pnumMaxAcked, p)
   106  			c.appendFrames(now, handshakeSpace, pnum, limit)
   107  			if logPackets {
   108  				logSentPacket(c, packetTypeHandshake, pnum, p.srcConnID, p.dstConnID, c.w.payload())
   109  			}
   110  			if c.logEnabled(QLogLevelPacket) && len(c.w.payload()) > 0 {
   111  				c.logPacketSent(packetTypeHandshake, pnum, p.srcConnID, p.dstConnID, c.w.packetLen(), c.w.payload())
   112  			}
   113  			if sent := c.w.finishProtectedLongHeaderPacket(pnumMaxAcked, c.keysHandshake.w, p); sent != nil {
   114  				c.packetSent(now, handshakeSpace, sent)
   115  				if c.side == clientSide {
   116  					// "[...] a client MUST discard Initial keys when it first
   117  					// sends a Handshake packet [...]"
   118  					// https://www.rfc-editor.org/rfc/rfc9001.html#section-4.9.1-2
   119  					c.discardKeys(now, initialSpace)
   120  				}
   121  			}
   122  		}
   123  
   124  		// 1-RTT packet.
   125  		if c.keysAppData.canWrite() {
   126  			pnumMaxAcked := c.loss.spaces[appDataSpace].maxAcked
   127  			pnum := c.loss.nextNumber(appDataSpace)
   128  			c.w.start1RTTPacket(pnum, pnumMaxAcked, dstConnID)
   129  			c.appendFrames(now, appDataSpace, pnum, limit)
   130  			if pad && len(c.w.payload()) > 0 {
   131  				// 1-RTT packets have no length field and extend to the end
   132  				// of the datagram, so if we're sending a datagram that needs
   133  				// padding we need to add it inside the 1-RTT packet.
   134  				c.w.appendPaddingTo(paddedInitialDatagramSize)
   135  				pad = false
   136  			}
   137  			if logPackets {
   138  				logSentPacket(c, packetType1RTT, pnum, nil, dstConnID, c.w.payload())
   139  			}
   140  			if c.logEnabled(QLogLevelPacket) && len(c.w.payload()) > 0 {
   141  				c.logPacketSent(packetType1RTT, pnum, nil, dstConnID, c.w.packetLen(), c.w.payload())
   142  			}
   143  			if sent := c.w.finish1RTTPacket(pnum, pnumMaxAcked, dstConnID, &c.keysAppData); sent != nil {
   144  				c.packetSent(now, appDataSpace, sent)
   145  				if c.skip.shouldSkip(pnum + 1) {
   146  					c.loss.skipNumber(now, appDataSpace)
   147  					c.skip.updateNumberSkip(c)
   148  				}
   149  			}
   150  		}
   151  
   152  		buf := c.w.datagram()
   153  		if len(buf) == 0 {
   154  			if limit == ccOK {
   155  				// We have nothing to send, and congestion control does not
   156  				// block sending. The congestion window is underutilized.
   157  				underutilized = true
   158  			}
   159  			return next
   160  		}
   161  
   162  		if sentInitial != nil {
   163  			if pad {
   164  				// Pad out the datagram with zeros, coalescing the Initial
   165  				// packet with invalid packets that will be ignored by the peer.
   166  				// https://www.rfc-editor.org/rfc/rfc9000.html#section-14.1-1
   167  				for len(buf) < paddedInitialDatagramSize {
   168  					buf = append(buf, 0)
   169  					// Technically this padding isn't in any packet, but
   170  					// account it to the Initial packet in this datagram
   171  					// for purposes of flow control and loss recovery.
   172  					sentInitial.size++
   173  					sentInitial.inFlight = true
   174  				}
   175  			}
   176  			// If we're a client and this Initial packet is coalesced
   177  			// with a Handshake packet, then we've discarded Initial keys
   178  			// since constructing the packet and shouldn't record it as in-flight.
   179  			if c.keysInitial.canWrite() {
   180  				c.packetSent(now, initialSpace, sentInitial)
   181  			}
   182  		}
   183  
   184  		c.endpoint.sendDatagram(datagram{
   185  			b:        buf,
   186  			peerAddr: c.peerAddr,
   187  		})
   188  	}
   189  }
   190  
   191  func (c *Conn) packetSent(now time.Time, space numberSpace, sent *sentPacket) {
   192  	c.idleHandlePacketSent(now, sent)
   193  	c.loss.packetSent(now, c.log, space, sent)
   194  }
   195  
   196  func (c *Conn) appendFrames(now time.Time, space numberSpace, pnum packetNumber, limit ccLimit) {
   197  	if c.lifetime.localErr != nil {
   198  		c.appendConnectionCloseFrame(now, space, c.lifetime.localErr)
   199  		return
   200  	}
   201  
   202  	shouldSendAck := c.acks[space].shouldSendAck(now)
   203  	if limit != ccOK {
   204  		// ACKs are not limited by congestion control.
   205  		if shouldSendAck && c.appendAckFrame(now, space) {
   206  			c.acks[space].sentAck()
   207  		}
   208  		return
   209  	}
   210  	// We want to send an ACK frame if the ack controller wants to send a frame now,
   211  	// OR if we are sending a packet anyway and have ack-eliciting packets which we
   212  	// have not yet acked.
   213  	//
   214  	// We speculatively add ACK frames here, to put them at the front of the packet
   215  	// to avoid truncation.
   216  	//
   217  	// After adding all frames, if we don't need to send an ACK frame and have not
   218  	// added any other frames, we abandon the packet.
   219  	if c.appendAckFrame(now, space) {
   220  		defer func() {
   221  			// All frames other than ACK and PADDING are ack-eliciting,
   222  			// so if the packet is ack-eliciting we've added additional
   223  			// frames to it.
   224  			if !shouldSendAck && !c.w.sent.ackEliciting {
   225  				// There's nothing in this packet but ACK frames, and
   226  				// we don't want to send an ACK-only packet at this time.
   227  				// Abandoning the packet means we wrote an ACK frame for
   228  				// nothing, but constructing the frame is cheap.
   229  				c.w.abandonPacket()
   230  				return
   231  			}
   232  			// Either we are willing to send an ACK-only packet,
   233  			// or we've added additional frames.
   234  			c.acks[space].sentAck()
   235  			if !c.w.sent.ackEliciting && c.shouldMakePacketAckEliciting() {
   236  				c.w.appendPingFrame()
   237  			}
   238  		}()
   239  	}
   240  	if limit != ccOK {
   241  		return
   242  	}
   243  	pto := c.loss.ptoExpired
   244  
   245  	// TODO: Add all the other frames we can send.
   246  
   247  	// CRYPTO
   248  	c.crypto[space].dataToSend(pto, func(off, size int64) int64 {
   249  		b, _ := c.w.appendCryptoFrame(off, int(size))
   250  		c.crypto[space].sendData(off, b)
   251  		return int64(len(b))
   252  	})
   253  
   254  	// Test-only PING frames.
   255  	if space == c.testSendPingSpace && c.testSendPing.shouldSendPTO(pto) {
   256  		if !c.w.appendPingFrame() {
   257  			return
   258  		}
   259  		c.testSendPing.setSent(pnum)
   260  	}
   261  
   262  	if space == appDataSpace {
   263  		// HANDSHAKE_DONE
   264  		if c.handshakeConfirmed.shouldSendPTO(pto) {
   265  			if !c.w.appendHandshakeDoneFrame() {
   266  				return
   267  			}
   268  			c.handshakeConfirmed.setSent(pnum)
   269  		}
   270  
   271  		// NEW_CONNECTION_ID, RETIRE_CONNECTION_ID
   272  		if !c.connIDState.appendFrames(c, pnum, pto) {
   273  			return
   274  		}
   275  
   276  		// PATH_RESPONSE
   277  		if pad, ok := c.appendPathFrames(); !ok {
   278  			return
   279  		} else if pad {
   280  			defer c.w.appendPaddingTo(smallestMaxDatagramSize)
   281  		}
   282  
   283  		// All stream-related frames. This should come last in the packet,
   284  		// so large amounts of STREAM data don't crowd out other frames
   285  		// we may need to send.
   286  		if !c.appendStreamFrames(&c.w, pnum, pto) {
   287  			return
   288  		}
   289  
   290  		if !c.appendKeepAlive(now) {
   291  			return
   292  		}
   293  	}
   294  
   295  	// If this is a PTO probe and we haven't added an ack-eliciting frame yet,
   296  	// add a PING to make this an ack-eliciting probe.
   297  	//
   298  	// Technically, there are separate PTO timers for each number space.
   299  	// When a PTO timer expires, we MUST send an ack-eliciting packet in the
   300  	// timer's space. We SHOULD send ack-eliciting packets in every other space
   301  	// with in-flight data. (RFC 9002, section 6.2.4)
   302  	//
   303  	// What we actually do is send a single datagram containing an ack-eliciting packet
   304  	// for every space for which we have keys.
   305  	//
   306  	// We fill the PTO probe packets with new or unacknowledged data. For example,
   307  	// a PTO probe sent for the Initial space will generally retransmit previously
   308  	// sent but unacknowledged CRYPTO data.
   309  	//
   310  	// When sending a PTO probe datagram containing multiple packets, it is
   311  	// possible that an earlier packet will fill up the datagram, leaving no
   312  	// space for the remaining probe packet(s). This is not a problem in practice.
   313  	//
   314  	// A client discards Initial keys when it first sends a Handshake packet
   315  	// (RFC 9001 Section 4.9.1). Handshake keys are discarded when the handshake
   316  	// is confirmed (RFC 9001 Section  4.9.2). The PTO timer is not set for the
   317  	// Application Data packet number space until the handshake is confirmed
   318  	// (RFC 9002 Section 6.2.1). Therefore, the only times a PTO probe can fire
   319  	// while data for multiple spaces is in flight are:
   320  	//
   321  	// - a server's Initial or Handshake timers can fire while Initial and Handshake
   322  	//   data is in flight; and
   323  	//
   324  	// - a client's Handshake timer can fire while Handshake and Application Data
   325  	//   data is in flight.
   326  	//
   327  	// It is theoretically possible for a server's Initial CRYPTO data to overflow
   328  	// the maximum datagram size, but unlikely in practice; this space contains
   329  	// only the ServerHello TLS message, which is small. It's also unlikely that
   330  	// the Handshake PTO probe will fire while Initial data is in flight (this
   331  	// requires not just that the Initial CRYPTO data completely fill a datagram,
   332  	// but a quite specific arrangement of lost and retransmitted packets.)
   333  	// We don't bother worrying about this case here, since the worst case is
   334  	// that we send a PTO probe for the in-flight Initial data and drop the
   335  	// Handshake probe.
   336  	//
   337  	// If a client's Handshake PTO timer fires while Application Data data is in
   338  	// flight, it is possible that the resent Handshake CRYPTO data will crowd
   339  	// out the probe for the Application Data space. However, since this probe is
   340  	// optional (recall that the Application Data PTO timer is never set until
   341  	// after Handshake keys have been discarded), dropping it is acceptable.
   342  	if pto && !c.w.sent.ackEliciting {
   343  		c.w.appendPingFrame()
   344  	}
   345  }
   346  
   347  // shouldMakePacketAckEliciting is called when sending a packet containing nothing but an ACK frame.
   348  // It reports whether we should add a PING frame to the packet to make it ack-eliciting.
   349  func (c *Conn) shouldMakePacketAckEliciting() bool {
   350  	if c.keysAppData.needAckEliciting() {
   351  		// The peer has initiated a key update.
   352  		// We haven't sent them any packets yet in the new phase.
   353  		// Make this an ack-eliciting packet.
   354  		// Their ack of this packet will complete the key update.
   355  		return true
   356  	}
   357  	if c.loss.consecutiveNonAckElicitingPackets >= 19 {
   358  		// We've sent a run of non-ack-eliciting packets.
   359  		// Add in an ack-eliciting one every once in a while so the peer
   360  		// lets us know which ones have arrived.
   361  		//
   362  		// Google QUICHE injects a PING after sending 19 packets. We do the same.
   363  		//
   364  		// https://www.rfc-editor.org/rfc/rfc9000#section-13.2.4-2
   365  		return true
   366  	}
   367  	// TODO: Consider making every packet sent when in PTO ack-eliciting to speed up recovery.
   368  	return false
   369  }
   370  
   371  func (c *Conn) appendAckFrame(now time.Time, space numberSpace) bool {
   372  	seen, delay := c.acks[space].acksToSend(now)
   373  	if len(seen) == 0 {
   374  		return false
   375  	}
   376  	d := unscaledAckDelayFromDuration(delay, ackDelayExponent)
   377  	return c.w.appendAckFrame(seen, d, c.acks[space].ecn)
   378  }
   379  
   380  func (c *Conn) appendConnectionCloseFrame(now time.Time, space numberSpace, err error) {
   381  	c.sentConnectionClose(now)
   382  	switch e := err.(type) {
   383  	case localTransportError:
   384  		c.w.appendConnectionCloseTransportFrame(e.code, 0, e.reason)
   385  	case *ApplicationError:
   386  		if space != appDataSpace {
   387  			// "CONNECTION_CLOSE frames signaling application errors (type 0x1d)
   388  			// MUST only appear in the application data packet number space."
   389  			// https://www.rfc-editor.org/rfc/rfc9000#section-12.5-2.2
   390  			c.w.appendConnectionCloseTransportFrame(errApplicationError, 0, "")
   391  		} else {
   392  			c.w.appendConnectionCloseApplicationFrame(e.Code, e.Reason)
   393  		}
   394  	default:
   395  		// TLS alerts are sent using error codes [0x0100,0x01ff).
   396  		// https://www.rfc-editor.org/rfc/rfc9000#section-20.1-2.36.1
   397  		var alert tls.AlertError
   398  		switch {
   399  		case errors.As(err, &alert):
   400  			// tls.AlertError is a uint8, so this can't exceed 0x01ff.
   401  			code := errTLSBase + transportError(alert)
   402  			c.w.appendConnectionCloseTransportFrame(code, 0, "")
   403  		default:
   404  			c.w.appendConnectionCloseTransportFrame(errInternal, 0, "")
   405  		}
   406  	}
   407  }
   408  

View as plain text