Nota
El acceso a esta página requiere autorización. Puede intentar iniciar sesión o cambiar directorios.
El acceso a esta página requiere autorización. Puede intentar cambiar los directorios.
La System.Net.Quic biblioteca usa clases de opciones para configurar los objetos de protocolo (QuicListener y QuicConnection) antes de su construcción e inicialización. Hay tres clases de opciones diferentes para hacerlo:
- QuicListenerOptions: para configurar QuicListener antes de comenzar con QuicListener.ListenAsync(QuicListenerOptions, CancellationToken)
- QuicClientConnectionOptions: para configurar la salida QuicConnection antes de establecerla a través de QuicConnection.ConnectAsync(QuicClientConnectionOptions, CancellationToken)
- QuicServerConnectionOptions: para configurar la entrada de QuicConnection antes de entregarse desde QuicListener.AcceptConnectionAsync(CancellationToken)
Todas las clases de opciones se pueden configurar de forma incremental, lo que significa que no requieren que ninguna de sus propiedades se inicialice a través del constructor y se pueda configurar de forma independiente. En el momento en que se utilizan para configurar un nuevo listener o una conexión, las opciones se validan y se arroja un tipo apropiado de ArgumentException para cualquier valor obligatorio faltante o mal configurado. Por ejemplo, si no se establece obligatorio QuicConnectionOptions.DefaultStreamErrorCode , la llamada a ConnectAsync(QuicClientConnectionOptions, CancellationToken) produce ArgumentOutOfRangeException.
QuicListenerOptions
QuicListenerOptions se usa en QuicListener.ListenAsync(QuicListenerOptions, CancellationToken) al iniciar un nuevo QuicListener. Las propiedades de configuración individuales son:
Protocolos de Aplicación
ApplicationProtocols defina los protocolos de aplicación aceptados por el servidor (RFC 7301 - ALPN). Puede contener varios valores para distintos protocolos que no pueden estar relacionados. En el proceso de aceptar una nueva conexión, el agente de escucha puede restringir o seleccionar un protocolo específico para cada conexión entrante, consulte QuicListenerOptions.ConnectionOptionsCallback. Esta propiedad es obligatoria y debe contener al menos un valor.
ConnectionOptionsCallback
ConnectionOptionsCallback es un delegado para elegir QuicServerConnectionOptions en una conexión entrante. La función recibe una instancia inicializada parcialmente de QuicConnection y SslClientHelloInfo contiene el nombre del servidor solicitado por el cliente (RFC 6066 - SNI). El delegado se invoca para cada conexión entrante. Puede devolver diferentes opciones en función de la información de cliente proporcionada o puede devolver de forma segura la misma instancia de las opciones cada vez. El propósito y la forma del delegado son intencionadamente similares a ServerOptionsSelectionCallback usado en SslStream.AuthenticateAsServerAsync(ServerOptionsSelectionCallback, Object, CancellationToken). Esta propiedad es obligatoria.
ListenBacklog
ListenBacklog determina el número de conexiones entrantes que el agente de escucha puede mantener antes de que se rechacen otras adicionales. Cada intento de establecer una conexión cuenta, incluso cuando falla o cuando la conexión se interrumpe mientras se espera en la cola. Los procesos en curso para establecer una nueva conexión también cuentan para este límite. Las conexiones o los intentos de conexión se cuentan hasta que se recuperan a través de QuicListener.AcceptConnectionAsync(CancellationToken). El propósito del límite de trabajos pendientes es evitar que los servidores se agoten por más conexiones entrantes de las que pueden procesar. Esta propiedad es opcional, el valor predeterminado es 512.
ListenEndPoint
ListenEndPoint contiene la dirección IP y el puerto en el que la escucha aceptará nuevas conexiones. Debido a la implementación subyacente, MsQuic
el agente de escucha siempre se enlaza a un socket comodín de pila dual, independientemente de lo que se especifique aquí. Esto puede provocar algunos comportamientos inesperados, especialmente en comparación con los sockets TCP normales, como en los casos HTTP/1.1 y HTTP/2. Para obtener más información, vea Guía de solución de problemas de QUIC.
Esta propiedad es obligatoria.
QuicConnectionOptions
QuicConnectionOptions las opciones se comparten entre QuicClientConnectionOptions y QuicServerConnectionOptions. Es una clase base abstracta y no se puede usar por sí misma. Contiene estas propiedades:
- DefaultCloseErrorCode
- DefaultStreamErrorCode
- HandshakeTimeout
- IdleTimeout
- InitialReceiveWindowSizes
- KeepAliveInterval
- MaxInboundBidirectionalStreams
- MaxInboundUnidirectionalStreams
- StreamCapacityCallback
DefaultCloseErrorCode
DefaultCloseErrorCode se usa cuando la conexión se elimina sin llamar a QuicConnection.CloseAsync(Int64, CancellationToken). Es necesario que el protocolo QUIC proporcione un motivo de nivel de aplicación para cerrar una conexión (RFC 9000 - Cierre de conexión). QuicConnection no tiene forma de forzar que el código de aplicación llame CloseAsync(Int64, CancellationToken) antes de eliminar la conexión. En tal caso, la conexión debe saber qué código de error se va a usar. Esta propiedad es obligatoria.
DefaultStreamErrorCode
DefaultStreamErrorCode se usa cuando se elimina una secuencia antes de leer todos los datos. Al recibir datos a través del flujo QUIC, una aplicación puede consumir todos los datos o, si no, debe abortar su lado de lectura. De forma similar al cierre de la conexión, el protocolo QUIC requiere un motivo de nivel de aplicación para anular el lado de lectura (RFC 9000 - Detener el envío). Esta propiedad es obligatoria.
HandshakeTimeout
HandshakeTimeout establece el límite de tiempo en el que se debe establecer completamente la conexión; de lo contrario, se anula. Es posible establecer este valor en InfiniteTimeSpan , pero no se recomienda. Los intentos de conexión pueden bloquearse indefinidamente y no hay ningún medio para borrarlos aparte de detener el QuicListener. Esta propiedad es opcional, el valor predeterminado es de 10 segundos.
TiempoDeInactividad
Si la conexión está inactiva durante más tiempo que el especificado IdleTimeout, se desconecta. Esta opción forma parte de la especificación del protocolo QUIC (RFC 9000 - Tiempo de espera de inactividad) y se envía al par durante el apretón de manos de la conexión. A continuación, la conexión toma el menor entre su propio valor y el tiempo de espera de inactividad del par y lo utiliza. Por lo tanto, la conexión puede cerrarse en el tiempo de espera de inactividad antes del tiempo configurado en esta opción. Esta propiedad es opcional, el valor predeterminado se basa en MsQuic, que es de 30 segundos.
InitialReceiveWindowSizes
InitialReceiveWindowSizes especifica un conjunto de valores que, inicialmente, limita la cantidad de datos que se pueden recibir mediante la conexión o el flujo. El protocolo QUIC define un mecanismo para limitar la cantidad de datos que se pueden enviar a través de las secuencias individuales, así como de forma acumulativa para toda la conexión (RFC 9000 - Control de flujo de datos). Estos límites solo se aplican antes de que la aplicación empiece a consumir los datos. Después, MsQuic
ajusta continuamente el tamaño de la ventana de recepción en función de la rapidez con la que la aplicación las lee. Esta propiedad es de QuicReceiveWindowSizes tipo , que contiene estas opciones:
- Connection: límite acumulado para los datos recibidos en todos los flujos que pertenecen a esta conexión.
- LocallyInitiatedBidirectionalStream: límite para los datos recibidos en un flujo bidireccional saliente.
- RemotelyInitiatedBidirectionalStream: límite para los datos recibidos en un flujo bidireccional entrante.
- UnidirectionalStream: límite para los datos recibidos en una secuencia unidireccional entrante.
Estos valores deben ser un entero no negativo que sea una potencia de 2; se trata de una limitación heredada de MsQuic
. Si se establece cualquiera de estos valores en 0, básicamente, no se recibirá ningún dato por la secuencia específica o una conexión en su conjunto.
Esta propiedad es opcional, los valores predeterminados son de 64 KB para una secuencia y 64 MB para una conexión.
KeepAliveInterval
KeepAliveInterval determina si y con qué frecuencia se envían fotogramas PING para mantener la conexión activa y evitar que se cierre IdleTimeout (RFC 9000 - Fotogramas PING). Si establece esta propiedad, considere la recomendación de RFC 9000: aplazar el tiempo de espera de inactividad. Establecer el valor demasiado bajo podría afectar negativamente al rendimiento. Además, establecer la propiedad demasiado cerca del tiempo de espera de inactividad podría provocar cierres de conexión. Esta propiedad es opcional, el valor predeterminado significa InfiniteTimeSpan que no se enviará ningún PING.
MaxInboundBidirectionalStreams
MaxInboundBidirectionalStreams determina el número máximo de secuencias bidireccionales simultáneamente activas que la conexión está dispuesta a aceptar. Tenga en cuenta que esto difiere de la forma en que la especificación QUIC define la simultaneidad de control (RFC 9000 - Controlar la simultaneidad). El protocolo QUIC cuenta los flujos acumulativamente, durante la duración de la conexión y usa un límite cada vez mayor para determinar el número total de secuencias aceptadas por la conexión, incluidas las secuencias ya cerradas (RFC 9000 - MAX_STREAMS Frames). Esta propiedad simplifica esto para que la aplicación solo especifique el límite de flujo simultáneo y MsQuic
se encarga de traducir este límite a los fotogramas correspondientes MAX_STREAMS
.
Esta propiedad es opcional, el valor predeterminado es 0 para las conexiones de cliente y 100 para las conexiones de servidor.
MaxInboundUnidirectionalStreams
MaxInboundUnidirectionalStreams determina el número máximo de secuencias unidireccionales simultáneamente activas que la conexión está dispuesta a aceptar. Tenga en cuenta que esto difiere de la forma en que la especificación QUIC define el control de la simultaneidad de flujos (RFC 9000 - Control de simultaneidad). El protocolo QUIC cuenta los flujos acumulativamente, durante la duración de la conexión y usa un límite cada vez mayor para determinar el número total de secuencias aceptadas por la conexión, incluidas las secuencias ya cerradas (RFC 9000 - MAX_STREAMS Frames). Esta propiedad simplifica esto para que la aplicación solo especifique el límite de flujo simultáneo y MsQuic
se encarga de traducir este límite a los fotogramas correspondientes MAX_STREAMS
.
Esta propiedad es opcional, el valor predeterminado es 0 para las conexiones de cliente y 10 para las conexiones de servidor.
StreamCapacityCallback
StreamCapacityCallback es una devolución de llamada que se invoca cada vez que el par libera una nueva capacidad de secuencia a través de MAX_STREAMS
y, como resultado, la capacidad actual está por encima de 0. Los valores proporcionados en los argumentos de devolución de llamada son incrementos de capacidad, lo que significa que la suma de todos los valores de la devolución de llamada será igual al último valor recibido de MAX_STREAMS
(RFC 9000 - MAX_STREAMS Frames). Esta devolución de llamada se diseñó para admitir la funcionalidad de SocketsHttpHandler.EnableMultipleHttp3Connections y viene con varias advertencias:
- Es necesario que la aplicación realice un seguimiento de todas las secuencias en proceso de apertura y las ya abiertas para conocer la capacidad real en cualquier momento.
- Es posible que se llame a la devolución de llamada en paralelo, por lo que depende de la aplicación gestionar correctamente la sincronización con respecto al recuento de secuencias.
- La primera invocación (con la capacidad inicial) puede producirse antes de que la instancia QuicConnection se entregue a través de QuicConnection.ConnectAsync(QuicClientConnectionOptions, CancellationToken) o QuicListener.AcceptConnectionAsync(CancellationToken).
El siguiente escenario simplificado captura el comportamiento de la apertura de una secuencia y de la función de devolución de llamada.
El cliente inicia la conexión al servidor a través de:
var client = await QuicConnection.ConnectAsync(new QuicClientConnectionOptions { ... StreamCapacityCallback = (connection, args) => Console.WriteLine($"{connection} stream capacity increased by: unidi += {args.UnidirectionalIncrement}, bidi += {args.BidirectionalIncrement}") };
El servidor envía la configuración inicial al cliente con el límite
2
de flujos para secuencias unidireccionales y0
para bidireccionales.Se invoca al objeto del cliente
StreamCapacityCallback
y este imprime:[conn][0x58575BF805B0] stream capacity increased by: unidi += 2, bidi += 0
La llamada del cliente a
ConnectAsync
se completa con la conexión[conn][0x58575BF805B0]
.El cliente intenta abrir algunos flujos:
var stream1 = await connection.OpenOutboundStreamAsync(QuicStreamType.Unidirectional); var stream2 = await connection.OpenOutboundStreamAsync(QuicStreamType.Unidirectional); // The following call will get suspended because the stream's limit has been reached. var taskStream3 = connection.OpenOutboundStreamAsync(QuicStreamType.Unidirectional);
El cliente finaliza y cierra las dos primeras secuencias:
await stream1.WriteAsync(data, completeWrites: true); await stream1.DisposeAsync(); await stream2.WriteAsync(data, completeWrites: true); await stream2.DisposeAsync(); Console.WriteLine($"Stream 3 {(taskStream3.IsCompleted ? "opened" : "pending")}");
El cliente imprime:
Stream 3 pending
El servidor libera capacidad adicional de
2
después de procesar las dos primeras secuencias.Suceden dos cosas en el cliente. En primer lugar, se abre una tercera secuencia:
var stream3 = await taskStream3;
A continuación, se vuelve a llamar al cliente
StreamCapacityCallback
y este imprime:[conn][0x58575BF805B0] stream capacity increased by: unidi += 2, bidi += 0
Esta propiedad es opcional.
QuicServerConnectionOptions
QuicServerConnectionOptions las opciones son específicas para una conexión del lado servidor. Aparte de las propiedades heredadas de QuicConnectionOptions, contiene lo siguiente:
OpcionesDeAutenticaciónDelServidor
ServerAuthenticationOptions contiene la configuración de TLS para la conexión del servidor. Las opciones son las mismas que se usan en SslStream.AuthenticateAsServer(SslServerAuthenticationOptions) y SslStream.AuthenticateAsServerAsync(SslServerAuthenticationOptions, CancellationToken). Para el servidor QUIC, SslServerAuthenticationOptions es válido si:
- Al menos una de las siguientes propiedades devuelve un certificado válido: ServerCertificateSelectionCallback, ServerCertificateContext, ServerCertificate.
- Al menos un protocolo de aplicación se define en ApplicationProtocols.
- Si se cambia, EncryptionPolicy no se establece en NoEncryption (el valor predeterminado es RequireEncryption).
- Si se establece, CipherSuitesPolicy contiene al menos una de las siguientes opciones: TLS_AES_128_GCM_SHA256, TLS_AES_256_GCM_SHA384, TLS_CHACHA20_POLY1305_SHA256 (el valor predeterminado es
null
y permiteMsQuic
usar todos los conjuntos de cifrado compatibles con QUIC compatibles con el sistema operativo).
Esta propiedad es obligatoria y debe cumplir las condiciones enumeradas.
QuicClientConnectionOptions
QuicClientConnectionOptions las opciones son específicas de una conexión del lado cliente. Aparte de las propiedades heredadas de QuicConnectionOptions, contiene lo siguiente:
ClientAuthenticationOptions
ClientAuthenticationOptions contiene la configuración de TLS para la conexión de cliente. Las opciones son las mismas que se usan en SslStream.AuthenticateAsClient(SslClientAuthenticationOptions) y SslStream.AuthenticateAsClientAsync(SslClientAuthenticationOptions, CancellationToken). Para el cliente QUIC, SslClientAuthenticationOptions es válido si:
- Al menos un protocolo de aplicación se define en ApplicationProtocols.
- Si se cambia, EncryptionPolicy no se establece en NoEncryption (el valor predeterminado es RequireEncryption).
- Si se establece, CipherSuitesPolicy contiene al menos una de las siguientes opciones: TLS_AES_128_GCM_SHA256, TLS_AES_256_GCM_SHA384, TLS_CHACHA20_POLY1305_SHA256 (el valor predeterminado es
null
y permiteMsQuic
usar todos los conjuntos de cifrado compatibles con QUIC compatibles con el sistema operativo).
Esta propiedad es obligatoria y debe cumplir las condiciones enumeradas.
LocalEndPoint
LocalEndPoint contiene la dirección IP y el puerto al que se enlazará la conexión de cliente. Si no se especifica, el sistema operativo asigna una dirección IP y un puerto. Esta propiedad es opcional.
Punto Final Remoto
RemoteEndPoint puede ser DnsEndPoint o IPEndPoint del par con el que se establece la conexión. Si es un DnsEndPoint, se usa la primera dirección IP devuelta por Dns.GetHostAddressesAsync(String, CancellationToken). Esta propiedad es obligatoria.