| File: System\Net\Quic\QuicConnectionOptions.cs | Web Access |
| Project: src\runtime\src\libraries\System.Net.Quic\src\System.Net.Quic.csproj (System.Net.Quic) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using System.Net.Security; using System.Runtime.CompilerServices; using System.Threading; using static System.Net.Quic.ThrowHelper; namespace System.Net.Quic; /// <summary> /// Collection of receive window sizes for <see cref="QuicConnection"/> as a whole and for individual <see cref="QuicStream"/> types. /// </summary> public sealed class QuicReceiveWindowSizes { /// <summary> /// The initial flow-control window size for the connection. /// </summary> public int Connection { get; set; } = QuicDefaults.DefaultConnectionMaxData; /// <summary> /// The initial flow-control window size for locally initiated bidirectional streams. /// </summary> public int LocallyInitiatedBidirectionalStream { get; set; } = QuicDefaults.DefaultStreamMaxData; /// <summary> /// The initial flow-control window size for remotely initiated bidirectional streams. /// </summary> public int RemotelyInitiatedBidirectionalStream { get; set; } = QuicDefaults.DefaultStreamMaxData; /// <summary> /// The initial flow-control window size for (remotely initiated) unidirectional streams. /// </summary> public int UnidirectionalStream { get; set; } = QuicDefaults.DefaultStreamMaxData; internal void Validate(string argumentName) { ValidatePowerOf2(argumentName, Connection); ValidatePowerOf2(argumentName, LocallyInitiatedBidirectionalStream); ValidatePowerOf2(argumentName, RemotelyInitiatedBidirectionalStream); ValidatePowerOf2(argumentName, UnidirectionalStream); static void ValidatePowerOf2(string argumentName, int value, [CallerArgumentExpression(nameof(value))] string? propertyName = null) { if (value <= 0 || ((value - 1) & value) != 0) { throw new ArgumentOutOfRangeException(argumentName, value, SR.Format(SR.net_quic_power_of_2, $"{nameof(QuicConnectionOptions.InitialReceiveWindowSizes)}.{propertyName}")); } } } } /// <summary> /// Arguments for <see cref="QuicConnectionOptions.StreamCapacityCallback"/>. /// </summary> public readonly struct QuicStreamCapacityChangedArgs { /// <summary> /// The increment saying how many additional bidirectional streams can be opened on the connection, increased via the latest MAX_STREAMS frame. /// </summary> public int BidirectionalIncrement { get; init; } /// <summary> /// The increment saying how many additional unidirectional streams can be opened on the connection, increased via the latest MAX_STREAMS frame. /// </summary> public int UnidirectionalIncrement { get; init; } } /// <summary> /// Shared options for both client (outbound) and server (inbound) <see cref="QuicConnection" />. /// </summary> public abstract class QuicConnectionOptions { /// <summary> /// Prevent sub-classing by code outside of this assembly. /// </summary> internal QuicConnectionOptions() { } /// <summary> /// The maximum number of concurrent bidirectional streams that the remote peer connection can create on an open connection. /// Default 0 for client and 100 for server connection. /// </summary> public int MaxInboundBidirectionalStreams { get; set; } /// <summary> /// The maximum number of concurrent unidirectional streams that the remote peer connection can create on an open connection. /// Default 0 for client and 10 for server connection. /// </summary> public int MaxInboundUnidirectionalStreams { get; set; } /// <summary> /// Idle timeout for connections, after which the connection will be closed. /// Default <see cref="TimeSpan.Zero"/> means underlying implementation default idle timeout. /// </summary> public TimeSpan IdleTimeout { get; set; } = TimeSpan.Zero; /// <summary> /// Error code used when the stream needs to abort read or write side of the stream internally. /// This property is mandatory and not setting it will result in validation error when establishing a connection. /// </summary> // QUIC doesn't allow negative value: https://www.rfc-editor.org/rfc/rfc9000.html#integer-encoding // We can safely use this to distinguish if user provided value during validation. public long DefaultStreamErrorCode { get; set; } = -1; /// <summary> /// Error code used for <see cref="QuicConnection.CloseAsync(long, Threading.CancellationToken)"/> when the connection gets disposed. /// This property is mandatory and not setting it will result in validation error when establishing a connection. /// </summary> /// <remarks> /// To use different close error code, call <see cref="QuicConnection.CloseAsync(long, Threading.CancellationToken)"/> explicitly before disposing. /// </remarks> // QUIC doesn't allow negative value: https://www.rfc-editor.org/rfc/rfc9000.html#integer-encoding // We can safely use this to distinguish if user provided value during validation. public long DefaultCloseErrorCode { get; set; } = -1; internal QuicReceiveWindowSizes? _initialReceiveWindowSizes; /// <summary> /// The initial receive window sizes for the connection and individual stream types. /// </summary> public QuicReceiveWindowSizes InitialReceiveWindowSizes { get => _initialReceiveWindowSizes ??= new QuicReceiveWindowSizes(); set => _initialReceiveWindowSizes = value; } /// <summary> /// The interval at which keep alive packets are sent on the connection. /// Value <see cref="TimeSpan.Zero"/> means underlying implementation default timeout. /// Default <see cref="Timeout.InfiniteTimeSpan"/> means never sending keep alive packets. /// </summary> public TimeSpan KeepAliveInterval { get; set; } = Timeout.InfiniteTimeSpan; /// <summary> /// The upper bound on time when the handshake must complete. If the handshake does not /// complete in this time, the connection is aborted. /// Value <see cref="TimeSpan.Zero"/> means underlying implementation default timeout. /// Default timeout is 10 seconds. /// </summary> public TimeSpan HandshakeTimeout { get; set; } = QuicDefaults.HandshakeTimeout; /// <summary> /// Optional callback that is invoked when new stream limit is released by the peer. Corresponds to receiving a MAX_STREAMS frame. /// The callback values represent increments of stream limits, e.g.: current limit is 10 bidirectional streams, callback arguments notify 5 more additional bidirectional streams => 15 bidirectional streams can be opened in total at the moment. /// The initial capacity is reported with the first invocation of the callback that might happen before the <see cref="QuicConnection"/> instance is handed out via either /// <see cref="QuicConnection.ConnectAsync(QuicClientConnectionOptions, CancellationToken)"/> or <see cref="QuicListener.AcceptConnectionAsync(CancellationToken)"/>. /// </summary> public Action<QuicConnection, QuicStreamCapacityChangedArgs>? StreamCapacityCallback { get; set; } /// <summary> /// Validates the options and potentially sets platform specific defaults. /// </summary> /// <param name="argumentName">Name of the from the caller.</param> internal virtual void Validate(string argumentName) { ValidateInRange(argumentName, MaxInboundBidirectionalStreams, ushort.MaxValue); ValidateInRange(argumentName, MaxInboundUnidirectionalStreams, ushort.MaxValue); ValidateTimeSpan(argumentName, IdleTimeout); ValidateTimeSpan(argumentName, KeepAliveInterval); ValidateErrorCode(argumentName, DefaultCloseErrorCode); ValidateErrorCode(argumentName, DefaultStreamErrorCode); ValidateTimeSpan(argumentName, HandshakeTimeout); _initialReceiveWindowSizes?.Validate(argumentName); } } /// <summary> /// Options for client (outbound) <see cref="QuicConnection" />. /// </summary> public sealed class QuicClientConnectionOptions : QuicConnectionOptions { /// <summary> /// Initializes a new instance of the <see cref="QuicClientConnectionOptions"/> class. /// </summary> public QuicClientConnectionOptions() { MaxInboundBidirectionalStreams = QuicDefaults.DefaultClientMaxInboundBidirectionalStreams; MaxInboundUnidirectionalStreams = QuicDefaults.DefaultClientMaxInboundUnidirectionalStreams; } /// <summary> /// Client authentication options to use when establishing a new connection. /// This property is mandatory and not setting it will result in validation error when establishing a connection. /// </summary> public SslClientAuthenticationOptions ClientAuthenticationOptions { get; set; } = null!; /// <summary> /// The remote endpoint to connect to. May be both <see cref="DnsEndPoint"/>, which will get resolved to an IP before connecting, or directly <see cref="IPEndPoint"/>. /// This property is mandatory and not setting it will result in validation error when establishing a connection. /// </summary> public EndPoint RemoteEndPoint { get; set; } = null!; /// <summary> /// The optional local endpoint that will be bound to. /// </summary> public IPEndPoint? LocalEndPoint { get; set; } /// <summary> /// Validates the options and potentially sets platform specific defaults. /// </summary> /// <param name="argumentName">Name of the from the caller.</param> internal override void Validate(string argumentName) { base.Validate(argumentName); // The content of ClientAuthenticationOptions gets validate in MsQuicConfiguration.Create. ValidateNotNull(argumentName, SR.net_quic_not_null_open_connection, ClientAuthenticationOptions); ValidateNotNull(argumentName, SR.net_quic_not_null_open_connection, RemoteEndPoint); } } /// <summary> /// Options for server (inbound) <see cref="QuicConnection" />. Provided by <see cref="QuicListenerOptions.ConnectionOptionsCallback"/>. /// </summary> public sealed class QuicServerConnectionOptions : QuicConnectionOptions { /// <summary> /// Initializes a new instance of the <see cref="QuicClientConnectionOptions"/> class. /// </summary> public QuicServerConnectionOptions() { MaxInboundBidirectionalStreams = QuicDefaults.DefaultServerMaxInboundBidirectionalStreams; MaxInboundUnidirectionalStreams = QuicDefaults.DefaultServerMaxInboundUnidirectionalStreams; } /// <summary> /// Server authentication options to use when accepting a new connection. /// This property is mandatory and not setting it will result in validation error when establishing a connection. /// </summary> public SslServerAuthenticationOptions ServerAuthenticationOptions { get; set; } = null!; /// <summary> /// Validates the options and potentially sets platform specific defaults. /// </summary> /// <param name="argumentName">Name of the from the caller.</param> internal override void Validate(string argumentName) { base.Validate(argumentName); // The content of ServerAuthenticationOptions gets validate in MsQuicConfiguration.Create. ValidateNotNull(argumentName, SR.net_quic_not_null_accept_connection, ServerAuthenticationOptions); } }