3.2. Ritrasmissione Rapida/Recupero Rapido
Un ricevitore TCP DOVREBBE (SHOULD) inviare immediatamente un riconoscimento duplicato quando arriva un segmento fuori sequenza. Lo scopo di questo ACK è informare il mittente che un segmento è stato ricevuto fuori sequenza e quale numero di sequenza è atteso. Dal punto di vista del mittente, i riconoscimenti duplicati possono essere causati da diversi problemi di rete. In primo luogo, possono essere causati da segmenti persi. In questo caso, tutti i segmenti successivi al segmento perso genereranno riconoscimenti duplicati finché la perdita non viene riparata. In secondo luogo, i riconoscimenti duplicati possono essere causati dal riordino dei segmenti di dati da parte della rete (evento non raro su alcuni percorsi di rete [Pax97]). Infine, i riconoscimenti duplicati possono essere causati dalla duplicazione di segmenti di ACK o di dati da parte della rete. Inoltre, un ricevitore TCP DOVREBBE (SHOULD) inviare immediatamente un ACK quando il segmento in ingresso colma del tutto o in parte una lacuna nello spazio delle sequenze. Ciò genererà informazioni più tempestive per un mittente che si riprende da una perdita tramite un timeout di ritrasmissione, una ritrasmissione rapida o un algoritmo avanzato di recupero dalla perdita, come delineato nella sezione 4.3.
Il mittente TCP DOVREBBE (SHOULD) utilizzare l'algoritmo di "ritrasmissione rapida" per rilevare e riparare la perdita, sulla base dei riconoscimenti duplicati in ingresso. L'algoritmo di ritrasmissione rapida utilizza l'arrivo di 3 riconoscimenti duplicati (come definiti nella sezione 2, senza ACK interposti che spostino SND.UNA) come indicazione che un segmento è andato perso. Dopo aver ricevuto 3 riconoscimenti duplicati, TCP esegue la ritrasmissione di quello che appare essere il segmento mancante, senza attendere la scadenza del timeout di ritrasmissione.
Dopo che l'algoritmo di ritrasmissione rapida ha inviato quello che appare essere il segmento mancante, l'algoritmo di "recupero rapido" governa la trasmissione di nuovi dati finché non arriva un ACK non duplicato. Il motivo per cui non si esegue l'avvio lento è che la ricezione dei riconoscimenti duplicati non indica soltanto che un segmento è andato perso, ma anche che i segmenti stanno molto probabilmente lasciando la rete (sebbene una massiccia duplicazione di segmenti da parte della rete possa invalidare questa conclusione). In altre parole, poiché il ricevitore può generare un riconoscimento duplicato solo quando un segmento è arrivato, quel segmento ha lasciato la rete ed è nel buffer del ricevitore, quindi sappiamo che non consuma più risorse di rete. Inoltre, poiché l'"orologio" degli ACK [Jac88] è preservato, il mittente TCP può continuare a trasmettere nuovi segmenti (sebbene la trasmissione debba continuare con un cwnd ridotto, poiché la perdita è un'indicazione di congestione).
Gli algoritmi di ritrasmissione rapida e recupero rapido sono implementati insieme come segue.
-
Al primo e al secondo riconoscimento duplicato ricevuto da un mittente, un TCP DOVREBBE (SHOULD) inviare un segmento di dati non precedentemente inviati secondo [RFC3042], a condizione che la finestra annunciata dal ricevitore lo consenta, che il FlightSize totale rimanga minore o uguale a cwnd più 2*SMSS e che vi siano nuovi dati disponibili per la trasmissione. Inoltre, il mittente TCP NON DEVE (MUST NOT) modificare cwnd per riflettere questi due segmenti [RFC3042]. Si noti che un mittente che utilizza SACK [RFC2018] NON DEVE (MUST NOT) inviare nuovi dati a meno che il riconoscimento duplicato in ingresso non contenga nuove informazioni SACK.
-
Quando viene ricevuto il terzo riconoscimento duplicato, un TCP DEVE (MUST) impostare ssthresh a un valore non superiore a quello dato dall'equazione (4). Quando [RFC3042] è in uso, i dati aggiuntivi inviati nella trasmissione limitata NON DEVONO (MUST NOT) essere inclusi in questo calcolo.
-
Il segmento perso che inizia da SND.UNA DEVE (MUST) essere ritrasmesso e cwnd impostato a ssthresh più 3*SMSS. Ciò "gonfia" artificialmente la finestra di congestione del numero di segmenti (tre) che hanno lasciato la rete e che il ricevitore ha memorizzato nel buffer.
-
Per ogni ulteriore riconoscimento duplicato ricevuto (dopo il terzo), cwnd DEVE (MUST) essere incrementato di SMSS. Ciò gonfia artificialmente la finestra di congestione al fine di riflettere il segmento aggiuntivo che ha lasciato la rete.
Nota: [SCWA99] discute un attacco lato ricevitore in cui molti riconoscimenti duplicati falsi vengono inviati al mittente dei dati al fine di gonfiare artificialmente cwnd e causare l'uso di una velocità di trasmissione superiore a quella appropriata. Un TCP PUÒ (MAY) pertanto limitare il numero di volte in cui cwnd viene gonfiato artificialmente durante il recupero dalla perdita al numero di segmenti in sospeso (o a un'approssimazione di esso).
Nota: quando non viene utilizzato un meccanismo avanzato di recupero dalla perdita (come quello delineato nella sezione 4.3), questo aumento del FlightSize può far sì che l'equazione (4) gonfi leggermente cwnd e ssthresh, poiché si presume che alcuni dei segmenti tra SND.UNA e SND.NXT abbiano lasciato la rete pur essendo ancora riflessi nel FlightSize.
-
Quando sono disponibili dati non precedentemente inviati e il nuovo valore di cwnd e la finestra annunciata dal ricevitore lo consentono, un TCP DOVREBBE (SHOULD) inviare 1*SMSS byte di dati non precedentemente inviati.
-
Quando arriva il successivo ACK che riconosce dati non precedentemente riconosciuti, un TCP DEVE (MUST) impostare cwnd a ssthresh (il valore impostato al passo 2). Questo è chiamato "sgonfiamento" (deflating) della finestra.
Questo ACK dovrebbe essere il riconoscimento suscitato dalla ritrasmissione del passo 3, un RTT dopo la ritrasmissione (sebbene possa arrivare prima in presenza di una significativa consegna fuori sequenza dei segmenti di dati al ricevitore). Inoltre, questo ACK dovrebbe riconoscere tutti i segmenti intermedi inviati tra il segmento perso e la ricezione del terzo riconoscimento duplicato, se nessuno di essi è andato perso.
Nota: è noto che questo algoritmo generalmente non recupera in modo efficiente da perdite multiple in un singolo volo di pacchetti [FF96]. La sezione 4.3 seguente affronta tali casi.