info@naevatec.com (+34) 911 407 507

QUIC frente a TCP/UDP: repensando el transporte para medios WebRTC

Visualización con la herramienta qvis de una conexión QUIC real, mostrando los paquetes transmitidos y recibidos a lo largo del tiempo junto con los frames por stream: datos STREAM, frames de control de flujo, ACKs y PATH_CHALLENGE/PATH_RESPONSE.

Si leíste nuestro post anterior sobre qué es QUIC y por qué importa para el vídeo en tiempo real, ya tienes la idea general: QUIC es un transporte moderno construido sobre UDP, con cifrado, streams multiplexados y un handshake rápido integrados. Este post va un nivel más allá (tres propiedades de QUIC a nivel de transporte con más detalle técnico, y una respuesta honesta a la pregunta que realmente importa si llevas un pipeline de medios basado en WebRTC): ¿qué te aporta todo esto hoy?

(Imagen de cabecera: una conexión QUIC real capturada y visualizada con qvis, la herramienta open source de depuración de QUIC/HTTP-3 de Robin Marx.)

Logotipo del protocolo QUIC.

Dónde encaja QUIC realmente

Uno de los errores más fáciles de cometer al acercarse a QUIC es pensar en él como un sustituto directo de TCP, o simplemente como "UDP con funciones extra". En realidad, se sitúa en algún punto intermedio entre esas dos descripciones.

TCP se encarga del transporte fiable, el control de flujo, el control de congestión y la recuperación de pérdidas. TLS se sitúa encima de TCP para aportar el cifrado, y la aplicación solo llega a ver el flujo de bytes seguro resultante (dos capas separadas, negociadas por separado, cada una con sus propios round trips). QUIC reorganiza estas responsabilidades en una única capa que funciona directamente sobre UDP: TLS 1.3 se integra en el propio handshake en lugar de añadirse después, y la fiabilidad, el control de flujo y la recuperación de pérdidas pasan a ser responsabilidad de QUIC en lugar de TCP.

Diagrama que compara la pila de protocolos de HTTP/2 (HTTP/2 y multistreaming sobre TLS sobre TCP) con la de HTTP/3 (HTTP/3 y QUIC, con multistreaming y TLS integrados en QUIC, sobre UDP), ambas sobre IP.

Fuente: SEC Consult, "Better don't be too QUIC(K)".

Esa reorganización no es solo orden arquitectónico, sino que también es de donde sale la ganancia más rápida y real de QUIC. TCP+TLS necesita entre dos y tres round trips antes de que un cliente pueda enviar su primera petición; un cliente QUIC que ya ha hablado antes con un servidor puede enviar datos de inmediato, con cero round trips. Cuando Google activó QUIC en sus balanceadores de carga HTTPS en 2018, ese ahorro de handshake por sí solo fue suficiente para acortar de forma medible el tiempo de carga de página de Google Search, un 8% de media a nivel global, y hasta un 13% en regiones de alta latencia. Es un benchmark de tráfico web, no de WebRTC, pero es evidencia real de que el ahorro de handshake que promete QUIC no es solo teórico.

Diagrama que compara el tiempo de establecimiento de una conexión HTTPS sobre TCP+TLS (200 ms en una reconexión, 300 ms en una conexión nueva) frente a HTTPS sobre QUIC (0 ms en una reconexión, 100 ms en una conexión nueva), del anuncio de Google Cloud de 2018 sobre el soporte de QUIC en sus balanceadores de carga HTTPS.

Fuente: Google Cloud Blog, "Introducing QUIC support for HTTPS load balancing" (2018).

Multiplexación sin head-of-line blocking

Ya lo vimos a alto nivel: QUIC mantiene streams independientes dentro de una única conexión, y un paquete perdido en uno de ellos no bloquea a los demás. Para un pipeline de medios de WebRTC en concreto, esto necesita una matización (el head-of-line blocking nunca fue realmente un problema de WebRTC). RTP ya funciona sobre UDP, no sobre TCP, así que el propio camino de medios nunca tuvo el head-of-line blocking de TCP para empezar.

Donde sí muerde es en la ruta de fallback: cuando un firewall estricto bloquea UDP por completo, WebRTC recurre a retransmitir el medio a través de un servidor TURN sobre TCP (habitualmente en el puerto 443, para mezclarse con el tráfico HTTPS normal). Ese fallback es exactamente donde el head-of-line blocking de TCP aparece en un despliegue real, y es un compromiso genuino, no hipotético. QUIC, sin embargo, no resuelve este problema en concreto (QUIC sigue siendo UDP por debajo), así que una red que bloquea UDP bloquea QUIC con la misma eficacia con la que bloquea RTP. La multiplexación sin head-of-line blocking es una propiedad real, pero no es la solución para el escenario de "nuestra red solo permite TCP" para el que existe TURN sobre TCP.

Control de congestión: intercambiable por diseño

RFC 9002 especifica un controlador de congestión base modelado sobre TCP NewReno, pero las señales de detección de pérdidas de QUIC son deliberadamente genéricas (una implementación es libre de sustituirlo por completo, y la mayoría de las implementaciones reales de QUIC lo hacen, normalmente con CUBIC o BBR).

WebRTC ya tiene su propia respuesta a este problema: el protocolo compañero de RTP, RTCP, transporta la información (pérdida de paquetes, jitter, round-trip time) que un controlador de congestión del lado emisor como Google Congestion Control usa para ajustar el bitrate en tiempo real. Así que el control de congestión no es una capacidad que le falte hoy al medio de WebRTC, sino que, más bien, QUIC junta transporte y control de congestión en una única capa, en lugar de que el feedback de RTCP se apoye encima de un socket UDP "tonto". Que esa consolidación merezca la pena depende de si estás construyendo la lógica de control de congestión tú mismo o apoyándote en un stack de WebRTC ya existente y ya afinado (para la mayoría de equipos que usan OpenVidu, es lo segundo), así que esta es un área en la que la ventaja de QUIC es más arquitectónica que inmediatamente práctica.

Migración de conexión: lo único que a WebRTC realmente le falta

Esta es la propiedad que más importa en la práctica. RFC 9000 define la migración de conexión en torno a los Connection IDs: una conexión QUIC se identifica por un ID negociado en el handshake, no por la IP y el puerto del cliente. Cuando esos cambian (al pasar de Wi-Fi a datos móviles, por ejemplo), el cliente puede seguir usando la misma conexión en la nueva ruta de red. Antes de comprometerse con esa nueva ruta, la valida con un intercambio PATH_CHALLENGE/PATH_RESPONSE, y en la versión actual de QUIC solo el cliente puede iniciar una migración.

El equivalente real en WebRTC es un ICE restart: la aplicación tiene que detectar el cambio de red, generar nuevos candidatos ICE y renegociar a través de su propio canal de señalización (un round trip por tu servidor de señalización, algo que la capa de transporte no te resuelve, y que interrumpe brevemente el medio mientras ocurre). La migración de conexión es genuinamente nativa del transporte; un ICE restart es algo que cada aplicación WebRTC tiene que construir y gestionar por su cuenta.

Conclusión

La importancia de QUIC no está en que sustituya a TCP o deje a UDP obsoleto, sino que, en la práctica, se sitúa en algún punto intermedio entre los dos. De TCP hereda la fiabilidad, el control de congestión, el control de flujo y la gestión de conexiones. De UDP hereda la flexibilidad, la baja sobrecarga y la libertad de no depender de un modelo de transporte estrictamente ordenado.

Para quien trabaja con WebRTC, esa combinación es lo que hace interesante a QUIC, no porque esté listo para sustituir el transporte de medios basado en RTP, sino porque representa una arquitectura de transporte moderna, pensada para las realidades de las redes móviles, el tráfico cifrado y las aplicaciones sensibles a la latencia.