Riassunto gerarchico delle nozioni del corso 2003-2004 di RETI
DI CALCOLATORI del Prof. G.Fenu - Università degli Studi di
Cagliari, Facoltà di Scienze Matematiche Fisiche Naturali,
Dipartimento di Matematica ed Informatica, Corso di Laurea in
Informatica
Riferimenti: Andrew S. Tanenbaum, Reti di Calcolatori IV ed.,
Prentice Hall
- 4. livello trasporto (transport layer)
- descrizione
- è il cuore dell'intera gerarchia di protocolli
- è posto tra il livello di rete (3) ed il livello applicativo (5)
- il suo compito è fornire il trasporto dei dati, affidabile ed efficiente in termini di costi, dal computer di origine a quello di destinazione, indipendentemente dalla rete o dalle reti fisiche effettivamente utilizzate
- senza lo strato di trasporto, l'intero concetto di protocolli a strati avrebbe poco senso
- servizio di trasporto
- il livello di trasporto fornisce servizi al livello applicativo
- servizi offerti agli strati superiori
- l'obiettivo finale è offrire un servizio efficace, affidabile ed efficiente in termini di costi ai suoi utenti (processi del livello applicativo)
- il livello trasporto utilizza i servizi offerti dal livello rete
- entità di trasporto
- l'hardware e/o il software all'interno dello strato di trasporto che svolge il lavoro
- può essere situata:
- nel kernel del sistema operativo
- in un processo utente separato
- in un pacchetto di librerie associato alle applicazioni di rete
- in una scheda di interfaccia di rete (in linea di principio)
- esistono due tipi di servizi simili a quelli del livello rete:
- servizio di trasporto orientato alla connessione
- è per molti aspetti simile al servizio equivalente di rete
- servizio di trasporto senza connessione (datagram)
- è molto simile al servizio equivalente di rete
- servizio di trasporto orientato alla connessione
- le connessioni seguono tre fasi:
- costituzione
- trasferimento dei dati
- rilascio
- anche l'indirizzamento ed il controllo del flusso sono simili a quelli del livello rete
- differenza tra i livelli trasporto e rete
- il codice di trasporto scorre interamente sulle macchine dell'utente mentre lo strato network è eseguito per la maggior parte nei router (che sono solitamente gestiti dall'operatore di telecomunicazioni)
- gli utenti generalmente non hanno il controllo sullo strato network
- lo strato di trasporto consente agli utenti di migliorare la qualità del servizio
- lo strato di trasporto consente al servizio di trasporto di essere più affidabile del sottostante servizio di rete
- il servizio network è destinato a modellare quello offerto dalle reti reali (nel bene e nel male) mentre il servizio di trasporto (orientato alla connessione) è affidabile, consente quindi di fornire un servizio affidabile ad una rete inaffidabile
- il servizio network è utilizzato quasi esclusivamente dalle entità di trasporto mentre le primitive di trasporto sono utilizzate da molti programmi e programmatori
- le primitive del servizio di trasporto possono essere
implementate come chiamate a procedure di libreria, per renderle
indipendenti dalle primitive del servizio di rete
- questo consente la sostituzione trasparente delle procedure di libreria del servizio di rete
- grazie allo strato di trasporto, i programmatori di applicazioni possono scrivere codice usando un insieme standard di primitive ed ottenere programmi funzionanti su molte reti diverse, senza doversi preoccupare della gestione delle interfacce delle sottoreti e delle trasmissioni affidabili
- nello strato di trasporto, persino un semplice scambio di dati unidirezionale è più complesso rispetto allo strato network ma nessuno dei meccanismi di acknowledgement, timing, ..., è visibile agli utenti del trasporto
- per gli utenti del trasporto, una connessione è un canale affidabile per i bit, la complessità è nascosta e questo è il motivo per cui i protocolli a strati sono uno strumento così potente
- distinzione tra fornitore ed utente
- fornitori del servizio di trasporto
- sono i quattro strati inferiori del modello OSI modificato (fisico, collegamento, rete, trasporto)
- utenti del servizio di trasporto
- strati superiori a quello di trasporto
- questa distinzione pone lo strato di trasporto in una posizione chiave, dal momento che forma il confine principale tra il fornitore e l'utente di un servizio di trasmissione dati affidabile
- fornitori del servizio di trasporto
- primitive del servizio di trasporto
- il servizio di trasporto deve essere conveniente e facile da utilizzare
- interfaccia di trasporto
- consente agli utenti di accedere al servizio di trasporto
- ogni servizio ha la propria interfaccia
- esempio di primitive per un semplice servizio di trasporto
orientato alla connessione:
-
primitiva pacchetto inviato significato LISTEN - si blocca fino a quando un processo cerca di connettersi CONNECT CONNECTION REQUEST tenta in modo attivo di stabilire una connessione SEND DATA invia informazioni RECEIVE - si blocca fino all'arrivo di un pacchetto DATA DISCONNECT DISCONNECTION REQUEST questo lato desidera rilasciare la connessione - consideriamo un'applicazione con un server e diversi client
remoti:
- il server esegue una primitiva LISTEN, chiamando generalmente una procedura di libreria, che esegue una chiamata di sistema per bloccare il server fino all'accensione di un client
- quando un client desidera comunicare con il server, esegue una
primitiva CONNECT
- l'entità di trasporto esegue questa primitiva bloccando il chiamante ed inviando un pacchetto al server
- incapsulato nel carico utile di questo pacchetto, troviamo un
messaggio dello strato trasporto per l'entità di trasporto del
server:
- TPDU (Transport Protocol Data Unit, unità dati del protocollo
di trasporto)
- messaggi inviati da entità di trasporto verso entità di trasporto
- lo scambio di TPDU avviene secondo la seguente gerarchia:
- frame scambiato dallo strato data link
- intestazione
- carico utile
- pacchetto scambiato dallo strato network
- intestazione
- carico utile
- TPDU scambiato dallo strato di trasporto
- intestazione
- carico utile
- TPDU scambiato dallo strato di trasporto
- pacchetto scambiato dallo strato network
- frame scambiato dallo strato data link
- TPDU (Transport Protocol Data Unit, unità dati del protocollo
di trasporto)
- la chiamata CONNECT del client provoca l'invio al server di una TPDU CONNECTION REQUEST
- all'arrivo della TPDU CONNECTION REQUEST, l'entità di trasporto controlla se il server è bloccato su una chiamata LISTEN (vale a dire se è interessato alla gestione delle richieste), sblocca il server ed invia una TPDU CONNECTION ACCEPTED al client
- quando arriva la TPDU CONNECTION ACCEPTED, il client viene sbloccato e la connessione è stabilita
- ora i dati possono essere scambiati con le primitive SEND e RECEIVE
- ogni lato può inviare una primitiva RECEIVE (di blocco) per attendere l'invio del SEND da parte del corrispondente
- quando arriva la TPDU il ricevitore viene sbloccato, può quindi elaborarla ed inviare una risposta
- finchè entrambi i lati possono tenere traccia dei turni di invio, lo schema funziona bene
- quando una connessione non è più necessaria deve essere rilasciata per liberare spazio nella tabella all'interno delle due entità di trasporto
- la disconnessione presenta due varianti:
- asimmetrica
- ogni utente del trasporto può emettere una primitiva DISCONNECT, che provoca l'invio di una TPDU DISCONNECT all'entità di trasporto remota
- dopo l'arrivo, la connessione viene rilasciata
- simmetrica
- ogni direzione viene chiusa separatamente, indipendentemente dall'altra
- quando un lato emette una primitiva DISCONNECT, significa che non ha altri dati da inviare ma è ancora in grado di accettare dati dal suo partner
- la connessione viene rilasciata quando entrambi i lati hanno inviato DISCONNECT
- asimmetrica
-
- socket Berkeley (TCP)
- primitive di trasporto utilizzate per TCP in Berkeley UNIX
- sono ampiamente utilizzate per la programmazione Internet
- primitive socket per TCP:
- SOCKET
- crea un nuovo punto finale di comunicazione
- alloca lo spazio corrispondente nella tabella all'interno dell'entità di trasporto
- se ha successo, restituisce un normale descrittore di file da utilizzare nelle chiamate successive (similmente ad OPEN)
- i socket appena creati non hanno indirizzi di rete
- i parametri della chiamata specificano:
- il formato dell'indirizzamento da utilizzare
- il tipo di servizio desiderato (es: flusso di byte affidabile)
- il protocollo
- BIND
- associa un indirizzo locale ad un socket
- i client remoti possono connettersi al server dopo questa operazione
- LISTEN
- annuncia la capacità di accettare connessioni
- dà la dimensione della coda
- alloca spazio per accodare le chiamate in ingresso nel caso in cui diversi client provino a connettersi contemporaneamente
- non è una chiamata bloccante
- ACCEPT
- blocca il chiamante fino all'arrivo di un tentativo di connessione
- restituisce un normale descrittore di file, che può essere utilizzato per leggere e scrivere in modo analogo ad un file
- quando arriva una TPDU che richiede una connessione, l'entità di trasporto crea un nuovo socket con le stesse proprietà di quello originale, e restituisce un corrispondente descrittore di file
- il server può quindi generare un processo od un thread per gestire la connessione sul nuovo socket, e tornare ad attendere la connessione successiva sul socket originale
- CONNECT
- tenta in modo attivo di stabilire una connessione
- blocca il chiamante ed avvia il processo di connessione
- quando la TPDU appropriata viene ricevuta dal server, il processo client è sbloccato e viene stabilita la connessione
- SEND
- invia alcuni dati sulla connessione
- RECEIVE
- riceve alcuni dati sulla connessione
- CLOSE
- rilascia la connessione in maniera simmetrica
- la connessione viene rilasciata quando entrambi i lati hanno eseguito questa primitiva
- SOCKET
- elementi dei protocolli di trasporto
- protocollo di trasporto
- implementa il servizio di trasporto
- è utilizzato tra due entità di trasporto
- è simile ai protocolli di collegamento (data link) ma esistono
delle importanti differenze:
- il canale fisico è sostituito dall'intera sottorete
- è richiesto l'indirizzamento esplicito delle destinazioni
- l'instaurazione della connessione è molto più complicata
- la capacità della sottorete di memorizzare i pacchetti può avere conseguenze disastrose e richiedere l'utilizzo di protocolli speciali
- la presenza di un enorme numero di connessioni (variabile dinamicamente) richiede un approccio particolare per il buffering ed il controllo di flusso
- ha a che fare (anche) con il controllo degli errori, l'ordinamento in sequenza ed il controllo del flusso
- indirizzamento
- specifica del processo applicativo remoto al quale intende connettersi un processo applicativo (per esempio un utente)
- consiste nel definire indirizzi di trasporto su cui i processi possono restare in ascolto delle richieste di connessione
- TSAP (Transport Service Access Point, punto di accesso al
servizio di trasporto)
- termine generico che prende diversi nomi a seconda della rete:
- Internet: porte (port)
- reti ATM: AAL-SAP
- termine generico che prende diversi nomi a seconda della rete:
- NSAP (Network Service Access Point, punto di accesso al
servizio di network)
- generico nome per i punti finali corrispondenti ai TSAP
- in alcuni computer esiste un solo NSAP
- gli indirizzi IP sono NSAP
- TSAP e NSAP sono uniti da una connessione di trasporto
- i processi applicativi, client e server, possono collegarsi ad
un TSAP per stabilire una connessione con un TSAP remoto
- queste connessioni scorrono attraverso gli NSAP su ogni host
- diversi TSAP possono collegarsi ad un unico NSAP
- scenario per una connessione di trasporto:
- 1. un processo del server sull'host 2 si collega ad un TSAP per
attendere una chiamata in ingresso
- il modo con cui un processo di collega a TSAP è esterno al modello di rete, e dipende internamente dal sistema operativo locale
- potrebbe essere utilizzata una chiamata LISTEN, per esempio
- 2. un processo applicativo sull'host 1 emette una richiesta
CONNECT specificando il proprio TSAP come origine ed il TSAP
dell'host 2 a cui è interessato come destinazione
- questa azione provoca la costituzione di una connessione di trasporto tra il processo applicativo sull'host 1 ed il server relativo al TSAP di destinazione sull'host 2
- 3. il processo applicativo invia una richiesta per le informazioni di cui necessita
- 4. il processo del server sull'host 2 risponde inviando le informazioni
- 5. la connessione di trasporto viene rilasciata
- 1. un processo del server sull'host 2 si collega ad un TSAP per
attendere una chiamata in ingresso
- scoperta del TSAP associato al server
- per conoscere il TSAP associato al server remoto esistono due
modi principali:
- 1. statico
- si usa per indirizzi TSAP che si riferiscono a server permanentemente collegati alle porte (servizi chiave che non cambiano mai)
- gli indirizzi TSAP vengono salvati localmente in posizioni ben note (es: /etc/services in UNIX)
- 2. dinamico
- a) protocollo di connessione iniziale (dinamico)
- permette ad un processo utente di conoscere il TSAP associato al server remoto al quale vuole accedere
- process server
- proxy per i server utilizzati più raramente
- è installato su ogni macchina che desidera offrire servizi agli utenti remoti
- ascolta un insieme di porte contemporaneamente, attendendo una richiesta di connessione
- funzionamento:
- i potenziali utenti di un servizio iniziano con una richiesta CONNECT, specificando l'indirizzo TSAP del servizio desiderato
- se nessun server è in attesa la connessione avviene con il process server
- il process server crea il server richiesto, consentendogli di ereditare la connessione esistente con l'utente
- il nuovo server svolge il lavoro, mentre il process server torna ad ascoltare nuove richieste
- funziona bene per i server che possono essere creati in caso di necessità, ma si verificano spesso situazioni dove i servizi esistono indipendentemente dal process server (es: file server che deve essere necessariamente eseguito su un hardware apposito e non può essere creato al volo)
- b) server dei nomi (name server, directory server)
- fornisce un'associazione tra i nomi dei servizio (stringa ASCII) ed i corrispondenti indirizzi TSAP
- un nuovo servizio appena creato si deve registrare sul server dei nomi
- funzionamento:
- l'utente apre una connessione con il server dei nomi (che ascolta un TSAP noto)
- l'utente invia un messaggio che specifica il nome del servizio
- il server dei nomi risponde con l'indirizzo TSAP
- l'utente rilascia la connessione con il server dei nomi
- l'utente stabilisce una connessione con il servizio desiderato
- a) protocollo di connessione iniziale (dinamico)
- 1. statico
- per conoscere il TSAP associato al server remoto esistono due
modi principali:
- stabilire la connessione
- è un'operazione sorprendentemente complessa
- il problema si verifica se la rete può perdere, memorizzare e
duplicare i pacchetti:
- in una sottorete molto congestionata gli acknowledgement non riescono quasi mai a tornare indietro in tempo, ogni pacchetto subisce un timeout e viene ritrasmesso due o tre volte
- se la sottorete usa datagrammi ed ogni pacchetto usa una via diversa, alcuni di questi potrebbero restare bloccati in una congestione del traffico e ricomparire con un notevole ritardo
- il problema dei duplicati ritardati può essere affrontato con
diverse metodologie:
- 1. indirizzi di trasporto monouso
- ogni volta che è necessario un indirizzo di trasporto ne viene generato uno nuovo
- quando la connessione viene rilasciata, l'indirizzo è scartato e non verrà mai più utilizzato
- questa strategia non consente di realizzare il modello di process server
- 2. si assegna ad ogni connessione un identificatore
- identificatore
- è costituito da un numero sequenziale incrementato ad ogni connessione stabilita
- è scelto dalla parte che inizia la comunicazione
- è inserito in ogni TPDU, compresa quella che richiede la connessione
- dopo il rilascio di una connessione, ogni entità di trasporto potrebbe aggiornare una tabella che elenca le connessioni obsolete sotto forma di coppie (entità di trasporto, identificatore di connessione)
- ogni volta che giunge una richiesta di connessione, è possibile confrontarla con la tabella per vedere se apparteneva ad una connessione rilasciata in precedenza
- difetto:
- richiede che ogni entità di trasporto mantenga indefinitamente una certa quantità di informazioni storiche
- se una macchina subisce un crash e perde la sua memoria, non saprà più quali identificatori di connessione sono stati già utilizzati
- identificatore
- 3. limitazione del tempo di vita del pacchetto
- la durata del pacchetto può essere limitata ad un valore
massimo prefissato utilizzando una o più delle seguenti tecniche:
- 1. progettazione di sottoreti limitate
- combina due elementi:
- una qualsiasi soluzione che impedisce ai pacchetti di essere ripetuti ciclicamente
- un modo per contenere il ritardo dovuto alla congestione sul percorso più lungo possibile (ora noto)
- combina due elementi:
- 2. inserimento di un contatore di salti in ogni pacchetto
- inizializza il conteggio dei salti ad un valore appropriato
- il contatore viene decrementato ogni volta che il pacchetto viene inoltrato
- il protocollo di rete scarta tutti i pacchetti dove il contatore di salti è arrivato a zero
- 3. applicazione di un contrassegno temporale (timestamp) ad
ogni pacchetto
- ogni pacchetto porta con se l'orario in cui è stato creato
- i router scarteranno ogni pacchetto più vecchio di un tempo stabilito
- ciò richiede che gli orologi dei router siano sincronizzati
- 1. progettazione di sottoreti limitate
- metodo dell'orologio Tomlinson (1975), Sunshine e Dalal (1978)
- mira al contenimento della durata dei pacchetti per stabilire connessioni in sicurezza
- occorre garantire non solo che un pacchetto sia defunto, ma anche che tutti i suoi acknowledgement siano stati rimossi
- alcune varianti sono ampiamente utilizzate in TCP
- aggira il problema di una macchina che perde tutta la memoria a seguito di un crash
- ogni host è equipaggiato con un orologio giornaliero:
- gli orologi in host diversi non devono essere necessariamente sincronizzati
- ciascun orologio è costituito da un contatore binario incrementato ad intervalli regolari
- il numero dei bit del contatore deve essere uguale o maggiore del numero di bit del numero di sequenza
- l'orologio deve continuare a funzionare anche se l'host si blocca e riavvia
- l'idea di base è assicurarsi che non siano mai in circolazione contemporaneamente due TPDU numerate in modo identico
- quando viene impostata una connessione, i bit k di ordine basso dell'orologio sono utilizzati come numero di sequenza iniziale (composto da k bit)
- ogni connessione inizia a numerare le sue TPDU con un numero di sequenza differente
- lo spazio di sequenza dovrebbe essere abbastanza grande da garantire che, nel momento in cui i numeri di sequenza riprendono dall'inizio, le vecchie TPDU con lo stesso numero di sequenza siano già state rimosse
- quando le entità di trasporto si sono accordate sul numero di sequenza iniziale, è possibile utilizzare qualsiasi protocollo sliding window per il controllo del flusso dei dati
- al riavvio dopo un crash occorre assegnare nuovi numeri di
sequenza alle TPDU
- occorre vietare l'assegnazione dei numeri di sequenza alle nuove TPDU per un tempo T prima del loro potenziale utilizzo come numeri di sequenza iniziali
- area proibita
- è costituita dalle combinazioni illegali di tempo e numero di sequenza
- prima di inviare una TPDU su una qualsiasi connessione, l'entità di trasporto deve leggere il clock e controllare se non si trova nell'area proibita, in tal caso deve ritardare la TPDU per T secondi o risincronizzare i numeri di sequenza
- questo protocollo presenta vari problemi:
- se un host invia i dati troppo velocemente su una connessione
appena aperta
- il numero di sequenza attuale potrebbe salire più rapidamente rispetto al numero di sequenza iniziale, sul diagramma temporale
- la velocità massima dei dati su qualsiasi connessione non deve superare una TPDU per battito dell'orologio
- l'entità di trasporto, prima di aprire una nuova connessione dopo il riavvio dopo un crash, deve attendere fino al battito dell'orologio per evitare di usare due volte lo stesso numero
- i problemi invitano a scegliere un ciclo di clock breve (pochi microsecondi o meno)
- per qualsiasi cadenza dei dati inferiore a quella
dell'orologio, la curva dei numeri di sequenza effettivi entra
nell'area proibita da sinistra
- maggiore è la pendenza della curva dei numeri di sequenza effettivi, più lungo sarà il ritardo di questo evento
- se un host invia i dati troppo velocemente su una connessione
appena aperta
- questo protocollo funziona solo una volta che è già stata stabilita la connessione
- three-way handshaking (handshake a tre vie, Tomlinson 1975)
- risolve il problema di TPDU ritardate e duplicate durante la connessione
- mette d'accordo entrambe le parti sul numero di sequenza iniziale
- non richiede ad entrambe le parti d'iniziare la trasmissione partendo dallo stesso numero di sequenza
- può essere utilizzato con metodi di sincronizzazione diversi dal metodo dell'orologio
- funzionamento:
- l'host 1 sceglie un numero di sequenza x ed invia una TPDU CONNECTION REQUEST contenente x all'host 2
- l'host 2 risponde con una TPDU ACK contenente:
- la conferma di x
- la proposta di un suo numero y di inizio sequenza
- l'host 1 invia un TPDU dati contenente:
- i primi dati del dialogo
- la conferma di y
- in questo schema, la possibilità di inviare dei TPDU REJECT consente di rifiutare il tentativo di stabilire una connessione che era stato precedentemente generato da un pacchetto duplicato in ritardo
- non esiste alcuna combinazione di vecchie TPDU che può provocare il fallimento del protocollo o l'instaurarsi accidentale di una connessione indesiderata
- la durata del pacchetto può essere limitata ad un valore
massimo prefissato utilizzando una o più delle seguenti tecniche:
- 1. indirizzi di trasporto monouso
- rilascio della connessione
- rilasciare una connessione è più facile che stabilirla, ache se sono presenti diverse problematiche
- esistono due modi per terminare una connessione:
- rilascio asimmetrico
- è il metodo utilizzato dal sistema telefonico
- quando una delle due parti riattacca la connessione viene interrotta
- è improvviso e può provocare una perdita di dati
- rilascio simmetrico
- tratta la connessione come se fosse composta da due connessioni unidirezionali separate, e richiede il rilascio separato di ognuna di esse
- un host può continuare a ricevere dati anche dopo aver inviato una TPDU DISCONNECT
- in alcune situazioni, determinare che tutto il lavoro è stato svolto e che la connessione dovrebbe essere terminata non è un'operazione così ovvia
- problema dei due eserciti
- un esercito bianco è accampato in fondo ad una valle
- sulle colline ai fianchi della valle sono accampati due eserciti blu
- l'esercito bianco è più grande di ognuno dei due eserciti blu
- gli eserciti blu insieme sono più grandi dell'esercito bianco
- per poter vincere gli eserciti blu dovranno attaccare contemporaneamente, dovranno quindi sincronizzarsi
- l'unico mezzo di comunicazione tra gli eserciti blu è l'invio di messaggeri a piedi lungo la valle, dove potrebbero essere catturati perdendo il messaggio (canale di comunicazione inaffidabile)
- per poter attaccare ognuno dei due eserciti blu dovrà essere sicuro che l'altro esercito abbia correttamente ricevuto il messaggio
- i due eserciti non potranno mai mettersi d'accordo perchè nessuno sarà mai sicuro che l'altro abbia effettivamente ricevuto il messaggio, anche inviando una sequenza infinita di acknowledgement degli acknowledgement (rimarrà sempre il dubbio)
- per ovviare al problema dei due eserciti si introduce una
temporizzazione e si usa un l'handshake a tre vie:
- funzionamento:
- l'host 1 invia un TPDU DISCONNECTION REQUEST (DR1) ed avvia un timer 1
- all'arrivo di del DR1, l'host 2 invia a sua volta un TPDU DISCONNECTION REQUEST (DR2) ed avvia un timer 2
- all'arrivo del DR2, l'host 1 invia un TPDU ACKNOWLEDGEMENT e
rilascia la connessione
- se il DR2 viene perso, allo scadere del timeout 1 l'host 1 ritrasmette il DR1 e riavvia il timer
- se l'host 1 non riceve DR2 dopo N tentativi, termina la connessione per timeout
- all'arrivo del TPDU ACKNOWLEDGEMENT, l'host 2 rilascia la
connessione
- se il TPDU ACKNOWLEDGEMENT viene perso, allo scadere del timeout 2 l'host 2 rilascia la connessione
- questo protocollo è generalmente sufficiente ma può fallire se vengono perse la DR iniziale e le N ritrasmissioni
- è possibile ovviare al problema delle connessioni rimaste a
metà imponendo una regola che termina la connessione se per un
certo numero di secondi non si ricevono più TPDU
- e necessario un timer in ogni entità di trasporto che venga ricaricato ad ogni TPDU ricevuta
- se il timer scade viene trasmessa una TPDU fittizia solo per impedire la disconnessione dell'altro lato
- funzionamento:
- rilascio asimmetrico
- controllo di flusso e buffering
- sotto certi aspetti il problema del controllo del flusso nello
strato di trasporto equivale a quello nello strato data link
- in entrambi gli strati su ogni connessione è necessaria una sliding window o un altro schema per impedire che un trasmettitore rapido sommerga un ricevitore lento
- la differenza principale sta nel fatto che un router presenta
di norma poche linee, mentre un host può avere numerose connessioni
- questo rende poco pratica l'implementazione nello strato di trasporto della strategia di buffering dello strato data link
- se la sottorete offre un servizio datagram (inaffidabile)
- l'entità di trasporto deve usare dei buffer in cui inserire le TPDU in uscita perchè potrebbe essere necessario ritrasmetterle
- se il ricevitore sa che il mittente inserisce nel buffer tutte le TPDU fino a quando non riceve l'acknowledgement, potrebbe decidere se dedicare o no buffer specifici alle singole connessioni
- il ricevitore potrebbe, per esempio, mantenere un singolo pool di buffer condiviso da tutte le connessioni
- all'arrivo di una TPDU, viene svolto un tentativo di acquisire dinamicamente un nuovo buffer
- se vi sono buffer disponibili, la TPDU viene accettata, altrimenti viene scartata
- lo scarto delle TPDU non provoca danni ad eccezione dello spreco di risorse, il mittente continua a provare finché non riceve l'acknowledgement
- se la rete offre un servizio affidabile
- se il mittente sa che il ricevitore ha sempre uno spazio nei buffer, non deve mantenere copie delle TPDU inviate
- se il ricevitore non può garantire l'accettazione di ogni TPDU in ingresso, il mittente dovrà comunque usare il buffer
- il mittente non può fidarsi dell'acknowledgement dello strato network, perché indica solo l'arrivo della TPDU e non la sua accettazione
- dimensione del buffer
- esistono varie possibilità per gestire i buffer:
- buffer di dimensione fissa
- si utilizzano se la maggior parte delle TPDU ha una dimensione simile
- si utilizza un pool di buffer con dimensione identica ed una TPDU per buffer
- buffer di dimensioni variabili
- si utilizza se esiste una variazione notevole nella dimensione della TPDU
- utilizzano meglio la memoria a scapito di una gestione più complicata
- singolo buffer circolare di grandi dimensioni per ogni
connessione
- fa un valido utilizzo della memoria quando tutte le connessioni sono caricate in modo pesante
- è scadente se alcune connessioni hanno poco carico
- buffer di dimensione fissa
- il miglior compromesso tra buffering di origine e destinazione
dipende dal tipo di traffico sulla connessione:
- per un traffico irregolare e con larghezza di banda ridotta
(traffico bursty ma poco gravoso)
- è preferibile eseguire il buffering nel mittente
- non è necessario bufferizzare la destinazione
- per un traffico uniforme a larghezza di banda elevata (es: file
transfer)
- è preferibile eseguire il buffering del ricevitore
- i buffer dovranno essere cospicui per accettare sempre ciò che arriva
- per un traffico irregolare e con larghezza di banda ridotta
(traffico bursty ma poco gravoso)
- esistono varie possibilità per gestire i buffer:
- allocazione del buffer
- con l'aprirsi ed il chiudersi delle connessioni ed il variare dello schema del traffico il mittente ed il ricevitore devono regolare dinamicamente le allocazioni dei buffer
- il protocollo di trasporto dovrebbe consentire ad un host mittente di richiedere spazio nel buffer dell'altra estremità
- i buffer possono essere allocati in vari modi:
- per connessione
- collettivamente per tutte le sessioni in esecuzione tra i due host
- il ricevitore potrebbe comunicare al mittente il numero di buffer a lui riservati
- se il numero di connessioni aperte aumenta può essere necessario ridurre un'allocazione
- allocazione dinamica
- consiste nel separare il buffering dagli acknowledgement
- si traduce nell'uso di una window di dimensione variabile
- inizialmente il mittente richiede un certo numero di buffer, basato sulla previsione delle proprie esigenze
- il ricevitore garantisce il numero che può permettersi
- ogni volta che il mittente trasmette una TPDU decrementa la sua allocazione, fermandosi quando raggiunge il valore zero
- il ricevitore può quindi aggiungere separatamente gli acknowledgement e le allocazioni del buffer sul traffico che scorre nella direzione opposta
- nelle reti a datagrammi, se le TPDU di controllo vengono perse
si possono verificare dei problemi (stallo)
- per ovviare a questi inconvenienti, ogni host deve periodicamente inviare TPDU di controllo per fornire l'acknowledgement e lo stato di connessione di ogni buffer
- capacità di trasporto della sottorete
- se router adiacenti possono scambiare al massimo x pacchetti al
secondo ed esistono k percorsi disgiunti tra una coppia di host,
non vi è modo per tali host di scambiare più di kx TPDU al secondo,
indipendentemente dalla quantità di buffer disponibile ad ogni
estremità
- se il mittente supera la velocità di kx TPDU/sec la sottorete si congestiona
- un meccanismo per regolare la velocità del flusso va applicato al mittente
- metodo di Belsnes (1975)
- schema di controllo del flusso sliding window
- il mittente regola dinamicamente la dimensione della window per farla corrispondere alla capacità di trasporto della rete
- se la rete può gestire c TPDU/sec ed r è la durata del ciclo (comprensiva di trasmissione, propagazione, accodamento, elaborazione nel ricevitore e restituzione dell'acknowledgement), la window del mittente dovrebbe corrispondere almeno a cr
- con una window di queste dimensioni, il mittente opera normalmente con il canale pieno
- un piccolo calo delle prestazioni di rete potrebbe provocarne il blocco
- per regolare periodicamente la dimensione della window, il
mittente potrebbe monitorare entrambe i parametri e poi calcolare
la dimensione desiderata per la window
- la capacità di trasporto potrebbe essere determinata con il semplice conteggio del numero di TPDU che hanno ricevuto acknowledgement in un dato periodo di tempo, e dividendo tale valore per il periodo esaminato
- durante la misura il mittente dovrebbe eseguire l'invio alla massima velocità (per assicurarsi che il fattore limitante è la capacità di trasporto della rete e non un valore ridotto della capacità di input)
- il tempo richiesto per dare l'acknowledgement ad una TPDU trasmessa è misurabile con precisione e se ne può calcolare una media mobile
- la dimensione della window dovrebbe essere regolata frequentemente per tener traccia dei cambiamenti nella capacità di trasporto
- Internet utilizza un meccanismo simile
- se router adiacenti possono scambiare al massimo x pacchetti al
secondo ed esistono k percorsi disgiunti tra una coppia di host,
non vi è modo per tali host di scambiare più di kx TPDU al secondo,
indipendentemente dalla quantità di buffer disponibile ad ogni
estremità
- sotto certi aspetti il problema del controllo del flusso nello
strato di trasporto equivale a quello nello strato data link
- multiplexing
- nello strato di trasporto l'esigenza del multiplexing può sorgere in molti modi
- se un host ha a disposizione un solo indirizzo di rete, tutte le connessioni di trasporto del computer devono utilizzare tale indirizzo
- upward multiplexing
- stabilisce a quale processo attribuire una TPDU entrante
- downward multiplexing
- consente di utilizzare una larghezza di banda superiore a quella consentita da una singola connessione network
- apre più connessioni di rete e distribuisce il traffico tra esse su base round robin
- con k connessioni di rete aperte, la larghezza di banda è aumentata di un fattore k
- esempio:
- utilizzo contemporaneo di due connessioni separate ISDN da 64Kbps per connettersi ad un provider Internet, ottenendo così una larghezza di banda di 128Kbps
- ripristino dopo un crash
- se l'entità di trasporto è interamente contenuta all'interno
degli host, il ripristino dopo un crash di rete o del router è
banale
- servizio datagram
- le entità di trasporto prevedono la perdita di TPDU e sanno come gestirla
- servizio orientato alla connessione
- la perdita di un circuito virtuale è gestita stabilendone uno nuovo e quindi sondando l'entità di trasporto remota per chiederle quali TPDU ha ricevuto e quali non sono ancora giunte a destinazione (queste ultime possono essere ritrasmesse)
- servizio datagram
- ripristino dopo il crash dell'host
- è il problema più complesso
- per recuperare lo stato precedente, il server potrebbe inviare una TPDU broadcast a tutti gli altri host, annunciando di aver subito un crash e richiedendo che i client lo informino dello stato delle connessioni aperte
- ogni client può trovarsi in uno dei seguenti stati:
- S1 : con una TPDU in circolazione
- S0 : senza TPDU in circolazione
- in base a queste informazioni di stato, il client deve decidere se ritrasmettere la TPDU più recente
- il problema si verifica se il crash avviene tra l'operazione di
scrittura di una TPDU nel flusso di output e l'invio
dell'acknowledgement (che sono due eventi distinti che non possono
essere eseguiti contemporaneamente)
- a seconda dell'ordine con cui vengono eseguite queste operazioni si avrà un pacchetto perso o uno duplicato
- indipendentemente dalla programmazione del client e del server,
esistono sempre situazioni in cui i protocolli falliscono il
corretto ripristino
- il server può essere programmato in due modi:
- prima il riconoscimento
- prima la scrittura
- il client può essere programmato in quattro modi:
- per ritrasmettere sempre l'ultima TPDU
- per non ritrasmettere mai l'ultima TPDU
- per ritrasmetterla solo nello stato S0
- per ritrasmetterla solo nello stato S1
- si ottengono otto combinazioni server-client, per ognuna delle quali esiste un insieme di eventi che provoca il fallimento del protocollo
- elaborando ulteriormente il protocollo non si ottengono risultati
- il crash ed il ripristino dell'host non possono essere resi trasparenti agli strati superiori
- un vero acknowledgement end-to-end, la cui ricezione indica che il lavoro è stato svolto e la cui mancanza indica il contrario, è praticamente impossibile da raggiungere
- combinazioni di strategie per client e server
-
strategia utilizzata dall'host che invia strategia utilizzata dell'host che riceve prima ACK, poi scrittura prima scrittura, poi ACK AC(W) AWC C(AW) C(WA) WAC WC(A) ritrasmetti sempre OK DUP OK OK DUP DUP non ritrasmettere mai LOST OK LOST LOST OK OK ritrasmette in S0 OK DUP LOST LOST DUP OK ritrasmette in S1 LOST OK OK OK OK DUP - legenda
- A = invio di un acknowledgement
- W = scrittura nel processo di output
- C = crash
- OK = il protocollo funziona correttamente
- DUP = il protocollo genera un messaggio duplicato
- LOST = il protocollo perde un messaggio
-
- il server può essere programmato in due modi:
- se l'entità di trasporto è interamente contenuta all'interno
degli host, il ripristino dopo un crash di rete o del router è
banale
- protocollo di trasporto
- semplice protocollo di trasporto
- analizziamo un semplice protocollo di trasporto di esempio simile al TCP
- in questo modello semplificato ogni TSAP può partecipare ad una sola connessione di trasporto
- ogni primitiva corrisponde esattamente ad una procedura di libreria che la esegue
- esempio di primitive di servizio:
- CONNECT
- connum = CONNECT(TSAP locale, TSAP remoto)
- prova a stabilire una connessione di trasporto tra i due TSAP
- durante la chiamata il chiamante viene bloccato (o sospeso) mentre l'entità di trasporto cerca di impostare la connessione
- se la connessione ha successo, il chiamante viene sbloccato e può iniziare a trasmettere dati
- connum può essere:
- numero non negativo utilizzato per identificare la connessione
- numero negativo in caso di fallimento della comunicazione (TSAP già in uso, inattività dell'host remoto, indirizzo locale o remoto non valido, ...)
- LISTEN
- connum = LISTEN(TSAP locale)
- annuncia il desiderio del chiamante di accettare le richieste di connessione dirette al TSAP indicato
- il processo resta bloccato fino a quando qualche processo remoto tenta di stabilire una connessione al suo TSAP
- non esiste un timeout
- è un modello altamente asimmetrico
- un lato è passivo ed esegue un listen attendendo che accada qualcosa
- l'altro lato è attivo ed inizia la connessione
- se il lato attivo inizia per primo è possibile seguire diverse
strategie:
- a) far fallire il tentativo di connessione se non ci sono processi in ascolto nel TSAP remoto
- b) bloccare chi inizia (magari in eterno) fino alla comparsa di un ascoltatore
- c) mantenere la richiesta di connessione all'estremità del
ricevente per un certo intervallo di tempo
- se un processo su tale host esegue la chiamata a listen prima della scadenza del timer, viene stabilita la connessione
- in caso contrario, la connessione viene rifiutata, il chiamante viene sbloccato e viene restituito un errore
- DISCONNECT
- status = DISCONNECT(connum)
- termina una connessione di trasporto indicata dal parametro connum
- si utilizza un modello di disconnessione simmetrico (quando entrambi i lati saranno disconnessi verrà rilasciata la connessione)
- status può riportare:
- 0 = operazione riuscita
- connum non è un numero di connessione valido
- connum appartiene ad un'altro processo
- SEND
- status = SEND(connum, buffer, bytes)
- trasmette il contenuto del buffer come un messaggio sulla connessione di trasporto indicata, se necessario diviso in più unità
- status può riportare:
- mancata connessione
- l'indirizzo del buffer non valido
- conteggio negativo
- RECEIVE
- status = RECEIVE(connum, buffer, bytes)
- indica il desiderio del chiamante di accettare dati
- la dimensione del messaggio di arrivo è inserita in bytes
- status può riportare:
- rilascio della connessione da parte del processo remoto
- l'indirizzo del buffer non valido
- crea un blocco fino all'arrivo di una TPDU
- CONNECT
- esempio di entità di trasporto
- questo esempio è notevolmente semplificato rispetto ai sistemi reali per motivi pedagogici
- un entità di trasporto realistica controllerà la validità dei parametri forniti dall'utente, gestirà il ripristino dei crash dello strato network, si occuperà delle collisioni tra le chiamate e supporterà un servizio di trasporto più generico che include caratteristiche come interrupt, datagram e versioni non bloccanti delle primitive SEND e RECEIVE
- consideriamo per semplicità un servizio di rete affidabile orientato alla connessione
- consideriamo che l'entità di trasporto sia stata programmata come package di libreria all'interno dello spazio di indirizzamento dell'utente
- con semplici modifiche l'entità di trasporto potrebbe anche essere resa parte del sistema operativo dell'host, agendo principalmente sul'acceso ai buffer da parte dell'utente
- l'entità di trasporto non è realmente un'entità separata ma fa
parte del processo utente
- se un utente esegue una primitiva che provoca un blocco come LISTEN, viene bloccata anche l'intera entità di trasporto
- su un host con più utenti sarebbe più naturale avere un'entità di trasporto strutturata come processo separato, distinto da tutti i processi utente
- l'interfaccia per lo strato network richiede le procedure
to_net e from_net
- ogni procedura ha sei parametri:
- identificatore della connessione
- viene associato ad ogni circuito virtuale di rete
- bit Q (Qualifier, qualificatore)
- 1 = messaggio di controllo (consente di evitare la trasmissione
di un'intestazione del protocollo di trasporto)
- questi messaggi sono rilevati ed elaborati dall'entità di trasporto ricevente
- 0 = messaggio ordinario inviato come pacchetto di dati
- 1 = messaggio di controllo (consente di evitare la trasmissione
di un'intestazione del protocollo di trasporto)
- bit M
- 1 = presenza di altri dati di questo messaggio nel pacchetto successivo
- tipo di pacchetto
- CALL REQUEST
- inviato per stabilire una connessione
- CALL ACCEPTED
- risposta a call request
- CLEAR REQUEST
- inviato per rilasciare una connessione
- CLEAR CONFIRMATION
- risposta a clear request
- DATA
- utilizzato per trasportare i dati
- CREDIT
- pacchetto di controllo per gestire la window
- CALL REQUEST
- puntatore ai dati
- punta ai dati veri e propri
- numero di byte di dati
- identificatore della connessione
- nelle chiamate a to_net, l'entità di trasporto compila tutti i parametri che devono essere letti dallo strato network
- nelle chiamate a from_net, lo strato scompone un pacchetto in ingresso per passarlo all'entità di trasporto
- ogni procedura ha sei parametri:
- passando le informazioni come parametri della procedura, anzichè fornire i pacchetti veri e propri in ingresso o in uscita, lo strato di trasporto viene protetto dai dettagli del protocollo dello strato network
- se l'entità di trasporto dovesse tentare di inviare un
pacchetto quando la sliding window del circuito virtuale
sottostante è piena, sarebbe sospesa all'interno di to_net fino a
quando si libera spazio nella window
- questo meccanismo è interamente trasparente rispetto all'entità di trasporto, ed è controllato dallo strato network utilizzando i comandi analoghi a enable_transport_layer e disable_transport_layer
- la gestione della window per lo strato di pacchetti è svolta sempre dallo strato network
- l'entità di trasporto esegue anche chiamate a procedure
esplicite:
- sleep
- viene chiamata quando l'entità di trasporto è bloccata in modo logico, in attesa di un evento esterno (generalmente l'arrivo di un pacchetto)
- wakeup
- questa chiamata provoca l'interruzione dell'esecuzione dell'entità di trasporto (ed il processo utente)
- sleep
- ogni connessione si trova sempre in uno dei sette stati:
- 1. IDLE (inattiva)
- la connessione non è ancora stata stabilita
- 2. WAITING (in attesa)
- CONNECT è stato eseguito e CALL REQUEST inviato
- 3. QUEUED (accodata)
- CALL REQUEST è arrivato, nessun LISTEN
- 4. ESTABLISHED (stabilita)
- la connessione è stata stabilita
- 5. SENDING (invio)
- l'utente attende l'autorizzazione per inviare un pacchetto
- 6. RECEIVING (ricezione)
- è stato eseguito RECEIVE
- 7. DISCONNECTING (disconnessione)
- è stato eseguito DISCONNECT localmente
- 1. IDLE (inattiva)
- le transizioni tra gli stati avvengono in corrispondenza dei
seguenti eventi:
- viene eseguita una primitiva
- arriva un pacchetto
- scade il timer
- le procedure dell'entità di trasporto sono di due tipi:
- invocabili direttamente dai programmi utente
- routine di interrupt
- vengono spontaneamente innescate da eventi esterni
- possono essere chiamate solo quando il processo utente è inattivo o eseguito all'esterno dell'entità di trasporto
- esempi:
- packet_arrival
- viene invocata all'arrivo di un pacchetto, che viene elaborato
- clock
- controlla il timeout delle richieste di connessione accodate
- packet_arrival
- la struttura principale utilizzata dall'entità di trasporto è
l'array conn , che contiene un record per ogni potenziale
connessione
- il record mantiene:
- lo stato della connessione
- gli indirizzi di trasporto di entrambe le estremità
- il numero di messaggi inviati
- il numero di messaggi ricevuti
- lo stato corrente
- il puntatore al buffer dell'utente
- il numero di byte del messaggio corrente inviati o ricevuti fin ora
- un bit che indica se l'utente remoto ha emesso un DISCONNECT
- un timer
- un contatore di autorizzazioni utilizzato per consentire l'invio di messaggi
- il record mantiene:
- funzionamento:
- si presume che ogni voce di conn sia inizializzata allo stato IDLE
- quando l'utente esegue la chiamata a CONNECT, lo strato network riceve l'ordine di inviare un pacchetto CALL REQUEST alla macchina remota, poi l'utente viene forzato in attesa
- quando il pacchetto CALL REQUEST giunge all'altro lato,
l'entità di trasporto viene interrotta per eseguire packet_arrival
e controllare se l'utente locale sta eseguendo l'ascolto
sull'indirizzo specificato
- in questo caso, viene restituito un pacchetto CALL ACCEPTED
- in caso contrario, CALL REQUEST viene accodato per TIMEOUT
battiti del clock
- se in questo periodo viene eseguito un LISTEN la connessione è stabilita
- in caso contrario, si verifica un timeout e la connessione viene rifiutata con un pacchetto CLEAR REQUEST affinchè non si blocchi per sempre
- occorre tener traccia di quale pacchetto appartiene a quale
connessione di trasporto
- l'approccio più semplice utilizza il numero del circuito virtuale dello strato network come numero della connessione di trasporto
- numero del circuito virtuale può anche essere usato come indice nell'array conn
- quando un pacchetto giunge sul circuito virtuale k dello strato network, appartiene alla connessione di trasporto k, il cui stato è contenuto nel record conn[k]
- per le connessioni iniziate da un'host, il numero di connessione è scelto dall'entità di trasporto originaria
- per le chiamate in ingresso, è lo stato network a compiere la scelta selezionando qualsiasi numero di circuito virtuale inutilizzato
- per evitare di dover fornire e gestire i buffer all'interno
dell'entità di trasporto, si utilizza un meccanismo di controllo
del flusso diverso dalla normale sliding window
- quando un utente esegue la chiamata a RECEIVE, uno speciale messaggio di credito è inviato all'entità di trasporto sulla macchina che trasmette ed è registrato nell'array conn.
- quando viene chiamato SEND, l'entità di trasporto controlla se
è giunto un credito sulla connessione specificata
- in questo caso, il messaggio viene inviato (con più pacchetti se necessario) ed il credito decrementato
- in caso contrario, l'entità di trasporto diventa inattiva fino all'arrivo di un credito
- questo meccanismo garantisce che non vengano mai inviati
messaggi se l'altra parte non ha gia chiamato un RECEIVE
- come risultato, all'arrivo di un messaggio è garantita la disponibilità di un buffer in cui inserire il messaggio
- lo schema può essere generalizzato per consentire ai ricevitori di fornire più buffer e richiedere più messaggi
- esempio come macchina a stati finiti
- per ridurre la possibilità di commettere errori, spesso è utile rappresentare lo stato del protocollo come macchina a stati finiti
- il protocolo di esempio presenta 7 stati per connessione
- è anche possibile isolare 12 eventi che possono spostare una
connessione da uno stato all'altro
- 5 sono primitive di servizio
- 6 sono l'arrivo di sei tipi di pacchetti ammessi
- 1 è la scadenza del timer
- è possibile rappresentare le azioni del protocollo principale
come una matrice (macchina a stati finiti)
- le colonne sono gli stati
- le righe sono gli eventi
- ogni voce della matrice contiene fino a tre campi:
- predicato
- indica a quale condizione viene svolta l'azione
- azione
- nuovo stato
- predicato
- la scelta degli stati da utilizzare nella matrice non è interamente dipendente dal protocollo stesso
- non vengono indicate le azioni minori, come l'inizializzazione dei campi di un record di connessione
- se un'azione coinvolge il risveglio di un processo inattivo, contano anche le azioni successive al risveglio
- dopo l'esecuzione di ogni azione, la connessione potrebbe passare ad un nuovo stato
- il vantaggio di rappresentare il protocollo come una matrice ha
tre risvolti:
- 1. facilita al programmatore il controllo sistematico di ogni
combinazione di stato ed evento, per vedere se è necessaria un
azione
- nelle implementazioni di produzione, alcune combinazioni sono utilizzate per la gestione degli errori
- 2. può semplificare l'implementazione rendendola più regolare e
sistematica
- è possibile immaginare un array bidimensionale in cui l'elemento a[i][j] è un puntatore o un indice per la procedura che gestisce l'evento i all'interno dello stato j
- si può scrivere l'entità di trasporto come un breve ciclo, con
l'attesa dell'evento all'inizio del ciclo
- al verificarsi di un'evento si individua la connessione di pertinenza e ne viene estratto lo stato
- conoscendo l'evento e lo stato, l'entità di trasporto indicizza l'array ed esegue la chiamata alla procedura appropriata
- 3. in alcuni documenti standard i protocolli sono forniti come macchine a stati finiti, ciò rende più semplice il passaggio dallo standard a protocolli funzionanti
- 1. facilita al programmatore il controllo sistematico di ogni
combinazione di stato ed evento, per vedere se è necessaria un
azione
- lo svantaggio può essere rappresentato dalla difficoltà di comprensione, che tuttavia può essere migliorata rappresentando la macchina a stati finiti come un grafico
- protocolli di trasporto Internet (TCP e UDP)
- Internet possiede due protocolli principali nello strato di
trasporto:
- TCP (Transmission Control Protocol)
- protocollo orientato alla connessione (affidabile)
- UDP (User Data Protocol)
- protocollo senza connessione (non affidabile)
- TCP (Transmission Control Protocol)
- TCP (Transmission Control Protocol, protocollo di controllo
della trasmissione, RFC 793, RFC 1122, RFC 1323)
- introduzione
- è stato progettato appositamente per fornire un flusso di byte affidabile end-to-end su una internetwork inaffidabile, per adattarsi dinamicamente alle proprietà della internetwork e per continuare ad offrire solide prestazioni in presenza di molti tipi di errore
- TCP è un servizio full-duplex punto-punto con gestione di acknowledgement e controllo del flusso
- TCP non supporta il multicasting o il broadcasting
- ogni computer che supporta TCP dispone di un'entità di
trasporto TCP
- può essere:
- una procedura di libreria
- processo utente
- parte del kernel
- gestisce i flussi TCP e le interfacce verso lo strato IP
- può essere:
- TCP si occupa di:
- accettare dai processi locali i flussi dati dell'utente (dal livello application)
- suddividere i dati in pezzi (segmenti) di dimensione non superiore a 64KB (in pratica sono quasi sempre 1460 byte, affinchè stiano nel frame Ethernet con le intestazioni IP e TCP)
- inviare ogni pezzo in un datagramma (datagram) IP autonomo (consegnare i segmenti al livello network)
- ricevere i segmenti dal livello network
- eseguire il timeout e la ritrasmissione secondo le necessità
- riassemblare i messaggi nella giusta sequenza eliminando buchi e doppioni
- consegnare i dati al livello application
- in generale, fornire l'affidabilità che la maggior parte degli utenti desidera e che IP non fornisce
- modello di servizio TCP
- il servizio TCP è ottenuto con la creazione di punti finali da parte di mittente e ricevente, che vengono chiamati socket
- socket
- per ottenere un servizio TCP si deve stabilire esplicitamente una connessione tra un socket sulla macchina di invio ed un socket sulla macchina ricevente
- un socket supporta più connessioni contemporaneamente (due o più connessioni possono terminare nello stesso socket)
- le connessioni sono individuate dagli identificatori di socket ad entrambe le estremità, vale a dire la coppia (socket 1, socket2)
- non vengono utilizzati i numeri di circuito virtuale o altri identificatori
- ogni socket possiede un indirizzo composto da:
- indirizzo IP dell'host
- porta
- numero di 16 bit locale all'host
- è il nome TCP per un TSAP
- i numeri di porta inferiori a 1024 identificano well-known
ports (porte ben note)
- sono riservate ai servizi standard:
- 21 FTP
- trasferimento di file
- 23 Telnet
- login remoto
- 25 SMTP
- posta elettronica
- 69 TFTP
- trivial file transfer protocol
- 79 finger
- ricerca di informazioni su un utente
- 80 HTTP
- World Wide Web
- 110 POP3
- accesso remoto alla posta elettronica
- 119 NNTP news di USENET
- 21 FTP
- sono riservate ai servizi standard:
- l'amministratore di sistema può configurare il computer perchè disponga di daemon permanenti sulle porte più usate (es: la porta 80) mentre inetd (Internet daemon) si occupa delle altre (quando arriva una connessione in ingresso inetd genera un nuovo processo e vi esegue il daemon appropriato)
- TCP è un flusso di byte, non di messaggi, quindi i confini dei messaggi non vengono conservati da un'estremità all'altra della connessione (il ricevente non può sapere l'unità di scrittura fondamentale dei dati)
- per TCP un byte è solo un byte, non ha idea del significato
- PUSH
- quando un'applicazione passa i dati a TCP, questo a sua discrezione può inviarli immediatamente o inserirli in un buffer, per raccoglierne una quantità maggiore da inviare tutta assieme
- per forzare l'uscita dei dati le applicazioni possono utilizzare il flag PUSH, che comunica a TCP di non ritardare la trasmissione
- se vengono ricevuti diversi flag PUSH prima della trasmissione del primo (per esempio perchè la linea di output è occupata), TCP è libero di raccogliere tutti i dati push in un singolo datagramma IP, senza separazione delle parti
- dati urgenti (URGENT)
- quando un'utente interattivo preme i tasti CANC o CTRL+C per interrompere un'elaborazione remota che ha già avuto inizio, l'applicazione trasmittente inserisce alcune informazioni di controllo nel flusso dei dati e le consegna a TCP con il flag URGENT
- questo evento obbliga TCP ad interrompere l'accumulazione dei dati e trasmettere immediatamente tutto ciò che ha a disposizione per quella connessione
- quando i dati urgenti vengono ricevuti dalla destinazione, l'applicazione ricevente viene fermata (per esempio con una signal di UNIX) in modo che possa interrompere ciò che stava facendo e leggere il flusso dei dati per trovare quelli urgenti
- la fine dei dati urgenti è contrassegnata, in modo che l'applicazione sappia dove terminano
- l'inizio dei dati urgenti non è contrassegnato ed è compito dell'applicazione calcolarlo
- questo schema fornisce un meccanismo di segnalazione basilare lasciando tutto il resto all'applicazione
- protocollo TCP
- ogni byte in una connessione TCP ha un numero di connessione di 32 bit
- alle attuali velocità di rete, i numeri di sequenza possono essere consumati a velocità preoccupanti
- per gli acknowledgement e per il meccanismo window si usano numeri di sequenza a 32 bit distinti
- segmento TCP (segment)
- forma con la quale vengono scambiati i dati tra entità TCP
- consiste in un'intestazione di 20 byte (più una parte facoltativa) seguita da zero o più byte di dati
- TCP decide la dimensione dei segmenti, e può accumulare in un segmento i dati provenienti da più scritture oppure dividere i dati di una scrittura in più segmenti
- i limiti sulla dimensione del segmento sono due:
- ogni segmento, compresa l'intestazione TCP, deve essere contenuto nel carico utile di 65.515 byte di IP
- MTU (Maximum Transfer Unit, unità di trasferimento massima)
- ogni rete ne ha una
- il segmento deve essere contenuto in una MTU
- generalmente è lunga 1500 byte (dimensione del carico utile Ethernet)
- il protocollo di base utilizzato dalle entità TCP è il
protocollo sliding window
- quando un mittente trasmette un segmento, avvia anche un timer
- quando il segmento arriva a destinazione, l'entità TCP invia un segmento (con i dati, se esistono, oppure senza) contrassegnato da un numero di acknowledgement uguale al numero di sequenza successivo che prevede di ricevere
- se il timer del mittente scade prima della ricezione dell'acknowledgement, il mittente ritrasmette il segmento
- problemi potenziali:
- i segmenti possono arrivare in ordine sbagliato, quindi i byte successivi potrebbero non ricevere acknowledgement perchè i precedenti non sono ancora arrivati
- i segmenti potrebbero ritardare durante il transito tanto da mandare in timeout il mittente e provocando quindi una ritrasmissione
- le ritrasmissioni possono includere intervalli di byte diversi rispetto alla trasmissione originale
- intestazione del segmento TCP
- ogni segmento inizia con un'intestazione di 20 byte con formato fisso
- può essere seguita da alcune opzioni dell'intestazione
- dopo le opzioni seguono fino a 65535 - 20 - 20 = 65495 byte di dati, dove i primi 20 fanno riferimento all'intestazione IP ed i secondi all'intestazione TCP
- sono ammessi segmenti senza dati, ampiamente usati per acknowledgement e messaggi di controllo
- formato:
- source port [16 bit] (porta di origine)
- identifica la porta di origine
- destination port [16 bit] (porta di destinazione)
- identifica la porta di destinazione
- sequence number [32 bit] (numero di sequenza)
- il numero di sequenza del primo ottetto di dati in questo segmento
- se SYN è impostato, rappresenta il numero di sequenza iniziale (ISN) ed il primo ottetto di dati è ISN + 1
- acknowledgement number [32 bit] (numero di acknowledgement)
- se il bit di controllo ACK è impostato, contiene il valore del prossimo numero di sequenza che il mittente del segmento si aspetta di ricevere
- quando una connessione è stabilita, questo viene sempre inviato
- data offset [4 bit] (lunghezza dell'intestazione TCP)
- indica il numero di word da 32 bit contenute nell'intestazione TCP, ovvero l'inizio dei dati
- questa informazione è necessaria perchè il campo option ha una lunghezza variabile
- reserved [6 bit] (riservato)
- riservato per usi futuri
- i bit dovrebbero essere impostati a zero
- control bits [6 bit] (bit di controllo)
- URG [1 bit] : Urgent Pointer field significant
- è impostato quando si usa urgent pointer (puntatore urgente), che indica l'offset in byte (partendo dal numero di sequenza corrente) in cui si trovano i dati urgenti
- questa funzionalità è utilizzata al posto dei messaggi di interrupt, per consentire al mittente di inviare segnali al ricevente senza coinvolgere TCP nel motivo dell'interrupt
- ACK [1 bit] : Acknowledgment field significant
- viene impostato ad 1 per indicare che acknowledgement number è valido
- quando è zero il campo acknowledgement number viene ignorato
- PSH [1 bit] : Push Function
- segnala la presenza di dati PUSH
- al ricevente viene chiesto di consegnare i dati all'applicazione all'arrivo senza archiviarli
- RST [1 bit] : Reset the connection
- viene utilizzato per reimpostare una connessione che è diventata incongruente a causa di un crash dell'host o per altre ragioni
- è utilizzato anche per rifiutare un segmento non valido o un tentativo di aprire una connessione
- indica sempre la presenza di un problema
- SYN [1 bit] : Synchronize sequence numbers
- viene utilizzato per stabilire le connessioni
- la richiesta di connessione (CONNECTION REQUEST) presenta SYN=1 e ACK=0
- la conferma di connessione (CONNECTION ACCEPTED) presenta SYN=1 e ACK=1
- FIN [1 bit] : No more data from sender
- viene utilizzato per rilasciare la connessione
- specifica che il mittente non ha altri dati da trasmettere
- dopo aver chiuso una connessione, il processo di chiusura potrebbe continuare a ricevere dati all'infinito
- URG [1 bit] : Urgent Pointer field significant
- window [16 bit] (dimensione finestra)
- indica la dimensione della finestra
- indica quanti byte possono essere inviati a partire da quello che ha ricevuto l'acknowledgement
- se impostato a zero significa che i byte fino ad acknowledge number - 1 compreso sono stati ricevuti, ma che il ricevente ha bisogno di riposo e non desidera altri dati per il momento
- il ricevente può in seguito dare l'autorizzazione all'invio trasmettendo un segmento con lo stesso acknowledgement number ed un campo window diverso da zero
- in TCP, gli acknowledgement e le autorizzazioni per inviare i dati aggiuntivi sono completamente separati (questo offre una flessibilità aggiuntiva)
- checksum [16 bit]
- esegue la somma di controllo dell'intestazione, dei dati e della pseudo intestazione
- calcolo del checksum:
- il campo checksum TCP viene impostato a zero
- il campo dati viene riempito con un'altro byte zero se la sua lunghezza è un numero dispari
- somma i complementi ad uno delle parole di 16 bit e quindi calcola il complemento ad uno della somma
- il risultato della verifica sull'intero segmento (incluso checksum) dovrebbe essere zero
- pseudo intestazione (pseudo header)
- è formata da:
- source address [32 bit] (indirizzo della sorgente)
- destination address [32 bit] (indirizzo di destinazione)
- zero [8 bit]
- tutti i bit di questo campo vanno impostati a 0
- PTCL [8 bit] (ProToCol Lenght)
- numero di protocollo per TCP
- TCP Length [16 bit] (lunghezza segmento TCP)
- conteggio dei byte TCP inclusa l'intestazione
- non considera i 12 ottetti della pseudo intestazione
- includendo la pseudo intestazione nel calcolo della somma di controllo TCP è possibile rilevare i pacchetti consegnati in modo errato, ma si viola la gerarchia di protocolli, perché gli indirizzi IP appartengono allo strato IP e non allo strato TCP
- UDP utilizza la stessa pseudo intestazione per il proprio checksum
- è formata da:
- urgent pointer [16 bit] (puntatore urgente)
- punta al numero di sequenza dell'ottetto che segue i dati urgenti
- è espresso come un offset positivo dal numero di sequenza nel segmento corrente
- questo campo verrà preso in considerazione solo se il bit di controllo URG è settato
- options [variable] (opzioni)
- è un modo per aggiungere caratteristiche extra non disponibili nella normale intestazione
- la lunghezza del campo option è un multiplo di 8 bit
- tutte le opzioni sono incluse nel checksum
- le opzioni iniziano con un campo kind [8 bit] che a seconda del
valore specifica:
- 0 End of option list (fini lista opzioni)
- 1 No-Operation (nessuna operazione)
- 2 Maximum Segment Size (massima lunghezza del segmento)
- permette di specificare ad ogni host il carico utile massimo che TCP potrà accettare
- se non si utilizza questa opzione, il carico utile è pari a 536 byte
- la dimensione massima del segmento nelle due direzioni può non essere la stessa
- questa opzione va utilizzata solo durante la richiesta di connessione (bit di controllo SYN impostato)
- a questo byte fanno seguito:
- Lenght [8 bit]
- indica la lunghezza del campo seguente
- normalmente è impostato al valore 4 = 16 bit
- Maximum Segment Size Option Data [16 bit] (massima lunghezza
del carico utile)
- specifica il carico utile massimo che TCP potrà accettare
- Lenght [8 bit]
- esistono vari RFC che propongono tecniche diverse per gestire dinamicamente finestre di grandi dimensioni (per trasmissioni su linee con grandi ritardi come quelle satellitari)
- padding [variable] (riempimento)
- campo utilizzato per assicurarsi che la lunghezza dell'intestazione TCP sia un multiplo di 32 bit
- tutti i bit del padding vanno impostati a zero
- source port [16 bit] (porta di origine)
- costituzione della connessione TCP
- le connessioni TCP vengono stabilite mediante l'handshake a tre vie
- per stabilire una connessione
- un lato (server) attende in modo passivo una connessione in ingresso eseguendo le primitive LISTEN e ACCEPT, indicando un'origine precisa oppure nessuna in particolare
- l'altro lato (client) esegue una primitiva CONNECT,
specificando:
- l'indirizzo IP e la porta a cui vuole connettersi
- la dimensione massima del segmento TCP che potrà accettare
- facoltativamente, alcuni dati utente (es: password)
- la primitiva CONNECT invia un segmento TCP con il bit SYN a 1 ed il bit ACK a 0, poi attende una risposta
- quando il segmento del client arriva a destinazione, l'entità
TCP controlla se esiste un processo che ha eseguito il LISTEN sulla
porta indicata nel campo destination port
- in caso negativo, invia una risposta con il bit RST a 1 per rifiutare la connessione
- in caso affermativo, riceve il segmento TCP in ingresso, quindi
può accettare o rifiutare la connessione
- se accetta, viene restituito un segmento di acknowledgement
- se due host tentano di stabilire contemporaneamente una connessione tra gli stessi due socket, verrà creata una sola connessione relativa alla prima che viene attivata
- il numero di sequenza di una connessione non è mai zero
- quando un host subisce un crash, potrebbe non essere riavviato per un tempo pari a quello di vita massimo del pacchetto, in modo tale da garantire che non vi siano in circolazione su Internet pacchetti riferiti a connessioni precedenti
- rilascio della connessione TCP
- anche se le connessioni TCP sono full-duplex è meglio immaginarle come una coppia di connessioni simplex, dove ogni connessione è rilasciata in modo indipendente
- entrambe le parti possono inviare un segmento TCP con il bit FIN impostato, per indicare che non hanno più dati da trasmettere
- quando FIN riceve l'acknowledgement, la direzione viene chiusa per i nuovi dati (i dati possono continuare a fluire indefinitivamente nell'altra direzione)
- quando entrambe le direzioni saranno state chiuse, la connessione sarà rilasciata
- normalmente sono necessari quattro segmenti TCP per rilasciare una connessione, un FIN ed un ACK per ogni direzione, ma è possibile inserire il primo ACK ed il secondo FIN nello stesso segmento, così da ridurre il totale a tre
- è anche possibile che entrambe le estremità di una connessione TCP inviino i segmenti FIN contemporaneamente
- per evitare il problema dei due eserciti si usano i timer
- se una risposta a FIN non arriva entro la durata massima di due pacchetti, il mittente FIN rilascia la connessione
- l'altro lato noterà l'assenza dell'ascoltatore ed andrà a sua volta in timeout
- anche se la soluzione non è perfetta, nella pratica raramente nascono problemi
- modello di gestione della connessione TCP
- i passaggi per stabilire e rilasciare le connessioni possono
essere rappresentati in una macchina a stati finiti con 11 stati:
- CLOSED
- nessuna connessione è attiva o in sospeso
- LISTEN
- il server è in attesa di una chiamata in ingresso
- SYN RCVD
- è arrivata una chiamata di connessione
- attesa di ACK
- SYN SENT
- l'applicazione ha iniziato ad aprire una connessione
- ESTABLISHED
- il normale stato di trasferimento dei dati
- FIN WAIT 1
- l'applicazione afferma di aver terminato
- FIN WAIT 2
- l'altro lato accetta il rilascio
- TIMED WAIT
- attende la scadenza di tutti i pacchetti
- CLOSING
- entrambi i lati hanno cercato di chiudere contemporaneamente
- CLOSE WAIT
- l'altro lato ha iniziato il rilascio
- LAST ACK
- attende la scadenza di tutti i pacchetti
- CLOSED
- in ogni stato sono ammessi alcuni eventi
- quando si verifica un evento ammesso è possibile svolgere alcune azioni
- se si verifica un evento non ammesso viene restituito un errore
- ogni connessione inizia nello stato CLOSED
- lo stato viene lasciato quando la connessione esegue un'apertura passiva LISTEN o un'apertura attiva CONNECT
- se l'altro lato esegue l'operazione opposta, è stabilita una connessione e lo stato diventa ESTABILISHED
- il rilascio della connessione può essere iniziato da una qualunque delle parti
- una volta completato lo stato ritorna a CLOSED
- percorso client
- connessione
- un programma applicativo sulla macchina client emette una richiesta CONNECT
- l'entità TCP locale crea un record per la connessione, la contrassegna nello stato SYN SENT ed invia un segmento SYN
- lo stato è relativo alla connessione ed è registrato nel record della connessione
- quando arriva SYN+ACK, TCP invia l'ACK finale dell'handshake a tre vie e passa nello stato ESTABILISHED
- ora è possibile inviare e ricevere dati
- disconnessione
- quando un'applicazione ha finito, esegue una primitiva CLOSE
- l'entità locale TCP invia un segmento FIN ed attende l'ACK corrispondente
- quando arriva l'ACK, viene eseguita una transizione allo stato FIN WAIT 2 ed una direzione della connessione si chiude
- quando ache l'altro lato esegue la chiusura, viene ricevuto un FIN che richiede l'invio di un ACK
- ora entrambe i lati sono chiusi ma TCP attende un tempo uguale alla durata massima del pacchetto per garantire che tutti i pacchetti della connessione siano scaduti (nel caso in cui l'ACK sia stato perso)
- alla scadenza del timer TCP elimina il record della connessione
- connessione
- percorso server
- connessione
- il server esegue un LISTEN ed attende che qualcuno effettui l'attivazione
- quando arriva SYN, provoca come risposta un ACK ed il server passa allo stato SYN RCVD
- quando il SYN del server riceve un ACK, l'handshake a tre vie è completo ed il server passa nello stato ESTABLISHED
- ora può avvenire il trasferimento dei dati
- disconnessione
- quando il client ha terminato esegue un CLOSE che provoca l'arrivo di FIN
- il server riceve un signal
- quando a sua volta esegue CLOSE, FIN viene mandato al client
- all'arrivo dell'ACK del client, il server rilascia la connessione ed elimina il record della connessione
- connessione
- i passaggi per stabilire e rilasciare le connessioni possono
essere rappresentati in una macchina a stati finiti con 11 stati:
- criterio di trasmissione TCP
- la gestione della finestra TCP non è associata direttamente agli acknowledgement (come nella maggior parte dei protocolli di collegamento dati)
- attraverso il campo window (dimensione finestra) nell'intestazione del segmento TCP, il ricevente comunica al mittente negli ACK di ritorno, la dimensione disponibile della finestra
- quando la finestra è 0, il mittente non può di norma inviare
segmenti
- esistono due eccezioni:
- è possibile inviare dati urgenti, per esempio per consentire all'utente di interrompere il processo in esecuzione sulla macchina remota
- il mittente può inviare un segmento di 1 byte, per fare in modo che il ricevente annunci di nuovo il successivo byte previsto e la dimensione della finestra
- le eccezioni sono esplicitamente fornite dallo standard TCP per scongiurare un blocco in caso di perdita di un annuncio della finestra
- esistono due eccezioni:
- i mittenti non sono obbligati a trasmettere i dati appena li ricevono dall'applicazione
- i riceventi non hanno l'obbligo di inviare gli acknowledgement il prima possibile
- la conoscenza della dimensione della finestra consente al mittente di variare dinamicamente la dimensione del carico utile, e quindi di migliorare le prestazioni
- algoritmo di Nagle (Nagle, 1984)
- cerca di risolvere lo spreco di banda nel caso che l'utente immetta pochi byte alla volta (es: telnet)
- quando i dati arrivano al mittente un byte alla volta, è sufficiente inviare il primo byte ed inserire il resto nel buffer fino a che arriva l'acknowledgement del byte circolante
- a questo punto si possono inviare tutti i caratteri nel buffer usando un solo segmento TCP, e iniziare ad inserire di nuovo nel buffer i successivi fino a quando arriva il prossimo acknowledgement
- se l'utente digita rapidamente e la rete è lenta, in ogni segmento è possibile inserire un buon numero di caratteri, riducendo ulteriormente la banda utilizzata
- l'algoritmo consente inoltre l'invio di un nuovo pacchetto se sono arrivati abbastanza dati da riempire metà della finestra o un segmento con dimensione massima
- è un'algoritmo ampiamente utilizzato in TCP ma a volte è preferibile disattivarlo (ad esempio se si inviano i movimenti del mouse ad un computer remoto)
- silly window syndrome (Clark, 1982)
- porta ad un degrado delle prestazioni TCP
- problema che si verifica quando i dati vengono passati all'entità TCP di invio in blocchi grandi, ma l'applicazione interattiva sul lato ricevente legge i dati un byte alla volta
- la lettura di 1 byte alla volta da parte del ricevente crea una situazione in cui la finestra oscilla tra un byte e zero
- la soluzione di Clark sta nell'impedire che il ricevente invii un aggiornamento della finestra per un byte, costringendolo ad attendere una certa quantità di spazio disponibile
- nello specifico, il ricevente può inviare un aggiornamento della finestra solo quando è in grado di gestire la dimensione massima del pacchetto (concordata quando la situazione è stata instaurata), o quando il suo buffer è pieno per metà
- il mittente potrebbe essere di aiuto se non invia segmenti di
piccole dimensioni
- dovrebbe attendere fino a quando ha accumulato spazio sufficiente nella finestra per inviare un segmento completo, o almeno un segmento contenente dati per la metà della dimensione del buffer di ricezione (che deve stimare dallo schema degli aggiornamenti della finestra ricevuti in passato)
- l'algoritmo di Nagle e la soluzione di Clark sono complementari
alla soluzione della silly window syndrome
- Nagle lavora principalmente sul mittente (in mittente non deve inviare segmenti troppo piccoli)
- Clark lavora principalmente sul ricevente (il ricevente non deve richiedere segmenti troppo piccoli)
- il TCP di ricezione può anche eseguire il buffering dei dati
per tenere bloccata una richiesta READ dell'applicazione fino a
quando può fornirgli un blocco di dati abbastanza grande
- si riduce il numero di chiamate a TCP, e quindi il sovraccarico
- si aumenta il tempo di risposta
- è conveniente per applicazioni non interattive (es: trasferimento file)
- segmenti fuori ordine
- possono essere conservati o scartati a discrezione del ricevente
- gli acknowledgement possono essere inviati solo quando sono stati ricevuti tutti i dati fino all'ultimo byte
- controllo della congestione TCP
- quando il carico applicato ad una rete è superiore a quello che può gestire, si verifica una congestione
- anche se lo strato network tenta di gestire le congestioni, la maggior parte del lavoro è svolta da TCP, perchè la vera soluzione alle congestioni è la diminuzione della velocità dei dati
- TCP tenta di ottenere questo obiettivo manipolando dinamicamente la dimensione della finestra
- rilevamento
- è il primo passo nella gestione delle congestioni
- la perdita di pacchetti dovuti ad errori di trasmissione è relativamente rara, perchè le linee più lunghe sono realizzate in fibra ottica (le reti wireless fanno eccezione)
- la maggior parte dei timeout su Internet sono dovuti alla congestione, e questo è quello che presume TCP
- TCP controlla i timeout per riscontrare problemi
- quando viene stabilita una connessione si deve scegliere una dimensione adatta per la finestra
- occorre tener conto di due problemi che vanno gestiti
distintamente
- si usano due finestre:
- finestra garantita dal ricevente
- è scelta dal ricevente
- scelta in base alla dimensione del buffer del ricevente
- evita il traboccamento del buffer all'estremità ricevente
- finestra di congestione (congestion window)
- è scelta dal mittente
- controlla la capacità della rete
- finestra garantita dal ricevente
- ogni finestra riflette il numero di byte che il mittente può trasmettere
- il numero di byte che possono essere inviati corrisponde alla più piccola delle due finestre
- la finestra effettiva corrisponde al valore minimo tra ciò che il mittente pensa che sia giusto e ciò che il ricevente pensa sia corretto
- si usano due finestre:
- avvio lento (slow start)
- è un algoritmo per la gestione della finestra di congestione
- deve essere supportato da tutte le implementazioni TCP
- quando viene stabilita una connessione, il mittente inizializza la finestra di congestione alla dimensione del segmento massimo ed invia un segmento massimo
- se il segmento riceve l'acknowledgement prima della scadenza del timer, la finestra di congestione viene raddoppiata e vengono inviati due segmenti massimi
- la finestra continua a raddoppiare fintanto che giungono tutti gli acknowledgement in tempo
- in pratica, ogni gruppo che riceve l'acknowledgement raddoppia la dimensione della finestra di congestione
- la finestra di congestione continua a crescere (esponenzialmente) fino al timeout o fino al raggiungimento della finestra del ricevente
- algoritmo di controllo della congestione Internet
- oltre alle due finestre, utilizza un terzo parametro, una soglia inizialmente pari a 64KB
- al verificarsi del timeout:
- la soglia viene impostata alla metà della finestra di congestione corrente
- la finestra di congestione viene impostata alla dimensione massima di un segmento
- al raggiungimento della soglia
- la crescita esponenziale della finestra di congestione dovuta all'avvio lento termina
- le trasmissioni avvenute con successo aumentano la finestra di congestione in maniera lineare (di un segmento di lunghezza massima per ogni blocco)
- questo algoritmo taglia a metà la finestra di congestione e poi lavora gradualmente partendo da questo valore
- l'arrivo di un pacchetto SOURCE QUENCH ICMP passato a TCP, viene trattato in modo simile ad un timeout
- gestione dei timer TCP
- TCP utilizza più timer (almeno concettualmente) per svolgere il proprio lavoro
- timer di ritrasmissione
- è il timer più importante
- ne viene attivato uno quando viene inviato un segmento
- se il segmento riceve l'acknowledgement prima della scadenza il timer viene fermato, altrimenti il segmento viene ritrasmesso ed il timer riavviato
- la determinazione della durata dell'intervallo è complicata
- è complicato determinare il tempo di round-trip (tempo richiesto da un ack TCP per tornare indietro)
- se il timeout è troppo breve si verificano ritrasmissioni non necessarie
- se il timeout è troppo lungo si verificheranno ritardi a scapito delle prestazioni
- la media e la varianza della distribuzione di arrivo degli acknowledgement possono cambiare rapidamente in pochi secondi, a causa di una congestione o della sua risoluzione
- algoritmo di Jacobson (1988)
- algoritmo dinamico che regola costantemente l'intervallo di timeout
- funzionamento:
- per ogni connessione, TCP mantiene una variabile RTT (Round Trip/Transmission Time)
- RTT rappresenta la miglior stima attuale del tempo di roud-trip per la destinazione in questione
- quando viene inviato un segmento si avvia un timer che serve a
due scopi:
- sapere quanto tempo richiede l'acknowledgement
- innescare un'eventuale ritrasmissione
- se l'ack ritorna indietro prima della scadenza del timer, TCP
misura il tempo richiesto M e riaggiorna RTT:
- RTT nuovo = αRTT vecchio + (1 - α)M
- α : fattore di perequazione che determina il peso dato al vecchio valore (generalmente corrisponde a 7/8)
- TCP calcola il tempo di ritrasmissione come: βRTT
- inizialmente β era un valore costante pari a 2, quindi inflessibile al cambiamento della varianza
- nel 1988 Jacobson ha proposto di rendere β proporzionale alla deviazione standard della funzione di densità di probabilità relativa al tempo di arrivo dell'acknowledgement, in modo che una varianza grande producesse un valore β elevato e viceversa
- la deviazione media D è stata utilizzata come approssimazione
della deviazione standard:
- D nuovo = αD vecchio + (1 - α)|RTT - M|
- Timeout = RTT + 4D
- è possibile eseguire questo calcolo solo con adizioni intere, sottrazioni e scorrimenti
- la scelta del fattore 4 è arbitraria (in realtà scelta
sperimentalmente) ma presenta due vantaggi:
- la moltiplicazione per 4 può essere effettuata con un solo scorrimento
- riduce il timeout e le ritrasmissioni inutili perchè meno dell'1% dei pacchetti giunge in un tempo superiore a 4 volte la deviazione standard
- algoritmo di Karn
- è stato pensato per l'uso di TCP con trasmissioni radio
- problema
- quando giunge un acknowledgement non è chiaro se fa riferimento alla prima trasmissione o ad una successiva ritrasmissione, questo inficia la stima di RTT
- funzionamento
- si evita di aggiornare RTT ad ogni segmento ritrasmesso
- il timeout viene raddoppiato ad ogni errore fino a quando i segmenti giungono a destinazione al primo tentativo
- timer di persistenza
- è progettato per impedire la situazione di stallo (deadlock)
seguente:
- il ricevente invia un acknowledgement con una dimensione della finestra pari a zero, chiedendo al mittente di aspettare
- in seguito, il mittente aggiorna la finestra, ma il pacchetto con l'aggiornamento viene perso
- ora sia il mittente che il ricevente attendono che l'altro faccia qualcosa
- funzionamento:
- quando il timer di persistenza scade, il mittente trasmette una sonda al ricevente
- la risposta alla sonda fornisce la dimensione della finestra
- se la finestra è ancora a zero, il timer di persistenza viene reimpostato ed il ciclo si ripete
- se la finestra non è zero, è possibile inviare i dati
- è progettato per impedire la situazione di stallo (deadlock)
seguente:
- timer keepalive
- scade quando una connessione è stata inattiva per lungo tempo, in modo che una delle parti controlli se l'altra è ancora presente
- se non ottiene risposta, la connessione viene terminata
- questa funzionalità è controversa perché aggiunge carico di lavoro è può terminare una connessione attiva a causa di una partizione transitoria della rete
- timer usato nello stato TIMED WAIT
- è utilizzato durante la chiusura
- il conteggio prosegue per un tempo pari al doppio del tempo di vita del pacchetto, per garantire che alla chiusura di una connessione tutti i pacchetti creati siano stati rimossi
- introduzione
- UDP (User Data Protocol, protocollo per datagrammi utente, RFC
768)
- protocollo di trasporto senza connessione (non affidabile)
- offre alle applicazioni un modo per inviare datagrammi IP incapsulati senza dover stabilire una connessione
- trasmette segmenti costituiti da un'intestazione di 8 byte seguita dal carico utile
- si occupa di fornire un'interfaccia al protocollo IP, con la caratteristica aggiunta del demultiplexing di più processi utilizzando le porte
- intestazione UDP
- source port [16 bit] (porta di origine)
- serve principalmente quando si deve inviare una risposta all'origine
- destination port [16 bit] (porta di destinazione)
- indica il destinatario del pacchetto
- UDP lenght [16 bit] (lunghezza UDP)
- include l'intestazione di 8 byte ed i dati
- UDP checksum [16 bit]
- è facoltativo e contiene 0 se non elaborato
- un vero 0 elaborato e memorizzato con tutti 1
- source port [16 bit] (porta di origine)
- funzionamento:
- quando arriva un pacchetto UDP, il suo carico utile è
consegnato al processo assegnato alla porta di destinazione
- questa associazione avviene con l'utilizzo della primitiva BIND o qualcosa di simile
- il valore principale di UDP rispetto ad IP è costituito dalla presenza delle porte di origine e destinazione che servono a consegnare correttamente il pacchetto
- quando arriva un pacchetto UDP, il suo carico utile è
consegnato al processo assegnato alla porta di destinazione
- cose che UDP non può fare:
- controllo di flusso
- controllo degli errori
- ritrasmissione dopo la ricezione di un segmento errato
- esempio applicativo:
- DNS (Domain Name System, sistema dei nomi di dominio)
- sono sufficienti due pacchetti UDP da e verso un server DNS per ottenere l'IP corrispondente ad un nome di dominio
- DNS (Domain Name System, sistema dei nomi di dominio)
- UDP e TCP wireless
- i protocolli di trasporto dovrebbero essere indipendenti dalla tecnologia dello strato network
- nella pratica la tecnologia impiegata è importante perchè TCP è stata ottimizzata sulla base di supposizioni valide per le reti cablate ma non per quelle wireless
- il problema principale è l'algoritmo di controllo della
congestione
- quasi tutte le implementazioni TCP presuppongono che i timeout siano provocati dalla congestione e non dai pacchetti persi
- nelle reti wireless è vero il contrario (si perdono molti pacchetti a causa dell'innaffidabilità del mezzo)
- la strategia TCP di rallentare la sorgente peggiora la situazione nelle reti wireless, dovrebbe invece ritentare con maggior determinazione
- se il mittente non conosce la rete è difficile prendere la decisione giusta
- spesso il percorso dal mittente al ricevente è eterogeneo (rete mista cablata e wireless)
- TCP indiretto (Bakne e Badrinath, 1995)
- soluzione al problema del TCP su percorso misto
- consiste nel dividere la connessione TCP in due connessioni
separate ed omogenee:
- dal mittente alla stazione base (rete cablata)
- i timeout possono rallentare il mittente
- dalla stazione base al ricevente (rete wireless)
- i timeout possono accelerare il mittente
- dal mittente alla stazione base (rete cablata)
- la stazione base copia semplicemente i pacchetti tra le connessioni, in entrambe le direzioni
- questo schema viola la semantica TCP
- un acknowledgement non indica che il ricevente ha ricevuto il segmento ma che lo ha ricevuto la base
- l'algoritmo di controllo della congestione non sarà mai avviato a meno che non ci sia una reale congestione nella parte cablata della rete
- soluzione di Balakrishnan (1995)
- non interrompe le semantiche TCP
- apporta diverse piccole modifiche al codice dello strato
network nella stazione base:
- agente di snooping
- osserva ed archivia nella cache i segmenti TCP in uscita dall'host mobile e gli acknowledgement provenienti da esso
- quando vede un segmento TCP in uscita dall'host mobile ma non rileva un acknowledgement prima della scadenza del suo timer, ritrasmette il segmento senza comunicare all'origine l'operazione
- esegue la ritrasmissione anche quando rileva acknowledgement duplicati provenienti dall'host mobile, che indicano che si è perso qualcosa
- gli acknowledgement duplicati sono scartati immediatamente, per evitare che l'origine li interpreti come una congestione
- agente di snooping
- se il collegamento wireless è molto soggetto a perdite, l'origine potrebbe provocare un timeout in attesa di un'acknowledgement ed invocare l'algoritmo di controllo della congestione
- offre anche una soluzione al problema dei segmenti persi
originati dall'host mobile
- quando una stazione base osserva una lacuna nei numeri di sequenza, genera una richiesta di ripetizione selettiva dei byte mancanti utilizzando un'opzione TCP
- utilizzando queste soluzioni il collegamento wireless diventa più affidabile in entrambe le direzioni, senza che l'origine sia a conoscenza del fatto e senza cambiare le semantiche TCP
- anche UDP presenta diversi problemi
- i programmi che usano UDP si aspettano un'alta affidabilità del mezzo trasmissivo, e questo non può accadere con il wireless
- una cospicua perdita di messaggi UDP potrebbe provocare prestazioni davvero scadenti
- Internet possiede due protocolli principali nello strato di
trasporto:
- descrizione