golang.org/x/net@v0.25.1-0.20240516223405-c87a5b62e243/quic/conn_recv.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 ( 10 "bytes" 11 "encoding/binary" 12 "errors" 13 "time" 14 ) 15 16 func (c *Conn) handleDatagram(now time.Time, dgram *datagram) (handled bool) { 17 if !c.localAddr.IsValid() { 18 // We don't have any way to tell in the general case what address we're 19 // sending packets from. Set our address from the destination address of 20 // the first packet received from the peer. 21 c.localAddr = dgram.localAddr 22 } 23 if dgram.peerAddr.IsValid() && dgram.peerAddr != c.peerAddr { 24 if c.side == clientSide { 25 // "If a client receives packets from an unknown server address, 26 // the client MUST discard these packets." 27 // https://www.rfc-editor.org/rfc/rfc9000#section-9-6 28 return false 29 } 30 // We currently don't support connection migration, 31 // so for now the server also drops packets from an unknown address. 32 return false 33 } 34 buf := dgram.b 35 c.loss.datagramReceived(now, len(buf)) 36 if c.isDraining() { 37 return false 38 } 39 for len(buf) > 0 { 40 var n int 41 ptype := getPacketType(buf) 42 switch ptype { 43 case packetTypeInitial: 44 if c.side == serverSide && len(dgram.b) < paddedInitialDatagramSize { 45 // Discard client-sent Initial packets in too-short datagrams. 46 // https://www.rfc-editor.org/rfc/rfc9000#section-14.1-4 47 return false 48 } 49 n = c.handleLongHeader(now, dgram, ptype, initialSpace, c.keysInitial.r, buf) 50 case packetTypeHandshake: 51 n = c.handleLongHeader(now, dgram, ptype, handshakeSpace, c.keysHandshake.r, buf) 52 case packetType1RTT: 53 n = c.handle1RTT(now, dgram, buf) 54 case packetTypeRetry: 55 c.handleRetry(now, buf) 56 return true 57 case packetTypeVersionNegotiation: 58 c.handleVersionNegotiation(now, buf) 59 return true 60 default: 61 n = -1 62 } 63 if n <= 0 { 64 // We don't expect to get a stateless reset with a valid 65 // destination connection ID, since the sender of a stateless 66 // reset doesn't know what the connection ID is. 67 // 68 // We're required to perform this check anyway. 69 // 70 // "[...] the comparison MUST be performed when the first packet 71 // in an incoming datagram [...] cannot be decrypted." 72 // https://www.rfc-editor.org/rfc/rfc9000#section-10.3.1-2 73 if len(buf) == len(dgram.b) && len(buf) > statelessResetTokenLen { 74 var token statelessResetToken 75 copy(token[:], buf[len(buf)-len(token):]) 76 if c.handleStatelessReset(now, token) { 77 return true 78 } 79 } 80 // Invalid data at the end of a datagram is ignored. 81 return false 82 } 83 c.idleHandlePacketReceived(now) 84 buf = buf[n:] 85 } 86 return true 87 } 88 89 func (c *Conn) handleLongHeader(now time.Time, dgram *datagram, ptype packetType, space numberSpace, k fixedKeys, buf []byte) int { 90 if !k.isSet() { 91 return skipLongHeaderPacket(buf) 92 } 93 94 pnumMax := c.acks[space].largestSeen() 95 p, n := parseLongHeaderPacket(buf, k, pnumMax) 96 if n < 0 { 97 return -1 98 } 99 if buf[0]&reservedLongBits != 0 { 100 // Reserved header bits must be 0. 101 // https://www.rfc-editor.org/rfc/rfc9000#section-17.2-8.2.1 102 c.abort(now, localTransportError{ 103 code: errProtocolViolation, 104 reason: "reserved header bits are not zero", 105 }) 106 return -1 107 } 108 if p.version != quicVersion1 { 109 // The peer has changed versions on us mid-handshake? 110 c.abort(now, localTransportError{ 111 code: errProtocolViolation, 112 reason: "protocol version changed during handshake", 113 }) 114 return -1 115 } 116 117 if !c.acks[space].shouldProcess(p.num) { 118 return n 119 } 120 121 if logPackets { 122 logInboundLongPacket(c, p) 123 } 124 if c.logEnabled(QLogLevelPacket) { 125 c.logLongPacketReceived(p, buf[:n]) 126 } 127 c.connIDState.handlePacket(c, p.ptype, p.srcConnID) 128 ackEliciting := c.handleFrames(now, dgram, ptype, space, p.payload) 129 c.acks[space].receive(now, space, p.num, ackEliciting) 130 if p.ptype == packetTypeHandshake && c.side == serverSide { 131 c.loss.validateClientAddress() 132 133 // "[...] a server MUST discard Initial keys when it first successfully 134 // processes a Handshake packet [...]" 135 // https://www.rfc-editor.org/rfc/rfc9001#section-4.9.1-2 136 c.discardKeys(now, initialSpace) 137 } 138 return n 139 } 140 141 func (c *Conn) handle1RTT(now time.Time, dgram *datagram, buf []byte) int { 142 if !c.keysAppData.canRead() { 143 // 1-RTT packets extend to the end of the datagram, 144 // so skip the remainder of the datagram if we can't parse this. 145 return len(buf) 146 } 147 148 pnumMax := c.acks[appDataSpace].largestSeen() 149 p, err := parse1RTTPacket(buf, &c.keysAppData, connIDLen, pnumMax) 150 if err != nil { 151 // A localTransportError terminates the connection. 152 // Other errors indicate an unparseable packet, but otherwise may be ignored. 153 if _, ok := err.(localTransportError); ok { 154 c.abort(now, err) 155 } 156 return -1 157 } 158 if buf[0]&reserved1RTTBits != 0 { 159 // Reserved header bits must be 0. 160 // https://www.rfc-editor.org/rfc/rfc9000#section-17.3.1-4.8.1 161 c.abort(now, localTransportError{ 162 code: errProtocolViolation, 163 reason: "reserved header bits are not zero", 164 }) 165 return -1 166 } 167 168 if !c.acks[appDataSpace].shouldProcess(p.num) { 169 return len(buf) 170 } 171 172 if logPackets { 173 logInboundShortPacket(c, p) 174 } 175 if c.logEnabled(QLogLevelPacket) { 176 c.log1RTTPacketReceived(p, buf) 177 } 178 ackEliciting := c.handleFrames(now, dgram, packetType1RTT, appDataSpace, p.payload) 179 c.acks[appDataSpace].receive(now, appDataSpace, p.num, ackEliciting) 180 return len(buf) 181 } 182 183 func (c *Conn) handleRetry(now time.Time, pkt []byte) { 184 if c.side != clientSide { 185 return // clients don't send Retry packets 186 } 187 // "After the client has received and processed an Initial or Retry packet 188 // from the server, it MUST discard any subsequent Retry packets that it receives." 189 // https://www.rfc-editor.org/rfc/rfc9000#section-17.2.5.2-1 190 if !c.keysInitial.canRead() { 191 return // discarded Initial keys, connection is already established 192 } 193 if c.acks[initialSpace].seen.numRanges() != 0 { 194 return // processed at least one packet 195 } 196 if c.retryToken != nil { 197 return // received a Retry already 198 } 199 // "Clients MUST discard Retry packets that have a Retry Integrity Tag 200 // that cannot be validated." 201 // https://www.rfc-editor.org/rfc/rfc9000#section-17.2.5.2-2 202 p, ok := parseRetryPacket(pkt, c.connIDState.originalDstConnID) 203 if !ok { 204 return 205 } 206 // "A client MUST discard a Retry packet with a zero-length Retry Token field." 207 // https://www.rfc-editor.org/rfc/rfc9000#section-17.2.5.2-2 208 if len(p.token) == 0 { 209 return 210 } 211 c.retryToken = cloneBytes(p.token) 212 c.connIDState.handleRetryPacket(p.srcConnID) 213 // We need to resend any data we've already sent in Initial packets. 214 // We must not reuse already sent packet numbers. 215 c.loss.discardPackets(initialSpace, c.log, c.handleAckOrLoss) 216 // TODO: Discard 0-RTT packets as well, once we support 0-RTT. 217 } 218 219 var errVersionNegotiation = errors.New("server does not support QUIC version 1") 220 221 func (c *Conn) handleVersionNegotiation(now time.Time, pkt []byte) { 222 if c.side != clientSide { 223 return // servers don't handle Version Negotiation packets 224 } 225 // "A client MUST discard any Version Negotiation packet if it has 226 // received and successfully processed any other packet [...]" 227 // https://www.rfc-editor.org/rfc/rfc9000#section-6.2-2 228 if !c.keysInitial.canRead() { 229 return // discarded Initial keys, connection is already established 230 } 231 if c.acks[initialSpace].seen.numRanges() != 0 { 232 return // processed at least one packet 233 } 234 _, srcConnID, versions := parseVersionNegotiation(pkt) 235 if len(c.connIDState.remote) < 1 || !bytes.Equal(c.connIDState.remote[0].cid, srcConnID) { 236 return // Source Connection ID doesn't match what we sent 237 } 238 for len(versions) >= 4 { 239 ver := binary.BigEndian.Uint32(versions) 240 if ver == 1 { 241 // "A client MUST discard a Version Negotiation packet that lists 242 // the QUIC version selected by the client." 243 // https://www.rfc-editor.org/rfc/rfc9000#section-6.2-2 244 return 245 } 246 versions = versions[4:] 247 } 248 // "A client that supports only this version of QUIC MUST 249 // abandon the current connection attempt if it receives 250 // a Version Negotiation packet, [with the two exceptions handled above]." 251 // https://www.rfc-editor.org/rfc/rfc9000#section-6.2-2 252 c.abortImmediately(now, errVersionNegotiation) 253 } 254 255 func (c *Conn) handleFrames(now time.Time, dgram *datagram, ptype packetType, space numberSpace, payload []byte) (ackEliciting bool) { 256 if len(payload) == 0 { 257 // "An endpoint MUST treat receipt of a packet containing no frames 258 // as a connection error of type PROTOCOL_VIOLATION." 259 // https://www.rfc-editor.org/rfc/rfc9000#section-12.4-3 260 c.abort(now, localTransportError{ 261 code: errProtocolViolation, 262 reason: "packet contains no frames", 263 }) 264 return false 265 } 266 // frameOK verifies that ptype is one of the packets in mask. 267 frameOK := func(c *Conn, ptype, mask packetType) (ok bool) { 268 if ptype&mask == 0 { 269 // "An endpoint MUST treat receipt of a frame in a packet type 270 // that is not permitted as a connection error of type 271 // PROTOCOL_VIOLATION." 272 // https://www.rfc-editor.org/rfc/rfc9000#section-12.4-3 273 c.abort(now, localTransportError{ 274 code: errProtocolViolation, 275 reason: "frame not allowed in packet", 276 }) 277 return false 278 } 279 return true 280 } 281 // Packet masks from RFC 9000 Table 3. 282 // https://www.rfc-editor.org/rfc/rfc9000#table-3 283 const ( 284 IH_1 = packetTypeInitial | packetTypeHandshake | packetType1RTT 285 __01 = packetType0RTT | packetType1RTT 286 ___1 = packetType1RTT 287 ) 288 for len(payload) > 0 { 289 switch payload[0] { 290 case frameTypePadding, frameTypeAck, frameTypeAckECN, 291 frameTypeConnectionCloseTransport, frameTypeConnectionCloseApplication: 292 default: 293 ackEliciting = true 294 } 295 n := -1 296 switch payload[0] { 297 case frameTypePadding: 298 // PADDING is OK in all spaces. 299 n = 1 300 case frameTypePing: 301 // PING is OK in all spaces. 302 // 303 // A PING frame causes us to respond with an ACK by virtue of being 304 // an ack-eliciting frame, but requires no other action. 305 n = 1 306 case frameTypeAck, frameTypeAckECN: 307 if !frameOK(c, ptype, IH_1) { 308 return 309 } 310 n = c.handleAckFrame(now, space, payload) 311 case frameTypeResetStream: 312 if !frameOK(c, ptype, __01) { 313 return 314 } 315 n = c.handleResetStreamFrame(now, space, payload) 316 case frameTypeStopSending: 317 if !frameOK(c, ptype, __01) { 318 return 319 } 320 n = c.handleStopSendingFrame(now, space, payload) 321 case frameTypeCrypto: 322 if !frameOK(c, ptype, IH_1) { 323 return 324 } 325 n = c.handleCryptoFrame(now, space, payload) 326 case frameTypeNewToken: 327 if !frameOK(c, ptype, ___1) { 328 return 329 } 330 _, n = consumeNewTokenFrame(payload) 331 case 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f: // STREAM 332 if !frameOK(c, ptype, __01) { 333 return 334 } 335 n = c.handleStreamFrame(now, space, payload) 336 case frameTypeMaxData: 337 if !frameOK(c, ptype, __01) { 338 return 339 } 340 n = c.handleMaxDataFrame(now, payload) 341 case frameTypeMaxStreamData: 342 if !frameOK(c, ptype, __01) { 343 return 344 } 345 n = c.handleMaxStreamDataFrame(now, payload) 346 case frameTypeMaxStreamsBidi, frameTypeMaxStreamsUni: 347 if !frameOK(c, ptype, __01) { 348 return 349 } 350 n = c.handleMaxStreamsFrame(now, payload) 351 case frameTypeDataBlocked: 352 if !frameOK(c, ptype, __01) { 353 return 354 } 355 _, n = consumeDataBlockedFrame(payload) 356 case frameTypeStreamsBlockedBidi, frameTypeStreamsBlockedUni: 357 if !frameOK(c, ptype, __01) { 358 return 359 } 360 _, _, n = consumeStreamsBlockedFrame(payload) 361 case frameTypeStreamDataBlocked: 362 if !frameOK(c, ptype, __01) { 363 return 364 } 365 _, _, n = consumeStreamDataBlockedFrame(payload) 366 case frameTypeNewConnectionID: 367 if !frameOK(c, ptype, __01) { 368 return 369 } 370 n = c.handleNewConnectionIDFrame(now, space, payload) 371 case frameTypeRetireConnectionID: 372 if !frameOK(c, ptype, __01) { 373 return 374 } 375 n = c.handleRetireConnectionIDFrame(now, space, payload) 376 case frameTypePathChallenge: 377 if !frameOK(c, ptype, __01) { 378 return 379 } 380 n = c.handlePathChallengeFrame(now, dgram, space, payload) 381 case frameTypePathResponse: 382 if !frameOK(c, ptype, ___1) { 383 return 384 } 385 n = c.handlePathResponseFrame(now, space, payload) 386 case frameTypeConnectionCloseTransport: 387 // Transport CONNECTION_CLOSE is OK in all spaces. 388 n = c.handleConnectionCloseTransportFrame(now, payload) 389 case frameTypeConnectionCloseApplication: 390 if !frameOK(c, ptype, __01) { 391 return 392 } 393 n = c.handleConnectionCloseApplicationFrame(now, payload) 394 case frameTypeHandshakeDone: 395 if !frameOK(c, ptype, ___1) { 396 return 397 } 398 n = c.handleHandshakeDoneFrame(now, space, payload) 399 } 400 if n < 0 { 401 c.abort(now, localTransportError{ 402 code: errFrameEncoding, 403 reason: "frame encoding error", 404 }) 405 return false 406 } 407 payload = payload[n:] 408 } 409 return ackEliciting 410 } 411 412 func (c *Conn) handleAckFrame(now time.Time, space numberSpace, payload []byte) int { 413 c.loss.receiveAckStart() 414 largest, ackDelay, n := consumeAckFrame(payload, func(rangeIndex int, start, end packetNumber) { 415 if end > c.loss.nextNumber(space) { 416 // Acknowledgement of a packet we never sent. 417 c.abort(now, localTransportError{ 418 code: errProtocolViolation, 419 reason: "acknowledgement for unsent packet", 420 }) 421 return 422 } 423 c.loss.receiveAckRange(now, space, rangeIndex, start, end, c.handleAckOrLoss) 424 }) 425 // Prior to receiving the peer's transport parameters, we cannot 426 // interpret the ACK Delay field because we don't know the ack_delay_exponent 427 // to apply. 428 // 429 // For servers, we should always know the ack_delay_exponent because the 430 // client's transport parameters are carried in its Initial packets and we 431 // won't send an ack-eliciting Initial packet until after receiving the last 432 // client Initial packet. 433 // 434 // For clients, we won't receive the server's transport parameters until handling 435 // its Handshake flight, which will probably happen after reading its ACK for our 436 // Initial packet(s). However, the peer's acknowledgement delay cannot reduce our 437 // adjusted RTT sample below min_rtt, and min_rtt is generally going to be set 438 // by the packet containing the ACK for our Initial flight. Therefore, the 439 // ACK Delay for an ACK in the Initial space is likely to be ignored anyway. 440 // 441 // Long story short, setting the delay to 0 prior to reading transport parameters 442 // is usually going to have no effect, will have only a minor effect in the rare 443 // cases when it happens, and there aren't any good alternatives anyway since we 444 // can't interpret the ACK Delay field without knowing the exponent. 445 var delay time.Duration 446 if c.peerAckDelayExponent >= 0 { 447 delay = ackDelay.Duration(uint8(c.peerAckDelayExponent)) 448 } 449 c.loss.receiveAckEnd(now, c.log, space, delay, c.handleAckOrLoss) 450 if space == appDataSpace { 451 c.keysAppData.handleAckFor(largest) 452 } 453 return n 454 } 455 456 func (c *Conn) handleMaxDataFrame(now time.Time, payload []byte) int { 457 maxData, n := consumeMaxDataFrame(payload) 458 if n < 0 { 459 return -1 460 } 461 c.streams.outflow.setMaxData(maxData) 462 return n 463 } 464 465 func (c *Conn) handleMaxStreamDataFrame(now time.Time, payload []byte) int { 466 id, maxStreamData, n := consumeMaxStreamDataFrame(payload) 467 if n < 0 { 468 return -1 469 } 470 if s := c.streamForFrame(now, id, sendStream); s != nil { 471 if err := s.handleMaxStreamData(maxStreamData); err != nil { 472 c.abort(now, err) 473 return -1 474 } 475 } 476 return n 477 } 478 479 func (c *Conn) handleMaxStreamsFrame(now time.Time, payload []byte) int { 480 styp, max, n := consumeMaxStreamsFrame(payload) 481 if n < 0 { 482 return -1 483 } 484 c.streams.localLimit[styp].setMax(max) 485 return n 486 } 487 488 func (c *Conn) handleResetStreamFrame(now time.Time, space numberSpace, payload []byte) int { 489 id, code, finalSize, n := consumeResetStreamFrame(payload) 490 if n < 0 { 491 return -1 492 } 493 if s := c.streamForFrame(now, id, recvStream); s != nil { 494 if err := s.handleReset(code, finalSize); err != nil { 495 c.abort(now, err) 496 } 497 } 498 return n 499 } 500 501 func (c *Conn) handleStopSendingFrame(now time.Time, space numberSpace, payload []byte) int { 502 id, code, n := consumeStopSendingFrame(payload) 503 if n < 0 { 504 return -1 505 } 506 if s := c.streamForFrame(now, id, sendStream); s != nil { 507 if err := s.handleStopSending(code); err != nil { 508 c.abort(now, err) 509 } 510 } 511 return n 512 } 513 514 func (c *Conn) handleCryptoFrame(now time.Time, space numberSpace, payload []byte) int { 515 off, data, n := consumeCryptoFrame(payload) 516 err := c.handleCrypto(now, space, off, data) 517 if err != nil { 518 c.abort(now, err) 519 return -1 520 } 521 return n 522 } 523 524 func (c *Conn) handleStreamFrame(now time.Time, space numberSpace, payload []byte) int { 525 id, off, fin, b, n := consumeStreamFrame(payload) 526 if n < 0 { 527 return -1 528 } 529 if s := c.streamForFrame(now, id, recvStream); s != nil { 530 if err := s.handleData(off, b, fin); err != nil { 531 c.abort(now, err) 532 } 533 } 534 return n 535 } 536 537 func (c *Conn) handleNewConnectionIDFrame(now time.Time, space numberSpace, payload []byte) int { 538 seq, retire, connID, resetToken, n := consumeNewConnectionIDFrame(payload) 539 if n < 0 { 540 return -1 541 } 542 if err := c.connIDState.handleNewConnID(c, seq, retire, connID, resetToken); err != nil { 543 c.abort(now, err) 544 } 545 return n 546 } 547 548 func (c *Conn) handleRetireConnectionIDFrame(now time.Time, space numberSpace, payload []byte) int { 549 seq, n := consumeRetireConnectionIDFrame(payload) 550 if n < 0 { 551 return -1 552 } 553 if err := c.connIDState.handleRetireConnID(c, seq); err != nil { 554 c.abort(now, err) 555 } 556 return n 557 } 558 559 func (c *Conn) handlePathChallengeFrame(now time.Time, dgram *datagram, space numberSpace, payload []byte) int { 560 data, n := consumePathChallengeFrame(payload) 561 if n < 0 { 562 return -1 563 } 564 c.handlePathChallenge(now, dgram, data) 565 return n 566 } 567 568 func (c *Conn) handlePathResponseFrame(now time.Time, space numberSpace, payload []byte) int { 569 data, n := consumePathResponseFrame(payload) 570 if n < 0 { 571 return -1 572 } 573 c.handlePathResponse(now, data) 574 return n 575 } 576 577 func (c *Conn) handleConnectionCloseTransportFrame(now time.Time, payload []byte) int { 578 code, _, reason, n := consumeConnectionCloseTransportFrame(payload) 579 if n < 0 { 580 return -1 581 } 582 c.handlePeerConnectionClose(now, peerTransportError{code: code, reason: reason}) 583 return n 584 } 585 586 func (c *Conn) handleConnectionCloseApplicationFrame(now time.Time, payload []byte) int { 587 code, reason, n := consumeConnectionCloseApplicationFrame(payload) 588 if n < 0 { 589 return -1 590 } 591 c.handlePeerConnectionClose(now, &ApplicationError{Code: code, Reason: reason}) 592 return n 593 } 594 595 func (c *Conn) handleHandshakeDoneFrame(now time.Time, space numberSpace, payload []byte) int { 596 if c.side == serverSide { 597 // Clients should never send HANDSHAKE_DONE. 598 // https://www.rfc-editor.org/rfc/rfc9000#section-19.20-4 599 c.abort(now, localTransportError{ 600 code: errProtocolViolation, 601 reason: "client sent HANDSHAKE_DONE", 602 }) 603 return -1 604 } 605 if c.isAlive() { 606 c.confirmHandshake(now) 607 } 608 return 1 609 } 610 611 var errStatelessReset = errors.New("received stateless reset") 612 613 func (c *Conn) handleStatelessReset(now time.Time, resetToken statelessResetToken) (valid bool) { 614 if !c.connIDState.isValidStatelessResetToken(resetToken) { 615 return false 616 } 617 c.setFinalError(errStatelessReset) 618 c.enterDraining(now) 619 return true 620 }