venerdì, 29 marzo 2024

Articoli

Mini introduzione alle reti interconnesse: Trasmission Control Protocol

12/10/2011

di Stefano Sacchini, Branch and product manager Dime Sicurezza

L'IP ti fa venire l'orticaria? Switch, Ethernet, gateway ti mandano i neuroni in TILT? Per te abbiamo inaugurato la rubrica IP for dummies, in ossequio alla fortunata catena di volumi tecnici per lettori di qualsiasi livello. Partendo dai fondamentali (anche i più banali e scontati) arriverai col tempo a costruire un vero "manuale TCP/IP per autostoppisti...dove finisce un allarmista e dove inizia un informatico". Nel precedente articolo siamo giunti quasi in cima alla torre ISO/OSI (se ti sei perso qualche puntata, puoi scaricare i numeri precedenti su http://www.secsolution.com/asitaly.asp). Oggi parliamo quindi di TCP, Trasmission Control Protocol, ossia il programma che si occupa di garantire l'integrità dei dati trasmessi. TCP è un utente di IP (Internet Protocol), nel senso che utilizza i suoi servizi per "trovare la giusta strada". Ma IP non fa altro che prendere i dati, incapsularli e spedirli, senza avere la minima cognizione di quello che succederà. Il buon esito della connessione è quindi affidato al nostro amico TCP. Vediamo come.

Quando spediamo una lettera, non possiamo sapere se è realmente arrivata a destinazione. L'unico modo per avere qualche certezza è spedire una Raccomandata A/R, attraverso la quale il destinatario ci invia un messaggio di ricezione. TCP fa esattamente questo: instaura un flusso di dati bidirezionale dove il mittente invia i dati e il destinatario spedisce le conferme di ricezione. Se il mittente non vede arrivare la conferma di ricezione, vuol dire che qualcosa è andato storto e bisognerà rieseguire la trasmissione. Il concetto è semplice ma la sua applicazione è un po' più complessa.

I fondamentali

TCP non vede i dati come pacchetti, ma come un unico flusso (data stream). Il flusso è full duplex ed è di tipo sequenziale, nel senso che i dati sono ricevuti nello stesso ordine in cui vengono trasmessi. TCP è un protocollo orientato alla connessione (connection oriented). Significa che è come se ci fosse una linea di comunicazione dedicata tra i due host interlocutori, al pari di una linea telefonica. Dal momento che questa connessione ENDtoEND non esiste fisicamente, si parla di Virtual Circuit Connection. Il datastream TCP è gestito a SEGMENTI e questi, a differenza del datagram IP, possono avere una lunghezza variabile. La dimensione dei blocchi è aggiornata in tempo reale perché l'algoritmo ha il compito di ottimizzare la trasmissione dei dati in funzione delle condizioni della rete. Inoltre, un blocco che non arriva a destinazione sarà rispedito; per questo si parla di POSITIVE ACKNOWLEDGMENT WITH RETRASMISSION. Naturalmente, i segmenti spediti non saranno tutti in sequenza, perché quelli ritrasmessi saranno in coda. Sarà poi l'applicazione a ricostruire la struttura originaria. Infatti, TCP non indaga il contenuto dei dati (UNSTRUCTURED STREAM). ...Non avete capito nulla?

Mi spiego meglio. Quando TCP trasporta i dati, avvia un flusso dall'host mittente (TX) a quello del destinatario (RX). L'host TX invia la prima parte di dato. L'host RX verifica che siano completi mediante un meccanismo di CHECKSUM e invia una conferma positiva di ricezione (POSITIVE ACK) al TX. Come dire: " OK …il primo gruppo di dati è arrivato... ora invia il secondo gruppo." Come notiamo, entrambi gli host trasmettono e ricevono, quindi, quando apriamo una connessione TCP (ad. es. per spedire una mail) generiamo quattro flussi di dati. A questo punto una domanda nasce spontanea: quanti dati devo spedire prima che mi arrivi la conferma di ricezione? Ogni volta che un segmento è inviato, il mittente fa partire un timer; entro lo scadere del tempo l'host TX deve avere conferma di ricezione; in caso contrario rispedisce il blocco di dati. Tale sistema risolve il problema dei dati andati persi, ma può crearne un altro: supponiamo che, a causa di una congestione della rete, il pacchetto impieghi più tempo ad arrivare. Il mittente, non vedendo conferma, fa partire un suo duplicato e il destinatario si vede arrivare due pacchetti identici. Tale problema si risolve facendo numerare al mittente in maniera sequenziale tutti i pacchetti spediti e facendo verificare al destinatario la giusta sequenza. I TIMEOUT di attesa sono dinamici e sono continuamente adattati alla condizione della rete. Su tale concetto si basa tutta l'efficienza del protocollo TCP.

Svantaggi

Il meccanismo della conferma di ricezione ha comunque un grosso svantaggio. I tempi di attesa causano un sottoutilizzo della rete. Ma si può correre ai ripari: la soluzione si chiama "finestre di scorrimento"(sliding windows). Immaginiamo di avere un tubo di gomma entro il quale facciamo cadere delle biglie di vetro. Io non so che la biglia è uscita dal tubo ed è arrivata a destinazione fintanto che non la sento cadere nell'erba. Ma, così facendo, il mio tubo per la maggior parte del tempo rimane vuoto e questo si traduce in uno spreco di tempo. La soluzione è allora di riempire il tubo con una serie di palline e lasciarle cadere tutte insieme. Man mano che il tubo si svuota, immettiamo altre biglie. In tal modo il canale rimane per la maggior parte del tempo pieno ed io massimizzo l'efficienza della mia trasmissione. Chiaramente le mie biglie sono numerate e alla loro uscita dal tubo devo poter ricostruire l'intera sequenza. Se spedisco cento palline, ma non arrivano tutte a destinazione, vorrà dire che qualcuna di esse si è persa, per cui dovrò re-immettere nel tubo i numeri mancanti. Il numero di palline immesse nel tubo (la grandezza del segmento TCP) costituisce la grandezza della finestra di scorrimento (window size). Se riesco ad ottenere una finestra lunga quanto il mio tubo, significa che lo sto utilizzando al massimo della sua capacità.

Capito la metafora? Il tubo rappresenta la rete, le biglie sono i singoli pacchetti di dati e la dimensione della finestra è la dimensione del segmento di dati. Ma qual è la dimensione ottimale di questa finestra? Non esiste un valore fisso perché continuamente modificato dagli algoritmi. In tal modo la rete si adatta continuamente al variare delle condizioni. Il controllo che TCP ha sul flusso dei dati è un aspetto vitale per le reti interconnesse perché rende possibile lo scambio dati tra hardware completamente differenti. TCP riesce a gestire anche "situazioni di urgenza". Normalmente un pacchetto, prima di essere spedito, deve aspettare che il BUFFER sia pieno. Solo allora il segmento sarà inviato. Ma può accadere che un pacchetto debba essere spedito immediatamente, senza aspettare il riempimento della finestra. Il tal caso porterà con sé un marcatore di urgenza. L'algoritmo quindi farà partire il segmento, anche se non è pieno.

TCP spalanca le sue porte

Che cosa occorre per identificare univocamente una connessione? Sicuramente gli indirizzi IP dei due ENDPOINT, ma evidentemente ciò non basta. Infatti, tra due host è possibile instaurare molteplici connessioni simultanee e ogni connessione deve far capo al relativo programma o processo. Affinché una connessione sia realmente univoca, TCP utilizza un valore, contenuto nella sua intestazione (header), denominata porta. La porta è un valore che identifica il tipo di trasferimento di dati. Ad esempio, tutti i dati che transitano su protocollo http, web, sono di solito identificati sulla porta 80, invece i dati riguardanti le Email transitano utilizzando la porta 25 e 110. Le prime 256 porte sono le cosiddette well known port, ovvero convenzionalmente associate ad una funzione specifica (80per il web, 21 per ftp, 110 per la posta, ecc). Le altre – fino alla 65535 - sono destinate all'assegnazione dinamica ed i sistemi operativi le assegnano ai processi che richiedono una connessione. L'associazione tra la porta e l'indirizzo IP viene chiamata "connessione socket". Ogni host ha una porta per comunicare, anzi, ha una porta per ogni connessione, per cui, nell'header del pacchetto IP, sono contenuti sia la "source port" che la "destination port". Quando si instaura una connessione TCP tra due host, il destinatario effettua l'apertura passiva di una porta (si dice che il servizio "ascolta" su una determinata porta) ed il mittente effettua un'apertura attiva.

Dopodiché tra i due avviene uno scambio di dati per "negoziare" i parametri della connessione. Diciamo che i due host raggiungono un accordo sui valori della connessione che… stanno bene ad entrambi. L'apertura di connessione è detta Three-way handshake (accordo a tre vie). Nel primo passaggio, il mittente invia un pacchetto con il valore SYN (sincronizzazione) a 1. Vuol dire che vuole sincronizzare con il destinatario i numeri sequenziali dei segmenti. Nel secondo passaggio, il destinatario che accetta la connessione risponde con un pacchetto che ha il valore ACK a 1 ed indica, nel campo ACKNOWLEDGMENT NUMBER, il numero di sequenza che si aspetta di ricevere. Nel terzo passaggio, il mittente comunica al destinatario il proprio ACK NUMBER. Ora i due host sono pronti a scambiare dei dati. Anche la chiusura di una sessione TCP richiede un'articolata procedura. Si tratta di un handshaking (stretta di mano) a tre vie modificato. In tal caso il pacchetto che effettua la chiusura ha il valore FIN attivato, mentre il destinatario risponde con un messaggio ACK di chiusura. In definitiva anche la più banale delle operazioni, come lo scrivere "CIAO" in una chat, è il risultato di frenetiche operazioni di calcolo, verifiche e aggiustamenti ed è solo grazie all'implementazione di algoritmi sempre più intelligenti che tutto ci appare veloce e cristallino. Ma chi volesse affacciarsi nel mondo dei bit che vanno e che vengono può farlo semplicemente andando a curiosare in INTERNET. Esiste una sterminata documentazione al riguardo e ogni singolo termine di quest'articolo potrà aprire un universo di informazioni.


Tag:   IP informatica

Tutti gli articoli