«Manda las descargas grandes por fuera de la VPN y deja las respuestas pequeñas dentro» suena a política de enrutamiento, y no lo es. Un enrutador decide con la información disponible en ese momento: direcciones, puertos, protocolo, marcas de firewall, un flujo identificado. El tamaño final de una respuesta no está en ese conjunto, porque aún no ha llegado, y para cuando el enrutador podría medir los bytes ya los está transportando. Si quiere dirigir por tarea, la decisión debe trasladarse a un punto que conozca la tarea, y la lista de comprobación de abajo sirve para averiguar si su diseño tiene ese punto.

Por qué un enrutador no puede medir una respuesta

En el momento en que un paquete necesita una ruta, el enrutador ha visto como mucho los primeros paquetes de un flujo. Puede decir quién habla con quién, por qué protocolo, con qué marca y cuántos bytes han pasado hasta ahora. Los bytes hasta ahora describen el pasado. El tamaño de la respuesta es una propiedad de una respuesta que aún no se ha generado, y en respuestas fragmentadas o en streaming puede que nunca se conozca de antemano.

Incluso los metadatos del propio protocolo son más débiles de lo que parecen. HTTP permite respuestas cuya longitud no se anuncia antes del cuerpo, y una sola acción del usuario puede producir muchas peticiones cuyo coste combinado no se parece a ningún valor de cabecera. Tratar una cabecera como el tamaño de una tarea es un error de modelado antes que un error de enrutamiento.

Comprobación 1: ¿hay un punto de decisión que pueda elegir una ruta?

Nombre el componente que tomará la decisión, y después nombre qué sabe en el momento de elegir. Un actualizador que descarga de un conjunto documentado de hosts conoce su propósito antes de que empiece la transferencia. Un servicio de descarga que consulta metadatos y luego abre la petición conoce la tarea antes de que exista la conexión. Un proxy colaborador puede aplicar políticas a nivel de petición o cachear la respuesta sin fingir ser un enrutador.

Si la respuesta es «la puerta de enlace», la lista ya ha fallado. Una puerta de enlace puede clasificar flujos conocidos por destino, marca o segmento de cliente y enviarlos por una ruta definida desde el primer paquete, lo que a menudo basta para un actualizador aprobado y nunca basta para un tamaño de respuesta desconocido.

Comprobación 2: ¿qué le dicen realmente los metadatos?

El direccionamiento consciente de la aplicación es tan bueno como los campos que lee. Las reglas de longitud de respuesta de la semántica de HTTP permiten casos en los que la longitud no está disponible al principio, y las codificaciones de contenido hacen que el recuento de bytes transferidos sea distinto del tamaño de la representación de todos modos. Por eso una política que cambia de ruta cuando una cabecera cruza un umbral se comportará de forma inconsistente, y sobre todo justo en las transferencias grandes que debía detectar.

Lo que los metadatos de la aplicación sí pueden sustentar es una decisión sobre una tarea: este flujo de trabajo es una sincronización masiva, este es interactivo, este es una actualización de software de un origen conocido. Eso es una política escrita en términos de intención, y es lo bastante estable para probarla. «Esta respuesta será mayor de cuarenta megabytes» no es ese tipo de política.

Comprobación 3: ¿el flujo ya existe?

El enrutamiento puede cambiar para un flujo sin cambiar la identidad de la conexión, y esa distinción conviene mantenerla clara. Una conexión TCP se identifica por las direcciones y los puertos de sus extremos, y los paquetes pueden tomar otra ruta si la tabla de enrutamiento cambia por debajo. Lo que no puede cambiar de forma invisible es el estado de traducción de direcciones de red: mover el tráfico a otra salida suele cambiar la tupla de origen pública, y el extremo remoto verá otro par sin estado coincidente.

conntrack -L -p tcp --dport 443 | head -5
ip route get 203.0.113.10
ss -tn state established dst 203.0.113.10

Así que la regla práctica es que un cambio a mitad de conexión de una salida a otra es una relación nueva, no una migración. Si el diseño exige que la misma conexión continúe, la decisión tenía que tomarse antes del primer SYN, y ninguna regla de paquetes añadida después puede reconstruirla limpiamente.

Comprobación 4: ¿el requisito real es latencia, no salida?

Muchísimas peticiones de «manda el tráfico masivo a otro sitio» son en realidad quejas de que una transferencia grande hace que el trabajo interactivo parezca lento. Eso es un problema de planificación, y tiene una respuesta de planificación: una cola justa o una política de ancho de banda soportada en la ruta existente evita que un flujo masivo deje sin recursos a un mensaje de chat sin mover ninguno de los dos.

tc qdisc replace dev eth0 root cake bandwidth 100mbit

Abordar el síntoma así mantiene la decisión de salida donde la puso la política de seguridad, y es reversible con un solo comando. Cambiar la salida para toda una clase de tráfico es un cambio de política con consecuencias de autenticación, registro y reglas de acceso, así que no debería ser la primera herramienta a la que se recurre ante una queja de latencia.

Si el requisito es de verdad una salida de Internet distinta, dígalo con esas palabras e impleméntelo en una frontera soportada: una conexión nueva desde un flujo de trabajo aprobado, o una aplicación que abre su propia petición por una salida elegida. Luego registre qué tareas usan qué salida, para que la siguiente persona no tenga que inferirlo de una tabla de enrutamiento.

Mantenga la lista de comprobación en el registro del cambio: el punto de decisión, el campo o la tarea que lo impulsa, si el flujo ya existe y si el síntoma medido era latencia o salida. Cuatro preguntas, y una política que responde a las cuatro es una que puede operar en lugar de defender.

Artículos relacionados