Resumo

  • cm_request informava que a aplicação queria transmitir, mas não entregava um buffer ao Congestion Manager; cmapp_send concedia até um limite, em geral um PMTU, e por prazo curto.
  • A concessão não provava fila, emissão ou entrega. A aplicação escolhia ou reempacotava o conteúdo, relatava os bytes colocados na saída IP com cm_notify e enviava evidência do receptor separadamente por cm_update.

Uma máquina, vários aprendizados sobre o mesmo gargalo

No início dos anos 2000, navegadores, programas de áudio e vídeo e outros serviços podiam manter diversos fluxos para o mesmo destino. Cada um estimava RTT, percebia perdas e ajustava a taxa por conta própria. Uma nova conexão ignorava o que outra acabara de aprender. O gargalo era compartilhado, mas sua memória estava fragmentada.

A RFC 2140 já tratava do compartilhamento de partes do estado TCP entre conexões de um par de hosts. Publicada no Standards Track em junho de 2001, a RFC 3124 propôs um serviço mais amplo no sistema terminal. O Congestion Manager, ou CM, agrupava fluxos em macroflows, compartilhava estado e algoritmos de congestionamento e expunha interfaces a aplicações, inclusive às que não usavam TCP.

Isso não transformava o CM em uma grande fila central. A arquitetura separava o conhecimento do momento disponível do conhecimento sobre o valor dos dados. O scheduler via pedidos concorrentes e a janela de congestionamento; a aplicação sabia qual quadro ou mensagem continuava útil.

O pedido não carregava o pacote

Ao chamar cm_request, a aplicação declarava demanda. Não passava um buffer para o CM armazenar. Portanto, o controlador não conservava payload, não inspecionava seu significado e não prometia transmitir uma mensagem específica mais tarde.

Quando havia oportunidade, o CM chamava cmapp_send. O callback autorizava uma quantidade máxima, normalmente um path MTU. Só nesse instante a aplicação escolhia o conteúdo. Um encoder podia abandonar um quadro antigo, reduzir qualidade ou reempacotar dados para caber na concessão.

Essa decisão tardia era uma vantagem central. Uma fila genérica teria congelado cedo demais o que seria enviado. Um scheduler totalmente privado impediria o compartilhamento da visão de congestionamento. A interface combinava os dois saberes sem fundi-los.

Por isso, um callback não era recibo de emissão. Depois dele ainda faltavam construir os dados, entregá-los ao IP e fazê-los sair pela interface. A aplicação poderia não usar a oportunidade ou recebê-la quando já estivesse vencida.

A autorização vencia e exigia prestação de contas

A validade terminava depois do maior valor entre um RTT e um limiar definido pela implementação. Uma aplicação não podia guardar o callback como crédito permanente. O estado que justificou a decisão mudava com o tempo.

Depois da tentativa, cm_notify(nsent) informava quantos bytes foram efetivamente colocados na saída IP. Se nada fosse enviado, a aplicação deveria informar zero e devolver a oportunidade. Pedido, concessão e uso real tornavam-se eventos diferentes no livro-caixa do controlador.

O desenho também tolerava falhas. Uma aplicação podia encerrar sem enviar a notificação zero. O CM precisava se recuperar para não bloquear todos os demais pedidos. Ainda assim, robustez não significava converter silenciosamente toda concessão em envio fictício.

nsent descrevia emissão no host, não recebimento no destino. Evidência remota chegava por cm_update, com distinções entre recepção, perda, notificação explícita de congestionamento e ausência de feedback. Assim, permissão, ato local e observação do receptor não ocupavam o mesmo campo.

Macroflow era uma hipótese operacional

Fluxos de um macroflow compartilhavam estado e scheduling. A aplicação podia influenciar o agrupamento, pois conhecia relações entre suas sessões. Mas um identificador comum não provava um caminho comum. Mudança de rota, múltiplas interfaces ou uma regra ampla demais podiam separar os gargalos reais.

Uma auditoria precisaria manter a chave do macroflow ao lado da rota, interface, destino e medições daquele momento. Sem isso, o grupo registra apenas uma escolha do software. Não certifica a topologia percorrida.

As RFCs 2581, 2861 e 5681 ajudam a situar o comportamento TCP, e a RFC 9040 retomou o compartilhamento de métricas entre conexões. A contribuição peculiar da RFC 3124 foi o protocolo pedido–concessão–notificação voltado às aplicações e um scheduler comum, não apenas um cache de métricas TCP.

“Bem comportada” era uma obrigação voluntária

O texto chamava de bem comportada a aplicação que só enviava com consentimento do CM e relatava corretamente todos os dados transmitidos. Era um contrato de cooperação. Não era uma barreira capaz de conter qualquer processo do host.

A RFC declarou que o CM não impunha o comportamento a todas as aplicações e não protegia a rede contra um host comprometido. Policiamento no host ou no roteador seria outro mecanismo, fora do escopo. Um programa malicioso ou não integrado poderia contornar a interface.

Logo, encontrar o módulo instalado não prova que todo o tráfego obedecia a ele. Ver chamadas de uma aplicação não elimina tráfego paralelo fora do CM. E uma sequência correta de chamadas ainda não demonstra que os pacotes percorreram o gargalo presumido pelo macroflow.

A adoção era opcional. Quem usasse o CM deveria seguir a especificação, mas a condição de Standards Track não fornece números de implantação nem resultados operacionais.

O desconhecido tinha valor próprio

Aplicações que mantinham seu scheduler podiam consultar o CM por meio de cm_query. A interface síncrona retornava estimativas de taxa, RTT e congestionamento. Quando a estimativa era inválida, retornava valor negativo, em vez de inventar capacidade zero.

Desconhecido e zero pedem decisões diferentes. Essa precisão também vale para a história: ausência de evidência de implantação não prova fracasso, e a existência da norma não prova adoção. A RFC 2914 expõe princípios de congestionamento; a RFC 2481 registra o contexto experimental de ECN; a RFC 1191 trata de PMTU; a RFC 8085 consolida responsabilidades posteriores para UDP. Nenhuma é recibo de uso da RFC 3124.

Uma transmissão exigia vários recibos

O registro completo começaria com cm_request, fluxo e macroflow, estado do scheduler, horário e tamanho do callback, PMTU, RTT e cálculo de expiração. Depois viriam conteúdo escolhido, cm_notify na saída IP, interface, rota e cada cm_update. Resultado percebido pelo usuário exigiria ainda outras medições.

Cada peça responde a uma pergunta: o pedido comprova demanda declarada; o callback, oportunidade temporária; a notificação positiva, relato local de emissão; o feedback, evidência posterior do caminho. Nenhuma pode representar as demais.

O legado da RFC 3124 está nessa separação disciplinada. Ela tentou compartilhar o controle de congestionamento sem transferir a propriedade dos dados. Uma autorização organizava o tempo; não era o pacote e muito menos sua chegada.

Fontes

  1. https://www.rfc-editor.org/rfc/rfc3124.txt
  2. https://www.rfc-editor.org/info/rfc3124
  3. https://datatracker.ietf.org/doc/rfc3124/
  4. https://www.rfc-editor.org/rfc/rfc2140.txt
  5. https://www.rfc-editor.org/rfc/rfc2914.txt
  6. https://www.rfc-editor.org/rfc/rfc2581.txt
  7. https://www.rfc-editor.org/rfc/rfc2861.txt
  8. https://www.rfc-editor.org/rfc/rfc2481.txt
  9. https://www.rfc-editor.org/rfc/rfc1191.txt
  10. https://www.rfc-editor.org/rfc/rfc5681.txt
  11. https://www.rfc-editor.org/rfc/rfc8085.txt
  12. https://www.rfc-editor.org/rfc/rfc9040.txt