Estou tentando solucionar problemas da minha conexão doméstica com a Internet, que geralmente é interrompida em downloads grandes. Acredito que consegui duplicar o problema entre meu computador doméstico e uma instância do Amazon EC2 com capturas de pacotes nas duas extremidades. Aqui está o mesmo comportamento que observei em dois problemas:
- Inicio um download TCP de um arquivo de 20 MB para meu computador doméstico a partir do servidor EC2 (o computador doméstico é cliente TCP, o servidor EC2 é o servidor TCP).
- O TCP SYN inicial tem uma opção MSS de 1418 bytes. Nenhum outro segmento do cliente tem uma opção MSS (o SYN / ACK do servidor tem a opção MSS 1460).
- Quando a maior parte da transferência continua, os pacotes do servidor são 2878 bytes. Esses pacotes são recebidos no cliente como dois pacotes de 1472 bytes (eu os chamarei de front e back half), cada um contendo um segmento TCP com metade dos dados.
- Em algum momento, um meio pacote frontal do servidor é perdido. O cliente começa a repetir os ACKs com uma opção SACK.
- Ao receber o primeiro ACK com uma opção SACK, o servidor começa a enviar pacotes de 1472 bytes (em vez de pacotes de 2878 bytes).
- Após alguns ACKs duplicados, o servidor faz Fast Retransmission, reenviando um pacote de 1472 bytes - ou seja, não o pacote de 2878 bytes originalmente enviado. Este pacote reenvio não aparece no cliente.
- Após o tempo limite, o servidor tenta Retransmission várias vezes mais, enviando novamente o pacote de 1472 bytes. Nenhum desses pacotes enviados são exibidos no cliente.
Eu tenho várias perguntas. Primeiro de tudo, por que o servidor está enviando pacotes de 2878 bytes para começar? Não é para honrar a opção MSS no pacote SYN?
Segundo, onde estão esses 2878 segmentos de bytes sendo divididos em dois segmentos de 1472 bytes?
Em terceiro lugar, onde e por que todos os pacotes retransmitidos estão sendo descartados?
Em quarto lugar, existe alguma maneira de evitar isso do lado do cliente?
Curiosamente, parece que a conexão pode se recuperar se um meio pacote de volta for perdido. Minha (possivelmente falsa) teoria é que algo ao longo do caminho está comendo os meios pacotes retransmitidos pela frente porque eles não correspondem ao seu tamanho original. Além disso, a mesma transferência encapsulada através do UDP (com OpenVPN) não trava (eu sei que isso significa que eu poderia fazer proxy de todo o meu tráfego dessa maneira, mas essa não é a resposta que estou procurando).
Aqui estão as capturas de pacotes para página inicial e server .
Acompanhamento: @DavidSchwartz sugere nos comentários que as anomalias do tamanho do segmento podem ser explicadas por TSO , e parece está correto. Desativar o TSO no servidor limita o tamanho do segmento em 1472 bytes. Infelizmente, a transferência ainda trava com pacotes retransmitidos não sendo recebidos.
Eu também tentei desativar as opções TCP SACK, timestamps e dimensionamento de janelas, além de reduzir o tamanho da janela para 8192 bytes. A transferência ainda trava. O cliente recebe pacotes enviados antes e depois de pacotes retransmitidos, mas não os próprios pacotes retransmitidos.