Atualmente em testes: o código do GitHub será aberto quando concluído.

Camada de Transporte

ItemValor
TransporteTCP (conexão persistente)
Porta padrão5225
Opções de socketTCP_NODELAY ativado — envia pacotes pequenos imediatamente, sem o atraso de coalescência do Nagle
TLSOpcional — se o servidor tiver um certificado configurado, todo o stream é envolvido em TLS unidirecional (autenticação do servidor)
CodificaçãoCampos binários de largura fixa + chaves UTF-8. Inteiros são big-endian (ordem de rede)
Terminador de quadroUm byte \n. Sem tratamento de \r
Quadro vazioUm \n isolado (posição do op é \n) é silenciosamente ignorado como keep-alive
Tamanho máximo do quadro192 bytes — inclui op, exclui \n (se exceder → E line_too_long e conexão fechada)
PipeliningPermitido — as respostas podem chegar em ordem diferente das requisições
Timeout de ociosidadeNenhum — o servidor nunca fecha uma conexão silenciosa
Progresso do quadroNo máximo 5 segundos do primeiro byte op até fixed header e LF; envio parcial não ocupa a conexão indefinidamente

Ordem de Estabelecimento da Conexão

  1. Conexão TCP
  2. Handshake TLS, se o servidor tiver TLS habilitado — conectar-se a um servidor TLS em texto claro resulta em desconexão nessa etapa
  3. Handshake de autenticação, uma vez
  4. Troca de quadros do protocolo de lock a partir daí

Regras de Enquadramento (Framing)

Toda mensagem é um quadro = uma linha.

[ op: 1 byte ][ cabeçalho fixo específico do op ][ corpo variável ] \n

O receptor deve olhar o op e ler o cabeçalho fixo pela sua contagem de bytes primeiro, só então buscando por \n. Isso porque o cabeçalho fixo é binário e pode conter 0x0A (\n) como valor (por exemplo, lease=100A). A busca por \n se aplica apenas ao segmento final de chave/texto.

DireçãoopCabeçalho fixo
Cliente → ServidorA10 bytes (wait:u8 + lease:u8 + owner:u64 BE)
Cliente → ServidorR8 bytes (token:u64 BE)
Servidor → ClienteA16 bytes (token:u64 BE + owner:u64 BE)
Servidor → ClienteT · B8 bytes (owner:u64 BE)
Servidor → ClienteR · N8 bytes (token:u64 BE)
Servidor → ClienteM · L · E0 bytes (address/reason UTF-8 text)

Se um quadro exceder 192 bytes ou estiver malformed, o servidor faz flush de E quando possível e fecha a conexão. O cliente também trata malformed, oversized, op desconhecido ou E não correlacionável como connection-fatal. Um acquire do qual ao menos um byte foi enviado nessa sessão não é repetido automaticamente e fica Indeterminate sem resposta definitiva.

Terminologia

  • Quadro (frame) — a unidade em que um fluxo contínuo de bytes (TCP) é cortado para significar "uma mensagem". Neste protocolo, uma linha terminada em \n é um quadro.
  • Big-endian — a ordem de bytes que escreve primeiro o byte mais significativo de um inteiro. É o padrão para protocolos de rede, por isso também é chamada de ordem de rede.
  • Pipelining — enviar a próxima requisição sem esperar pela resposta anterior. Sobrepor a latência de ida e volta dessa forma aumenta a taxa de transferência.
  • Keep-alive — um sinal sem significado enviado periodicamente para anunciar que uma conexão ainda está viva. Aqui, um quadro vazio (\n) desempenha esse papel.