Resumo

  • O RFC 3018 reuniu nós numa memória endereçada em 128 bits e definiu leitura, escrita, alocação, liberação, operações de objeto e transferências de controle executadas por máquinas virtuais remotas.
  • Uma transação devia executar todas as instruções de uma vez ou nenhuma, mas não havia cancelamento depois da execução. O próprio texto citava a transferência de controle como efeito possivelmente impossível de desfazer.

Antes da execução, a transação tinha uma forma material. Era uma cadeia completa, identificada e armazenada no destino. Podia receber uma ordem para executar. Podia receber outra ordem para ser apagada.

Depois da execução, já não era apenas uma cadeia. Era memória alterada, recurso alocado, objeto chamado ou um novo fluxo de controle em outra máquina.

O RFC 3018 faz essa separação sem eufemismo. O cancelamento posterior não é previsto. Uma reversão, se necessária, deve existir na máquina virtual, pois algumas instruções—uma transferência de controle, por exemplo—podem ser impossíveis de cancelar.

Publicado em dezembro de 2000 como Experimental, o Unified Memory Space Protocol Specification propunha esconder a rede atrás de um modelo de computação. O programa usaria endereços de 128 bits. A VM converteria as operações destinadas a outro nó em instruções UMSP. Ler, escrever, reservar memória, liberar, comparar, mover código, chamar um procedimento ou saltar para uma posição remota fariam parte da mesma linguagem.

A distância desaparecia do código-fonte. Continuava presente na prova operacional.

O endereço era comum; a guarda, distribuída

O modelo separava job, task e thread. O job representava a aplicação distribuída. Em cada nó, ele tinha uma task. Cada task podia ter vários fluxos de controle. Um Job Control Point, JCP, coordenava o ciclo de vida e atribuía identificadores.

Essa centralização não transferia toda a autoridade ao JCP. A memória local pertencia à VM. A VM ordenava instruções, administrava recursos e cuidava dos ponteiros. O protocolo não controlava a memória do job nem rastreava os fluxos do usuário. Quando uma task terminava, cabia à VM invalidar os ponteiros relacionados.

O endereço de dezesseis octetos juntava rede, nó e memória local numa chave. Ele não juntava relógios, diários ou responsáveis por recuperação. Um salto para endereço remoto criava outro thread naquele nó; um segmento contínuo de código, porém, não podia atravessar os nós.

A abstração unificava o nome do lugar. Não eliminava quem tinha de provar o que aconteceu naquele lugar.

Recepção completa ainda não era decisão

O UMSP tinha cadeias de tipos diferentes. A sequência representava dependência: se uma instrução falhasse, as posteriores seriam canceladas. A transação reunia instruções até sem relação entre si, sob a condição de todas executarem juntas ou nenhuma executar.

O tamanho precisava ser conhecido antes, por causa do buffering. _BEGIN_TR iniciava o conjunto, _END_CHAIN marcava a última instrução. Só então existia uma transação completa no receptor.

Se TRR=1, o fim da transferência liberava a execução imediatamente. Se TRR=0, o receptor esperava EXEC_TR. Antes de começar, CANCEL_TR apagava as instruções armazenadas sem possibilidade de restaurá-las.

O sinalizador TRE tornava a falha de sessão ainda mais importante. Com valor 1, uma transação completa, porém não executada, deveria rodar ao expirar sua vida ou ao ocorrer um encerramento emergencial. Com valor 0, deveria ser cancelada. O relógio só começava quando todas as instruções haviam chegado; zero retirava o limite.

Assim, “a sessão caiu” podia descrever quatro situações opostas: transferência incompleta, conjunto completo em espera, execução já ordenada ou execução disparada pela própria regra de emergência.

Uma auditoria precisa guardar separadamente o hash ordenado do conjunto, o recibo de completude, o estado de espera, a causa de executar ou cancelar e os resultados observados. Um único campo de commit não contém essa história.

Atomicidade não criava a operação inversa

O RFC definia a entrada conjunta na execução. Não prometia que qualquer efeito já produzido pudesse ser devolvido ao estado anterior.

Uma escrita pode ser lida por outro thread. FREE pode invalidar uma referência que circula em outra parte do job. Código transferido pode continuar agindo. Um procedimento de objeto pode alterar um sistema externo. JUMP e CALL podem criar fluxos que sobrevivem à cadeia original.

Imagine uma transação que aloca memória, instala código e transfere controle. O protocolo pode impedir a execução de apenas duas dessas três instruções. Mas, se o novo thread enviar uma mensagem ou acionar um equipamento, apagar a cadeia inicial não recolhe a mensagem nem desfaz a ação.

Cancelar é decidir sobre algo que ainda espera. Compensar é agir sobre um mundo que já mudou. A compensação precisa entender o efeito; não pode ser deduzida de modo universal a partir do opcode.

Por isso, EXEC_TR é um recibo da decisão de liberar uma cadeia. Não é, sozinho, o recibo de que cada ação terminou, que os efeitos ocorreram uma vez ou que o objetivo do job foi alcançado.

A entrega de TCP não fechava a lacuna

O UMSP exigia TCP para troca confiável e permitia UDP para dados que dispensassem confirmação. O RFC 793 entrega fluxo ordenado de octetos e trata perda, duplicação, dano e reordenação. O RFC 768 fornece o contrato mínimo de datagramas.

Essas propriedades não sobem automaticamente até a VM. Um ACK de TCP confirma recepção naquele nível. Não confirma validação UMSP, associação à cadeia correta, liberação pela autoridade esperada, execução sobre a versão certa de memória ou conclusão da aplicação.

O RFC 1831 mostra problema semelhante em ONC RPC. Uma resposta sobre TCP permite inferir execução dentro do modelo descrito. Se não houver resposta, o cliente não pode concluir que nada foi executado: o servidor pode ter agido antes da conexão falhar. Chamadas remotas também trazem falhas, efeitos laterais, desempenho e autenticação diferentes de uma chamada local.

O UMSP tornava a operação remota ainda mais parecida com uma instrução de processador. Quanto mais conveniente a ilusão, maior a necessidade de preservar as diferenças de evidência.

O JCP coordenava, mas não observava tudo

O Job Control Point atribuía o identificador global, acompanhava tasks e podia servir à identificação centralizada de usuários e à proteção contra ataques.

Ainda assim, memória e ponteiros permaneciam sob a VM. Um thread remoto podia produzir efeito fora da visão imediata do JCP. A conexão podia falhar depois da execução e antes da resposta. Reinícios exigiam distinguir segmentos de sessões anteriores.

Portanto, fim de task, fim de job e efeito útil são registros diferentes. Uma task encerrada não prova persistência de cada escrita. Um job concluído não prova que toda ação externa aconteceu uma única vez nem que todas as capacidades foram revogadas.

Segurança era uma agenda futura, por decisão explícita

A seção de segurança afirma que as questões de proteção foram excluídas para reduzir a complexidade inicial. As ideias seguintes são recomendações de expansão.

O documento menciona proteções de TCP/IP, chains com processamento especial para integridade ou criptografia e parâmetros de autenticação em cabeçalhos de extensão. Propõe combinações de autenticação entre os nós e o JCP. Para ataques intermediários, imagina caminhos não sobrepostos e reconhece que uma mesma gateway enfraquece o método.

Também aponta JUMP e CALL como riscos de negação de serviço, cuja limitação de recursos deve ficar com a VM. Código ativo baixado para o cliente eleva o risco do cliente; código do cliente executado no servidor exige endurecimento do servidor.

Esse mapa de risco não é um protocolo de segurança completo. Não especifica algoritmos, chaves, autorização, antirreplay, revogação e auditoria.

O RFC 3552, posterior, oferece contraste: seu modelo supõe que o atacante possa ler, retirar, modificar ou injetar tráfego. Não é correto impor essa orientação retrospectivamente ao autor de 2000. É correto evitar que rotas separadas ou extensões ainda indefinidas sejam tratadas como prova pronta de segurança.

Experimental preservava uma proposta, não uma implantação

Segundo o RFC 2026, documentos Experimental ficam fora da trilha de padronização e não são Internet Standards. Podem registrar pesquisa e desenvolvimento. O RFC 2119 fornecia palavras normativas; o RFC 2234, ABNF. TCP, UDP e ONC RPC delimitam os contratos adjacentes.

Nada nessas fontes prova adoção, produto, interoperabilidade, incidente ou uso atual do UMSP. Elas sustentam o desenho e os limites que o próprio desenho declarou.

O valor histórico está em observar uma abstração levada muito longe sem esconder seu ponto de ruptura. Um endereço podia ser unificado enquanto a guarda permanecia distribuída. Uma transação podia estar completa sem estar liberada. A liberação podia ser atômica sem ser reversível. O job podia acabar sem provar o resultado externo.

As ideias de Lu Heng entram como lentes declaradas. Running-Code Primacy separa a instrução publicada do fato produzido por código em execução. Reality Layers mantém mensagem, buffer, decisão, execução e resultado em camadas diferentes. Minimum Initial Specification explica a utilidade de um núcleo pequeno, mas exige que segurança, compensação e observação ausentes continuem visíveis.

Não são afirmações sobre a intenção do autor do RFC.

O protocolo sabia quando o lote atravessava a porta. O restante dependia do mundo que ele acabara de alterar.

Sources