Rede Yggdrasil em Go
Visão Geral
Use esta habilidade para construir programas Go que se conectam e servem na
mesh Yggdrasil IPv6 com criptografia ponta a ponta: clientes, servidores HTTP/TCP/UDP,
proxies SOCKS5, encaminhadores de porta e nós que publicam metadados de descoberta. O nó
é executado em modo usuário sobre uma pilha de rede gVisor — sem dispositivo TUN, sem root, sem
daemon yggdrasil externo e sem binário yggstack. Você disca e escuta sobre
Yggdrasil com interfaces Go padrão (net.Conn, net.Listener,
net.PacketConn, http.Transport).
A biblioteca de incorporação é github.com/voluminor/ratatoskr: crie o nó com
ratatoskr.New e dirija tudo através de sua API Go. O escopo e a estabilidade de
seus pacotes são resumidos abaixo.
Projeto para uma Mesh Restrita
Yggdrasil é uma mesh overlay com criptografia ponta a ponta, não uma malha de datacenter. Os links têm alta latência, baixa largura de banda, são instáveis e intermitentes; um par acessível agora pode desaparecer um segundo depois, e o tráfego pode cruzar muitos saltos. Construa toda solução Yggdrasil como se fosse para uma conexão fraca e instável. Isso não é opcional — é a forma padrão de código correto aqui.
- Nunca sem limite. Um prazo em cada discagem e requisição
(
context.WithTimeout); repetições limitadas; filas limitadas. Sem esperas infinitas. - Limite a concorrência. Restrinja o trabalho em andamento: SOCKS
MaxConnections, forwardSetMaxUDPSessions,http.Transport.MaxConnsPerHost/MaxIdleConnsPerHost, seus próprios pools de workers. Ambos padrão para ilimitado — defina limites reais. - Divida transferências grandes, verifique, retome. Nunca mova um arquivo grande de uma vez.
Divida em pequenos blocos (ex.: HTTP
Range), verifique cada um (tamanho/checksum) e torne-o retomável para que um link caído custe um bloco, não a transferência inteira. - Repita com backoff + jitter, de forma idempotente. Espere desconexões no meio da operação. Torne as operações retomáveis/idempotentes; backoff exponencial com jitter; limite as tentativas.
- Mantenha as cargas pequenas. Evite protocolos verbosos e polling; compacte; use codificações compactas. Mantenha NodeInfo/sigilos bem abaixo do limite de 16 KB.
- Dimensione buffers para o link. Use
node.MTU()para buffers de pacotes (MTU em modo usuário é dinâmico, mínimo de 1280). - Degrade, não martele. Em falha, faça backoff e retorne resultados parciais; nunca repita agressivamente um par ou inunde a mesh.
Um ingênuo "servir um arquivo grande sobre net/http" ou "uma requisição/resposta gigante" é a
forma errada. A forma correta é limitada, fragmentada, retomável, tolerante a falhas por
padrão. Veja o padrão de transferência para mesh restrita em
references/integrations.md.
Fonte da Verdade
O módulo ativo é autoritativo — não a memória, não textos README desatualizados, não esta habilidade. Antes de escrever orientações específicas de versão, inspecione do que o projeto depende:
go list -m github.com/voluminor/ratatoskr # versão selecionada
go doc github.com/voluminor/ratatoskr # API raiz como compilada
go doc github.com/voluminor/ratatoskr/mod/peermgr ConfigObj
Para ler o código fonte real da versão selecionada, resolva-o a partir do cache do módulo em vez de adivinhar um caminho:
go list -m -f '{{.Dir}}' github.com/voluminor/ratatoskr
Não congele a versão mínima de Go a partir do texto README — ela pode ficar defasada em relação
a diretiva go.mod. Leia o go.mod ativo da versão selecionada do Ratatoskr.
Fluxo de Trabalho Padrão
- Identifique a forma do aplicativo: nó incorporado, cliente/servidor HTTP, TCP/UDP bruto, SOCKS5, encaminhamento de porta, gerenciamento de pares ou NodeInfo/sigilos.
- Use o pacote raiz
github.com/voluminor/ratatoskrpara aplicativos. Acessemod/coreapenas através do contratocore.Interface; evite*core.Obj/UnsafeCore()a menos que um pacote de baixo nível realmente exija. - Possua um
context.Context, passe-o comoratatoskr.ConfigObj.Ctx, e ainda façadefer node.Close()após uma inicialização bem-sucedida. Ambos são necessários. - Configure pares em exatamente um lugar:
- Pares Yggdrasil estáticos:
cfg.Config.Peers - Gerenciador de pares Ratatoskr:
ratatoskr.ConfigObj.Peers(então deixecfg.Config.Peersvazio, ouNewretornaErrPeersConflict).
- Pares Yggdrasil estáticos:
- Use
node.DialContextpara TCP/UDP de saída enode.Listen/node.ListenPacketpara serviços dentro do Yggdrasil. - Coloque endereços IPv6 entre colchetes em URLs e strings host-porta:
http://[200:abcd::1]:8080, nuncahttp://200:abcd::1:8080. - Trate o link como fraco: coloque um prazo em cada chamada, limite a concorrência e divida/verifique/retome transferências grandes (veja Projeto para uma Mesh Restrita).
- Ao gerar código em um projeto real, adicione uma verificação de compilação ou teste focado em vez de assumir que compila.
Escopo e Estabilidade do Módulo
Endereços Yggdrasil são derivados da chave do nó, então a superfície de rede é pequena e estável. Prefira as partes que a biblioteca trata como finalizadas; sinalize o resto explicitamente em vez de construir sobre ele.
| Pacote | Status | Use através de |
|---|---|---|
raiz ratatoskr | Estável, API primária | New, EnableSOCKS, Ask/AskAddr, Snapshot, Close |
mod/core | Contrato estável | os métodos core.Interface incorporados no nó |
mod/peermgr | Estável | ratatoskr.ConfigObj.Peers |
mod/socks | Estável | node.EnableSOCKS (não instancie diretamente) |
mod/resolver | Estável | criado automaticamente por EnableSOCKS; uso direto é avançado |
mod/forward | Estável | forward.New → Add* → Start |
mod/sigils (+ info, services, public, inet) | Estável | ratatoskr.ConfigObj.Sigils |
mod/ninfo | Estável | node.Ask / node.AskAddr |
mod/probe | Avançado / instável — requer UnsafeCore(), API pode mudar | apenas quando rastreamento de topologia/rota é explicitamente necessário |
mod/settings | Trabalho em andamento — esquema não finalizado | evite; use yggdrasil-go/src/config diretamente |
cmd/* | Aplicativos de exemplo, não API de biblioteca importável | leia como padrões, nunca importe |
Raiz vs submódulos: padrão para ratatoskr.New (core + SOCKS + gerenciador de pares
- ninfo + sigilos por trás de um
Close). Desça paramod/coreviacore.Newapenas para a menor superfície (discagem/escuta bruta), ou componha submódulos em torno decore.Interfacepara transportes personalizados e testes. Cada submódulo (peermgr/socks/forward/resolver/ninfo) aceita umcore.Interface. Veja references/overview.md.
Sigilos do Sistema — Publique Aqui Primeiro
NodeInfo é como um nó se descreve para a rede. Quatro sigilos embutidos ("do sistema")
são analisados automaticamente por cada nó, então os dados que você coloca neles
são reconhecidos por outros participantes. Recorra a estes antes de inventar um
sigilo personalizado; passe-os via ratatoskr.ConfigObj.Sigils. Mantenha cada um
pequeno — eles compartilham um orçamento de NodeInfo de 16 KB.
| Sigilo | O que pertence aqui | Por que usar |
|---|---|---|
info | Identidade do nó: nome, tipo, localização, contatos, descrição | Permite que outros saibam quem/o que seu nó é. |
services | Portas que você expõe dentro do Yggdrasil, como nome → porta | Descoberta de serviços sem varredura de portas. |
public | Seus URIs de peering público agrupados por rede | Permite que outros façam peering diretamente com você. |
inet | Seus endereços do mundo real (domínios/IPs) | Mapeia seu nó Yggdrasil para identidade na rede limpa. |
Coloque dados descobertos e padrão nestes para que toda a rede possa lê-los.
Apenas defina um sigilo personalizado para dados que nenhum dos quatro cobre — e lembre-se
apenas pares executando seu código o analisarão. Construtores validam e retornam erros;
trate-os antes de ratatoskr.New. Detalhes, limites exatos, acesso tipado e
criação de sigilos personalizados: references/nodeinfo-sigils.md
e references/custom-sigils.md.
Mapa de Referência
Leia apenas os arquivos necessários para a tarefa atual:
- Fundamentos de nó incorporado, Ratatoskr vs yggstack, arquitetura, escopo: references/overview.md
ratatoskr.New,ConfigObj, ciclo de vida, segurança de threads, métodos raiz, erros, snapshot: references/root-api.md- TCP, UDP,
DialContext,Listen,ListenPacket, cliente/servidor HTTP, multicast/admin, pontos de teste: references/networking.md - Pares estáticos, gerenciador de pares, SOCKS5, resolvedor, encaminhamento de porta: references/peers-socks-forwarding.md
- NodeInfo,
Ask/AskAddr, sigilos embutidos com limites exatos: references/nodeinfo-sigils.md - Acesso tipado e criação/conexão de seus próprios sigilos (sem
map[string]anybruto): references/custom-sigils.md - Modelos de cliente/servidor e integrações de frameworks (net/http, fasthttp, gRPC, ponte gnet): references/integrations.md
- Áreas avançadas/em andamento (probe, settings) e padrões de CLI/app de exemplo: references/advanced-and-examples.md
- Receitas de aplicativos prontas para adaptação: references/recipes.md
Erros Comuns
| Erro | Correção |
|---|---|
| Iniciar um daemon Yggdrasil externo para um app incorporado | Use ratatoskr.New; ele executa uma pilha de rede gVisor em modo usuário. |
Recomendar yggstack para integração de biblioteca | yggstack é um binário para usuário final. Use Ratatoskr para controle de API Go. |
Configurar ambos cfg.Config.Peers e ConfigObj.Peers | Escolha pares estáticos ou o gerenciador de pares; nunca ambos → ErrPeersConflict. |
Passar Ctx mas pular Close (ou vice-versa) | Faça ambos: cancelamento dispara desligamento, Close libera recursos. |
| Construir URLs sem colchetes IPv6 | Use fmt.Sprintf("http://[%s]:%d", ip, port). |
Criar ninfo.New para consultas básicas | Use node.Ask / node.AskAddr; o objeto raiz já constrói ninfo. |
| Montar ou registrar sigilos dinamicamente em tempo de execução | Sigilos são montados estritamente em código; chaves duplicadas ou sobrescritas são erros duros por design, não mesclagens silenciosas. Publique via ConfigObj.Sigils; leia suas próprias chaves de res.Node.Extra. |
Recorrer a UnsafeCore() / mod/probe / mod/settings por padrão | Fique na API raiz; estes são avançados ou trabalho em andamento. |
| Codificar uma versão de Go do README | Leia o go.mod ativo da versão do módulo selecionado. |
Validação
Mantenha SKILL.md como a camada de navegação e coloque detalhes pesados de API em
references/. Teste as alterações em relação aos cenários em
evals/evals.json antes de publicar.