golang.org/x/net@v0.25.1-0.20240516223405-c87a5b62e243/quic/quic.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  	"time"
    11  )
    12  
    13  // QUIC versions.
    14  // We only support v1 at this time.
    15  const (
    16  	quicVersion1 = 1
    17  	quicVersion2 = 0x6b3343cf // https://www.rfc-editor.org/rfc/rfc9369
    18  )
    19  
    20  // connIDLen is the length in bytes of connection IDs chosen by this package.
    21  // Since 1-RTT packets don't include a connection ID length field,
    22  // we use a consistent length for all our IDs.
    23  // https://www.rfc-editor.org/rfc/rfc9000.html#section-5.1-6
    24  const connIDLen = 8
    25  
    26  // Local values of various transport parameters.
    27  // https://www.rfc-editor.org/rfc/rfc9000.html#section-18.2
    28  const (
    29  	defaultMaxIdleTimeout = 30 * time.Second // max_idle_timeout
    30  
    31  	// The max_udp_payload_size transport parameter is the size of our
    32  	// network receive buffer.
    33  	//
    34  	// Set this to the largest UDP packet that can be sent over
    35  	// Ethernet without using jumbo frames: 1500 byte Ethernet frame,
    36  	// minus 20 byte IPv4 header and 8 byte UDP header.
    37  	//
    38  	// The maximum possible UDP payload is 65527 bytes. Supporting this
    39  	// without wasting memory in unused receive buffers will require some
    40  	// care. For now, just limit ourselves to the most common case.
    41  	maxUDPPayloadSize = 1472
    42  
    43  	ackDelayExponent = 3                     // ack_delay_exponent
    44  	maxAckDelay      = 25 * time.Millisecond // max_ack_delay
    45  
    46  	// The active_conn_id_limit transport parameter is the maximum
    47  	// number of connection IDs from the peer we're willing to store.
    48  	//
    49  	// maxPeerActiveConnIDLimit is the maximum number of connection IDs
    50  	// we're willing to send to the peer.
    51  	//
    52  	// https://www.rfc-editor.org/rfc/rfc9000.html#section-18.2-6.2.1
    53  	activeConnIDLimit        = 2
    54  	maxPeerActiveConnIDLimit = 4
    55  )
    56  
    57  // Time limit for completing the handshake.
    58  const defaultHandshakeTimeout = 10 * time.Second
    59  
    60  // Keep-alive ping frequency.
    61  const defaultKeepAlivePeriod = 0
    62  
    63  // Local timer granularity.
    64  // https://www.rfc-editor.org/rfc/rfc9002.html#section-6.1.2-6
    65  const timerGranularity = 1 * time.Millisecond
    66  
    67  // The smallest allowed maximum datagram size.
    68  // https://www.rfc-editor.org/rfc/rfc9000#section-14
    69  const smallestMaxDatagramSize = 1200
    70  
    71  // Minimum size of a UDP datagram sent by a client carrying an Initial packet,
    72  // or a server containing an ack-eliciting Initial packet.
    73  // https://www.rfc-editor.org/rfc/rfc9000#section-14.1
    74  const paddedInitialDatagramSize = smallestMaxDatagramSize
    75  
    76  // Maximum number of streams of a given type which may be created.
    77  // https://www.rfc-editor.org/rfc/rfc9000.html#section-4.6-2
    78  const maxStreamsLimit = 1 << 60
    79  
    80  // Maximum number of streams we will allow the peer to create implicitly.
    81  // A stream ID that is used out of order results in all streams of that type
    82  // with lower-numbered IDs also being opened. To limit the amount of work we
    83  // will do in response to a single frame, we cap the peer's stream limit to
    84  // this value.
    85  const implicitStreamLimit = 100
    86  
    87  // A connSide distinguishes between the client and server sides of a connection.
    88  type connSide int8
    89  
    90  const (
    91  	clientSide = connSide(iota)
    92  	serverSide
    93  )
    94  
    95  func (s connSide) String() string {
    96  	switch s {
    97  	case clientSide:
    98  		return "client"
    99  	case serverSide:
   100  		return "server"
   101  	default:
   102  		return "BUG"
   103  	}
   104  }
   105  
   106  func (s connSide) peer() connSide {
   107  	if s == clientSide {
   108  		return serverSide
   109  	} else {
   110  		return clientSide
   111  	}
   112  }
   113  
   114  // A numberSpace is the context in which a packet number applies.
   115  // https://www.rfc-editor.org/rfc/rfc9000.html#section-12.3-7
   116  type numberSpace byte
   117  
   118  const (
   119  	initialSpace = numberSpace(iota)
   120  	handshakeSpace
   121  	appDataSpace
   122  	numberSpaceCount
   123  )
   124  
   125  func (n numberSpace) String() string {
   126  	switch n {
   127  	case initialSpace:
   128  		return "Initial"
   129  	case handshakeSpace:
   130  		return "Handshake"
   131  	case appDataSpace:
   132  		return "AppData"
   133  	default:
   134  		return "BUG"
   135  	}
   136  }
   137  
   138  // A streamType is the type of a stream: bidirectional or unidirectional.
   139  type streamType uint8
   140  
   141  const (
   142  	bidiStream = streamType(iota)
   143  	uniStream
   144  	streamTypeCount
   145  )
   146  
   147  func (s streamType) qlogString() string {
   148  	switch s {
   149  	case bidiStream:
   150  		return "bidirectional"
   151  	case uniStream:
   152  		return "unidirectional"
   153  	default:
   154  		return "BUG"
   155  	}
   156  }
   157  
   158  func (s streamType) String() string {
   159  	switch s {
   160  	case bidiStream:
   161  		return "bidi"
   162  	case uniStream:
   163  		return "uni"
   164  	default:
   165  		return "BUG"
   166  	}
   167  }
   168  
   169  // A streamID is a QUIC stream ID.
   170  // https://www.rfc-editor.org/rfc/rfc9000.html#section-2.1
   171  type streamID uint64
   172  
   173  // The two least significant bits of a stream ID indicate the initiator
   174  // and directionality of the stream. The upper bits are the stream number.
   175  // Each of the four possible combinations of initiator and direction
   176  // each has a distinct number space.
   177  const (
   178  	clientInitiatedStreamBit = 0x0
   179  	serverInitiatedStreamBit = 0x1
   180  	initiatorStreamBitMask   = 0x1
   181  
   182  	bidiStreamBit    = 0x0
   183  	uniStreamBit     = 0x2
   184  	dirStreamBitMask = 0x2
   185  )
   186  
   187  func newStreamID(initiator connSide, typ streamType, num int64) streamID {
   188  	id := streamID(num << 2)
   189  	if typ == uniStream {
   190  		id |= uniStreamBit
   191  	}
   192  	if initiator == serverSide {
   193  		id |= serverInitiatedStreamBit
   194  	}
   195  	return id
   196  }
   197  
   198  func (s streamID) initiator() connSide {
   199  	if s&initiatorStreamBitMask == serverInitiatedStreamBit {
   200  		return serverSide
   201  	}
   202  	return clientSide
   203  }
   204  
   205  func (s streamID) num() int64 {
   206  	return int64(s) >> 2
   207  }
   208  
   209  func (s streamID) streamType() streamType {
   210  	if s&dirStreamBitMask == uniStreamBit {
   211  		return uniStream
   212  	}
   213  	return bidiStream
   214  }
   215  
   216  // packetFate is the fate of a sent packet: Either acknowledged by the peer,
   217  // or declared lost.
   218  type packetFate byte
   219  
   220  const (
   221  	packetLost = packetFate(iota)
   222  	packetAcked
   223  )