github.com/danielpfeifer02/quic-go-prio-packs@v0.41.0-28/interface.go (about) 1 package quic 2 3 import ( 4 "context" 5 "crypto/tls" 6 "errors" 7 "io" 8 "net" 9 "time" 10 11 "github.com/danielpfeifer02/quic-go-prio-packs/internal/handshake" 12 "github.com/danielpfeifer02/quic-go-prio-packs/internal/protocol" 13 "github.com/danielpfeifer02/quic-go-prio-packs/logging" 14 "github.com/danielpfeifer02/quic-go-prio-packs/priority_setting" 15 ) 16 17 // The StreamID is the ID of a QUIC stream. 18 type StreamID = protocol.StreamID 19 20 // PRIO_PACKS_TAG 21 // Priority is the priority of a QUIC stream. 22 type Priority = priority_setting.Priority 23 24 // A Version is a QUIC version number. 25 type Version = protocol.Version 26 27 // A VersionNumber is a QUIC version number. 28 // Deprecated: VersionNumber was renamed to Version. 29 type VersionNumber = Version 30 31 const ( 32 // Version1 is RFC 9000 33 Version1 = protocol.Version1 34 // Version2 is RFC 9369 35 Version2 = protocol.Version2 36 ) 37 38 // A ClientToken is a token received by the client. 39 // It can be used to skip address validation on future connection attempts. 40 type ClientToken struct { 41 data []byte 42 } 43 44 type TokenStore interface { 45 // Pop searches for a ClientToken associated with the given key. 46 // Since tokens are not supposed to be reused, it must remove the token from the cache. 47 // It returns nil when no token is found. 48 Pop(key string) (token *ClientToken) 49 50 // Put adds a token to the cache with the given key. It might get called 51 // multiple times in a connection. 52 Put(key string, token *ClientToken) 53 } 54 55 // Err0RTTRejected is the returned from: 56 // * Open{Uni}Stream{Sync} 57 // * Accept{Uni}Stream 58 // * Stream.Read and Stream.Write 59 // when the server rejects a 0-RTT connection attempt. 60 var Err0RTTRejected = errors.New("0-RTT rejected") 61 62 // ConnectionTracingKey can be used to associate a ConnectionTracer with a Connection. 63 // It is set on the Connection.Context() context, 64 // as well as on the context passed to logging.Tracer.NewConnectionTracer. 65 var ConnectionTracingKey = connTracingCtxKey{} 66 67 type connTracingCtxKey struct{} 68 69 // QUICVersionContextKey can be used to find out the QUIC version of a TLS handshake from the 70 // context returned by tls.Config.ClientHelloInfo.Context. 71 var QUICVersionContextKey = handshake.QUICVersionContextKey 72 73 // Stream is the interface implemented by QUIC streams 74 // In addition to the errors listed on the Connection, 75 // calls to stream functions can return a StreamError if the stream is canceled. 76 type Stream interface { 77 ReceiveStream 78 SendStream 79 // SetDeadline sets the read and write deadlines associated 80 // with the connection. It is equivalent to calling both 81 // SetReadDeadline and SetWriteDeadline. 82 SetDeadline(t time.Time) error 83 // PRIO_PACKS_TAG 84 // Priority returns the stream specific priority used for potential adaptive streaming 85 Priority() Priority 86 // PRIO_PACKS_TAG 87 // SetPriority sets the stream specific priority used for potential adaptive streaming 88 SetPriority(Priority) 89 } 90 91 // A ReceiveStream is a unidirectional Receive Stream. 92 type ReceiveStream interface { 93 // StreamID returns the stream ID. 94 StreamID() StreamID 95 // Read reads data from the stream. 96 // Read can be made to time out and return a net.Error with Timeout() == true 97 // after a fixed time limit; see SetDeadline and SetReadDeadline. 98 // If the stream was canceled by the peer, the error implements the StreamError 99 // interface, and Canceled() == true. 100 // If the connection was closed due to a timeout, the error satisfies 101 // the net.Error interface, and Timeout() will be true. 102 io.Reader 103 // CancelRead aborts receiving on this stream. 104 // It will ask the peer to stop transmitting stream data. 105 // Read will unblock immediately, and future Read calls will fail. 106 // When called multiple times or after reading the io.EOF it is a no-op. 107 CancelRead(StreamErrorCode) 108 // SetReadDeadline sets the deadline for future Read calls and 109 // any currently-blocked Read call. 110 // A zero value for t means Read will not time out. 111 112 SetReadDeadline(t time.Time) error 113 // PRIO_PACKS_TAG 114 // Priority returns the stream specific priority used for potential adaptive streaming 115 Priority() Priority 116 // PRIO_PACKS_TAG 117 // SetPriority sets the stream specific priority used for potential adaptive streaming 118 SetPriority(Priority) 119 } 120 121 // A SendStream is a unidirectional Send Stream. 122 type SendStream interface { 123 // StreamID returns the stream ID. 124 StreamID() StreamID 125 // Write writes data to the stream. 126 // Write can be made to time out and return a net.Error with Timeout() == true 127 // after a fixed time limit; see SetDeadline and SetWriteDeadline. 128 // If the stream was canceled by the peer, the error implements the StreamError 129 // interface, and Canceled() == true. 130 // If the connection was closed due to a timeout, the error satisfies 131 // the net.Error interface, and Timeout() will be true. 132 io.Writer 133 // Close closes the write-direction of the stream. 134 // Future calls to Write are not permitted after calling Close. 135 // It must not be called concurrently with Write. 136 // It must not be called after calling CancelWrite. 137 io.Closer 138 // CancelWrite aborts sending on this stream. 139 // Data already written, but not yet delivered to the peer is not guaranteed to be delivered reliably. 140 // Write will unblock immediately, and future calls to Write will fail. 141 // When called multiple times or after closing the stream it is a no-op. 142 CancelWrite(StreamErrorCode) 143 // The Context is canceled as soon as the write-side of the stream is closed. 144 // This happens when Close() or CancelWrite() is called, or when the peer 145 // cancels the read-side of their stream. 146 // The cancellation cause is set to the error that caused the stream to 147 // close, or `context.Canceled` in case the stream is closed without error. 148 Context() context.Context 149 // SetWriteDeadline sets the deadline for future Write calls 150 // and any currently-blocked Write call. 151 // Even if write times out, it may return n > 0, indicating that 152 // some data was successfully written. 153 // A zero value for t means Write will not time out. 154 SetWriteDeadline(t time.Time) error 155 // PRIO_PACKS_TAG 156 // Priority returns the stream specific priority used for potential adaptive streaming 157 Priority() Priority 158 // PRIO_PACKS_TAG 159 // SetPriority sets the stream specific priority used for potential adaptive streaming 160 SetPriority(Priority) 161 } 162 163 // A Connection is a QUIC connection between two peers. 164 // Calls to the connection (and to streams) can return the following types of errors: 165 // * ApplicationError: for errors triggered by the application running on top of QUIC 166 // * TransportError: for errors triggered by the QUIC transport (in many cases a misbehaving peer) 167 // * IdleTimeoutError: when the peer goes away unexpectedly (this is a net.Error timeout error) 168 // * HandshakeTimeoutError: when the cryptographic handshake takes too long (this is a net.Error timeout error) 169 // * StatelessResetError: when we receive a stateless reset (this is a net.Error temporary error) 170 // * VersionNegotiationError: returned by the client, when there's no version overlap between the peers 171 type Connection interface { 172 // AcceptStream returns the next stream opened by the peer, blocking until one is available. 173 // If the connection was closed due to a timeout, the error satisfies 174 // the net.Error interface, and Timeout() will be true. 175 AcceptStream(context.Context) (Stream, error) 176 // AcceptUniStream returns the next unidirectional stream opened by the peer, blocking until one is available. 177 // If the connection was closed due to a timeout, the error satisfies 178 // the net.Error interface, and Timeout() will be true. 179 AcceptUniStream(context.Context) (ReceiveStream, error) 180 181 // OpenStream opens a new bidirectional QUIC stream. 182 // There is no signaling to the peer about new streams: 183 // The peer can only accept the stream after data has been sent on the stream. 184 // If the error is non-nil, it satisfies the net.Error interface. 185 // When reaching the peer's stream limit, err.Temporary() will be true. 186 // If the connection was closed due to a timeout, Timeout() will be true. 187 OpenStream() (Stream, error) 188 // PRIO_PACKS_TAG 189 // same as OpenStream, but with priority 190 OpenStreamWithPriority(Priority) (Stream, error) 191 192 // OpenStreamSync opens a new bidirectional QUIC stream. 193 // It blocks until a new stream can be opened. 194 // There is no signaling to the peer about new streams: 195 // The peer can only accept the stream after data has been sent on the stream, 196 // or the stream has been reset or closed. 197 // If the error is non-nil, it satisfies the net.Error interface. 198 // If the connection was closed due to a timeout, Timeout() will be true. 199 OpenStreamSync(context.Context) (Stream, error) 200 // PRIO_PACKS_TAG 201 // same as OpenStreamSync, but with priority 202 OpenStreamSyncWithPriority(context.Context, Priority) (Stream, error) 203 204 // OpenUniStream opens a new outgoing unidirectional QUIC stream. 205 // If the error is non-nil, it satisfies the net.Error interface. 206 // When reaching the peer's stream limit, Temporary() will be true. 207 // If the connection was closed due to a timeout, Timeout() will be true. 208 OpenUniStream() (SendStream, error) 209 // PRIO_PACKS_TAG 210 // same as OpenUniStream, but with priotity 211 OpenUniStreamWithPriority(Priority) (SendStream, error) 212 213 // OpenUniStreamSync opens a new outgoing unidirectional QUIC stream. 214 // It blocks until a new stream can be opened. 215 // If the error is non-nil, it satisfies the net.Error interface. 216 // If the connection was closed due to a timeout, Timeout() will be true. 217 OpenUniStreamSync(context.Context) (SendStream, error) 218 // PRIO_PACKS_TAG 219 // same as OpenUniStreamSync, but with priority 220 OpenUniStreamSyncWithPriority(context.Context, Priority) (SendStream, error) 221 222 // LocalAddr returns the local address. 223 LocalAddr() net.Addr 224 // RemoteAddr returns the address of the peer. 225 RemoteAddr() net.Addr 226 // CloseWithError closes the connection with an error. 227 // The error string will be sent to the peer. 228 CloseWithError(ApplicationErrorCode, string) error 229 // Context returns a context that is cancelled when the connection is closed. 230 // The cancellation cause is set to the error that caused the connection to 231 // close, or `context.Canceled` in case the listener is closed first. 232 Context() context.Context 233 // ConnectionState returns basic details about the QUIC connection. 234 // Warning: This API should not be considered stable and might change soon. 235 ConnectionState() ConnectionState 236 237 // SendDatagram sends a message using a QUIC datagram, as specified in RFC 9221. 238 // There is no delivery guarantee for DATAGRAM frames, they are not retransmitted if lost. 239 // The payload of the datagram needs to fit into a single QUIC packet. 240 // In addition, a datagram may be dropped before being sent out if the available packet size suddenly decreases. 241 // If the payload is too large to be sent at the current time, a DatagramTooLargeError is returned. 242 SendDatagram(payload []byte) error 243 244 // DATAGRAM_PRIO_TAG 245 SendDatagramWithPriority(p []byte, prio priority_setting.Priority) error 246 247 // ReceiveDatagram gets a message received in a datagram, as specified in RFC 9221. 248 ReceiveDatagram(context.Context) ([]byte, error) 249 250 // PRIO_PACKS_TAG 251 // get the priority of a corresponding stream using the streamID 252 GetPriority(StreamID) Priority 253 254 // PACKET_NUMBER_TAG 255 // SetPacketNumber sets the packet number for the next packet sent on the connection. 256 // This is needed if bpf porgrams are sending packets. 257 SetPacketNumber(int64) 258 // SetHighestSent sets the highest packet number sent on the connection. 259 // This is needed if bpf porgrams are sending packets. 260 SetHighestSent(int64) 261 // (Un-)Locking the packet number setting so that it is not changed during actively checking 262 // a packet number of a packet. 263 Lock() 264 Unlock() 265 266 // BPF_MAP_TAG 267 GetDestConnID(Stream) ConnectionID 268 } 269 270 // An EarlyConnection is a connection that is handshaking. 271 // Data sent during the handshake is encrypted using the forward secure keys. 272 // When using client certificates, the client's identity is only verified 273 // after completion of the handshake. 274 type EarlyConnection interface { 275 Connection 276 277 // HandshakeComplete blocks until the handshake completes (or fails). 278 // For the client, data sent before completion of the handshake is encrypted with 0-RTT keys. 279 // For the server, data sent before completion of the handshake is encrypted with 1-RTT keys, 280 // however the client's identity is only verified once the handshake completes. 281 HandshakeComplete() <-chan struct{} 282 283 NextConnection() Connection 284 } 285 286 // StatelessResetKey is a key used to derive stateless reset tokens. 287 type StatelessResetKey [32]byte 288 289 // TokenGeneratorKey is a key used to encrypt session resumption tokens. 290 type TokenGeneratorKey = handshake.TokenProtectorKey 291 292 // A ConnectionID is a QUIC Connection ID, as defined in RFC 9000. 293 // It is not able to handle QUIC Connection IDs longer than 20 bytes, 294 // as they are allowed by RFC 8999. 295 type ConnectionID = protocol.ConnectionID 296 297 // ConnectionIDFromBytes interprets b as a Connection ID. It panics if b is 298 // longer than 20 bytes. 299 func ConnectionIDFromBytes(b []byte) ConnectionID { 300 return protocol.ParseConnectionID(b) 301 } 302 303 // A ConnectionIDGenerator is an interface that allows clients to implement their own format 304 // for the Connection IDs that servers/clients use as SrcConnectionID in QUIC packets. 305 // 306 // Connection IDs generated by an implementation should always produce IDs of constant size. 307 type ConnectionIDGenerator interface { 308 // GenerateConnectionID generates a new ConnectionID. 309 // Generated ConnectionIDs should be unique and observers should not be able to correlate two ConnectionIDs. 310 GenerateConnectionID() (ConnectionID, error) 311 312 // ConnectionIDLen tells what is the length of the ConnectionIDs generated by the implementation of 313 // this interface. 314 // Effectively, this means that implementations of ConnectionIDGenerator must always return constant-size 315 // connection IDs. Valid lengths are between 0 and 20 and calls to GenerateConnectionID. 316 // 0-length ConnectionsIDs can be used when an endpoint (server or client) does not require multiplexing connections 317 // in the presence of a connection migration environment. 318 ConnectionIDLen() int 319 } 320 321 // Config contains all configuration data needed for a QUIC server or client. 322 type Config struct { 323 // GetConfigForClient is called for incoming connections. 324 // If the error is not nil, the connection attempt is refused. 325 GetConfigForClient func(info *ClientHelloInfo) (*Config, error) 326 // The QUIC versions that can be negotiated. 327 // If not set, it uses all versions available. 328 Versions []Version 329 // HandshakeIdleTimeout is the idle timeout before completion of the handshake. 330 // If we don't receive any packet from the peer within this time, the connection attempt is aborted. 331 // Additionally, if the handshake doesn't complete in twice this time, the connection attempt is also aborted. 332 // If this value is zero, the timeout is set to 5 seconds. 333 HandshakeIdleTimeout time.Duration 334 // MaxIdleTimeout is the maximum duration that may pass without any incoming network activity. 335 // The actual value for the idle timeout is the minimum of this value and the peer's. 336 // This value only applies after the handshake has completed. 337 // If the timeout is exceeded, the connection is closed. 338 // If this value is zero, the timeout is set to 30 seconds. 339 MaxIdleTimeout time.Duration 340 // The TokenStore stores tokens received from the server. 341 // Tokens are used to skip address validation on future connection attempts. 342 // The key used to store tokens is the ServerName from the tls.Config, if set 343 // otherwise the token is associated with the server's IP address. 344 TokenStore TokenStore 345 // InitialStreamReceiveWindow is the initial size of the stream-level flow control window for receiving data. 346 // If the application is consuming data quickly enough, the flow control auto-tuning algorithm 347 // will increase the window up to MaxStreamReceiveWindow. 348 // If this value is zero, it will default to 512 KB. 349 // Values larger than the maximum varint (quicvarint.Max) will be clipped to that value. 350 InitialStreamReceiveWindow uint64 351 // MaxStreamReceiveWindow is the maximum stream-level flow control window for receiving data. 352 // If this value is zero, it will default to 6 MB. 353 // Values larger than the maximum varint (quicvarint.Max) will be clipped to that value. 354 MaxStreamReceiveWindow uint64 355 // InitialConnectionReceiveWindow is the initial size of the stream-level flow control window for receiving data. 356 // If the application is consuming data quickly enough, the flow control auto-tuning algorithm 357 // will increase the window up to MaxConnectionReceiveWindow. 358 // If this value is zero, it will default to 512 KB. 359 // Values larger than the maximum varint (quicvarint.Max) will be clipped to that value. 360 InitialConnectionReceiveWindow uint64 361 // MaxConnectionReceiveWindow is the connection-level flow control window for receiving data. 362 // If this value is zero, it will default to 15 MB. 363 // Values larger than the maximum varint (quicvarint.Max) will be clipped to that value. 364 MaxConnectionReceiveWindow uint64 365 // AllowConnectionWindowIncrease is called every time the connection flow controller attempts 366 // to increase the connection flow control window. 367 // If set, the caller can prevent an increase of the window. Typically, it would do so to 368 // limit the memory usage. 369 // To avoid deadlocks, it is not valid to call other functions on the connection or on streams 370 // in this callback. 371 AllowConnectionWindowIncrease func(conn Connection, delta uint64) bool 372 // MaxIncomingStreams is the maximum number of concurrent bidirectional streams that a peer is allowed to open. 373 // If not set, it will default to 100. 374 // If set to a negative value, it doesn't allow any bidirectional streams. 375 // Values larger than 2^60 will be clipped to that value. 376 MaxIncomingStreams int64 377 // MaxIncomingUniStreams is the maximum number of concurrent unidirectional streams that a peer is allowed to open. 378 // If not set, it will default to 100. 379 // If set to a negative value, it doesn't allow any unidirectional streams. 380 // Values larger than 2^60 will be clipped to that value. 381 MaxIncomingUniStreams int64 382 // KeepAlivePeriod defines whether this peer will periodically send a packet to keep the connection alive. 383 // If set to 0, then no keep alive is sent. Otherwise, the keep alive is sent on that period (or at most 384 // every half of MaxIdleTimeout, whichever is smaller). 385 KeepAlivePeriod time.Duration 386 // DisablePathMTUDiscovery disables Path MTU Discovery (RFC 8899). 387 // This allows the sending of QUIC packets that fully utilize the available MTU of the path. 388 // Path MTU discovery is only available on systems that allow setting of the Don't Fragment (DF) bit. 389 // If unavailable or disabled, packets will be at most 1252 (IPv4) / 1232 (IPv6) bytes in size. 390 DisablePathMTUDiscovery bool 391 // Allow0RTT allows the application to decide if a 0-RTT connection attempt should be accepted. 392 // Only valid for the server. 393 Allow0RTT bool 394 // Enable QUIC datagram support (RFC 9221). 395 EnableDatagrams bool 396 Tracer func(context.Context, logging.Perspective, ConnectionID) *logging.ConnectionTracer 397 } 398 399 type ClientHelloInfo struct { 400 RemoteAddr net.Addr 401 } 402 403 // ConnectionState records basic details about a QUIC connection 404 type ConnectionState struct { 405 // TLS contains information about the TLS connection state, incl. the tls.ConnectionState. 406 TLS tls.ConnectionState 407 // SupportsDatagrams says if support for QUIC datagrams (RFC 9221) was negotiated. 408 // This requires both nodes to support and enable the datagram extensions (via Config.EnableDatagrams). 409 // If datagram support was negotiated, datagrams can be sent and received using the 410 // SendDatagram and ReceiveDatagram methods on the Connection. 411 SupportsDatagrams bool 412 // Used0RTT says if 0-RTT resumption was used. 413 Used0RTT bool 414 // Version is the QUIC version of the QUIC connection. 415 Version Version 416 // GSO says if generic segmentation offload is used 417 GSO bool 418 }