Expiração do mapeamento NAT ou do load balancer no meio da conexão NAT / load balancer mapping expired mid-connection
ID da causa rt-mapping · Responsável principal Desenvolvimento do cliente (Equipe de desenvolvimento) · Também envolvidos Desenvolvimento do servidor (Equipe de desenvolvimento), Infraestrutura de rede (Equipe de infraestrutura), Infraestrutura de servidores (Equipe de infraestrutura)
Se um equipamento no caminho apaga o mapeamento de uma conexão ociosa (a entrada que diz para onde encaminhar essa conexão), o próximo pacote enviado não é entregue. A conexão fica só retransmitindo até cair, ou o equipamento devolve uma recusa (RST) e ela cai na hora.
Por quê Uma conexão sem pacotes por um tempo (jogador ausente, lobby) → Efeito O NAT do roteador, o CGNAT da operadora, o firewall, o load balancer ou o grupo de segurança da nuvem apaga o mapeamento ocioso → Na tela Ao voltar a se mexer, vêm retransmissões seguidas e depois a desconexão, ou a desconexão é imediata
Responsável principal Desenvolvimento do cliente (Equipe de desenvolvimento) · Também envolvidos Desenvolvimento do servidor (Equipe de desenvolvimento), Infraestrutura de rede (Equipe de infraestrutura), Infraestrutura de servidores (Equipe de infraestrutura)
O que fazer (Equipe de desenvolvimento)
Cliente: enviar heartbeats em intervalos de no máximo metade do menor timeout de inatividade (o mapeamento do roteador do jogador e do CGNAT da operadora só é renovado com certeza por pacotes que saem de dentro, e não temos como mudar esse timeout, por isso quem envia é o cliente), reconectar automaticamente se cair. Servidor: responder aos heartbeats e encerrar por conta própria a conexão que passar um tempo sem recebê-los (reduzir o intervalo do keepalive TCP com opções de socket como TCP_KEEPIDLE, detectar rápido com TCP_USER_TIMEOUT), retomar a sessão com um token de sessão.
O que fazer (Equipe de infraestrutura)
Rede: levantar os timeouts de inatividade dos firewalls e load balancers do caminho e compartilhar com a equipe de desenvolvimento, aumentar os dos nossos firewalls e load balancers se necessário. Servidores/SO: verificar o tempo de rastreamento de conexões do grupo de segurança da nuvem e compartilhar com a equipe de desenvolvimento.
Números de referência
O tempo que cada equipamento mantém um mapeamento TCP varia de alguns minutos a algumas horas. Quando o grupo de segurança da nuvem rastreia as conexões, nos tipos de instância AWS Nitro v6 a entrada de rastreamento é apagada por padrão após 350 segundos (nos outros tipos, 5 dias; veja “Expiração do rastreamento de conexões no grupo de segurança da nuvem”). O keepalive TCP do Linux tem como padrão “verificar após 2 horas de inatividade”, mais tarde que a maioria dos equipamentos.
No gráfico
Queda de conexões em massa · Desconexões, tempo ocioso antes da queda
Onde olhar
Ver os últimos minutos das conexões que caíram por captura de pacotes no servidor e, nas conexões vivas, o tempo ocioso por lastsnd e lastrcv do ss -ti (ms desde o último envio e o último recebimento). Ver também TcpExtTCPAbortOnTimeout no nstat (conexões abandonadas porque o timer esgotou)
Confirma se
Em cada conexão que caiu, o tempo ocioso logo antes da queda passou de um valor parecido (o timeout de inatividade de um equipamento do caminho, ex.: 350 s do grupo de segurança em instâncias AWS Nitro v6), e, desde o primeiro pacote após a inatividade, só há retransmissões sem ACK até a desistência, ou um RST volta na hora
Descarta se
Cai também durante o jogo, sem relação com o tempo ocioso: outra causa (“Mudança de rota ou caminho ECMP com defeito”, “Descarte pelo firewall ou pelo rastreamento de conexões”). Conexão com heartbeat em intervalos de no máximo metade do menor timeout de inatividade: esta causa fica descartada
Como verificar
Ferramentas de infra (sem precisar do código do jogo)
Fontes
RFC 5382: NAT Behavioral Requirements for TCPIETF Recomendação de que o timeout de inatividade de conexões TCP no NAT seja de pelo menos 2 horas e 4 minutos (partindo do princípio de que os equipamentos podem apagar antes as sessões ociosas)
Amazon EC2 security group connection trackingAWS Timeout padrão de rastreamento de TCP ocioso: 350 segundos nos tipos de instância Nitro v6 e 432.000 segundos (5 dias) nos demais. Recomenda-se keepalive em intervalos menores que 5 minutos
IP SysctlLinux kernel tcp_keepalive_time com padrão de 2 horas
tcp(7) — Linux manual pageLinux man-pages TCP_KEEPIDLE (tempo ocioso antes de começar o keepalive), TCP_USER_TIMEOUT (tempo esperando a confirmação dos dados antes de fechar a conexão)
RFC 5482: TCP User Timeout OptionIETF Timeout de usuário do TCP: quanto tempo os dados enviados podem ficar sem confirmação antes de a conexão ser fechada
ss(8) — Linux manual pageiproute2 lastsnd e lastrcv no ss -i: tempo (ms) desde o último envio e o último recebimento
SNMP counterLinux kernel TcpExtTCPAbortOnTimeout: número de conexões abandonadas sem RST porque um timer do TCP esgotou