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