A razão pela qual você não pode alterar o RTO especificamente é porque não é um valor estático. Em vez disso (exceto o SYN inicial, naturalmente), ele é baseado no RTT (Round Trip Time) para cada conexão. Na verdade, é baseado em uma versão suavizada do RTT e na variação do RTT com algumas constantes lançadas na mistura. Portanto, é um valor dinâmico calculado para cada conexão TCP, e eu recomendo este artigo que entra em mais detalhes sobre o cálculo e o RTO em geral.
Também relevante é a RFC 6298, que afirma (entre muitas outras coisas):
Sempre que o RTO é calculado, se for inferior a 1 segundo, o RTO DEVE ser arredondado para 1 segundo.
O kernel sempre define o RTO para 1 segundo? Bem, com o Linux, você pode mostrar os valores atuais de RTO para suas conexões abertas executando o ss -i
comando:
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
A descrição acima é a saída de uma VM na qual estou conectado com o SSH e tem algumas conexões abertas no google.com. Como você pode ver, o RTO é de fato definido como 200-ish (milissegundos). Você notará que não é arredondado para o valor de 1 segundo da RFC e também pode achar que é um pouco alto. Isso ocorre porque há limites mínimos (200 milissegundos) e máximos (120 segundos) em jogo quando se trata do RTO para Linux (há uma grande explicação sobre isso no artigo que eu linkei acima).
Portanto, você não pode alterar diretamente o valor do RTO, mas para redes com perdas (como a sem fio), você pode tentar ajustar o F-RTO (isso já pode estar ativado, dependendo da sua distribuição). Na verdade, existem duas opções relacionadas ao F-RTO que você pode ajustar (bom resumo aqui ):
net.ipv4.tcp_frto
net.ipv4.tcp_frto_response
Dependendo do que você está tentando otimizar, elas podem ou não ser úteis.
EDIT: acompanhamento da 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 (aparte, você pode fazê-lo para SCTP - eles são expostos no sysctl), mas a boa notícia é que você pode ajustar o valor mínimo do RTO em uma rota por rota base. Aqui está minha tabela de roteamento na minha VM 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 rto_min na rota padrão da seguinte maneira:
ip route change default via 10.0.2.2 dev eth0 rto_min 5ms
E agora, minha tabela de roteamento fica 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
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 mais de 200 como antes.
Eu realmente gosto dessa abordagem - ela permite que você defina o valor mais baixo nas rotas apropriadas, em vez de globalmente, onde isso pode atrapalhar outro tráfego. Da mesma forma (consulte a página de manual do ip ), você pode ajustar a estimativa inicial do rtt e o rttvar inicial da 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 em geral não será tão útil.