Resumo

  • O RFC 3542 separou as opções IPv6 persistentes do socket dos dados auxiliares associados a uma mensagem. O dado auxiliar substitui somente a opção persistente de mesmo nome; as demais continuam valendo.
  • O alcance tem limites definidos: um dado de comprimento zero pode desativar uma opção para um datagrama, pacotes já enfileirados podem não trazer metadados recém-solicitados e chamadas de envio TCP não correspondem individualmente a segmentos transmitidos.

Imagine um socket UDP duradouro usado por um aplicativo de diagnóstico. O programa escolheu uma interface de saída e opções IPv6 que devem valer para cada datagrama. Uma mensagem excepcional precisa seguir outra rota. Se a implementação tratar esse dado pontual como substituto de todo o conjunto de padrões, talvez o pacote siga a rota desejada, mas também abandone escolhas que o aplicativo nunca pediu para alterar.

Publicado em maio de 2003 como Advanced Sockets Application Program Interface (API) for IPv6, o RFC 3542 tornou essa fronteira explícita. Ele é um documento Informational, não um protocolo na rede. Seu objeto é a interface entre o aplicativo e o kernel: o que o programa pode solicitar sobre o IPv6, e não o que a rede necessariamente transmitiu. Uma chamada aceita ainda não comprova o caminho do pacote nem o resultado da aplicação.

A comparação com o RFC 2292, que o documento substituiu, explica o ajuste. No modelo anterior, opções persistentes podiam ser configuradas como um conjunto; dados auxiliares de uma mensagem substituíam esse conjunto. O RFC 3542 separou mais opções e tornou os controles individualmente endereçáveis. Quando o estado deixou de ser um bloco único, a substituição também deveria deixar de ser global: apenas a opção de mesmo tipo seria sobreposta.

Isso é mais que um detalhe de programação. Define a área de impacto de uma exceção. Se o socket mantém escolhas para interface, classe de tráfego e cabeçalhos de extensão, um dado auxiliar de roteamento não autoriza apagar as outras duas. O kernel combina o estado persistente com a exceção de escopo estreito ao construir o datagrama. O resultado dessa construção ainda é diferente de observar o pacote efetivamente enviado.

A regra também permite pedir uma ausência específica. O aplicativo pode manter uma opção persistente IPV6_HOPOPTS e enviar, para uma mensagem, um dado auxiliar do mesmo tipo com comprimento zero. Isso omite o cabeçalho Hop-by-Hop naquele datagrama. O zero não significa “esquecer todos os padrões”; desativa uma opção nomeada, uma vez. O próximo datagrama volta a herdar o valor persistente, a menos que o aplicativo o altere de outra forma.

Na recepção, o problema é temporal. O programa ativa opções IPV6_RECVxxx, e recvmsg() pode devolver as informações disponíveis em objetos auxiliares. Se o objeto esperado não aparece, talvez a característica estivesse ausente do pacote. Mas o RFC 3542 também alerta que datagramas já enfileirados quando a opção foi ativada podem não carregar os novos metadados. A ausência pode dizer algo sobre o pacote ou sobre quando a observação começou; sozinha, não resolve o que havia no fio.

O TCP marca o limite da analogia com datagramas. O RFC 3542 não define o mesmo controle auxiliar por envio para TCP, pois uma chamada do aplicativo não se transforma em um único segmento transmitido. Uma retransmissão pode usar informações persistentes antigas ou novas; o padrão não promete um controle por mensagem onde essa correspondência não existe. Ele também deixa indefinidas certas informações opcionais de recepção TCP e desaconselha seu uso em decisões de controle de acesso.

Os exemplos históricos precisam de contexto temporal. O RFC 3542 mostra um cabeçalho de roteamento Type 0 herdado do período do RFC 2460. O RFC 8200 é hoje a especificação-base do IPv6. O exemplo antigo registra as funções da API naquela época; não é uma recomendação atual de roteamento.

A história do RFC 3542 é a de uma exceção mais bem delimitada: a substituição de um conjunto inteiro no RFC 2292 virou sobreposição apenas da opção homônima. Para provar o resultado, registre separadamente os padrões do socket antes da chamada, o dado auxiliar da mensagem, o pacote observado e o resultado posterior. Uma chamada sendmsg() aceita prova que a interface recebeu uma intenção, não que o pacote percorreu a rota esperada.

Fontes