Conexão TCP Preso no Linux

1

Problema estranho. Eu tenho o servidor "ALPHA" em Dallas e o servidor "BETA" em Hong Kong, cerca de 195 ms de tempo de ping entre eles. ALPHA está conectado em 1gbps e BETA em 10Mbps. Ocasionalmente, quando se comunicam entre si por TCP, a conexão é interrompida. Eventualmente ALPHA desiste e fecha a conexão, mas BETA ainda vê a conexão como estabelecido e espera por um longo tempo até que eventualmente expire.

Exemplo.

Em BETA, wget -O /dev/null ALPHA:50001/1mb.test

--2013-05-19 02:45:54--  http://ALPHA:50001/1mb.test Resolving dfw... ip.address.redacted Connecting to ALPHA|ip.address.redacted|:50001... connected. HTTP request sent, awaiting response... 200 OK Length: 1000000 (977K)
[application/octet-stream] Saving to: '/dev/null'

e congela a 0 bytes recebidos. Note que ele recebeu 200 OK do servidor, então eles pareciam ter sucesso com o handshake. Para eliminar o wget como parte do problema, eu fiz um telnet:

telnet ALPHA 50001
Trying ip.address.redacted...
Connected to ALPHA.
Escape character is '^]'.
GET /1mb.test HTTP/1.0

HTTP/1.1 200 OK
Server: nginx
Date: Sun, 19 May 2013 22:43:48 GMT
Content-Type: application/octet-stream
Content-Length: 1000000
Last-Modified: Sat, 21 Jan 2012 21:47:29 GMT
Connection: close
ETag: "4f1b3271-f4240"
Accept-Ranges: bytes

Ele também congela nesse ponto.

Ambos os servidores possuem regras iptables de -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT

Aqui está um tcpdump que estava sendo executado no ALPHA durante o congelamento do wget acima. link

Esse problema ocorre apenas ocasionalmente. Às vezes funciona muito bem. Na verdade, se eu executar cerca de 3 a 5 wget, geralmente tudo começa a funcionar na quarta ou quinta tentativa.

O BETA pode se comunicar com o GAMMA, o DELTA e meus outros servidores sem problemas. Só parece acontecer quando se fala de ALPHA. Pings ICMP não mostram perdas de pacotes, mas mesmo se houvesse perda de pacotes, isso diminuiria a velocidade, não desconectaria. Ambas as máquinas possuem o mesmo sistema operacional CentOS 6.4 de 64 bits, kernel 2.6.32-358.6.2.el6.x86_64. Nada útil registrado em arquivos / var / log. ALPHA está escutando em 50001 usando nginx-1.4.1-1.el6.ngx.x86_64. O arquivo de log de acesso nginx mostra 200 (pedido OK) 43440 bytes entregues durante a conexão congelada.

O problema não parece ser relacionado ao nginx, já que eu tive uma conexão ssh também congelada no meio da comunicação no mesmo dia. Outros servidores se conectam a esse nginx e nunca tiveram problemas.

Em resumo, isso parece ser o que está acontecendo nessa comunicação específica:

BETA -> ALPHA "SYN!"
ALPHA -> BETA "SYN Acknowledgement"
BETA -> ALPHA "ACK"
ALPHA -> BETA "Established"
BETA -> ALPHA "GET /file HTTP/1.0"
ALPHA -> BETA "200 OK, here's a bunch of data"
BETA freezes, gets no data.

Alguém viu uma situação como essa?

    
por Crash Override 20.05.2013 / 00:48

3 respostas

6

Talvez um problema de MTU / MSS? Os pequenos pacotes iniciais passam, os grandes (transferência de dados) são mortos em algum lugar?

Uma solução alternativa é reduzir um pouco o MTU (em ambos os lados), de 1500 para 1450, e. Ou para usar o destino do Netfilter TCPMSS apenas para as conexões afetadas (ou de maneira diferente para conexões separadas).

Mas a solução real é fazer com que a descoberta MTU do caminho funcione novamente. Portanto, verifique se os pacotes ICMP (fragmentação necessária: Tipo 3, Código 4) estão bloqueados. Use tcpdump -i $ifname -n icmp para ver se tais pacotes chegam.

    
por 20.05.2013 / 01:54
2

Há de fato a desfragmentação ocorrendo. É isso que o IPTABLES faz para inspecionar os pacotes. Deve remontá-los para validar o conteúdo.

No meu caso, eu veria quedas de ping periódicas e bloqueios de navegadores enquanto eu navegava na Web em um sistema CentOS 7, ou minhas sessões PuttY do Windows misteriosamente penduravam - permanentemente.

Eu usei uma variante do método que Mick gentilmente forneceu para determinar o tamanho da MTU. O problema com esse método é que, se você definir o tamanho da MTU como pequeno, obterá uma leitura falsa na fragmentação. Portanto, defina o tamanho grande (jumbo frame / 9000) e inicie as sondagens de ping.

Depois de configurar o MTU para 1472 (o que determinei foi o valor correto), o problema do ping ao navegar foi embora. Espero que quando eu próximo ssh do windows, que vai funcionar também.

    
por 19.03.2015 / 06:56
1

Meu primeiro palpite é que é um problema de dimensionamento da janela TCP:

link

Desative nas duas extremidades e veja se o problema desaparece. Outra opção (como sugeriu Hauke) é que haja desfragmentação.

Você pode usar o ping para verificar a fragmentação de pacotes, um simples HOWTO está aqui:

link

Editar: perdeu uma palavra.

    
por 21.05.2013 / 05:46