In questo e nel prossimo articolo, dedicati ai protocolli del livello di trasporto, ci poniamo come obiettivo quello di capire i principi che sono alla base dei servizi offerti da questo layer, ovvero:

  • Comunicazione tra processi: come fanno due processi su due host diversi a comunicare fra loro,
  • Multiplexing/Demultiplexing,
  • Trasferimento dei dati affidabile: vedremo in che modo è possibile essere sicuro che i dati scambiati sulla rete sono preservati.
  • Controllo di flusso,
  • Controllo di congestione.

Dopo aver descritto questi servizi offerti dal livello di trasporto vedremo i possibili protocolli che li implementano:

  • TCP: Trasporto orientato alla connessione e il suo sistema di controllo congestione,
  • UDP: User Data Protocol, trasporto senza connessione.

Vediamo quindi subito come comunicano i processi

Connessione logica a livello trasporto

I protocolli di trasporto forniscono la comunicazionelogica tra processi applicativi di hostdifferenti, ovvero gli host eseguono i processi come se fossero direttamenteconnessi (anche se in realtà si possono trovare molto distanti fra loro).
I protocolli di trasporto vengono eseguiti nei sistemi terminali:

  • Il lato che invia, incapsula (multiplexing) i messaggi in segmenti e li passa al livello inferiore, di rete.
  • Il lato che riceve, decapsula (demultiplexing) i segmenti in messaggi e li passa al livello applicazione.

Il livello di rete si basa sui servizi del livello di collegamento ed offre il servizio di comunicazione tra host al livello di trasporto che, a sua volta, offre la comunicazione tra processi al livello applicazione (ha senso se vi ricordate la pila tcp/ip).

Il compito dei servizi di trasporto è la consegna process-to-process ovvero tra processi in esecuzione tra sistemi terminali diversi.
Il servizio, può essere:

  • Affidabile, in questo caso la consegna avviane nell’ ordine originario di invio e in questo caso sfruttiamo TCP che inoltre, è caratterizzato da un controllo di congestione, controllo di flusso e setup della connessione.
  • Inffidabile, i pacchetti inviati non sono in relazione fra loro e quindi possono arrivare in qualsiasi ordine. In questo caso si utilizza UDP.

Se state seguendo la serie di articoli sui sistemi operativi, saprete senz’altro che al giorno d’oggi SO sono multiutente e soprattutto multiprocesso. Questo vuol dire che sull’ host locale potrebbero esserci diversi processi client attivi, e analogamente potrebbero esserci diversi processi server in esecuzione sull’ host remoto.
Quindi, per stabilire ua comunicazione tra due dispositivi è necessario conoscere:

  • Host locale,
  • Host remoto,
  • Processo locale,
  • Processo remoto.

Dove con Host intendiamo l’ indirizzo ip, e con processo il numero di porta sulla quale gira.
La coppia di elementi host+processo, identifica un indirizzo socket (socket address).

Multiplexing/Demultiplexing

Quando sull’host mittente il livello di trasporto deve raccogliere i dati in uscita dalle socket e passarli a livello rete, le incapsula con un’intestazione usata dal demultiplexing e li spedisce ai rispettivi destinatari eseguendo un’azione di multiplexing.

Dall’ altro lato, quando il livello di trasporto dell’ host riceve i dati dal livello di rete sottostante, deve indirizzare i dati a uno dei processi del livello di applicazione: per farlo legge l’header aggiunto durante il multiplexing.

Nel caso del trasporto senza connessione (UDP) l’host che riceve il segmento UDP controlla il numero della porta di destinazione delsegmento e invia il segmento UDP alla socket con quel numero di porta. Inoltre, la socket UDP è caratterizzata da l’ indirizzo IP di destinazione e il numero di porta di destinazione.

Nel caso invece del trasporto con connessione (TCP), la sua socket è identificata da: indirizzo IP di origine, numero di porta di origine, indirizzo IP di destinazione, numero di porta di destinazione.
Un host server supporta più socket tcp contemporanee essendo ogni socket identificata dai 4 parametri: in ogni ccaso comunque vengono create socket differenti per ogni connessione client.

Controllo di flusso

Quando un’entità produce dati che un’altra entità deve consumare, deve esitere un equilibrio fra la velocità di produzione e velocità di consumo dei dati.
A volte infatti può succedere che:

  • Se velocità di produzione > velocità di consumo: Il consumatore potrebbe essere sovraccaricato e costretto a eliminare alcuni.
  • Se velocità di produzione < velocità di consumo: Il consumatore rimane in attesa riducendo l’efficenza del sistema.

Ed è per cercare di bilanciare la prima situazione che si utilizza il controllo di flusso: questo perchè una perdita di dati è inaccettabile.

Come facciamo quindi a realizzare un controllo di flusso?
Utilizziamo un Buffer: un buffer è un’insieme di locazioni di memoria che possono contenere pacchetti.

  • Il livello di trasporto del mittente, segnala al livello dell’ applicazione di sospende l’ invio dei messaggi quando ha il buffer saturo. Non appena si libera spazio nel buffer, segnalerà al livello applicativo di riprendere l’ invio di messaggi.
  • Il livello di trasporto del destinatario, a sua volta, può richiedere al mittente di sospendere l’ invio di messaggi quando ha il buffer saturo. Anche in questo caso, appena liberato dello spazio nel buffer verrà segnalato al mittente di riprendere l’invio di messaggi.

transport

Controllo degli errori

Per implementare un controllo sugli errori, visto che il livello di rete è inaffidabile, dobbiamo implementarlo a livello di trasporto.
Per avere un servizio di trasporto affidabile è necessario implementare un controllo degli errori che ha il compito di:

  • Rilevare e scartare i pacchetti corrotti,
  • Tenere traccia dei pacchetti persi e ne deve gestire il rinvio,
  • Riconoscere pacchetti duplicati e scartarli,
  • Bufferizzare i pacchtti fuori sequenza finchè arrivano i pacchetti mancanti.

Il destinatario deve sapere in che modo tenere traccia dei pacchetti duplicati o fuori sequenza, e il mittente deve avere un modo per sapere quali pacchetti ritrasmettere.
Per risolvere questo problema, si uilizza un sistema di numerazione dei pacchetti con numeri di sequenza specificati nell’ header del livello di trasporto.
E’ ovviamente un numero sequenziale e poichè deve essere inserito nell’ intestazione del pacchetto, occorre specificarne la dimensione massima.

Se l’ header prevede m bit per il numeri di sequenza, allora questo può assumere valori fra 0 e 2m-1.
Implementando questo numero di sequenza, il destinatario può facilmente capire se i pacchetti arrivano nell’ ordine in cui sono stati spediti, se sono corrotti o duplicati. Ma come può il mittente capire se un pacchetto è andato perso?

Si utilizza il numero di riscontro (acknowledgment, inglese di conferma e chiamato più concisamente ack) permette di notificare al mittente la corretta ricezione di un pacchetto.

Integrare il controllo degli errori col controllo di flusso

Come abbiamo visto, il controllo di flusso richiede due buffer. Il controllo degli errori richiede un numero di sequenza e un ack.
Combinando i due meccanismi, creiamo un buffer numerato (sia nel mittente che nel destinatario).
Più precisamente, il Mittente:

  1. Prepara un nuovo pacchetto e usa come numero di sequenza (x) il numero della prima locazione libera nel buffer
  2. Quando invia il pacchetto, ne memorizza una copia in locazione x e quando riceve l’ack del pacchetto, ne libera lo spazio da lui occupato.

Il Destinatario:

  1. Quando riceve un pacchetto con numero di sequenza y, lo memorizza in locazione y finquando lo strato applicativo è pronto a riceverlo. Inviato il pacchetto al livello superiore, lo elimina dal buffer ed invia un ack al mittente.

Controllo della congestione

Nelle reti a commutazone di pacchetto, la congestione avviene se il carico della rete è superiore alla capacità della rete. Con il controllo della congestione, implementiamo un meccanismo che permette di controllare e mantenere il carico della rete sotto alle sue capacità.
Se vi ricordate com’è fatto un router, allora ricorderete sicuramente che genera dei ritardi dovuti al tempo necessario a elaborare ed inviare i pacchetti.

Servizi del livello di trasporto: Connection-oriented (TCP)

E’ un servizio end-to-end in cui viene stabilita una connessione logica prima di scambiarsi i dati. E’ possibile implementare il controllo di flusso, controllo degli errori e il controllo della congestione.

Servizi del livello di trasporto: Connection-less(UDP)

Il mittente divide i suoi messaggi in porzioni di dimensioni accettabili dal livello di trasporto a cui conseglarli uno per uno.
Ogni pacchetto, come già abbiamo detto è indipendente dagli altri: la sequenza di arrivo può infatti essere diversa da quella di spedizione.
Non c’è infine, a differenza del servizio connection-oriented, nessuna coordinazione tra livello di trasporto mittente e destinataro.