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