Solución de problemas de QUIC en .NET
En este artículo, aprenderá a diagnosticar los problemas más comunes con QUIC en .NET.
La biblioteca System.Net.Quic
se basa en la implementación de QUIC de código abierto MsQuic. Debido a esto, el comportamiento difiere de los sockets normales, a veces por diseño. Además, se basa en el protocolo UDP y no proporciona la misma experiencia exacta que con TCP.
El cliente de escucha se está ejecutando, pero no recibe ningún dato
Si un cliente de escucha se está ejecutando pero nunca recibe datos, podría deberse a que otro proceso está escuchando en el mismo puerto. Para comprobar qué proceso usa qué puerto, ejecute lo siguiente:
sudo ss -tulpw
Este comportamiento es por diseño, ya que MsQuic
usa SO_REUSEPORT
para lograr un mejor rendimiento. Para obtener más información, consulte la documentación de ListenerStart y el problema original dotnet/runtime#59382.
Nota
Este problema no se produce en Windows, donde MsQuic intentará realizar una reserva de puertos. Esto hace que la aplicación que intenta abrir el segundo cliente de escucha en el mismo puerto no se inicie.
QuicListener siempre escucha en cualquier dirección
Incluso si se proporciona una dirección específica desde la propiedad ListenEndpoint
, QuicListener todavía abre un socket comodín de pila doble. Este comportamiento está diseñado así debido a MsQuic
. La dirección IP de escucha se sigue usando para realizar el filtrado dentro de MsQuic
. Para más información, vea la documentación de ListenerStart y la incidencia original [dotnet/runtime#92812].
El cliente recibe un error de ALPN inesperado
El cliente intenta conectarse, pero recibe Application layer protocol negotiation error was encountered
a pesar de usar el mismo ALPN que el servidor.
Lo que sucede es que el cliente de escucha siempre se enlaza a la dirección comodín en modo dual, independientemente de lo que haya especificado la aplicación. A continuación, coincide con las conexiones entrantes por dirección IP y ALPN. Si no se encuentra ninguna coincidencia, notifica el error mencionado anteriormente. Como resultado, la falta de coincidencia entre la dirección IP de escucha y la de conexión producirá un error de ALPN.
Para evitar este error, asegúrese de que se está conectando a la misma dirección para la que se inició el cliente de escucha. Por ejemplo, imprima la dirección de escucha del cliente de escucha:
await using var listener = QuicListener.ListenAsync(new() /* appropriate options */);
Console.WriteLine(listener.LocalEndPoint);
Este problema puede ocurrir en varios escenarios diferentes, como en este problema dotnet/runtime#85412. El servidor se inició para la dirección Loopback
(127.0.0.1
) y todo funcionó cuando se ejecutó en la misma máquina. Sin embargo, cuando el cliente intentó conectarse desde otra, la dirección no coincidía con la dirección de bucle invertido del servidor y se rechazó con el error de ALPN.
Nota
Esto sucede cuando el cliente de escucha usa MsQuic, por ejemplo a través de .NET QuicListener
.
El cliente de escucha se inicia correctamente para IPv6 a pesar de estar deshabilitado
A pesar de que IPv6 está deshabilitado, QuicListener.ListenAsync
se realiza correctamente con una dirección IPv6. Esto está relacionado con el problema anterior, ya que MsQuic
se enlaza a la dirección comodín y, por lo tanto, lo hace correctamente. Como resultado, el cliente de escucha se inicia, pero no se puede establecer ninguna conexión con él. Se trata de una diferencia de comportamiento de los sockets, que se produce en ese caso.
Hay muchas maneras de comprobar si IPv6 está habilitado; por ejemplo, en Linux, compruebe el estado del módulo IPv6:
cat /sys/module/ipv6/parameters/disable
# 0 - IPv6 is enable
# 1 - IPv6 is disabled
Como se ha indicado anteriormente, el comportamiento de MsQuic aquí es intencional. Sin embargo, este problema concreto podría mitigarse en el lado de .NET en el futuro. Para obtener más información, consulte dotnet/runtime#75343.
El cliente de escucha no se inicia con el error QUIC_STATUS_ADDRESS_IN_USE
Se trata de un problema específico de Windows. El cliente de escucha produce QuicException
un error QUIC_STATUS_ADDRESS_IN_USE
a pesar de que no se está ejecutando ningún otro proceso en una dirección y un puerto concretos. El error se debe al intervalo de exclusión de puertos definido para el mismo puerto en el que el cliente de escucha está intentando escuchar. Para comprobar los intervalos de exclusión, ejecute lo siguiente:
netsh.exe int ip show excludedportrange protocol=udp
La obtención de un error al intentar el enlace en un puerto que procede del intervalo de exclusión es un comportamiento esperado. Por ese motivo, no hay planes inmediatos para corregirlo. Puede encontrar más detalles en dotnet/runtime#71518.