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 )