Linux Slow Start: Alterar a rota IP não tem efeito na janela inicial

10

Alterei a janela inicial do TCP na minha máquina para 10, como mostrado abaixo

[user@site etc]$ sudo ip route change default via 17.255.209.1 dev eth0  proto static initcwnd 10 

E alterado tcp_slow_start_after_idleconforme mostrado abaixo

[user@site etc]$ sudo sysctl -a | grep tcp_slow_start_after_idle
net.ipv4.tcp_slow_start_after_idle = 0

uma rota ip mostra confirmação é dada abaixo

[user@site etc]$ ip route show
default via 17.255.209.1 dev eth0  proto static  initcwnd 10
169.254.0.0/16 dev eth0  scope link  metric 1002
17.255.209.0/24 dev eth0  proto kernel  scope link  src 17.255.209.19

Agora, quando eu faço um tcpdump no site, não pareço ver uma alteração na janela inicial com o WIN / MSS restante 4 como padrão. 5840/1460 = 4

[user@site etc]$ sudo tcpdump -n -i any 'tcp[tcpflags] & (tcp-syn|tcp-ack) == tcp-syn and port 80'
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on any, link-type LINUX_SLL (Linux cooked), capture size 65535 bytes
11:17:45.048174 IP 21.101.151.198.45873 > 17.255.209.19.http: Flags [S], seq 2008673341, win 5840, options [mss 1460,sackOK,TS val 1724223146 ecr 0,nop,wscale 6], length 0

O hit de curl que fiz na página da Web solicitou cerca de 30 KB de dados.

[user@machine ~]$ curl http://www.site.com/js/main.js > /dev/null
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100 88212  100 88212    0     0   179k      0 --:--:-- --:--:-- --:--:--  272k

O que poderia estar errado na minha abordagem?

Núcleo

[user~]$ uname -r
3.0.4x86_64-linode21

Como atualização, aqui estão os resultados quando tento google.com

[user@site ~]$ sudo tcpdump -n -i any 'tcp[tcpflags] & (tcp-syn|tcp-ack) == tcp-syn and host www.google.com'
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on any, link-type LINUX_SLL (Linux cooked), capture size 65535 bytes
17:20:28.033236 IP 17.255.209.19.42799 > 74.125.127.106.http: Flags [S], seq 3148947324, win 14600, options [mss 1460,sackOK,TS val 193695310 ecr 0,nop,wscale 4], length 0

Como você pode ver, o WIN / MSS é 14600/1460 = 10 neste caso

Eu tentei acessar meu site a partir da própria máquina do servidor através do curl e aqui está o resultado:

[user@site ~]$ sudo tcpdump -n -i any 'tcp[tcpflags] & (tcp-syn|tcp-ack) == tcp-syn and host www.site.com'
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on any, link-type LINUX_SLL (Linux cooked), capture size 65535 bytes
17:25:14.584338 IP 17.255.209.19.35008 > 17.255.209.19.http: Flags [S], seq 3894567470, win 32792, options [mss 16396,sackOK,TS val 193981861 ecr 0,nop,wscale 4], length 0

WIN / MSS é 32792/16396 = 2 neste caso

Quintin Par
fonte
lembre-se, se você estiver acessando isso de uma máquina Linux, também precisará estar no 3.0, vasculhará a fonte / tags para confirmar a versão exata 3 que instalou a mudança
Sam Saffron
@QuintinPar Você poderia adicionar a saída tcpdump com a saída da conexão da sua máquina de teste?
Kupson
@kupson Eu atualizei a questão
Quintin Par
Tanto quanto sei, você não pode influenciar a Janela Inicial nas conexões de entrada. Sua conexão com o google mostra que você configurou o IW como 10. A inferface de loopback é muito especial com esse MTU grande, talvez haja algum limite na Janela Inicial na fonte do kernel.
Kupson
lembre-se de que duas coisas determinarão o IW. Janela máxima de congestionamento inicial dos clientes e servidores IW. As vitórias menores. Execute o teste em 2 máquinas, o servidor deve ter o IW definido por padrão em 3.0 ... e os clientes XP / Vista / Win7 não restringem o IW, portanto, faça bons clientes para o teste. Os clientes Linux 3.0 também funcionam, mas devem ser uma máquina separada.
Sam Saffron

Respostas:

9

Eu acho que você está entendendo mal como o TCP funciona.

Cada pacote enviado sempre anunciará uma janela do receptor (também conhecida como RWIN) e um fator de escala opcional, consulte RFC 1323

O remetente não tem permissão para enviar mais do que a quantidade de dados especificada no RWIN sem que seja reconhecida. Dependendo da janela de congestionamento, o remetente pode decidir preencher o RWIN ou não.

Portanto, existem dois bits de informação que são públicos nos pacotes TCP. O RWIN no servidor e o RWIN no cliente. Ambas as figuras determinam qual pode ser o tamanho máximo da janela de congestionamento nas duas extremidades.

O RWIN no servidor é interessante quando estamos tentando otimizar o desempenho para, por exemplo, upload de arquivos.

O RWIN no cliente é interessante quando estamos tentando determinar a velocidade do download.

Nenhum desses números torna pública a janela de congestionamento .

Portanto, se eu tiver um RWIN de 64k, a janela de congestionamento no servidor poderá ser QUALQUER número menor que 64k.

A única maneira de determinar qual é a janela de congestionamento real é contar pacotes.

Se eu soubesse:

  1. Meu tempo de ida e volta (RTT) é de ~ 200 ms.
  2. Acabei de solicitar um recurso de 100k.
  3. Eu tenho um RWIN de 64k.

Se eu receber 2 pacotes de volta do servidor com 1452 bytes de comprimento dentro de ~ 200ms, é provável que a janela de congestionamento no servidor seja menor que 4356, porque se fossem maiores, seriam enviados 3 pacotes. Se o IW estivesse definido como 10, eu veria uma explosão de 10 pacotes em torno da marca de 200ms.

Se você alterar seu IW e quiser confirmar que a alteração funcionou, precisará contar os pacotes para obter uma estimativa do tamanho da janela de congestionamento no servidor.

Lembre-se de que você provavelmente deseja examinar a conversa diretamente após o SYN, SYN-ACK, ACK para garantir que não esteja olhando no meio de uma conversa (onde a janela de congestionamento já poderia ter crescido).

Sam Saffron
fonte
1
A diferença entre a janela de congestionamento e a janela tcp é declarada em 20.6 (inicialização lenta) do TCP / IP. Ilustrado: "A inicialização lenta adiciona outra janela ao TCP do remetente: a janela de congestionamento, chamada cwnd" (negrito é meu). Existe um diagrama de seqüência em 20.7 que mostra isso em jogo durante a transferência em massa.
Kyle Brandt
7

O tamanho da janela será o menor: tamanho da janela de inicialização do servidor ou cliente RWIN. Como 5840 é o RWIN padrão para Linux 2.6, parece que seu cliente é o fator limitante aqui.

Tente em uma caixa do Windows. O Windows XP possui um RWIN de 64k, versão mais recente 8k.

Fonte: http://www.cdnplanet.com/blog/tune-tcp-initcwnd-for-optimum-performance/ (a parte interessante está abaixo do vídeo)

Editar: expandir a resposta para torná-la mais clara:

  • No handshake TCP, o cliente envia um pacote SYN ao servidor enviando o tamanho máximo permitido da janela. (Como mostra a saída do tcpdump, são 5840 bytes)
  • O servidor agora responde com o SYN ACK e o tamanho da janela em que gostaria de concordar. Esse tamanho da janela só pode ser menor do que o proposto pelo cliente, não maior. Não importa como o servidor esteja configurado, ele nunca poderá ter tamanhos de janela maiores que 5840 bytes com esse cliente.
  • O cliente retorna o ACK e troca felizmente os dados para sempre.

Edit2: Os tcpdumps adicionados à pergunta mostram o servidor abrindo conexões com o google e com ele próprio ATUANDO COMO CLIENTE.

Alguém
fonte
A janela inicial (proposta no pacote SYN) é 5840. É o primeiro pacote e a máquina de envio que não sabe nada sobre o receptor no momento (eu testei com "cache de liberação de rota ip").
kupson
17.255.209.0 é a sua sub-rede do servidor, certo? O pacote que você está vendo é de 21.101.151.198.45873 a 17.255.209.19.http. Não sou especialista na saída do tcpdump, mas para mim está o seguinte: Olá servidor, sou seu cliente, gosto de janelas de 5840 bytes. :) O próximo pacote seria o servidor responder com ACK, 5840 é ótimo, felicidades. :)
Alguém
Só para enfatizar, acho que você entendeu errado: A primeira máquina de envio é o cliente, pois abre a conexão, não o servidor. É o cliente que oferece a janela de 5840 bytes. O servidor não pode propor um tamanho de janela maior, apenas um menor.
Alguém
1
Eu não sou o autor original desta pergunta. Eu testei (com resultados semelhantes) em meu próprio ambiente de teste e também não posso alterá-lo. O tamanho inicial da janela de congestionamento (initcwnd) não tem nada a ver com o outro lado da conexão.
Kupson #
Não conheço sua configuração. O pôster original perguntou por que, apesar de aumentar o tamanho da janela inicial no servidor, sua conexão de teste tem apenas um tamanho de janela de 5840 bytes. A resposta é: porque o cliente com quem ele testou não permite um tamanho de janela maior. Não posso comentar sobre outras configurações ou possivelmente outros problemas / bugs com o conceito em geral.
Alguém