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