Resumo

  • O cliente enviava RRQ ou WRQ ao TID conhecido 69, mas o servidor aceitante respondia de um TID escolhido por ele; o par passava a identificar os endpoints UDP daquela transferência.
  • Um TID de origem diferente recebia o erro 5 sem derrubar a conversa válida, e as correções de retransmissão e extensões posteriores preservaram esse limite mesmo ao aumentar a vazão.

Pouca memória não significava pouco significado

RFC 783 descreveu um protocolo restrito a ler e escrever arquivos, sem listagem de diretórios nem autenticação de usuário. Essa limitação permitia uma implementação pequena. O lado que envia DATA conservava o bloco atual; o lado que recebe não precisava reordenar vários blocos; o ACK indicava quando avançar.

O custo da economia foi concentrar significado no TID, no número do bloco e no temporizador. Eles formavam a memória da conversa. Sem uma conexão TCP persistente ou um canal de controle, o protocolo precisava saber a qual transferência pertencia cada datagrama e se ele representava avanço, repetição ou outra conversa.

A porta 69 só iniciou o encontro

O cliente escolhe um TID e envia a leitura ou escrita ao TID conhecido 69 do servidor. Quando uma leitura é aceita, o primeiro DATA sai de um TID escolhido pelo servidor. Na escrita, o ACK zero faz o mesmo anúncio. Os TIDs são usados como portas de origem e destino no transporte datagrama e permanecem durante a operação.

Isso permite que o mesmo ouvinte receba novos pedidos enquanto cada arquivo circula em seu par próprio. A regra “TFTP é porta 69” é útil para localizar o pedido e incompleta para observar o serviço. Depois da primeira resposta, insistir em 69 perde o fluxo correto.

O par não é uma credencial. Escolher valores difíceis de repetir separa operações próximas, mas não autentica pessoa ou máquina, não cifra o arquivo e não atesta sua procedência. O TID responde a uma pergunta local: este pacote pertence à conversa que aceitamos?

O pacote estranho não podia matar o correto

Uma rede pode duplicar o RRQ antes de a resposta chegar. O servidor pode aceitar as duas cópias e devolver respostas com TIDs diferentes. O cliente fixa o servidor da transferência na primeira resposta positiva que adota. A segunda não deve ser incorporada nem causar a perda da primeira.

O comportamento definido é descartar o pacote e responder com ERROR 5, Unknown transfer ID, sem perturbar a transferência em curso. RFC 1350 apresenta a porta de origem incorreta como o erro reconhecido que não encerra a conexão. Os demais ERROR normalmente encerram e nem sequer são confirmados ou retransmitidos.

Essa exceção distribui a falha de modo preciso. O datagrama de fora recebe a recusa. O estado de dentro continua. Um tratamento que cancelasse tudo daria ao tráfego estranho autoridade sobre a conversa válida.

Um ACK por bloco e uma armadilha de duplicação

No desenho básico, DATA começa no bloco um. Cada bloco de 512 octetos aguarda o ACK correspondente. Um DATA menor encerra; se o arquivo mede exatamente um múltiplo do bloco, um DATA vazio explicita a conclusão. Após o ACK final, o receptor pode aguardar por pouco tempo e repeti-lo caso o último DATA reapareça.

A primeira redação de retransmissão, porém, permitia que qualquer lado respondesse a um datagrama antigo reenviando o atual. Depois de um atraso e de um timeout, uma cópia tardia podia gerar outra resposta; a resposta duplicada gerava outra cópia. DATA e ACK seguiam aos pares pelo resto do arquivo.

RFC 1123 chamou o defeito de síndrome do aprendiz de feiticeiro. O conteúdo podia terminar correto e, ainda assim, o mecanismo agravar congestionamento e fazer a operação expirar. A correção obrigatória determinou que o originador de DATA não retransmitisse o bloco atual apenas por receber ACK duplicado. O timeout apropriado, não qualquer eco antigo, autoriza recuperar. RFC 1350 substituiu RFC 783 com essa correção.

O cliente propunha, o servidor respondia

Uma janela de um bloco funcionava para código pequeno, mas deixava capacidade ociosa. RFC 2347 criou opções no RRQ e WRQ mantendo a iniciativa no cliente. O servidor só pode colocar no OACK aquilo que foi pedido. Pode omitir o que não suporta; o cliente ignora o que não foi reconhecido.

Em leitura, ACK zero aceita o OACK. Em escrita, DATA um o aceita. RFC 2348 negociou tamanho de bloco. RFC 2349 tratou intervalo de timeout e tamanho total. RFC 7440 permitiu uma janela de blocos consecutivos, confirmada pelo ACK do último bloco enviado.

Mais blocos antes do ACK aumentam a vazão e também o estado pendente. A extensão não elimina os TIDs, a sequência nem a necessidade de acordo. Tampouco acrescenta autenticação ou autorização de arquivo. Ela muda a quantidade de trabalho consentido entre duas evidências de progresso.

A transferência correta ainda podia carregar o arquivo errado

Nada no par de TID decide quais caminhos o servidor deve expor, quem pode escrever ou qual imagem deve iniciar uma máquina. Esses controles ficam em raízes de arquivos, permissões, alcance de rede, verificação do artefato e registros que ligam o pedido em 69 ao par dinâmico.

Middleboxes também precisam respeitar a mudança. Permitir só respostas de 69 interrompe o protocolo. Abrir uma faixa UDP sem limite para “fazer TFTP funcionar” remove a separação. O estado adequado nasce da primeira resposta aceita e deve ser tão específico quanto aquela transferência.

A história do TFTP mostra que a simplicidade bem definida não elimina governança; ela a torna visível. Uma porta tem autoridade para receber pedidos. Dois endpoints têm autoridade para classificar os pacotes daquela operação. Um número de bloco evidencia progresso. Um timer dispara recuperação. Nenhum deles, sozinho, tem autoridade para declarar o arquivo confiável.

Fontes e limites

O desenho inicial está em RFC 783, a correção de duplicação em RFC 1123 e a revisão em RFC 1350. As opções estão em RFC 2347, RFC 2348, RFC 2349 e RFC 7440. O registro IANA lista a porta 69. As fontes não medem adoção em 2026 e não fazem do TID prova de identidade, permissão, sigilo ou integridade.