Resumen

  • Un ACK retrasado podía hacer que ambos extremos repitieran sus paquetes actuales y sostener una cadena de duplicados.
  • RFC 1123 prohibió que el emisor DATA respondiera a un ACK duplicado retransmitiendo el bloque actual. El riesgo era que la congestión impidiera completar la transferencia, no que corrompiera un archivo terminado.

Un solo bloque pendiente

En junio de 1981, Karen Sollins publicó la segunda revisión del Trivial File Transfer Protocol. «Trivial» describía una interfaz deliberadamente reducida: leer o escribir un archivo remoto, sin listar directorios ni autenticar al usuario. Los datos avanzaban en bloques de 512 bytes. Cada bloque no final debía recibir un acuse antes de que el emisor enviara el siguiente. Así, el emisor solo necesitaba conservar un paquete pendiente para volver a mandarlo. El esquema de parada y espera también ofrecía control de flujo y evitaba tener que reordenar bloques.

La economía importaba en máquinas que debían obtener el sistema operativo antes de disponer de una configuración de red completa. RFC 1123, publicado en 1989, describe el uso principal de TFTP como el arranque de un host en la red local: era lo bastante pequeño para caber en EPROM. BOOTP podía proporcionar la configuración; después TFTP podía descargar la imagen. Eran etapas distintas, y la transferencia seguía dependiendo del tiempo y de los acuses.

TFTP operaba sobre UDP y asumía su propia fiabilidad. Si la respuesta esperada no llegaba antes de vencer el temporizador, el emisor podía retransmitir el paquete pendiente. La regla parecía sencilla cuando un paquete se perdía. Un paquete demorado producía otra situación.

El ACK antiguo que provoca nuevos duplicados

Supongamos que el host A recibe ACK X−1 y envía DATA X. El host B recibe el bloque y responde ACK X, pero el acuse se demora. Vence el temporizador de A, así que A vuelve a enviar DATA X. B ya aceptó el bloque; reconoce el duplicado y envía otra vez ACK X. Cuando llega el primer ACK, el que estaba retrasado, A avanza y transmite DATA X+1. Entonces llega el segundo ACK X. Según la regla original, A responde al acuse antiguo retransmitiendo el paquete que tiene ahora en curso: DATA X+1.

B recibe X+1 dos veces y genera dos ACK X+1. Si uno llega después de que A ha avanzado a DATA X+2, el acuse antiguo puede provocar otro duplicado del bloque actual. El paquete atrasado no repite simplemente el bloque anterior; dispara una respuesta calculada según el estado presente de cada extremo. Un duplicado puede inducir así un duplicado nuevo en el otro host.

RFC 1123 llamó al fenómeno síndrome del aprendiz de brujo. Su ejemplo muestra que los siguientes paquetes de la transferencia pueden duplicarse, salvo que una pérdida interrumpa el patrón. El problema no implica que los bytes del archivo final queden mal. RFC 1123 señala que, si la transferencia termina, el archivo es correcto. El riesgo es que la repetición consuma tiempo y capacidad hasta que la transferencia venza sin completarse.

Por eso «fiable» no significaba «inmune a la demora». Los números de bloque identificaban el acuse, pero no volvían inocua toda respuesta a un bloque antiguo. El emisor DATA y el emisor ACK podían responder a los duplicados repitiendo el paquete que cada uno consideraba actual. Cada reacción parecía sensata por separado; juntas, formaban una realimentación.

La demora que alimenta la congestión

El documento de 1989 explica la secuencia. Un ACK demorado puede llegar después de que el temporizador ya haya provocado una retransmisión. El DATA repetido genera otro ACK. Si el primer acuse llega cuando el emisor ya avanzó, puede hacer que repita el bloque nuevo, que a su vez produce más ACK. Mientras ningún paquete perdido rompa la secuencia, los bloques posteriores también pueden viajar duplicados.

La congestión puede ser tanto el disparador como la consecuencia. Un enlace cargado demora el ACK lo suficiente para iniciar el ciclo. Los DATA y ACK duplicados ocupan más capacidad y aumentan la posibilidad de nuevos retrasos. RFC 1123 advierte que esto puede generar más congestión y más paquetes demorados. No afirma que toda transferencia lenta sufriera el síndrome ni atribuye una interrupción histórica concreta a él: describe una realimentación a nivel de protocolo.

RFC 1123 también separó este problema de la política ordinaria de temporizadores. Exigió un tiempo de espera adaptable y recomendó al menos un crecimiento exponencial del intervalo de retransmisión. Mejorar el temporizador ayuda a tolerar variaciones de latencia; no elimina la regla que deja que un ACK antiguo provoque un nuevo DATA. Había que cambiar la reacción ante un acuse duplicado.

Una regla pequeña antes de la revisión

RFC 1123 hizo obligatoria la corrección: el extremo que envía DATA nunca debe volver a enviar el DATA actual al recibir un ACK duplicado. Al suprimir esa respuesta, un ACK repetido deja de provocar otro DATA duplicado y la cadena no avanza. El receptor puede retirar su propio temporizador porque repetir ACK ya no desencadena una acción; también puede mantenerlo si el nuevo acuse puede reemplazar a uno que sí se perdió. El emisor DATA sigue necesitando un temporizador.

Para un protocolo destinado a ejecutarse en un programa de arranque, la corrección también podía simplificar al receptor. No exigía una ventana mayor, bloques distintos de 512 bytes ni sustituir UDP. Cortaba la realimentación peligrosa y conservaba el modelo de un paquete en memoria.

En julio de 1992, RFC 1350 reemplazó RFC 783 y pasó a ser STD 33. Su sección de agradecimientos dice que Noel Chiappa corrigió el fallo del protocolo en la revisión de mayo de 1992. Las fechas no deben confundirse: RFC 1123 ya había exigido el comportamiento para las implementaciones; el texto de 1992 incorporó la corrección a la revisión de TFTP. La fecha posterior no demuestra que todas las implementaciones fallaran hasta entonces ni que todas hubieran actualizado en 1989.

Las extensiones posteriores abordaron otro límite. La opción de tamaño de bloque de 1998 y las opciones siguientes mejoraron el rendimiento cuando la parada y espera resultaba lenta; más tarde, una ventana permitió varios bloques en vuelo. No eran la corrección del ACK duplicado. Una mejora amplía el caudal; la otra impide que un acuse antiguo multiplique el tráfico actual.

La historia de TFTP muestra que un diseño mínimo puede trasladar su complejidad a las transiciones de estado. Mantener un solo bloque activo ahorraba memoria y trabajo de implementación. Pero una demora hizo que ambos hosts discreparan sobre cuál era el «paquete actual». La solución también fue pequeña: no dejar que un ACK duplicado ordenara al emisor DATA repetir lo que estaba enviando. La fiabilidad dependía tanto de saber cuándo no retransmitir como de saber cuándo volver a intentarlo.

Fuentes