Alterando o valor TCP RTO no Linux

9

Eu quero alterar o valor timeout de retransmissão para uma conexão e algumas leituras que eu fiz sugerem que eu poderia fazer isso, mas não revela onde e como mudá-lo.

Eu olhei as variáveis /proc/sys/net/ipv4 , mas nenhuma das variáveis está relacionada ao RTO. Eu apreciaria se alguém pudesse me dizer como alterar esse valor.

    
por obiigbe91 17.06.2015 / 21:23

1 resposta

23

O motivo pelo qual você não pode alterar o RTO especificamente é porque não é um valor estático. Em vez disso (exceto para o SYN inicial, naturalmente) é baseado no RTT (Round Trip Time) para cada conexão. Na verdade, ele é baseado em uma versão suavizada do RTT e na variação do RTT com algumas constantes lançadas na mistura. Portanto, é um valor calculado e dinâmico para cada conexão TCP, e eu recomendo altamente este artigo que entra em mais detalhes sobre o cálculo e RTO em geral.

Também relevante é o RFC 6298 que afirma (entre muitas outras coisas):

Whenever RTO is computed, if it is less than 1 second, then the RTO SHOULD be rounded up to 1 second.

O kernel sempre configura o RTO para 1 segundo depois? Bem, com o Linux você pode mostrar os valores RTO atuais para suas conexões abertas executando o comando ss -i :

State       Recv-Q Send-Q                                                  Local Address:Port     Peer Address:Port
ESTAB       0      0                                                           10.0.2.15:52861   216.58.219.46:http
     cubic rto:204 rtt:4/2 cwnd:10 send 29.2Mbps rcv_space:14600
ESTAB       0      0                                                           10.0.2.15:ssh          10.0.2.2:52586
     cubic rto:201 rtt:1.5/0.75 ato:40 cwnd:10 send 77.9Mbps rcv_space:14600
ESTAB       0      0                                                           10.0.2.15:52864   216.58.219.46:http
     cubic rto:204 rtt:4.5/4.5 cwnd:10 send 26.0Mbps rcv_space:14600

O acima é a saída de uma VM com a qual eu estou conectado com SSH e tem algumas conexões abertas para google.com. Como você pode ver, o RTO é, na verdade, definido como 200-ish (milissegundos). Você vai notar que não é arredondado para o valor de 1 segundo do RFC, e você também pode pensar que é um pouco alto. Isso porque existem limites mínimos (200 milissegundos) e máximos (120 segundos) no jogo quando se trata de RTO para Linux (há uma grande explicação disso no artigo que eu relacionei acima).

Assim, você não pode alterar o valor RTO diretamente, mas para redes com perdas (como sem fio), você pode tentar alterar F-RTO (isso pode já estar ativado dependendo da sua distribuição). Existem duas opções relacionadas ao F-RTO que você pode ajustar (bom resumo). -wireless-networks / "> aqui ):

net.ipv4.tcp_frto
net.ipv4.tcp_frto_response

Dependendo do que você está tentando otimizar, isso pode ou não ser útil.

EDIT: acompanhando a capacidade de ajustar os valores rto_min / max para TCP dos comentários.

Você não pode alterar o RTO mínimo global para TCP (como um aparte, você pode fazê-lo para SCTP - esses são expostos em sysctl), mas a boa notícia é que você pode ajustar o valor mínimo do RTO em um por rota. Aqui está minha tabela de roteamento na minha VM do CentOS:

ip route
10.0.2.0/24 dev eth0  proto kernel  scope link  src 10.0.2.15 
169.254.0.0/16 dev eth0  scope link  metric 1002 
default via 10.0.2.2 dev eth0

Eu posso alterar o valor de rto_min na rota padrão da seguinte forma:

ip route change default via 10.0.2.2 dev eth0 rto_min 5ms

E agora, minha tabela de roteamento é assim:

ip route
10.0.2.0/24 dev eth0  proto kernel  scope link  src 10.0.2.15 
169.254.0.0/16 dev eth0  scope link  metric 1002 
default via 10.0.2.2 dev eth0  rto_min lock 5ms

Por fim, vamos iniciar uma conexão e verificar ss -i para ver se isso foi respeitado:

ss -i
State       Recv-Q Send-Q                                               Local Address:Port                                                   Peer Address:Port   
ESTAB       0      0                                                        10.0.2.15:ssh                                                        10.0.2.2:50714   
     cubic rto:201 rtt:1.5/0.75 ato:40 cwnd:10 send 77.9Mbps rcv_space:14600
ESTAB       0      0                                                        10.0.2.15:39042                                                 216.58.216.14:http    
     cubic rto:15 rtt:5/2.5 cwnd:10 send 23.4Mbps rcv_space:14600

Sucesso! O rto na conexão HTTP (após a alteração) é de 15 ms, enquanto a conexão SSH (antes da alteração) é de 200+ como antes.

Na verdade, eu gosto dessa abordagem - ela permite que você defina o valor mais baixo nas rotas apropriadas, em vez de globalmente, onde pode atrapalhar outros tráfegos. Da mesma forma (veja a página de manual ip ) você pode ajustar a estimativa inicial de rtt e o rttvar inicial para a rota (usada ao calcular o RTO dinâmico). Embora não seja uma solução completa em termos de ajustes, acho que a maioria das peças importantes está lá. Você não pode ajustar a configuração máxima, mas acho que isso não será tão útil em geral, de qualquer forma.

    
por 17.06.2015 / 22:00