Travessia de NAT
-A maioria dos dispositivos na internet ficam atras de um NAT (Network Address Translator). Seu roteador atribui ao seu dispositivo um endereco privado (como 192.168.1.100) e o traduz para um endereco publico quando voce conecta para fora. Isso funciona bem para navegar na web, mas cria um problema para redes P2P: dois dispositivos atras de NATs diferentes nao conseguem se conectar diretamente sem ajuda.
Tesseras resolve isso com uma abordagem em tres camadas, tentando a opcao mais barata primeiro:
--
-
- Conexao direta — se ambos os nos tem IPs publicos, eles conectam diretamente -
- UDP hole punching — um terceiro no apresenta os dois peers para que eles possam furar seus NATs -
- Relay — um no com IP publico encaminha pacotes entre os dois peers -
Descoberta do tipo de NAT
-Quando um no inicia, ele envia requisicoes STUN (Session Traversal Utilities for NAT) para multiplos servidores publicos. Comparando os enderecos externos que esses servidores reportam, o no classifica seu NAT:
-| Tipo de NAT | O que significa | Hole punching? |
|---|---|---|
| Public | Sem NAT — seu dispositivo tem IP publico | Nao necessario |
| Cone | NAT mapeia a mesma porta interna para a mesma porta externa independente do destino | Funciona bem (~80%) |
| Symmetric | NAT atribui uma porta externa diferente para cada destino | Nao confiavel |
| Unknown | Nao conseguiu alcancar servidores STUN | Relay necessario |
Seu no divulga seu tipo de NAT em mensagens Pong do DHT, para que outros nos saibam se hole punching vale a pena tentar.
-Hole punching
-Quando o no A (atras de um NAT Cone) quer conectar ao no B (tambem atras de um NAT Cone), nenhum consegue alcancar o outro diretamente. A solucao:
--
-
-
-
A envia uma mensagem PunchIntro ao no I (um introdutor — qualquer no com IP publico que ambos conhecam). A mensagem inclui o endereco externo de A (do STUN) e uma assinatura Ed25519 provando a identidade de A.
-
- -
-
I verifica a assinatura e encaminha um PunchRequest a B, incluindo o endereco de A e a assinatura original.
-
- -
-
B verifica a assinatura (provando que a requisicao realmente veio de A, nao de uma fonte falsificada). B entao envia um pacote UDP para o endereco externo de A — isso abre um pinhole no NAT de B. B tambem envia uma mensagem PunchReady de volta a A com o endereco externo de B.
-
- -
-
A envia um pacote UDP para o endereco externo de B. Ambos os NATs agora tem pinholes, e os dois nos podem se comunicar diretamente.
-
-
O processo inteiro leva 2-5 segundos. As assinaturas Ed25519 previnem ataques de reflexao, onde um atacante reproduz uma introducao antiga para redirecionar trafego.
-Fallback por relay
-Quando hole punching falha (NAT Symmetric, firewalls estritos ou redes corporativas), nos usam relay atraves de um no com IP publico:
--
-
- A envia um RelayRequest ao no R (um no com IP publico com relay habilitado). -
- R cria uma sessao e envia um RelayOffer a ambos A e B, contendo o endereco do relay e um token de sessao. -
- A e B enviam seus pacotes a R, prefixados com o token de sessao. R remove o token e encaminha o payload ao outro peer. -
Sessoes de relay tem limites de largura de banda:
--
-
- 256 KB/s para peers com boa reciprocidade (eles armazenam fragmentos para outros) -
- 64 KB/s para peers sem reciprocidade -
- Sessoes nao reciprocas sao limitadas a 10 minutos -
Isso incentiva nos a contribuir armazenamento — bons cidadaos da rede recebem melhor servico de relay.
-Migracao de endereco
-Quando um dispositivo movel troca de rede (Wi-Fi para celular), seu endereco IP muda. Ao inves de encerrar e reconstruir sessoes de relay, o no envia uma mensagem RelayMigrate assinada para atualizar seu endereco na sessao existente. Isso evita reestabelecer conexoes do zero.
-Configuracao
-A secao [nat] na configuracao do daemon controla a travessia de NAT:
[nat]
-# Servidores STUN para deteccao de tipo de NAT
-stun_servers = ["stun.l.google.com:19302", "stun.cloudflare.com:3478"]
-
-# Habilitar relay (encaminhar trafego para outros nos com NAT)
-relay_enabled = false
-
-# Maximo de sessoes de relay simultaneas
-relay_max_sessions = 50
-
-# Limite de largura de banda para peers reciprocos (KB/s)
-relay_reciprocal_kbps = 256
-
-# Limite de largura de banda para peers nao reciprocos (KB/s)
-relay_bootstrap_kbps = 64
-
-# Timeout de inatividade de sessao relay (segundos)
-relay_idle_timeout_secs = 60
-
-Para executar um no relay, defina relay_enabled = true. Seu no deve ter um IP publico (ou roteador com port forwarding) para servir como relay.
Reconexao mobile
-Quando o app Tesseras detecta uma mudanca de rede em um dispositivo movel, ele executa uma sequencia de reconexao em tres fases:
--
-
- Migracao QUIC (0-2s) — QUIC suporta migracao de conexao nativamente. O app tenta migrar todas as conexoes ativas para o novo endereco. -
- Re-STUN (2-5s) — descobre o novo endereco externo e re-anuncia ao DHT. -
- Reestabelecimento (5-10s) — reconecta peers que a migracao nao conseguiu salvar, em ordem de prioridade: nos bootstrap primeiro, depois nos que guardam seus fragmentos, depois nos cujos fragmentos voce guarda. -
O app mostra progresso de reconexao atraves do stream de eventos NetworkChanged.
Monitoramento
-A travessia de NAT expoe metricas Prometheus em /metrics:
-
-
tesseras_nat_type— tipo de NAT detectado atualmente
-tesseras_stun_requests_total/tesseras_stun_failures_total— confiabilidade STUN
-tesseras_punch_attempts_total{initiator_nat, target_nat}— taxa de sucesso de punch por par de NAT
-tesseras_relay_sessions_active— carga atual de relay
-tesseras_relay_bytes_forwarded— largura de banda total de relay
-tesseras_network_change_total— frequencia de mudanca de rede no mobile
-