The Cable GuyOttimizzazione automatica della finestra di ricezione del TCP

Joseph Davies

Benvenuti al primo numero di The Cable Guy, su TechNet Magazine. Quelli che seguono questa rubrica sul sito Web di TechNet sanno già che ci occupiamo di tutto quello che riguarda il networking e continueremo anche qui, ogni mese, questa tradizione. Chi invece è nuovo ed è alla ricerca di un archivio dei numeri precedenti può andare sul sito di Cable Guy site.

Cominciamo ora con il primo argomento, la finestra di ricezione del TCP.

Il throughput delle connessioni TCP può essere limitato dalle applicazioni che inviano e ricevono dati, dalle implementazione del TCP e dal percorso di trasmissione fra le due entità TCP. In questo articolo parlerò della finestra di ricezione del TCP e del suo impatto sul throughput del protocollo, di come usare il "windows scaling" per il TCP e della nuova funzionalità di auto configurazione della finestra di ricezione presente in Windows Vista, che ottimizza le prestazioni del TCP in fase di ricezione.

La finestra di ricezione del TCP

Una connessione TCP ha svariate caratteristiche importanti. Prima di tutto si tratta di una connessione punto-a-punto fra due protocolli del livello di Applicazione. Il TCP non fornisce servizi di consegna uno-a-molti, ma solo servizi di tipo uno-a-uno.

In secondo luogo, le connessioni TCP sono orientate alla connessione. Prima che i dati possano essere trasferiti, due processi a livello Applicazione devono negoziare formalmente una connessione, mediante la procedura di apertura della connessione TCP. In modo analogo, una connessione TCP viene formalmente chiusa dopo la negoziazione, mediante la relativa procedura di terminazione.

Terzo, i dati trasmessi in modo affidabile su una connessione TCP sono sequenzializzati e il destinatario è tenuto a inviare la conferma della corretta ricezione. Quando questa conferma non viene ricevuta, il segmento è ritrasmesso. Il destinatario scarta eventuali segmenti duplicati e quelli che arrivano fuori sequenza sono rimessi nell'ordine corretto.

Quarto punto, una connessione TCP è full-duplex. Per ogni entità TCP la connessione TCP consiste di due canali logici: uno in uscita e uno in ingresso. L'intestazione TCP contiene sia un numero di sequenza dei dati in uscita che la conferma (ACK) di quelli in ingresso.

In più, il TCP vede i dati inviati lungo i due canali logici (quello in ingresso e quello in uscita) come un flusso continuo di byte. In ogni intestazione TCP, il numero di sequenza e quello di conferma sono definiti ai confini fra byte. Il TCP non ha alcuna nozione di separazione fra record o messaggi all'interno del flusso di byte. Sarà il protocollo a livello Applicazione a doversi occupare della separazione del flusso di byte in ingresso (parsing).

Per limitare la quantità di dati che possono essere inviati fino a un certo istante e per permettere il controllo di flusso da parte del destinatario, le entità TCP fanno uso di una finestra. La finestra è la quantità di dati che il destinatario permette al mittente di inviare. Il mittente può inviare solo i byte del flusso che sono compresi all'interno della finestra. La finestra scorre sul flusso in uscita del mittente e su quello in ingresso del destinatario.

Per un certo canale logico (una delle due direzioni nella connessione full-duplex del TCP), il mittente gestisce una finestra di trasmissione e il destinatario gestisce una finestra di ricezione. Quando non ci sono segmenti dati o segmenti ACK in transito, le due finestre di uno stesso canale logico, quella di trasmissione e quella di ricezione, coincidono. In altre parole, la quantità di dati del flusso di byte in uscita che il mittente ha il permesso di inviare coincide con la quantità di dati del flusso di byte in ingresso che il destinatario è in grado di ricevere. La Figura 1 illustra questa relazione fra invio e ricezione.

Figura 1 Corrispondenza tra finestra di invio e finestra di ricezione

Figura 1** Corrispondenza tra finestra di invio e finestra di ricezione **(Fare clic sull'immagine per ingrandirla)

Per indicare la dimensione della finestra di ricezione, l'intestazione del TCP contiene un campo, chiamato Window, di 16 bit. Quando il destinatario riceve dei dati, invia al mittente delle conferme o ACK, indicando i byte che sono stati ricevuti correttamente. In ogni ACK, il campo Windows indica il numero di byte rimanenti nella finestra di ricezione. Quando i dati sono inviati, confermati ed estratti dall'applicazione, sia la finestra di trasmissione che quella di ricezione scorrono verso destra. La finestra di ricezione è quella che controlla quanti dati non confermati possono essere "in volo" fra mittente e destinatario.

Poiché nella finestra di ricezione possono esserci dati non ancora estratti dall'applicazione e dati ricevuti ma non ancora confermati, la finestra di ricezione ha una struttura aggiuntiva come illustrato nella Figura 2.

Figura 2 Tipi di dati nella finestra di ricezione del TCP

Figura 2** Tipi di dati nella finestra di ricezione del TCP **(Fare clic sull'immagine per ingrandirla)

Osserviamo la differenza fra la finestra massima di ricezione e quella corrente. La finestra massima di ricezione ha una dimensione fissa. La finestra di ricezione corrente ha dimensione variabile e corrisponde alla quantità rimanente di dati che il destinatario autorizza il mittente a inviare. La dimensione della finestra di ricezione corrente coincide con il valore del campo Window degli ACK restituiti al mittente ed è la differenza fra la dimensione massima della finestra di ricezione e la quantità di dati che sono stati ricevuti e confermati ma non ancora estratti dall'applicazione.

Finestra di ricezione e throughput del TCP

Per ottimizzare il throughput del TCP (ipotizzando un canale ragionevolmente privo di errore) il mittente dovrebbe inviare abbastanza pacchetti da saturare il canale logico fra mittente e destinatario. La capacità del canale logico può essere calcolata mediante la seguente formula:

Capacity in bits = path bandwidth in bits per second * round-trip time (RTT) in seconds

La capacità è detta anche prodotto banda-ritardo (BDP: bandwidth-delay product). Il canale può essere largo (grande larghezza di banda) o stretto (piccola larghezza di banda), oppure corto (RTT piccolo) o lungo (RTT elevato). I canali larghi e lunghi sono quelli che hanno la capacità (BDP) maggiore. Esempi di canali a grande capacità sono quelli satellitari o le reti geografiche (WAN: wide area network) che comprendono tratti intercontinentali in fibra ottica.

Come aumentare le prestazioni del mittente per canali ad alta capacità.

La nuova funzionalità di ottimizzazione automatica della finestra di ricezione permette prestazioni migliori nella ricezione su canali a grande capacità, ma cosa si può dire sulle prestazioni in fase di invio?

Gli algoritmi attualmente in uso per impedire a un mittente TCP di "ingolfare" la rete sono lo slow start (partenza lenta) e la prevenzione della congestione. Questi algoritmi incrementano la dimensione della finestra di trasmissione (il numero di segmenti che il mittente può inviare) all'inizio della trasmissione sulla connessione e durante la correzione della perdita di un segmento.

Lo slow start incrementa la dimensione della finestra di trasmissione di un intero segmento TCP per ogni segmento di conferma ricevuto ( in Windows XP e Windows Server 2003) o per ogni segmento confermato (per il TCP in Windows Vista e Windows Server "Longhorn"). La prevenzione della congestione incrementa la dimensione della finestra di trasmissione di un intero segmento TCP per ogni finestra intera di dati di cui viene ricevuta conferma.

Questi algoritmi funzionano bene per piccole capacità di canale e finestre di ricezione di piccole dimensioni. Tuttavia, in caso di connessioni TCP con una larga finestra di ricezione su un canale di grande capacità (come nel caso della replica di dati fra due server su una rete geografica ad alta velocità con un tempo di round-trip di 100 ms) questi algoritmi non incrementano la finestra di trasmissione sufficientemente in fretta per utilizzare al meglio la banda della connessione.

Per sfruttare meglio la banda messa a disposizione da connessioni TCP di questo tipo, lo stack TCP/IP Next Generation implementa il Compound TCP (CTCP). Il CTCP incrementa in modo più aggressivo la dimensione della finestra di trasmissione per connessioni caratterizzate da grandi finestre di ricezione e grande capacità. Il CTCP cerca di massimizzare il throughput su connessioni di questo tipo monitorando le variazioni di ritardo e le perdite di segmenti. Inoltre, il CTCP agisce in modo tale che il suo comportamento non influisce negativamente sulle altre connessioni TCP.

Durante i test eseguiti in Microsoft, è stato possibile ridurre i tempi di backup di file di grandi dimensioni di almeno la metà per connessioni da 1 Gigabit al secondo e un tempo di round-trip di 50 ms. Connessioni con capacità maggiori possono far registrare prestazioni ancora migliori. Il CTCP e l'ottimizzazione automatica della finestra di ricezione agiscono insieme per garantire una maggiore utilizzazione del canale e possono avere come risultato incrementi sostanziali di prestazione su connessioni di grande capacità.

Il CTCP è abilitato in partenza sui sistemi Windows Server "Longhorn" e disabilitato sui sistemi Windows Vista. È possibile abilitare il CTCP con il comando "netsh interface tcp set global congestionprovider=ctcp". È possibile disabilitare il CTCP con il comando "netsh interface tcp set global congestionprovider=none".

La dimensione del campo Window nell'intestazione TCP è di 16 bit, il che permette a una entità TCP di comunicare una dimensione massima della finestra di ricezione pari a 65.535 byte. Data una certa dimensione della finestra TCP è possibile calcolare in modo approssimato il throughput mediante la seguente formula:

Throughput = TCP maximum receive windowsize / RTT

Per esempio, con una finestra di ricezione di 65.535 byte e un canale con un RTT pari a 100 ms è possibile ottenere un throughput massimo di circa 5,24 Mbps, indipendentemente dalla larghezza di banda del canale. Con i canali ad alta capacità disponibili oggi, la dimensione della finestra TCP pensata in origine, anche al suo valore massimo, diventa un collo di bottiglia in termini di throughput.

Il Window Scaling

A proposito di finestre più ampie per sfruttare meglio i canali di trasmissione ad alta velocità, l' RFC 1323 (ietf.org/rfc/rfc1323.txt) definisce il "window scaling" che permette a un destinatario di comunicare dimensioni della finestra maggiori di 65.535 byte. L'opzione Scala Finestra TCP esprime un fattore di scala, che combinato con il campo Window a 16 bit dell'intestazione TCP, può portare la dimensione della finestra di ricezione fino a un massimo di circa 1 GB. L'opzione Scala finestra è presente solo nei segmenti di sincronizzazione (SYN) scambiati durante la procedura di apertura della connessione. Entrambe le entità TCP possono indicare fattori di scala diversi da utilizzare per le loro finestre di ricezione. Permettendo a un mittente di inviare più dati su una connessione, il meccanismo del "window scaling" consente ai nodi TCP di utilizzare meglio alcuni tipi di canali ad alta capacità.

Sebbene la dimensione della finestra di ricezione sia importante per il throughput del TCP, un altro fattore importante per determinare le prestazioni ottimali è la velocità con cui l'applicazione estrae i dati accumulati nella finestra di ricezione (il tasso di estrazione dell'applicazione). Se l'applicazione non estrae i dati, la finestra di ricezione comincerà a riempirsi e il destinatario dovrà comunicare una dimensione della finestra corrente più piccola. In casi estremi l'intera finestra di ricezione finirà per essere riempita e il destinatario comunicherà una dimensione della finestra di 0 byte. In questo caso il mittente sospenderà l'invio di ulteriori dati fino a che riceverà la comunicazione che la finestra di ricezione è stata svuotata. Quindi, per ottimizzare le prestazioni del TCP, la finestra di ricezione di una connessione dovrebbe essere configurata ad un valore tale da riflettere sia la capacità del canale che il tasso di estrazione dell'applicazione.

Anche quando questi due valori possano essere determinati con esattezza, essi possono comunque cambiare nel tempo. La capacità del canale (il BDP) può variare a seguito della congestione di traffico, mentre il tasso di estrazione dell'applicazione può modificarsi in funzione del numero di connessioni attraverso le quali l'applicazione sta ricevendo i dati.

La finestra di ricezione in Windows XP

Per quanto riguarda lo stack TCP/IP di Windows XP (e di Windows Server® 2003), la dimensione massima della finestra di ricezione ha diversi attributi importanti. In primo luogo, il valore di default è basato sulla velocità di linea dell'interfaccia mittente. Il valore effettivo si adatta automaticamente agli incrementi della massima dimensione dei segmenti (MSS: maximum segment size) negoziata durante la fase di apertura della connessione.

In secondo luogo, la dimensione massima della finestra di ricezione può essere configurata manualmente. I valori del registry HKLM\System\CurrentControlSet\Services\Tcpip\Parameters\TCPWindowSize e HKLM\System\CurrentControlSet\Services\Tcpip\Parameters\Interface\InterfaceGUID\TCPWindowSize possono essere configurati a un massimo di 65.535 byte (senza window scaling) o 1.073.741.823 (con window scaling).

Terzo aspetto, la dimensione massima della finestra di ricezione può utilizzare il window scaling. Per abilitare il window scaling occorre impostare il valore del registry HKLM\System\CurrentControlSet\Services\Tcpip\Parameters\Tcp1323Opts su 1 o su 3. Per impostazione predefinita, il window scaling è usato su una connessione solo se il segmento SYN che è stato ricevuto contiene l'opzione Scala finestra.

Infine, la dimensione massima della finestra di ricezione può essere specificata da un'applicazione mediante l'opzione Windows Sockets SO_RCVBUF, nel momento dell'inizializzazione della connessione. Per abilitare il window scaling, l'applicazione deve specificare una dimensione della finestra maggiore di 65.535 byte.

Nonostante il supporto alla scalabilità delle finestre, la dimensione massima della finestra di ricezione in Windows XP può ancora limitare il throughput, in quanto è uguale per tutte le connessioni TCP (se non diversamente impostato dalla singola applicazione). Pertanto, le prestazioni possono migliorare su alcune connessioni e peggiorare su altre. In più, il valore fisso della dimensione massima della finestra di ricezione per una connessione TCP non cambia a fronte di variazioni nel tasso di estrazione dell'applicazione o della congestione del canale di trasmissione

Ottimizzazione automatica della finestra di ricezione in Windows Vista

Per ottimizzare il throughput del TCP, specialmente per i canali di trasmissione ad alta capacità, lo stack TCP/IP Next Generation in Windows Vista (e nella prossima generazione di Windows Server, chiamata in codice "Longhorn") prevede il supporto all'ottimizzazione automatica della finestra di ricezione. Questa funzionalità determina l'ampiezza ottimale della finestra di ricezione misurando la capacità del canale (cioè il BDP) e il tasso di estrazione dell'applicazione e adattando la dimensione della finestra all'andamento nel tempo di questi due parametri.

L'ottimizzazione automatica della finestra di ricezione abilita per default il window scaling, consentendo dimensioni massime della finestra di ricezione fino a 16 MB. Man mano che i dati passano attraverso la connessione, lo stack TCP/IP Next Generation monitora la connessione, misura i valori del BDP e del tasso di estrazione e regola la dimensione della finestra di ricezione per ottimizzare il throughput. Lo stack TCP/IP Next Generation non utilizza più il valore del registry TCPWindowSize.

L'ottimizzazione automatica della finestra di ricezione presenta tutta una serie di vantaggi. Determina automaticamente il valore ottimale della dimensione della finestra, connessione per connessione. In Windows XP, il valore di registry TCPWindowSize vale per tutte le connessioni. Le applicazioni non hanno più bisogno di specificare le dimensioni delle finestre TCP mediante le opzioni Windows Sockets. L'amministratore non deve più configurare manualmente la dimensione della finestra di ricezione TCP nodo per nodo.

Con l'ottimizzazione automatica della finestra di ricezione, un'entità TCP in Windows Vista comunicherà di solito dimensioni della finestra di ricezione molto più grandi di quanto avviene in Windows XP. Questo permette alle altre entità TCP di inviare a un'entità di pari livello su un sistema Windows Vista molti più segmenti dati, senza bisogno di aspettare un ACK (sempre entro i vincoli imposti dal controllo della congestione). Per un tipico traffico di rete basato sui client, come quello relativo a pagine Web o alla posta elettronica, il server Web o il server di posta potranno inviare dati ai client più rapidamente, con il risultato di un miglioramento complessivo del traffico di rete. Maggiori sono i valori del BDP e del tasso di estrazione dell'applicazione e più sensibile sarà il miglioramento delle prestazioni.

L'impatto sulla rete è che un flusso di pacchetti dati TCP che normalmente sarebbero inviati con frequenza più limitata sono immessi in rete molto più velocemente, con un picco di utilizzo più largo durante il trasferimento. Per sistemi basati su Windows XP e Windows Vista che effettuano un trasferimento di dati su un canale lungo e largo, la quantità di dati trasferiti non cambia. Tuttavia, il trasferimento effettuato dal client Windows Vista è più veloce, data la maggiore dimensione della finestra di ricezione e la possibilità per il server di saturare il canale che lo collega al client.

Poiché l'ottimizzazione automatica della finestra di ricezione migliorerà l'utilizzo dei canali di comunicazione a grande capacità, può diventare importante l'impiego di tecniche di qualità del servizio (QoS: quality of service) o di misurazione del tasso di invio delle applicazioni, per quei canali che operano ai limiti della loro capacità. Per rispondere a questa possibile esigenza, Windows Vista supporta le impostazioni del QoS a livello di policy di gruppo. Queste permettono di definire i tassi di trasmissione per ogni singolo indirizzo IP o per ogni porta TCP. Per ulteriori informazioni vedere le risorse sulla QoS basate su policy.

Incremento del throughput del TCP per reti ad alto tasso di perdita.

Le reti ad alto tasso di perdita possono ridurre in modo drastico le prestazioni del TCP, a causa di frequenti timeout e ritrasmissioni. Esempi di reti di questo tipo sono le reti wireless, come quella basate sullo standard IEEE 802.11, quelle GPRS (General Packet Radio Service) o UMTS (Universal Mobile Telecommunications System), che possono registrare forti perdite di pacchetti a causa delle condizioni generali della rete, attenuazione del segnale, interferenza elettromagnetica e spostamenti del computer.

Lo stack TCP/IP di nuova generazione supporta i seguenti quattro RFC, per ottimizzare il throughput in ambienti ad alto tasso di perdita.

RFC 2582: la modifica NewReno all'algoritmo di recupero rapido del TCP

L'algoritmo di recupero rapido, definito nell'RFC 2001, è basato sull'algoritmo di Reno, che aumenta la quantità di dati inviabili da un mittente quando un segmento viene ritrasmesso a causa di evento rapido di ritrasmissione. Sebbene l'algoritmo di Reno si comporti bene nel caso di perdita di singoli segmenti, non funziona altrettanto bene quando vanno persi più segmenti. Con l'algoritmo NewReno si ottengono velocità maggiori grazie alla modifica delle modalità in cui un mittente può aumentare la velocità di invio durante un ripristino veloce quando in una finestra di dati vengono perduti più segmenti e il mittente riceve una conferma parziale (una conferma solo per la parte di dati ricevuta in modo corretto).

RFC 2883: un'estensione dell'opzione di conferma selettiva (SACK: Selective Acknowledgement) per il TCP

La conferma SACK, definita nell'RFC 2018, permette a un destinatario di indicare fino a quattro blocchi non contigui di dati ricevuti, mediante un'opzione SACK TCP. L'RFC 2883 introduce un utilizzo ulteriore dei campi dell'opzione SACK TCP, per confermare pacchetti duplicati. Grazie a ciò, il mittente può determinare quando ha ritrasmesso un segmento senza necessità e regolare il proprio comportamento in modo da evitare in futuro ritrasmissioni non necessarie. Minore è il numero di ritrasmissioni e migliori sono le prestazioni complessive.

RFC 3517: un algoritmo di recupero più prudente basato sulla conferma selettiva per il TCP

Nell'implementazione del TCP/IP in Windows Server 2003 e Windows XP, le informazioni SACK vengono utilizzate unicamente per determinare i segmenti TCP che non sono giunti a destinazione. L'RFC 3517 definisce un metodo per l'utilizzo delle informazioni SACK per il recupero dei dati perduti quando si ricevono conferme duplicate, con la sostituzione dell'algoritmo di recupero rapido nei casi in cui sulla connessione sia attivata l'opzione SACK. Lo stack TCP/IP Next Generation consente di registrare le informazioni SACK in base a ciascuna connessione e di monitorare le conferme in ingresso e quelle duplicate, in modo da effettuare recuperi più rapidi quando più segmenti non vengono ricevuti dal destinatario.

RFC 4138: Forward RTO-Recovery (F-RTO): un algoritmo per il rilevamento di timeout di ritrasmissioni spurie con TCP e SCTP (Stream Control Transmission Protocol)

Ritrasmissioni non necessarie di segmenti TCP possono verificarsi a causa di innalzamenti improvvisi dell'RTT, che fanno scattare il timeout di ritrasmissione (RTO: retransmission timeout) per segmenti inviati in precedenza e la loro conseguente ritrasmissione da parte del TCP. Se l'innalzamento si verifica appena prima dell'invio di una intera finestra di dati, il mittente può ritrasmettere anche l'intera finestra. L'algoritmo F-RTO previene le ritrasmissioni spurie di segmenti TCP nel modo seguente.

Quando scade l'RTO per più segmenti, il TCP ritrasmette solo il primo. Quando viene ricevuta la prima conferma, il TCP inizia a inviare nuovi segmenti (se questo è possibile dalla dimensione della finestra che è stata comunicata). Se la conferma successiva è relativa agli altri segmenti che sono andati in time out ma che non sono stati ritrasmessi, il TCP deduce che il timeout era fittizio e non ritrasmette gli altri segmenti in timeout.

Il risultato è che in ambienti soggetti a improvvisi e temporanei innalzamenti dell'RTT, come quando un client wireless si sposta da un punto di accesso a un altro, l'F-RTO previene ritrasmissioni di segmenti non necessarie, con un ritorno rapido alla normale velocità di trasmissione. L'uso del recupero delle perdite basato su SACK e di F-RTO è particolarmente adatto per connessioni su canali GPRS.

Joseph Daviesè un technical writer di Microsoft. Dal 1992 tiene corsi e scrive su argomenti legati alle reti Microsoft. Ha scritto cinque libri per Microsoft Press ed è autore della rubrica mensile Cable Guy su TechNet.

© 2008 Microsoft Corporation e CMP Media, LLC. Tutti i diritti riservati. È vietata la riproduzione completa o parziale senza autorizzazione.