Modifica del valore TCP RTO in Linux


12

Voglio modificare il valore TCP RTO (timeout di ritrasmissione) per una connessione e alcune letture che ho fatto suggeriscono che potrei farlo, ma non rivelano dove e come modificarlo.

Ho esaminato le /proc/sys/net/ipv4variabili, ma nessuna delle variabili è correlata a RTO. Gradirei se qualcuno potesse dirmi come modificare questo valore.


Questo non funziona per me. Almeno includendo 'ms' con il tempo rto mi dà un errore! Ho fatto funzionare il comando, ma ss -i dice il contrario. Inoltre, i 2 sistemi non esistono. Sono in esecuzione su un kernel 4.4
Mark Seger il

Ho provato una distro più recente e ip route replaceinvece ho avuto successo - sembra che la ip routesintassi sia cambiata un po '. Tuttavia, sono stato in grado di apportare modifiche con successo. Solo per notare, dovresti commentare la risposta, non la domanda se vuoi fare un rumore metallico - Ho praticamente visto questo per caso, pura fortuna che fosse recente :)
Adam C

Risposte:


30

Il motivo per cui non è possibile modificare l'RTO specificamente è perché non è un valore statico. Invece (ad eccezione del SYN iniziale, naturalmente) si basa sull'RTT (Round Trip Time) per ogni connessione. In realtà, si basa su una versione smussata di RTT e sulla varianza di RTT con alcune costanti gettate nel mix. Quindi, si tratta di un valore dinamico e calcolato per ogni connessione TCP e consiglio vivamente questo articolo che approfondisce il calcolo e l'RTO in generale.

Anche rilevante è RFC 6298 che afferma (tra le altre cose):

Ogni volta che viene calcolato RTO, se è inferiore a 1 secondo, RTO DOVREBBE essere arrotondato per eccesso a 1 secondo.

Quindi il kernel imposta sempre RTO su 1 secondo? Bene, con Linux puoi mostrare gli attuali valori RTO per le tue connessioni aperte eseguendo il ss -icomando:

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

Quanto sopra è l'output di una macchina virtuale a cui ho effettuato l'accesso con SSH e ha un paio di connessioni aperte su google.com. Come puoi vedere, l'RTO è infatti impostato su 200 ish (millisecondi). Noterai che non è arrotondato al valore di 1 secondo dall'RFC e potresti anche pensare che sia un po 'alto. Questo perché ci sono limiti min (200 millisecondi) e max (120 secondi) in gioco quando si tratta di RTO per Linux (c'è una grande spiegazione di questo nell'articolo che ho linkato sopra).

Pertanto, non è possibile modificare direttamente il valore RTO, ma per le reti con perdita di dati (come il wireless) è possibile provare a modificare F-RTO (questo potrebbe essere già abilitato a seconda della distribuzione). Esistono due opzioni correlate a F-RTO che puoi modificare (buon riassunto qui ):

net.ipv4.tcp_frto
net.ipv4.tcp_frto_response

A seconda di ciò che stai cercando di ottimizzare, questi potrebbero essere o non essere utili.

EDIT: follow-up sulla possibilità di modificare i valori rto_min / max per TCP dai commenti.

Non puoi modificare l'RTO minimo globale per TCP (a parte, puoi farlo per SCTP - quelli sono esposti in sysctl), ma la buona notizia è che puoi modificare il valore minimo dell'RTO su una rotta base. Ecco la mia tabella di routing sulla mia 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

Posso modificare il valore rto_min sulla route predefinita come segue:

ip route change default via 10.0.2.2 dev eth0 rto_min 5ms

E ora, la mia tabella di routing è simile alla seguente:

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

Infine, iniziamo una connessione e controlliamo ss -iper vedere se questo è stato rispettato:

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

Successo! Il rto sulla connessione HTTP (dopo la modifica) è 15ms, mentre la connessione SSH (prima della modifica) è 200+ come prima.

In realtà mi piace questo approccio: ti consente di impostare il valore più basso su percorsi appropriati anziché a livello globale dove potrebbe rovinare altro traffico. Allo stesso modo (vedi la pagina man di ip ) puoi modificare la stima iniziale di rtt e la rttvar iniziale per il percorso (usata per calcolare l'RTO dinamico). Anche se non è una soluzione completa in termini di modifiche, penso che la maggior parte dei pezzi importanti ci siano. Non puoi modificare l'impostazione massima, ma penso che in genere non sarà altrettanto utile.


Grazie @Adam C per il chiarimento, ma hai menzionato il minimo (200 milli) e il massimo (120sec), posso cambiare uno di questi (minimo o massimo)? se sì, come? ...
obiigbe91,

Credo che siano costanti nel codice, e non sono a conoscenza di un modo per impostarle in modo dinamico ma scenderò un po 'e vedrò dato che suppongo che alterare il codice e compilare il proprio kernel sia un po' troppo :)
Adam C

Ho capito come modificare rto_min e l'ho aggiunto e un paio di altre cose correlate nella risposta :)
Adam C

Perché non c'è niente del genere rto_max? Come possiamo impostare un timeout massimo globale?
est,

Se si imposta il minimo (o si accetta il valore predefinito) e quindi si modifica il numero di tentativi ( net.ipv4.tcp_retries1e / net.ipv4.tcp_retries2o IIRC simili) consentiti, penso che si possa arrivare a un equivalente di un massimo RTO.
Adam C
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.