12 puntos por GN⁺ 2025-08-02 | 1 comentarios | Compartir por WhatsApp
  • Se envió el primer parche para integrar oficialmente el protocolo QUIC en el kernel de Linux
  • El objetivo es mejorar las limitaciones de TCP (latencia, head-of-line blocking, osificación del protocolo por dispositivos intermedios, etc.)
  • QUIC se basa en UDP, ofrece soporte de multistream y cifrado de extremo a extremo, y su adopción en el kernel podría ampliar las posibilidades de uso en más plataformas y hardware
  • Aunque el rendimiento de la implementación inicial en el kernel se midió por debajo de TCP y de kernel TLS, se espera que mejore con offloading de hardware y optimizaciones futuras
  • Actualmente hay un intenso debate sobre su soporte en Samba, SMB/NFS basado en kernel, curl y otros, aunque todavía se prevé que falte tiempo para su integración en mainline

Contexto de la aparición de QUIC y limitaciones de TCP

  • QUIC fue creado con el objetivo de resolver varios problemas que TCP presenta en Internet
  • La experiencia web se degrada por la latencia causada por el 3-way handshake del proceso de conexión de TCP, la falta de soporte sólido para multistream y el fenómeno de head-of-line blocking ante pérdida de paquetes
  • Los metadatos de TCP se transmiten sin cifrar, lo que implica riesgo de filtración de información, y las middleboxes (dispositivos intermedios) filtran el tráfico según la información de la conexión, lo que termina derivando en osificación del protocolo (ossification)
  • Incluso los intentos de mejorar TCP, como Multipath TCP, no pueden funcionar con normalidad si no se hacen pasar por TCP tradicional

Características de QUIC y ventajas técnicas

  • QUIC funciona sobre UDP y puede establecer conexiones rápidamente sin un 3-way handshake separado durante el proceso de conexión
  • Su diseño de transmisión multistream evita que la pérdida de paquetes afecte a todo el flujo
  • Los datos de transporte relacionados con QUIC siempre van con cifrado de extremo a extremo (basado en TLS), por lo que los dispositivos intermedios no pueden acceder a los mensajes internos
  • Si el entorno de red permite el paso de paquetes UDP, QUIC también puede funcionar con normalidad

Resumen del parche de integración de QUIC en el kernel de Linux

  • El parche presentado introduce un nuevo tipo de protocolo llamado IPPROTO_QUIC, lo que permite aprovechar la llamada al sistema socket() existente
  • Igual que con TCP, se pueden usar llamadas como bind(), connect(), listen() y accept(), aunque el procesamiento posterior tiene diferencias
  • La gestión de sesiones TLS y el proceso de autenticación/cifrado se manejan en espacio de usuario, y tras establecer la conexión cada extremo debe completar el TLS handshake antes de poder enviar y recibir datos
  • Después de la conexión inicial, los resultados de la negociación TLS pueden almacenarse en caché, lo que permite acelerar considerablemente la reconexión entre dos sistemas

Retos de rendimiento y perspectivas

  • La implementación de QUIC dentro del kernel presentada todavía muestra desventaja en rendimiento frente a kernel TLS y TCP
    • Menos de un tercio del throughput frente a TLS en kernel, y hasta 4 veces menos throughput que TCP incluso con el cifrado desactivado
  • Entre las causas señaladas están la falta de soporte para segmentation offloading, copias adicionales de datos en la ruta de envío y el proceso de cifrado de encabezados
  • Se espera que el rendimiento mejore cuando se agregue soporte para offloading de hardware y se optimice la implementación dentro del kernel

Estado de adopción y perspectivas futuras

  • En varios proyectos como el servidor/cliente de Samba, los sistemas de archivos SMB y NFS del kernel, y curl, hay un debate activo sobre el soporte de QUIC dentro del kernel
  • El parche tiene unas 9,000 líneas y por ahora solo incluye código de soporte de bajo nivel. La implementación completa está prevista en parches adicionales
  • La revisión del código y el debate sobre su integración apenas están comenzando, por lo que todavía se espera que falte tiempo para su uso real
    • Considerando el precedente reciente del protocolo Homa, cuya integración al kernel requirió 11 envíos durante 9 meses, se estima que QUIC también podría entrar en mainline después de 2026

1 comentarios

 
GN⁺ 2025-08-02
Comentarios de Hacker News
  • Recientemente agregué ssl_preread_server_name en la configuración de NGINX para hacer proxy_pass de las solicitudes de ciertos dominios a otra instancia de NGINX
    La primera instancia simplemente reenvía el flujo TLS en bruto (incluyendo proxy_protocol), y la segunda instancia se encarga de la terminación TLS real
    Este método es efectivo al implementar failover: si la ruta principal del servidor se cae, actualizas el registro DNS A para que apunte al NGINX de la máquina de failover, y esa instancia enruta las solicitudes de dominios específicos de vuelta al backend original por una ruta separada
    Es conveniente porque no hace falta duplicar toda la configuración TLS
    Pero este método no aplica a HTTP/3
    HTTP/3 está basado en QUIC, funciona sobre UDP, y cifra el SNI durante el handshake, así que no se puede hacer enrutamiento por dominio con ssl_preread_server_name
    Me pregunto si existe alguna alternativa que permita enrutamiento basado en SNI en HTTP/3, o si, cuando se necesita esta función, todavía hay que quedarse con HTTP/1.1 o HTTP/2 sobre TLS
    • La mayoría de los clientes que soportan QUIC también soportan registros DNS HTTPS, así que una opción es agregar un registro de menor prioridad para failover y dejar que el cliente lo resuelva
      En la práctica, el comportamiento varía según la implementación del cliente (ver el estado del soporte de registros HTTPS en Chromium en este enlace del issue), pero cuando falla una conexión QUIC, el cliente suele hacer fallback de forma transparente a HTTP/1.1/2, y también respeta el encabezado Alt-Svc
      Si el failover es planeado, también podrías simplemente dejar de enviar el encabezado Alt-Svc y esperar a que expire por timeout hacia la instancia alternativa
      Si realmente necesitas routing de QUIC, por suerte la información de SNI siempre está en el primer paquete, así que se puede enrutar inspeccionando paquetes
      El udpgrm de Cloudflare puede servir como referencia, y esto funciona mientras no haya ECH (Encrypted Client Hello)
      Si hay ECH, el router tendría que tener la clave de descifrado para poder tomar decisiones de routing, y a nivel de protocolo también se podría diseñar failover en cascada
      Puedes ver una implementación concreta en este ejemplo de udpgrm
    • Terminar TLS directamente en el edge (por ejemplo, en NGINX) no es un punto de riesgo tan grande hoy en día en un entorno con letsencrypt
      Si un atacante logra acceder a ese servidor, también le sería fácil emitir de nuevo el certificado SSL, así que en vez de complicarte con un sistema de failover sofisticado, probablemente tenga más sentido terminar TLS directamente
      Personalmente nunca he logrado reproducir por mí mismo las ventajas de rendimiento o confiabilidad de QUIC
      Lo he probado repetidamente durante años, pero casi siempre termino desactivándolo por temas de rendimiento u otros motivos
      El failover basado en DNS también tarda varios minutos en reflejarse en la práctica, y con clientes simples como los navegadores muchas veces ni siquiera funciona bien
      Por eso uso directamente un manejador onerror para cargar una segunda ruta
      Por ejemplo, para tracking publicitario uso código de ese estilo, y también ofrezco un wrapper del API de fetch de la misma forma
      Este enfoque ha sido mucho más eficiente que cualquier otro intento
    • Si estás en un entorno de failover, yo no me preocuparía por el failover de QUIC
      Aunque el navegador falle al establecer una conexión QUIC (incluso si está anunciada en DNS), hará fallback automáticamente a HTTP/1 o HTTP/2 sobre TLS, así que puedes usar exactamente el mismo método de failover que ya tenías
    • Este problema entra en la categoría de “no es un bug”
      Una característica de diseño de HTTP/3 es precisamente no exponer información del endpoint hasta la capa TLS
      Personalmente lo veo como una ventaja
      HAProxy puede hacer proxy de TLS en bruto, pero no routing por nombre de host
      Cloudflare Tunnel tiene una función especial que permite routing por nombre de host sin terminar TLS, pero para usarla también necesitas llevar tu DNS a Cloudflare
      Me recordó a esta tira de xkcd
    • Buena pregunta
      Me pregunto si la misma limitación también existe en entornos TCP+TLS cuando se usa Encrypted Client Hello
      Imagino que la respuesta sería casi la misma
  • Desde hace tiempo recuerdo este artículo relacionado sobre las desventajas de QUIC
    Siento que esta discusión va en la dirección de ir resolviendo esos problemas poco a poco
    También queda abierta la posibilidad de soporte por hardware en las tarjetas de red en el futuro
    • QUIC no es muy adecuado para tráfico entre máquinas
      Pero hoy la mayor parte del tráfico de internet va entre móviles y servidores, y ahí es donde QUIC y HTTP/3 realmente brillan
      Para otros usos se puede seguir usando TCP
  • Tengo curiosidad por cómo quedará la API de sockets para multistream
    Supongo que se verá como varias conexiones, pero con caching interno
    A mí me gustaría más recibir explícitamente un objeto de conexión y abrir streams aparte, aunque por ahora también podría aceptar el enfoque actual
    Revisando esta discusión relacionada, parece que, si esto no es una extensión, en el lado del servidor también se pueden crear nuevos streams después de establecer la conexión
    Del lado del cliente, aunque en realidad sean streams, parece difícil abstraerlos como “conexiones” separadas, y en el fondo da la impresión de que hace falta una abstracción de API completamente nueva
    Probablemente cada nuevo stream termine entregando un file descriptor vía recvmsg
    • La capacidad de múltiples streams ya está soportada por la API de sockets de SCTP, así que valdría la pena tomar como referencia la interfaz de SCTP
  • Independientemente de la implementación en el kernel, me gustaría que OpenSSH tuviera soporte para QUIC
    Quisiera algo tan resistente a problemas de red como Mosh, pero conservando todas las funciones de OpenSSH (SFTP, SOCKS, port forwarding, manejo de estado, roaming, etc.)
    Me pregunto si OpenSSH podría aprovechar soporte del kernel
    Ver Mosh
    • SSH tendría que reemplazar por completo sus capas de cifrado y multiplexación con QUIC, así que sería un trabajo enorme
      Probablemente sería mejor crear un protocolo de login aparte basado en QUIC
      Ya hay varios enfoques en etapa de prototipo
    • OpenSSH es un proyecto de OpenBSD, así que quizá no le preste mucha atención a una API específica de Linux
  • Se dice que el cuello de botella de TCP es el handshake, pero yo entendía que eso se resuelve con reutilización de conexiones o multiplexación
    Sin embargo, también se comenta que la implementación actual de QUIC en kernel es entre 3 y 4 veces más lenta que la de Linux, y que la diferencia de rendimiento se cerrará pronto
    Si la ventaja de QUIC es la velocidad, pero en la práctica es más lento, entonces ¿cuál es el motivo para usarlo?
    Incluso el autor del PR dice que parte de la pérdida de rendimiento viene del diseño del protocolo, así que pregunto si en TCP hay otros problemas que también necesiten corregirse
    • El artículo también menciona muchas de las razones por las que QUIC es más lento
      En su mayoría se pueden resumir como “todavía no lo han optimizado”
      Por ejemplo, falta soporte para segment offload, hay copias de datos adicionales en la ruta de transmisión, y hay overhead por el cifrado de headers; todo eso tiene buenas posibilidades de solucionarse
      Además, el benchmarking se hizo en un entorno muy idealizado
      En la práctica, en entornos móviles la variabilidad de la red es alta, así que las limitaciones estructurales de TCP se vuelven mucho más evidentes
      De hecho, muchos casos ya implementan sobre TCP funciones similares a las de QUIC, como hace HTTP/2
      Al final, QUIC es un stack de networking integral que opera por encima de la capa 5 del modelo OSI, mientras que TCP es más bien un motor del nivel de la capa 3, así que compararlos estructuralmente no es sencillo
      Sobre todo, la ventaja de QUIC está en conexiones y reconexiones más rápidas, y en garantizar continuidad de sesión incluso cuando cambia la IP
      Su estructura de multiplexación y streams no bloqueantes simplifica de forma drástica el diseño de protocolos de nivel superior
      Si esa arquitectura entra al kernel, también hay muchísimo margen para optimización de rendimiento
      A futuro, en vez de seguir construyendo soluciones multicapa sobre las limitaciones de TCP, deberíamos usar más a diario tecnologías base más avanzadas como QUIC
    • El cuello de botella de TCP no es solo el handshake
      Cuando hay pérdida de paquetes, todo lo que viene después se retrasa hasta que se recupere esa transmisión, así que tiene una limitación estructural importante por HOL blocking
    • No puedes reutilizar una “conexión que no existe”, así que muchas de estas discusiones se enfocan en reducir latencia
      No se trata solo de velocidad, sino de mejorar la latencia
    • La ventaja de QUIC está en la capacidad de seguimiento basada en el connection ID que entrega el servidor
      Consulta este documento técnico
  • Me confunde el mensaje de que mover el stack de networking a user space mejora el rendimiento, frente a esta discusión que propone moverlo hacia el kernel
    • La mayoría de los stacks QUIC funcionan sobre UDP dentro del kernel
      El principal cuello de botella está en los context switches entre kernel y espacio de usuario
      El networking en user space (por ejemplo, acceso directo al NIC) elimina las entradas al kernel
      Por otro lado, ofrecer funciones en espacio kernel (por ejemplo sendfile, TLS en kernel, offloading del NIC, DMA directo del disco al NIC) también reduce los context switches totales y las copias de datos
      Los stacks QUIC actuales no aprovechan bien ninguna de las dos ventajas
      La entrada y salida de paquetes sigue basada en syscalls y no puede evitar copias de datos
      Con I/O por lotes usando io_uring y similares sí puedes reducir switches, pero no las copias en sí
    • Exacto
      Hay dos enfoques: kernel bypass + DMA, o excluir user space como en sendfile/ktls
      La implementación de QUIC en kernel no tiene realmente ninguna de las dos ventajas
    • Al final igual tienes que pasar los datos al buffer del NIC
      Si puedes escribir directo al NIC con DMA o si tienes que pasar por syscalls del kernel, la diferencia de rendimiento es grande
      El networking en user space solo resulta convincente cuando existe esa estructura de transición de privilegios y DMA
    • Que user space acceda directamente a datos de red (probablemente sin syscalls) no tiene mucho sentido para software de usuario común
      Solo lo aprovechan empresas enormes (MOFAANG y similares)
      En teoría se esperaba que io_uring generalizara esos beneficios, pero todavía no está en una etapa de uso real generalizado
    • Los cambios de contexto al acceder al hardware son demasiado lentos
      Por eso TCP/IP sigue en el kernel en los principales sistemas operativos
  • “¿Por qué meter cada vez más funciones en el kernel?”
    Yo pensaba que el kernel debía encargarse de memoria, hardware y gestión de tareas; ¿no sería más correcto que los protocolos por encima de IP se procesaran en userland?
    • Si pones networking, routing, VPN, etc. en kernel space, en algunos casos mejora el rendimiento
      Por otro lado, separar esos stacks en user space también mejora el rendimiento en algunos casos
    • Estar en el kernel aporta ventajas de hardening, soporte LTS y optimizaciones a nivel de kernel y red
    • La razón principal es optimizar transferencias DMA y offloading del NIC
    • Si dejas todos los protocolos por encima de IP en user space, no puedes tener uso multiproceso
      Como TCP/UDP arbitran en el kernel el routing de sockets por puertos, varios programas pueden usar TCP/UDP al mismo tiempo
      QUIC funciona sobre UDP, así que el punto de la discusión sigue siendo válido
      La observación es que lo que no se puede ejecutar en user space son solo los protocolos que van directamente sobre IP
  • Creo que QUIC representa un cambio importante para mucha gente
    Espero que internet se vuelva un poco más rápido a futuro
    En entornos como 5G quizá no se note mucho la diferencia, pero sigue siendo un avance valioso
    Me parece interesante que tenga una estructura separada de handshake de enlace
    Yo pensaba que QUIC integraba TLS completamente dentro de sí, pero no era exactamente así
  • La razón principal de que la web completa se haya vuelto más lenta es que los sitios son demasiado pesados
    Aun así, creo que esta tecnología sí podría reducir más la latencia en juegos
    • La paradoja de Jevons también aplica aquí
      Cuando mejoran los recursos de cómputo y la eficiencia de red, también aumenta la demanda
      En juegos o cómputo científico eso no importa porque buscas “mejores resultados”
      Pero en la web muchas veces tiene el efecto contrario por más anuncios, tracking y JavaScript
  • El artículo dice que en QUIC la conexión se establece con bind(), connect(), listen(), accept(), etc., como en TCP, pero luego cambia a una estructura basada en las syscalls sendmsg() y recvmsg()
    Me gustaría que también explicaran por qué eligieron ese enfoque y por qué no crear syscalls separadas específicas para QUIC