Si tratta di cose lette tanto tanto tempo fa e in cui mi sono nuovamente imbattuto stamattina: tanto vale scriverci sopra qualche nota.
Si parla di protocollo TCP e di gestione delle situazioni di congestione.
(di solito di TCP non mi occupo minimamente: ma è pur sempre il protocolo che abbiamo "sotto il culo" (cit.). Per cui un minimo minimo di ripassino, quando mi capita, me lo faccio)
Ok, veniamo a noi...
Ci sono due soluzioni parzialmente contradditorie (vedremo perché) per contenere la congestione su una rete TCP:
- algoritmo di Nagle
- ACK differiti
In soldoni l'algoritmo di Nagle prevede che la logica della socket implementi una sorta di aggregazione di dati prima di spedirli alla destinazione: il grado di aggregazione dei dati è controllato da dimensione della Sliding Window, dal valore dell' MSS ed infine ... dal ricevimento di ACK!
Vediamo in dettaglio il ruolo del ricevimento dell'ACK da parte del destinatario. Il mittente, a parte fare dei calcoli sulla dimensione massima per l'aggregazione, applica il seguente criterio per decidere di inviare il pacchetto, si chiede: "sono stati inviati dati non ancora confermati"? Sì? Allora memorizza i dati ma non inviarli ancora".
Quello appena descritto è uno dei passi chiave dell'algoritmo di Nagle, ora accantoniamolo per un attimo l'algoritmo di Nagle e vediamo ora cosa significhi invece ACK differiti. La tecnica degli ACK differiti è anche essa una forma di ottimizzazione che punta a limitare il numero di ACK inviati dal destinatario: in pratica il destinatario risponde con ACK non pacchetto per pacchetto bensì solo dopo che ha ricevuto vari pacchetti. A il destinatario invia un unico pacchetto ACK che contiene anche informazioni sull' aggiornamento della dimensione della finestra (Sliding Window) ed eventualmente anche un payload di risposta.
Bang!!!
Chiaro il problema? Vediamolo con un esempio di due interlocutori che applicano rispettivamente "algoritmo di Nagle" lato mittente e "ACK differiti" lato destinatario.
- Mittente: ho delle cose da dirti... ma dimmi tu se ti va bene (attesa dell'ACK)
- Destinatario:
- Mittente:
- Destinatario: <... ok, mi sono stufato ...> "Sì, ci sono: che c'è?" (invio ACK dopo timeout)
- Mittente: ecco qua un bel pacchettone di dati per te
Fortuna che ci sono i timeout!
Nella vita reale una comunicazione simile porta a divorzi o dimissioni... nel campo del TCP introduce solo ritardi
Tutta la descrizione precedente parte da un vecchio post della ottima Julia Evans e su cui mi sono reimbattuto oggi https://jvns.ca/blog/2015/11/21/why-you-should-understand-a-little-about-tcp/
Non ho fatto molto altro se non riformularlo in italiano.
Come bonus aggiungo un minimo di "glossario" che è facilmente approfondibile online:
"Nagle's alghorithm": messo a punto da Nagle a metà degli anni ottanta e orientato a ridurre la congestione sulle reti TCP. Può essere disattivato su una singola socket tramite l'opzione TCP_NODELAY
"ACK delay": altra proposta emersa più o meno nello stesso periodo e con lo stesso obiettivo (... pare che i due gruppi fossero all'oscuro l'uno dei lavori dell'altro...). Può essere disattivato su una singola socket tramite l'opzione TCP_QUICKACK (il "setsockopt" va rieseguito dopo ogni "recv")
"Sliding Windows": la stabilisce il destinatario e la aggiorna via via durante la comunicazione passando il valore nel pacchetto ACK: rappresenta la dimensione del payload che il destinatario si aspetta di ricevere. La finestra potrebbe perfino chiudersi durante la comunicazione, questo avviene nel caso il destinatario rilevi una potenziale congestione sulla rete.
"MSS": massima dimensione del payload in un segmento TCP, è negoziata nell'handshake iniziale e non cambia durante la comunicazione
"MTU": massima dimensione del pacchetto TCP, normalmente il MSS è pari all'MTU meno 40 byte (20 byte di header IP e 20 byte di header TCP)
Può essere che non sia stato molto accurato nella descrizione precedente: ripeto che al momento sono solo degli appunti di promemoria: se avete qualche osservazione o correzione vi ringrazio molto!
... strace, tcpdump, wireshark sono ovviamente ottimi amici se vogliamo monitorare il comportamento di queste cose