Modification de la valeur TCP RTO sous Linux


12

Je veux modifier la valeur TCP RTO (délai de retransmission) pour une connexion, et certaines lectures que j'ai faites suggèrent que je pourrais le faire, mais ne révèlent pas où et comment la changer.

J'ai regardé les /proc/sys/net/ipv4variables, mais aucune des variables n'est liée à RTO. J'apprécierais que quelqu'un me dise comment modifier cette valeur.


Ça ne marche pas pour moi. À tout le moins, inclure "ms" avec le temps rto me donne une erreur! J'ai réussi à faire fonctionner la commande, mais ss -i dit le contraire. De plus, les 2 vars sysctl n'existent pas. J'utilise un noyau 4.4
Mark Seger

J'ai essayé une distribution plus récente et j'ai réussi à le faire ip route replace- la ip routesyntaxe semble avoir un peu changé. J'ai réussi à effectuer la modification avec succès. Juste pour noter, vous devriez commenter la réponse, pas la question si vous voulez me cingler - j'ai essentiellement vu cela par accident, par pure chance que c'était récent :)
Adam C

Réponses:


30

La raison pour laquelle vous ne pouvez pas modifier spécifiquement le RTO est qu'il ne s'agit pas d'une valeur statique. Au lieu de cela (sauf pour le SYN initial, naturellement), il est basé sur le RTT (Round Trip Time) pour chaque connexion. En fait, il est basé sur une version lissée de RTT et la variance RTT avec quelques constantes jetées dans le mix. Par conséquent, c'est une valeur calculée et dynamique pour chaque connexion TCP, et je recommande fortement cet article qui va plus en détail sur le calcul et le RTO en général.

La RFC 6298 est également pertinente et indique (entre autres):

Chaque fois que le RTO est calculé, s'il est inférieur à 1 seconde, alors le RTO DEVRAIT être arrondi à 1 seconde.

Le noyau définit-il toujours RTO à 1 seconde alors? Eh bien, avec Linux, vous pouvez afficher les valeurs RTO actuelles pour vos connexions ouvertes en exécutant la ss -icommande:

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

Ce qui précède est la sortie d'une machine virtuelle à laquelle je suis connecté avec SSH et a quelques connexions ouvertes sur google.com. Comme vous pouvez le voir, le RTO est en fait réglé sur 200 ish (millisecondes). Vous remarquerez que ce n'est pas arrondi à la valeur de 1 seconde du RFC, et vous pouvez également penser que c'est un peu élevé. C'est parce qu'il y a des limites min (200 millisecondes) et max (120 secondes) en jeu quand il s'agit de RTO pour Linux (il y a une grande explication à cela dans l'article que j'ai lié ci-dessus).

Donc, vous ne pouvez pas modifier directement la valeur RTO, mais pour les réseaux avec perte (comme le sans fil), vous pouvez essayer de modifier le F-RTO (cela peut déjà être activé en fonction de votre distribution). Il existe en fait deux options liées au F-RTO que vous pouvez modifier (bon résumé ici ):

net.ipv4.tcp_frto
net.ipv4.tcp_frto_response

Selon ce que vous essayez d'optimiser, cela peut être utile ou non.

EDIT: suivi de la possibilité de modifier les valeurs rto_min / max pour TCP à partir des commentaires.

Vous ne pouvez pas changer le RTO minimum global pour TCP (en passant, vous pouvez le faire pour SCTP - ceux-ci sont exposés dans sysctl), mais la bonne nouvelle est que vous pouvez modifier la valeur minimale du RTO sur une route par route base. Voici ma table de routage sur ma machine virtuelle 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

Je peux modifier la valeur rto_min sur l'itinéraire par défaut comme suit:

ip route change default via 10.0.2.2 dev eth0 rto_min 5ms

Et maintenant, ma table de routage ressemble à ceci:

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

Enfin, commençons une connexion et vérifions ss -ipour voir si cela a été respecté:

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

Succès! La rto sur la connexion HTTP (après le changement) est de 15 ms, tandis que la connexion SSH (avant le changement) est de 200+ comme avant.

En fait, j'aime cette approche - elle vous permet de définir la valeur inférieure sur les itinéraires appropriés plutôt que globalement là où cela pourrait gâcher le trafic. De même (voir la page de manuel ip ), vous pouvez modifier l’estimation rtt initiale et la rttvar initiale pour l’itinéraire (utilisé lors du calcul du RTO dynamique). Bien que ce ne soit pas une solution complète en termes de peaufinage, je pense que la plupart des éléments importants sont là. Vous ne pouvez pas modifier le paramètre maximum, mais je pense que cela ne sera généralement pas aussi utile dans tous les cas.


Merci @Adam C pour la clarification, mais vous avez mentionné le min (200 milli) et le max (120sec), puis-je changer l'un d'eux (min ou max)? si oui, comment? ...
obiigbe91

Je crois que ce sont des constantes dans le code, et je ne suis pas au courant d'un moyen de les définir dynamiquement, mais je vais creuser un peu et voir car je suppose que modifier le code et compiler votre propre noyau est un peu trop :)
Adam C

Compris comment modifier rto_min et l'ajouté et quelques autres choses connexes dans la réponse :)
Adam C

Pourquoi n'y a-t-il rien de tel rto_max? Comment définir un délai maximum global?
is

Si vous définissez le minimum (ou acceptez la valeur par défaut) puis modifiez le nombre de nouvelles tentatives ( net.ipv4.tcp_retries1et / net.ipv4.tcp_retries2ou IIRC similaire) autorisé, je pense que vous pouvez obtenir un équivalent d'un maximum de RTO.
Adam C
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.