...

Source file src/golang.org/x/net/internal/quic/conn_recv.go

Documentation: golang.org/x/net/internal/quic

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

View as plain text