Rete di Calcolatori e Internet PDF

Document Details

AgileOrientalism7007

Uploaded by AgileOrientalism7007

Università degli Studi di Catania

Tags

reti di calcolatori internet protocollo informatica

Summary

Questo documento riassume concetti fondamentali sulle reti di calcolatori e su Internet. Vengono descritti gli elementi hardware e software di base, le infrastrutture di rete e i protocolli utilizzati. Il testo evidenzia le connessioni tra reti di accesso, mezzi trasmissivi e la commutazione di pacchetto.

Full Transcript

RETI DI CALCOLATORI E INTERNET Che cos’è Internet? Esistono un paio di risposte a questa domanda. La prima è descrivere gli ingranaggi di Internet, ossia i componenti di base hardware e software che lo compongono. Un altro modo consiste nel descrivere Internet in termini di infrastrutture di rete ch...

RETI DI CALCOLATORI E INTERNET Che cos’è Internet? Esistono un paio di risposte a questa domanda. La prima è descrivere gli ingranaggi di Internet, ossia i componenti di base hardware e software che lo compongono. Un altro modo consiste nel descrivere Internet in termini di infrastrutture di rete che forniscono servizi ad applicazioni distribuite. Internet è una rete di calcolatori che interconnette centinaia di milioni di dispositivi di calcolo in tutto il mondo. In gergo, tutti questi dispositivi sono detti host (ospiti) o sistemi periferici (end system). I sistemi periferici sono connessi tra loro tramite una rete di collegamenti e commutatori di pacchetti. Collegamenti diversi possono trasmettere dati a velocità differenti, tale velocità di trasmissione (trasmission rate) viene misurata in bit/secondo (bps). Quando un sistema periferico vuole inviare dati a un altro sistema periferico, suddivide i dati in sottoparti e aggiunge un’intestazione a ciascuna di esse: l’insieme delle informazioni risultati viene chiamato pacchetto. I pacchetti sono inviati attraverso la rete alla destinazione, dove vengono riassemblati per ottenere i dati originari. Un commutatore di pacchetto prende un pacchetto che arriva e lo ritrasmette su uno di quelli di uscita. Esistono commutatori di pacchetto di varia forma e natura, ma i due principali nell’odierna Internet sono i router e i commutatori a livello di collegamento. I sistemi periferici accedono a Internet tramite i cosiddetti Internet service provider (ISP) che comprendono ISP residenziali quali le compagnie telefoniche, IPS aziendali, IPS universitari e ISP che forniscono accesso al Wi-Fi. Sistemi periferici, commutatori e altre parti di Internet fanno uso di protocolli che controllano l’invio e la ricezione di informazioni all’interno della rete. Due dei principali protocolli Internet sono il transmission control protocol (TCP), e l’Internet protocol (IP). Quest’ultimo specifica il formato dei pacchetti scambiati tra router e sistemi periferici. I principali protocolli Internet sono noti con il nome di TCP/IP. Data la loro importanza per Internet, un accordo sulle funzioni svolte da ogni singolo protocollo risulta fondamentale. Ecco dove entrano in gioco gli standard. Gli standard di Internet vengono sviluppati dalla IETF (Internet Engineering Task Force), i documenti degli standard di Internet vengono detti request for comment (RFC). Possiamo inoltre descrivere Internet da un punto completamente differente, cioè come un’infrastruttura che fornisce servizi alle applicazioni. Tali applicazioni includono posta elettronica, navigazione nel Web e molte altre. Queste applicazioni sono dette applicazioni distribuite, in quanto coinvolgono più sistemi periferici che si scambiano reciprocamente dati. Protocollo Una semplice analogia si può fare con la comunicazione umana. Dove la conversazione inizia con un saluto e successivamente prosegue con una domanda da parte dell’interlocutore che riceverà una risposta. In modo del tutto analogo funziona la comunicazione attraverso due macchine. Un protocollo definisce il formato e l’ordine dei messaggi scambiati tra due o più entità in comunicazione, così come le azioni intraprese in fase di trasmissione e/o di ricezione di un messaggio o di un altro evento. Internet fa un uso estensivo di protocolli. Le reti di accesso Andiamo ad esaminare le reti di accesso (access network), cioè la rete che connette fisicamente un sistema al suo edge router (router di bordo), che è il primo router sul percorso dal sistema d’origine a un qualsiasi altro sistema di destinazione collocato al di fuori della stessa rete di accesso. Accesso residenziale: I due accessi residenziali a larga banda più diffusi sono il digital subscriber line (DSL) e quello via cavo. Un accesso residenziale a Internet di tipo DSL viene generalmente fornito dalla stessa compagnia telefonica che fornisce anche il servizio di telefonia fissa. In questo modo, in presenza di un accesso DSL, la compagnia telefonica assume anche il ruolo di ISP. Il modem DSL dell’utente usa la linea telefonica esistente (doppino telefonico intrecciato in rame) per scambiare dati con un digital subscriber line access multiplex (DSLAM) che si trova nella centrale locale della compagnia telefonica. Il modem DLS residenziale converte i dati digitali in toni ad alta frequenza per poterli trasmettere alla centrale locale sul cavo telefonico; tutti i segnali analogici in arrivo dalle abitazioni vengono riconvertiti in formato digitale nel DSLAM. Le linee telefoniche residenziali trasportano contemporaneamente dati e segnali telefonici codificandoli in tre bande di frequenza non sovrapposte: Un canale di downstream (verso l’abitazione) ad alta velocità, nella banda tra 50kHz e 1 MHz. Un canale di upstream (verso il DSLAM) a velocità media, nella banda tra 4 e 50kHz ed un canale telefoni ordinario a due vie, nella banda tra 0 e 4kHz. Tale approccio fa apparire un singolo collegamento DSL come tre collegamenti separati, in modo che una chiamata telefonica, e una connessione a Internet possano contemporaneamente condividere lo stesso collegamento DSL. Mentre la DSL usa le infrastrutture già esistenti l’acceso a Internet via cavo utilizza le infrastrutture esistenti dalla televisione via caso. Accesso aziendale (e residenziale): Ethernet e Wi-Fi: Per collegare i sistemi periferici al router di bordo si utilizza una rete locale (LAN, local area network). In una LAN wireless gli utenti trasmettono e ricevono pacchetti da e verso un access point wireless (detto anche base station). Accesso wireless su scala geografica 3G e LTE: A differenza del Wi-Fi, l’utente può trovarsi a decine di chilometri dalla stazione base, invece che a pochi metri. Mezzi trasmissivi Il mezzo fisico può presentarsi in diverse forme e dimensioni e non deve necessariamente essere dello stesso tipo per ogni coppia trasmettitore-ricevitore lungo il percorso. I mezzi fisici ricadono in due categorie: i mezzi vincolati e quelli non vincolati. Nei primi, le onde vengono contenute in un mezzo fisico, quale un cavo in fibra ottica, un filo di rame o un cavo coassiale. Nei secondi, le onde si propagano nell’atmosfera e nello spazio esterno. Il costo effettivo di un collegamento fisico è spesso inferiore rispetto ad altri costi delle reti. In particolare, il costo del lavoro associato all’installazione del collegamento fisico può superare di vari ordini di grandezza quello del materiale. Doppino di rame intrecciato: Il mezzo trasmissivo vincolato meno costoso e più utilizzato è il doppino di rame intrecciato. E’ costituito da due fili di rame distinti, ciascuno spesso meno di 1mm, disposti a spirale regolare. I fili vengono intrecciati assieme per ridurre l’interferenza elettrica generata da altre coppie presenti nelle vicinanze. Di regola, un certo numero di doppini viene riunito e avvolto in uno schermo protettivo a formare un cavo. Una coppia di fili costituisce un singolo collegamento di comunicazione. Il doppino intrecciato non schermato (UTP) viene comunemente utilizzato per le reti all’interno di un edificio. Cavo coassiale: Costituito da due conduttori di rame, ma questi sono concentrici. Con questa struttura, e grazie a uno speciale isolamento e schermatura, il cavo coassiale può raggiungere alte frequenze di trasmissione. Il cavo coassiale può essere utilizzato come mezzo condiviso vincolato. Più sistemi periferici possono essere connessi direttamente al cavo e tutti ricevono quanto inviato da altri sistemi periferici. Fibra ottica: Mezzo sottile e flessibile che conduce impulsi di luce, ciascuno dei quali rappresenta un bit. Una singola fibra ottica può sopportare enormi velocità trasmissive. Tale mezzo è immune all’interferenza elettromagnetica, presenta attenuazioni di segnale molto bassa nel raggio di 100 chilometri ed è molto difficile da intercettare. Canali radio terrestri: I canali radio trasportano segnali all’interno dello spettro elettromagnetico. E’ in grado di attraversare le pareti, fornisce connettività agli utenti mobili e riesce a trasportare un segnale per lunghe distanze. Le caratteristiche dei canali radio dipendono in modo significativo dall’ambiente di propagazione e dalla distanza alla quale il segnale deve essere inviato. L’ambiente determina la perdita di segnale lungo il percorso causata dalla distanza, dall’attraversamento di ostacoli, dalla riflessione sulle superfici o dall’interferenza con altri canali radio o segnali elettromagnetici. Canali radio satellitari: Un satellite per le comunicazioni collega due o più trasmettitori terrestri a microonde noti come stazioni terra. Il satellite riceve le trasmissioni su una banda di frequenza, rigenera il segnale utilizzando un ripetitore e trasmette segnali su un’altra frequenza. Nelle comunicazioni si usano due tipi di satelliti: quelli geostazionari e quelli a bassa quota. Commutazione di pacchetto Per eseguire compiti le applicazioni distribuite scambiano messaggi. Possono contenere qualunque cosa il progettista del protocollo desideri. La sorgente suddivide i messaggi lunghi in parti più piccole note come pacchetti. Tra la sorgente e la destinazione, questi pacchetti viaggiano attraverso collegamenti e commutatori di pacchetto. I pacchetti vengono trasmessi su ciascun collegamento a una velocità pari alla velocità totale di trasmissione del collegamento stesso. Quindi, se un sistema periferico o un commutatore inviano un pacchetto di L bit su un canale con velocità di R bps, il tempo di trasmissione risulta pari a L/R secondi. La maggior parte dei commutatori di pacchetto utilizza la trasmissione store-and-forward. Ciò significa che il commutatore deve ricevere l’intero pacchetto prima di poterne cominciare a trasmettere sul collegamento in uscita il primo bit. Il pacchetto viene ricevuto e verificato, e solo allora viene inoltrato al nodo successivo; ciò implica quindi lo svantaggio che se tra due singoli nodi vi è un ritardo, questo verrà moltiplicato per tutti i nodi che l'informazione dovrà attraversare per giungere a destinazione. Allo stesso tempo, lo store and forward è alla base del funzionamento delle reti a commutazione di pacchetto e consente di raggiungere un'elevata utilizzazione delle risorse di rete, traendo massimo vantaggio dalla multiplazione statistica dei dati. Ogni commutatore di pacchetto connette più collegamenti. Per ciascuno di questi, il commutatore mantiene un buffer di output per conservare i pacchetti che sta per inviare sul quel collegamento. I buffer di output rivestono un ruolo chiave nella commutazione di pacchetto. Se un pacchetto in arrivo richiede l’invio attraverso un collegamento, ma lo trova occupato dalla trasmissione di un altro, quello in arrivo deve attendere nella coda di output. Di conseguenza, oltre ai ritardi store- and-forward, i pacchetti subiscono anche i ritardi di accordamento nei buffer di output. Tali ritardi sono variabili e dipendono dal livello di traffico nella rete. Dato che la dimensione del buffer è finita, un pacchetto in arrivo può trovare il buffer completamente riempito da altri pacchetti che attendono la trasmissione. In questo caso si verificherà una perdita di pacchetto, verrà eliminato o il pacchetto in arrivo o uno di quelli che si trova già in coda. Ogni sistema periferico ha un indirizzo chiamato indirizzo IP. Ogni pacchetto che percorre la rete contiene nella propria intestazione l’indirizzo della sua destinazione che presenta una struttura gerarchica. Quando un pacchetto giunge a un router nella rete, quest’ultimo esamina una parte dell’indirizzo di destinazione o lo inoltra a un router adiacente. Più specificamente, ogni router ha una tabella di inoltro (forwarding table) che mette in relazione gli indirizzi di destinazione con i collegamenti in uscita. Troviamo la presenza di protocolli di instradamento (routing protocol) specifici che si usano per impostare automaticamente le tabella di inoltro. Commutazione di circuito Oltre alla presenza dei commutatori di pacchetto troviamo anche la presenza dei commutatori di circuito in cui le risorse richieste lungo un percorso per consentire la comunicazione tra sistemi periferici sono riservate per l’intera durata della sessione di comunicazione, a differenza di quella di pacchetto. Le reti telefoniche sono esempi di reti a commutazione di circuito. Nella figura adiacente ne è rappresentata la forma. Gli host sono tutti direttamente connessi a uno dei commutatori. Quando due host desiderano comunicare la rete stabilisce una connessione end-to-end (o connessione punto a punto) dedicata a loro. Confronto tra commutazione di pacchetto e di circuito I sostenitori della commutazione a circuito ritengono inadatta la commutazione di pacchetto per i servizi in tempo reale a causa dei suoi ritardi end-to-end variabili e non determinabili a priori. I sostenitori della commutazione di pacchetto rispondono che non solo essa offre un maggior utilizzo della lunghezza di banda ma che è anche più semplice. La commutazione di pacchetto risulta più vantaggiosa in quanto: Si possono avere più utenti collegati Se vi è un solo utente attivo che deve trasferire molti pacchetti impiegherà molto meno tempo in quella a pacchetto in quanto non deve dividere la velocità con nessuno. Una rete di reti Nel corso degli anni la rete di reti che forma Internet si è evoluta in una struttura altamente complessa. Per la maggior parte questa evoluzione è stata pilotata da fattori economici e politici più che delle prestazioni. Per comprendere la struttura di rete dell’Internet odierna costruiamo ora una sequenza incrementale di strutture di rete in cui ogni nuova struttura ne sia un’approssimazione migliore. Struttura di rete 1: Interconnette tutti gli IPS di accesso con un unico ISP globale di transito. Il nostro ISP globale di transito è una rete di router e collegamenti che non solo copre l’intero globo, ma anche almeno un router prossimo a ognuna delle centinaia di migliaia di IPS di accesso. Naturalmente sarebbe molto costoso per l’ISP globale costruire una rete così estesa. Per averne un profitto dovrebbe far pagare la connettività a ognuno degli ISP di accesso, a un prezzo che rifletta la quantità di traffico che l’ISP di accesso scambia con quello globale. Poiché l’ISP di accesso paga quello globale allora è detto cliente, invece quello globale prende il nome di fornitore. Se tuttavia un’azienda costruisse e gestisse un ISP globale che si rilevasse vantaggioso, allora altre aziende si costruirebbero il proprio ISP globale di transito e si metterebbero in competizione con quello originario. Passiamo alla struttura di rete 2. Struttura di rete 2: Gli ISP di accesso connessi a uno dei provider globali di transito non potrebbero comunicare con un ISP di accesso connesso a un altro provider globale di transito. Nella realtà, sebbene alcuni ISP abbiano una copertura globale impressionante, nessun ISP è presente in ogni città al mondo. Al contrario in ogni regione può esservi un ISP regionale al quale tutti gli ISP di accesso della regione si connettono. Ogni ISP regionale si connette all’ISP di primo livello. Un ISP di accesso può anche connettersi direttamente a un ISP di primo livello e in tal caso lo paga direttamente. Quindi c’è una relazione cliente-fornitore a ogni livello della gerarchia. Tale gerarchia a molti livelli ci fa passare alla struttura di rete 3. Struttura di rete 3/4: Andiamo ad aggiungere i PoP (point of presence) i quali esistono in tutti i livelli della gerarchia tranne che in quello degli ISP di accesso. Un PoP è un gruppo di router vicini tra loro nella rete del provider, tramite il quale gli ISP clienti possono connettersi al fornitore. Qualsiasi ISP, tranne quelli di primo livello, può scegliere la modalità multi-home che consiste nel connettersi a uno o più ISP fornitori. Per ridurre i costi, una coppia di ISP vicini e di pari livello gerarchico può fare uso di peering, cioè connettere direttamente le loro reti in modo che tutto il traffico tra di esse passi attraverso una connessione diretta piuttosto che transitare da un intermediario. In questa modalità nessun ISP effettua pagamenti all’altro. Utilizzando queste connessioni un’azienda può creare un IXP (Internet exchange point), un punto d’incontro dove più ISP possono fare peering tra di loro. Struttura di rete 5: Infine ci basta aggiungere i content provider networks per giungere ad una rappresentazione come mostrato in figura. Ritardi, perdite e throughput nelle reti a commutazione di pacchetto Un pacchetto parte da un host, passa attraverso una serie di router e conclude il viaggio in un altro host. A ogni tappa, il pacchetto subisce vari tipi di ritardo a ciascun nodo del tragitto. I principali tipi di ritardo sono il ritardo di elaborazione, il ritardo di accodamento, il ritardo di trasmissione e il ritardo di propagazione, che complessivamente formano il ritardo totale di nodo. Ritardo di elaborazione: Il tempo richiesto per esaminare l’intestazione del pacchetto e per determinare dove dirigerlo fa parte di tale ritardo. Questo può anche includere altri fattori, tra i quali il tempo richiesto per controllare errori a livello di bit. Ritardo di accodamento: Una volta in coda, il pacchetto subisce tale ritardo mentre attende la trasmissione sul collegamento. La lunghezza per uno specifico pacchetto dipenderà dal numero di pacchetti precedentemente arrivati, accordati e in attesa di trasmissione. Se la coda è vuota e non è in corso la trasmissione di altri pacchetti, allora il ritardo di accodamento per il nostro pacchetto sarà nullo. Ritardo di trasmissione: Assumendo che i pacchetti siano trasmessi secondo la politica FIFO il nostro pacchetto può essere trasmetto solo dopo la trasmissione di tutti quelli che lo hanno preceduto nell’arrivo. Sia L la lunghezza del pacchetto, in bit, e R bps la velocità di trasmissione del collegamento dal router A al router B. Tale ritardo risulta essere L/R. Questo è il tempo richiesto per trasmettere tutti i bit del pacchetto sul collegamento. Non ha nulla a che fare con la distanza tra i due router. Ritardo di propagazione: Una volta immesso sul collegamento un bit deve propagarsi fino al router B. Il tempo impiegato è tale ritardo. Il bit viaggia alla velocità di propagazione del collegamento, che dipende dal mezzo fisico. Non ha nulla a che fare con la lunghezza del pacchetto. Ritardo di accodamento e perdita di pacchetti A differenza degli altri ritardi esso può variare da pacchetto a pacchetto. Il ritardo di accodamento può essere trascurato a seconda della velocità di trasmissione del collegamento e dalla natura del traffico entrante, ossia se il traffico arriva periodicamente o a raffiche. Denotiamo con a la velocità media di arrivo dei pacchetti nella coda, espressa in pacchetti al secondo. Il rapporto La/R, detto intensità di traffico, spesso gioca un importante ruolo nella stima dell’entità del ritardo di accodamento. Se La/R > 1 allora la velocità media di arrivo dei bit nella coda supera la velocità alla quale i bit vengono ritrasmessi in uscita da essa; in tale situazione la coda tenderà a crescere senza limiti e il ritardo di coda tenderò all’infinito. Il traffico non deve superare 1. Se La/R ≤ 1 La natura del traffico in arrivo influisce sul ritardo di coda. Se i pacchetti arrivano a cadenza periodica, allora ciascun pacchetto troverà una coda vuota e non ci saranno ritardi. Se invece i pacchetti arrivano a raffiche periodiche, si possono verificare dei significati ritardi di coda. Quando l’intensità di traffico è vicina a 1, si riscontrano intervalli di tempo in cui la velocità di arrivo supera la capacità trasmissiva e si forma una coda e altri in cui la capacità trasmissiva è inferiore e quindi la coda si riduce. Ciò nonostante, quando l’intensità di traffico si avvicina a 1, la lunghezza media della coda aumentare sempre di più. Le code hanno una capacità finita, sebbene la capacità di accodamento dipendono fortemente dalla struttura del router e dal suo costo. Poiché la capacità delle code è finita, i ritardi dei pacchetti non tendono all’infinto quando l’intensità di traffico si approssima a 1, ma un pacchetto può trovare la coda piena. Non essendo possibile memorizzare il pacchetto, il router lo eliminerà e il pacchetto andrà perduto. Tale fenomeno è detto anche buffer overflow. Dal punto di vista dei sistemi periferici, la perdita sembrerà come se il pacchetto fosse stato inviato in rete ma non fosse più riemerso alla destinazione. La frazione di pacchetti perduti aumenta in proporzione all’intensità di traffico. Quindi, le prestazioni di un nodo sono spesso misurate non solo in termini di ritardo, ma anche sulla base della probabilità di perdita di pacchetti. Ritardo end-to-end Vediamo adesso il ritardo che si ha tra il sorgente e la destinazione. Supponiamo l’esistenza di N-1 router tra l’host sorgente e quello di destinazione. Ipotizziamo inoltre che la rete non sia congestionata e che il ritardo di elaborazione a ciascun router e presso il mittente sia di d elab , la velocità di trasmissione in uscita a ogni router e all’host sorgente sia di R bps e la propagazione su ciascun collegamento sia d prop. I ritardi si accumulano in: d end-to-end = N(d elab + d trans + d prop ) Throughput nelle reti di calcolatori Un’altra misura critica è il throughput end-to-end. Consideriamo il trasferimento di un file voluminoso da A ad B, attraverso la rete. Il throughput istantaneo in ogni istante di tempo è la velocità (in bps) alla quale B sta ricevendo il file; Se il file consiste di F bit e il trasferimento richiede T secondi affinché B riceva tutti gli F bit, allora il throughput medio del trasferimento del file è di F/T bps. Sia R s la velocità del collegamento tra il server e il router R c quella del collegamento tra il router e il client. SI supponga che i soli bit inviati sull’intera rete siano quelli tra il server e il client. Se R s < R c allora i bit immessi dal server scorreranno attraverso il router e arriveranno al client a una velocità di R s bps, dando un throughput di R s. Se, dall’altro lato, R c < R s allora il router non sarà in grado di inoltrare i bit alla stessa velocità alla quale li riceve. In tal caso, i bit lasceranno il router a una velocità R c dando un throughput di R c. Quindi per questa semplice rete con due collegamenti, il throughput è il min(R c , R s ), cioè la velocità di trasmissione del collegamento che fa da collo di bottiglia (bottleneck). Architettura a livelli I protocolli sono organizzati in livelli o strati (layer). Ciascun protocollo appartiene a uno dei livelli. Un livello di protocolli può essere implementato via software, hardware o con una combinazione dei due. La stratificazione dei protocolli presenta vantaggi concettuali e strutturali. Fornisce un modo strutturato per trattare i componenti dei sistemi. La modularità rende più facile aggiornare la componentistica. Un eventuale svantaggio legato alla stratificazione è la possibilità che un livello duplichi le funzionalità di quello inferiore. Considerati assieme, i protocolli dei vari livelli sono detti pila di protocolli (protocol stack). La pila di protocolli di Internet consiste di cinque livelli: fisico, collegamento, rete, trasporto e applicazione. Livello applicazione: E’ la sede della applicazioni di rete e dei relativi protocolli. I protocolli più importanti sono HTTP, SMTP e FTP. Un protocollo a livello di applicazione è distribuito su più sistemi periferici i quali grazie ad esso possono scambiare pacchetti di informazioni con l’applicazione di un altro sistema periferico; tali pacchetti prendono il nome di messaggi. Livello di trasporto: Trasferisce i messaggi dal livello di applicazione. Abbiamo due protocolli su Internet: TCP e UDP. I pacchetti a livello di trasporto prendono il nome di segmenti. Livello di rete: Il livello di rete si occupa di trasferire i pacchetti a livello di rete, detti datagrammi, da un host a un altro. Mette a disposizione il servizio di consegna del segmento al livello di trasporto nell’host di destinazione. Il protocollo più importante è IP. Livello di collegamento: Trasferisce un pacchetto da un nodo a quello successivo sul percorso. I servizi forniti dipendono dallo specifico protocollo. In questo livello i pacchetti prendono il nome di frame. Livello fisico: Trasferisce i singoli bit del frame da un nodo a quello successivo. I protocolli di questo livello sono ancora dipendenti dal collegamento e in più dipendono dall’effettivo mezzo trasmissivo. La figura (b.) raffigura il Modello OSI. Negli anni 70 l’ISO propose che le reti di calcolatori fossero organizzate in sette livelli, chiamati modello open system interconnection (OSI). Il ruolo del livello di presentazione è fornire servizi che consentano ad applicazioni che vogliono comunicare di interpretare il significato dei dati scambiati (cifratura e compressione dei dati). Il livello di sessione fornisce la delimitazione e la sincronizzazione dello scambio di dati, compresi, i mezzi per costruire uno schema di controllo e di recupero degli stessi. Incapsulamento Preso un host mittente, un messaggio a livello di applicazione M viene passato a livello di trasporto. Nel caso più semplice, questo livello prende il messaggio e gli concatena informazioni aggiuntive che saranno utilizzate dalla parte ricevente del livello di trasporto. Il messaggio a livello di applicazione e le informazioni di intestazione a livello di trasporto costituiscono il segmento a livello di trasporto che incapsula il messaggio a livello di applicazioni. Le informazioni aggiunte potrebbero includere dati che consento al livello di trasporto lato ricevente di conoscere il messaggio all’applicazione desiderata, o potrebbero includere bit per il rilevamento degli errori che consentono al ricevente di determinare l’eventuale cambiamento di alcuni bit del messaggio durante il percorso. Il livello di trasporto passa il segmento al livello di rete, che aggiunge informazioni di intestazione proprie del livello di rete, quali gli indirizzi dei sistemi periferici di sorgente e di destinazione, andando così a creare un datagramma da livello di rete. A questo punto, il datagramma viene passato al livello di collegamento, il quale aggiunge le proprie informazioni di intestazione creando un frame a livello di collegamento. Quindi, a ciascun livello, il pacchetto ha due tipi di campi: quello di intestazione e quello di payload (il carico utile trasportato). Il payload è tipicamente un pacchetto proveniente dal livello superiore. Reti sotto attacco Un'ampia classe di minacce alla sicurezza può essere classificata come attacchi di negazione del servizio (DoS, denial-of-service). Come suggerisce il nome, un attacco DoS rende inutilizzabile dagli utenti legittimi una rete, un host o un'altra parte di infrastruttura. Web server di posta elettronica, DNS e reti istituzionali possono essere tutti soggetti ad attacchi DoS. Gli attacchi DoS Internet sono estremamente comuni e se ne verificano a migliaia ogni anno. Molti attacchi DoS su Internet ricadono all'interno di tre categorie. Attacchi alla vulnerabilità dei sistemi: Questo comporta l'invio di pochi messaggi, ben costruiti, a un'applicazione vulnerabile o a un sistema operativo in esecuzione sull'host bersaglio. Se viene inviata la sequenza corretta di pacchetti il servizio può fermarsi o, ancora peggio, l'host può spegnersi. Bandwidth flooding (inondazione di banda): L'attaccante invia un "diluvio" di pacchetti all'host bersaglio, così tanti che il suo collegamento di accesso viene ostruito, impedendo ai pacchetti legittimi di raggiungere il server. Connection flooding (inondazione di connessioni): L'attaccante stabilisce un gran numero di connessioni TCP completamente o solo parzialmente aperte all'host bersaglio. L'host può così "ingorgarsi" con queste connessioni senza poter accettare le connessioni valide. Analizzando la bandwidth flooding vediamo che se il server ha una velocità di accesso R bps, l’attaccante dovrà mandare dati a una velocità approssimabile ad R per fare danni. Un solo computer può non essere sufficiente o essere bloccato. Per questo negli attacchi DoS distribuiti (DDoS) l’attaccante controlla più sorgenti. Un rilevatore passivo in prossimità di un trasmettitore wireless può ottenere una copia di ogni pacchetto trasmetto. Tali pacchetti possono contenere password, tale processo è detto packet sniffer. Dato che i packet sniffer sono passivi, cioè non immettono pacchetti sul canale, sono difficili da individuare; la migliore difesa in tal caso è la crittografia. La capacità di mettere pacchetti in Internet con un indirizzo sorgente falso è nota come IP spoofing, ed è uno dei molti modi attraverso cui un utente può spacciarsi per un altro. Per risolvere tale problema abbiamo bisogno di autentificare il punto terminare della comunicazione, cioè un meccanismo che ci permetta di determinare con certezza se il messaggio ha avuto origine da dove supponiamo l’abbia avuta. Internet è stata originalmente progettata proprio così, basata sul modello “gruppo di utenti mutamente fidati e collegati da una rete trasparente”. LIVELLO DI APPLICAZIONE Per lo sviluppatore l’architettura di rete è fissata e fornisce alle applicazioni uno specifico insieme di servizi; il suo compito è progettare l’architettura dell’applicazione e stabilire la sua organizzazione sui vari sistemi periferici. Nella scelta lo sviluppatore si baserà probabilmente su una delle due principali architettura attualmente utilizzate: l’architettura client-server o P2P. Nell’architettura client-server vi è un host sempre attivo, chiamato server, che risponde alle richieste di servizio di molti altri host, detti client. Un esempio classico è rappresentato dall’applicazione web, in cui web server, sempre attivo, risponde alle richieste dei browser in funzione sui client. Spesso in un’applicazione client-server un singolo host che esegue un server non è in grado di rispondere a tutte le richieste dei suoi client; per questo motivo nella architetture client-server si usano i data center, che ospitano molti host, per creare un potente server virtuale. In un’architettura P2P l’infrastruttura di server in data center è minima o del tutto assente; si sfrutta la comunicazione diretta tra coppie arbitrarie di host, chiamati peer (ossia pari), collegati in modo intermittente. I peer non appartengono a un fornitore di servizi, ma sono computer fissi e portatili, controllati dagli utenti, che per la maggior parte si trovano nelle abitazioni. Dato che i peer comunicano senza passare attraverso un server specializzato, l’architettura viene detta peer-to-peer. Questa architettura comprende la condivisione di file, sistemi per aumentare le prestazioni nel trasferimento di file, la telefonia su Internet. Uno dei punti di forza dell’architettura P2P è la sua intrinseca scalabilità e sono economicamente convenienti perché normalmente non richiedono per i server né una significativa infrastruttura né una disponibilità di banda elevata. Tuttavia, in futuro le applicazioni P2P dovranno affrontare tre grandi sfide. Migliore convivenza con gli ISP: molti ISP residenziali hanno dimensionato l’uso dell’ampiezza di banda favorendo il downstream rispetto all’upstream. Ma le applicazioni P2P di streaming video e distribuzione di file spostano il traffico di upstream dai server agli IPS residenziali, mettendoli in difficoltà. Sicurezza: a causa della loro natura fortemente distribuita e aperta le applicazioni P2P possono rappresentare una sfida per la sicurezza. Incentivazione: in futuro il successo della applicazioni P2P dipenderà anche dall’abilità di convincere gli utenti a fornire banda, memoria e capacità di calcolo alle applicazioni. Processi comunicanti I processi su due sistemi terminali comunicano scambiandosi messaggi attraverso la rete: il processo mittente crea e invia messaggi nella rete e il processo destinatario li riceve e, quando previsto, invia messaggi di risposta. Per ciascuna coppia di processi comunicanti, generalmente ne etichettiamo uno come client e l’altro come server. Nel Web, il browser rappresenta un processo client, mentre il web server è un processo server. Nel contesto di una sessione di comunicazione tra una coppia di processi quello che avvia la comunicazione (cioè, contatta l’altro processo all’inizio della sessione) è indicato come client mentre quello che attende di essere contattato per iniziare la sessione è detto server. Ogni messaggio inviato da un processo a un altro deve passare attraverso la rete sottostante. Un processo invia messaggi nella rete e riceve un messaggio dalla rete attraverso un’interfaccia software detta socket. Un processo che vuole inviare un messaggio a un altro processo o a un altro host, fa uscire il messaggio dalla propria porta (socket). Il processo presuppone l’esistenza di un’infrastruttura esterna che trasporterà il messaggio attraverso la rete fino alla porta del processo di destinazione. Quando il messaggio giunge al destinatario, attraverso la porta (socket) del processo ricevente che infine opera sul messaggio. Il progettista può scegliere il protocollo di trasporto e determinare alcuni parametri a livello di trasporto. Dopo aver scelto il protocollo di trasporto, si costruisce l’applicazione usando i servizi del livello di trasporto forniti dal protocollo. In Internet, gli host vengono identificati attraverso i loro indirizzi IP. Oltre a conoscere l’indirizzo dell’host cui è destinato il messaggio, il mittente deve anche identificare il processo destinatario, più specificamente la socket che deve ricevere il dato. Questa informazione è necessaria in quanto sull’host potrebbero essere in esecuzione molte applicazioni di rete. Un numero di porta di destinazione assolve questo compito. Alle applicazioni più note sono stati assegnati numeri di porta specifici: 80 per i web server, 25 per il protocollo SMTP per il server di posta. Servizi di trasporto disponibili per le applicazioni Trasferimento dati affidabile: In una rete di calcolatori i pacchetti possono andare perduti, quindi per supportare applicazioni che non possono permettersi la perdita di pacchetti occorre garantire che i dati inviati siano consegnati corretti e completi. Se un protocollo fornisce questo tipo di servizio di consegna garantita dei dati, si dice che fornisce un trasferimento dati affidabile (realible data transfer). Trasferimento dati non affidabile: Quando un protocollo a livello di trasporto non fornisce trasferimento dati affidabile, i dati inviati dal processo mittente potrebbero non arrivare mai a quello ricevente. Ciò potrebbe essere accettabile per le applicazioni che tollerano le perdite (loss-tolerant), in particolare le applicazioni multimediali audio/video. Throughput Tasso al quale il processo mittente può inviare i bit al processo ricevente. Dato che altre sessioni condivideranno la banda sul percorso di rete e poiché queste sessioni verranno istituite e rilasciate dinamicamente, il throughput disponibile può fluttuare nel tempo, a livello di trasporto ne può garantire una disponibilità. Con tale servizio l’applicazione può richiedere un throughput disponibile garantito. Le applicazioni che hanno requisiti di throughput vengono dette applicazioni sensibili alla banda; mentre le applicazioni elastiche possono farne di tanto o di poco uso, a seconda di quanto ce ne sia a disposizione. Temporizzazione Un protocolo a livello di trasporto può anche fornire garanzie di temporizzazione che possono assumere varie forme. Per esempio, la garanzia potrebbe essere che ogni bit che il mittente invia sulla socket venga ricevuto dalla socket di destinazione non più di 100 millisecondi più tardi. Sicurezza Un protocollo a livello di trasporto può fornire a un’applicazione uno o più servizi di sicurezza. Ad esempio il protocollo di trasporto può decifrare i dati prima di consegnarli al processo ricevente. Servizi TCP TCP prevede un servizio orientato alla connessione e il trasporto affidabile dei dati. Quando un’applicazione invoca TCP come protocollo di trasporto, riceve entrambi questi servizi. Servizio orientato alla connessione: TCP fa in modo che client e server si scambino informazioni di controllo a livello di trasporto prima che i messaggi a livello di applicazione comincino a fluire. Questa procedura, detta di handshaking, mette in allerta client e server, preparandoli alla partenza dei pacchetti. Dopo la fase di handshaking, si dice che esiste una connessione TCP tra la socket dei due processi. Tale connessione è full-duplex, nel senso che i due processi possono scambiarsi contemporaneamente messaggi sulle connessione. Quando l’applicazione termina l’invio deve chiudere la connessione. Servizio di trasferimento affidabile: I processi comunicanti possono contare su TCP per trasportare i dati senza errori e nel giusto ordine. TCP include anche un meccanismo di controllo della congestione, un servizio che riguarda il benessere generale di Internet e non quello diretto dei processi comunicanti. Servizi UDP UDP è un protocollo di trasporto leggero e senza fronzoli, dotato di un modello di servizi minimalista. UDP è senza connessione, non necessità quindi di handshaking, e fornisce un servizio di trasferimento dati non affidabile. Così, quando un processo invia un messaggio tramite la socket UDP, il protocollo non garantisce che questo raggiunga il processo di destinazione. Inoltre i messaggi potrebbero giungere a destinazione non in ordine. UDP non include un meccanismo di controllo della congestione, pertanto un processo d’invio UDP può spingere i dati al livello sottostante a qualsiasi velocità. Le applicazioni in cui i ritardi relativi sono un fatto critico, non possono funzionare su Internet? La risposta ovviamente è negativa, le applicazioni di questo genere sono state progettate per convivere, nel miglior modo possibile, con l’assenza di garanzie. In conclusione, Internet può, in molti casi, offrire un servizio soddisfacente alle applicazioni con sensibilità ai ritardi, ma non fornisce garanzie sulla temporizzazione o sul throughput disponibile. Molti firewall sono configurati per bloccare la maggior parte del traffico UDP, molte applicazioni di telefonia su Internet sono progettate per utilizzare TCP come operazione di riserva nei casi in cui UDP non sia utilizzabile. Protocolli a livello di applicazione Un protocollo a livello di applicazione definisce come i processi di un’applicazione, in esecuzione su sistemi periferici diversi, si scambiano i messaggi. In particolare, un protocollo a livello di applicazione definisce: I tipi di messaggi scambiati (per esempio, di richiesta o di risposta). La sintassi dei vari tipi di messaggio (per esempio, quali sono i campi nel messaggio o come vengono descritti). La semantica dei campi, ossia il significato delle informazioni che contengono Le regole per determinare quando e come un processo invia e risponde ai messaggi. Alcuni protocolli a livello di applicazione vengono specificati negli RFC e sono pertanto di pubblico dominio, un esempio è HTTP (hypertext transfer protocolo). E’ importante distinguere tra applicazioni di rete e protocolli a livello di applicazione. Un protocollo a livello di applicazione è solo una parte di un’applicazione di rete. Web e HTTP HTTP, protocollo a livello di applicazione del Web, definito in RFC, costituisce il cuore del Web. Questo protocollo è implementato in due programmi, client e server, in esecuzione su sistemi periferici diversi che comunicano tra loro scambiandosi messaggi HTTP. Il protocollo definisce sia la struttura dei messaggi sia la modalità con cui client e server si scambiano i messaggi. Una pagina web, detta anche documento, è costituita da oggetti. Un oggetto è semplicemente un file indirizzabile tramite URL. La maggioranza delle pagine web consiste di un file HTML principale e diversi oggetti referenziati da esso. Ogni URL ha due componenti: il nome dell’host del server che ospita l’oggetto e il percorso dell’oggetto. Un browser web implementa il lato client di HTTP. Un web server, che implementa il lato server di HTTP, ospita oggetti web, indirizzabili tramite URL. HTTP definisce in che modo i client web richiedono le pagine ai web server come questi ultimi le trasferiscano. Utilizza TCP come protocollo di trasporto. Il client HTTP per prima cosa inizia una connessione TCP con il server. Una volta stabilita, i processi client e server accedono a TCP attraverso le proprie socket. Il client invia richieste e riceve risposte HTTP tramite la propria interfaccia socket, analogamente il server riceve richieste e invia messaggi di risposta attraverso la propria interfaccia socket. Una volta passata alla socket, questo messaggio non è più in suo possesso ma si trova nelle mani di TCP Questo è uno dei grandi vantaggi di un’architettura organizzata a livelli: HTTP non si deve preoccupare dei dati smarriti o di come TCP recuperi le perdite o riordini i dati all’interno della rete. Dato che i server HTTP non mantengono informazioni sui client, HTTP è classificato come protocollo senza memoria di stato. Connessioni persistenti e non persistenti A seconda dell’applicazione e del suo impiego la serie di richieste potrebbe essere effettuata in sequenza, periodicamente a intervalli regolari o in maniera intermittente. Quando tale interazione client-server ha luogo su TCP, gli sviluppatori dell’applicazione devono prendere una decisione importante: ciascuna coppia richiesta/risposta deve essere inviata su una connessione TCP separata o devono essere inviate sulla stessa connessione TCP? Nel primo approccio si dice che l’applicazione usa connessioni non persistenti, mentre nel secondo caso usa connessioni persistenti. HTTP con connessioni non persistenti Seguiamo passo dopo passo il trasferimento di una pagina web dal server al client. Supponiamo che la pagina consista di un file HTML principale e di 10 immagini JPEG, e che tutti gli undici oggetti risiedano sullo stesso server. 1. Il processo client HTTP inizializza una connessione TCP con il server sulla porta 80, che è la porta di default. Associate alla connessione TCP ci saranno una socket per il client e una per il server 2. Il client HTTP, tramite la propria socket, invia al server un messaggio di richiesta HTTP che include il percorso. 3. Il processo server riceve il messaggio di richiesta attraverso la propria socket associata alla connessione, recupera l’oggetto dalla memoria, lo incapsula in un messaggio di risposta HTTP che viene inviato al client attraverso la socket. 4. Il processo server comunica a TCP di chiudere la connessione. Questo però, non termina la connessione finché non sia certo che il client abbia ricevuto integro il messaggio di risposta. 5. Il client riceve il messaggio di risposta. La connessione TCP termina. Il messaggio indica che l’oggetto incapsulato è un file HTML. Il client estrae il file dal messaggio di risposta, esamina il file HTML e trova i 10 riferimenti a oggetti JPG. 6. Vengono quindi ripetuti i primi quattro passi per ciascuno degli oggetti referenziati. Ogni connessione TCP viene chiusa dopo l’invio dell’oggetto da parte del server, vale a dire che ciascuna trasporta soltanto un messaggio di richiesta e un messaggio di risposta. Alcuni browser di default aprono dalle 5 alle 10 connessioni TCP parallele, e ciascuna di queste gestisce una transazione di richiesta e risposta. Definiamo il round-trip time (RTT), che rappresenta il tempo impiegato da un piccolo pacchetto per viaggiare dal client al server e poi tornare al client. Il RTT include i ritardi di propagazione, di accodamento nei router e nei commutatori intermedi nonché di elaborazione del pacchetto. Una inizializzazione di connessione TCP con il web server comporta un handshake a tre vie: il client invia un piccolo segmento TCP al server, quest’ultimo manda una conferma per mezzo di un piccolo segmento TCP. Infine, il client da anch’esso una conferma di ritorno al server. Le prime due parti richiedono un RTT. Dopo il loro completamento, il client invia un messaggio di richiesta HTTP combinato con la terza parte dell’handshake tramite la connessione TCP. Quando il messaggio di richiesta arriva al server, quest’ultimo inoltra il file HTML sulla connessione TCP. La richiesta-risposta consuma un altro RTT. Pertanto il tempo di risposta totale è approssimativamente di due RTT, più il tempo di trasmissione da parte del server del file HTML. HTTP con connessioni persistenti Le connessioni non persistenti presentano alcuni limiti: il primo è che per ogni oggetto richiesto occorre stabilire e mantenere una nuova connessione. Per ciascuna di queste connessioni si devono allocare buffer e mantenere variabili TCP sia nel client sia nel server. Ciò pone un grave onere sul web server, che può dover servire contemporaneamente richieste provenienti da centinaia di diversi client. In secondo luogo ciascun oggetto subisce un ritardo di consegna di due RTT. Nelle connessioni persistenti il server lascia la connessione TCP aperta dopo l’invio di una risposta, per cui le richieste e le risposte successive tra gli stessi client e server possono essere trasmesse sulla stessa connessione. In generale il server HTTP chiude la connessione quando essa rimane inattiva per un dato lasso di tempo. Formato dei messaggi HTTP Questo descrive un tipico messaggio di richiesta HTTP. Il messaggio è scritto in testo ASCII, in modo che l’utente sia in grado di leggerlo. Consiste di 5 righe ognuna seguita da un carattere di ritorno a capo e un carattere di nuova linea. L’ultima riga è seguita da una coppia di caratteri di ritorno a capo e nuova linea aggiuntivi. In generale, i messaggi di richiesta possono essere costituiti da un numero indefinito di righe, anche una sola. La prima riga è detta riga di richiesta e quelle successive righe di intestazione. La riga di richiesta presenta tre campi, il campo metodo, il campo URL e il campo versione di HTTP. Il campo metodo può assumere diversi valori, tra cui GET, POST, HEAD, PUT e DELETE. La maggior parte dei messaggi di richiesta HTTP usa il metodo GET, adottato quando il browser richiede un oggetto identificato dal campo URL. La riga Host specifica l’host in cui risiede l’oggetto. Includendo Connection: close, il browser sta comunicando al server che non si deve occupare di connessioni persistenti, ma vuole che questi chiuda la connessione dopo aver inviato l’oggetto richiesto. La riga di intestazione User-agent specifica il tipo di browser che sta effettuando la richiesta al server. Dopo i campi appena visti troviamo un corpo (entity body). Quest’ultimo è vuoto nel caso del metodo GET, ma viene utilizzato dal metodo POST. Il metodo HEAD è simile a GET. Quando un server riceve una richiesta con il messaggio HEAD, risponde con un messaggio HTTP, ma tralascia gli oggetti richiesti. Il metodo PUT, frequentemente usato assieme agli strumenti di pubblicazione sul Web, consente agli utenti di inviare un oggetto a un percorso specifico su uno specifico web server. Il metodo DELETE consente invece la cancellazione di un oggetto su un server. Osserviamo la presenza di 3 sezioni: una riga di stato iniziale, sei righe di intestazione e il corpo. Quest’ultimo è il fulcro del messaggio; contiene l’oggetto richiesto. La riga di stato presenta tre campi: la versione del protocollo, un codice di stato e un corrispettivo messaggio di stato. Il server utilizza la riga di intestazione Connection: close per comunicare al client che ha intenzione di chiudere la connessione TCP dopo l’invio del messaggio. La riga Date: indica l’ora e la data di creazione e invio, da parte del server, della risposta HTTP. La riga Server indica che il messaggio è stato generato da un web serve Apache. La riga Last-Modified indica l’instante e la data in cui l’oggetto è stato creato o modificato l’ultima volta. Tale riga è importante per la gestione dell’oggetto nelle cache, sia nel client locale sia in alcun server in rete. La riga di intestazione Content-Lenght contiene il numero di byte dell’oggetto inviato. La riga Content-Type indica la tipologia dell’oggetto nel corpo. Vediamo la presenza di diversi codici di stato il quale indica il risultato della richiesta. 200 OK: la richiesta ha avuto successo e in risposta si invia l’informazione. 301 Moved Permanently: L’oggetto richiesto è stato trasferito in modo permanente; il nuovo URL è specificato nell’intestazione Location: del messaggio di risposta. Il client recupererà automaticamente il nuovo URL. 400 Bad Request: Si tratta di un codice di errore generico che indica che la richiesta non è stata compresa dal server. 404 Not Found: Il documento richiesto non esiste sul server. 505 HTTP Version Not Supported: Il server non dispone della versione di protocollo HTTP richiesta. Interazione utente-server: i cookie In molti casi i web server devono autentificare gli utenti per limitare la navigazione in alcune zone del sito. A tale scopo HTTP adotta i cookie, i quali consentono al server di tener traccia degli utenti. La tecnologia dei cookie presenta quattro componenti. 1. Riga di intestazione del messaggio di risposta HTTP. 2. Riga di intestazione del messaggio di richiesta HTTP. 3. Un file mantenuto sul sistema dell’utente e gestito dal browser. 4. Un database sul sito. I cookie possono essere usati per identificare gli utenti la prima volta che visitano un sito, successivamente il browser passa un’intestazione di cookie al server durante tutte le successive visite al sito, identificando l’utente sul server. I cookie possono anche essere usati per creare un livello di sessione utente al di sopra di HTTP che è privo di stato. Nonostante i cookie siano molto utili sono fonte di controversie: possono essere considerati violazione della privacy dell’utente. Web caching Una web cache, nota anche come proxy server, è un’entità di rete che soddisfa richieste HTTP al posto del web server effettivo. Il proxy ha una propria memoria sul disco (una cache) in cui conserva copie di oggetti usualmente richiesti. Il browser di un utente può essere configurato in modo che tutte le richieste HTTP dell’utente vengano innanzitutto dirette al proxy server. Supponiamo che venga richiesto un dato oggetto. 1. Il browser stabilisce una connessione TCP con il proxy server e invia una richiesta HTTP per l’oggetto specificato. 2. Il proxy controlla la presenza di una copia dell’oggetto memorizzata localmente. Se l’oggetto viene rilevato, il proxy lo inoltra all’interno di un messaggio di risposta HTTP al browser. 3. Se la cache non dispone dell’oggetto, apre una connessione TCP verso il server di origine. Poi, il proxy invia al server una richiesta HTTP per l’oggetto. Una volta ricevuta tale richiesta, il server di origine invia al proxy l’oggetto all’interno di una risposta HTTP. 4. Quando il proxy riceve l’oggetto ne salva una copia nella propria memoria locale e ne inoltra un’altra copia, all’interno di un messaggio di risposta HTTP, al browser. Si noti che il proxy è contemporaneamente server e client. Il web caching si è sviluppato in Internet per due ragioni. Un proxy può ridurre in modo sostanziale i tempi di risposta alle richieste dei client, in particolare se l’ampiezza di banda che costituisce il collo di bottiglia tra il client e il server di origine è molto inferiore rispetto all’ampiezza di banda minima tra client e proxy. I proxy possono ridurre sostanzialmente il traffico sul collegamento di accesso a Internet, con il vantaggio di non dover aumentare l’ampiezza di banda frequentemente e ottenere quindi una riduzione dei costi. Possono ridurre notevolmente il traffico globale del Web in Internet, migliorando le prestazioni di tutte le applicazioni. GET condizionale Sebbene il web caching riduca i tempi di risposta percepiti dall’utente, introduce un nuovo problema: la copia di un oggetto che risiede in cache potrebbe essere scaduta. Fortunatamente HTTP presenta un meccanismo che permette alla cache di verificare se i suoi oggetti sono aggiornati: questo meccanismo è chiamato GET condizionale. Un messaggio di richiesta HTTP viene detto messaggio di GET condizionale se usa il metodo GET e include una riga di intestazione If-modified-since. Il proxy inoltra l’oggetto al browser richiedente e pone anche l’oggetto nella cache locale. Una settimana più tardi, un altro browser richiede lo stesso oggetto attraverso il proxy, e l’oggetto si trova ancora nelle cache. Dato che tale oggetto può essere stato modificato nel web server durante la settimana trascorsa, il proxy effettua un controllo di aggiornamento inviando un GET condizionale. Questo GET condizionale sta comunicando al server di inviare l’oggetto solo se è stato modificato rispetto alla data specificata. Trasferimento di file: FTP In una tipica sessione FTP, l’utente utilizza un host (locale) per trasferire file da o verso un host remoto. Per accedere ed essere autorizzato a scambiare informazioni con il file system remoto, l’utente deve fornire un nome identificato e una password, dopo di che può trasferire file tra i due file system. Innanzi tutto l’utente fornisce il nome dell’host remoto, in modo che il processo FTP client nell’host locale stabilisca una connessione TCP con il processo FTP server nell’host remoto e fornisce nome identificato e password, inviate sulla connessione TCP come parte dei comandi FTP. Una volta ottenuta l’autorizzazione dal server può quindi inviare uno o più file memorizzati nel file system locale verso quello remoto (o viceversa). FTP utilizza due connessioni TCP parallele, dette connessione di controllo e connessione dati. La prima viene usata per inviare informazioni di controllo tra gli host, quali identificativo dell’utente, password, comandi per cambiare directory remota e comandi per inviare e ricevere file. La connessione dati viene utilizzata per il vero e proprio invio dei file. Dato che FTP usa una connessione di controllo separata, si dice che tale protocollo invii le proprie informazioni di controllo fuori banda. Quando un utente inizia una sessione FTP con un host remoto, il lato client FTP (l’utente) come prima cosa inizializza una connessione di controllo TCP con il lato server (l’host remoto) sulla porta 21 del server, dove poi invia l’identificativo dell’utente e la password. Inoltre, il lato client di FTP spedisce sulla connessione di controllo i comandi per cambiare la directory remota. Quando il lato server riceve sulla connessione di controllo un comando di trasferimento file, inizializza una connessione dati TCP verso il lato client. FTP invia esattamente un file sulla connessione dati e quindi la chiude. Se l’utente volesse inviare un altro file nel corso della stessa sessione, FTP aprirebbe un’altra connessione dati. Pertanto la connessione di controllo rimane aperta per l’intera durata della sessione utente, ma si crea una nuova connessione dati per ogni file trasferito all’interno della sessione (le connessioni dati sono non persistenti). Per tutto l’arco di una sessione il server FTP deve mantenere lo stato dell’utente. Tener traccia di tale informazione di stato per ogni sessione in corso limita in modo significativo il numero totale di sessioni che FTP riesce a gestire contemporaneamente. Al contrario, HTTP è privo di informazioni di stato, ossia non deve tener traccia dello stato dell’utente. Posta elettronica in Internet La posta elettronica è un mezzo asincrono dove le persone inviano e leggono i messaggi nel momento per loro più opportuno, senza doversi coordinare con gli altri utenti. Dalla figura adiacente vediamo la presenza di tre componenti principali: gli user agent, i server di posta e il protocollo SMTP. I mail server costituiscono la parte centrale dell’infrastruttura del servizio di posta elettronica. Ciascun destinatario ha una casella di posta (mailbox) collocata in un mail server. La mailbox gestisce e contiene i messaggi inviati all’utente. Un tipico messaggio inizia il proprio viaggio dallo user agent, giunge al mail server del mittente e prosegue fino al mail server del destinatario, dove viene depositato nella sua casella. Per accedere ai messaggi dalla propria casella bisogna essere autentificati dal server, che lo ospita, tramite nome utente e password. Il mail server deve anche gestire eventuali problemi del server. Se il server mittente non può consegnare la posta al server destinatario allora questo la trattiene in una coda di messaggi e cerca di trasferirla in un secondo momento. In genere i tentativi vengono effettuati ogni 30 minuti e, se dopo alcuni giorni non si ottiene successo, il server rimuove il messaggio e notifica la mancata consegna al mittente con un messaggio di posta elettronica. SMTP rappresenta il principale protocollo a livello di applicazione per la posta elettronica su Internet. Fa uso del servizio di trasferimento dati affidabile proprio di TCP per trasferire la mail dal server mittente a quello destinatario. SMTP Questo protocollo costituisce il cuore della posta elettronica su Internet. SMTP trasferisce i messaggi dal mail server del mittente a quello del destinatario. Per illustrare le operazioni di base di SMTP, presentiamo uno scenario tipico: supponiamo che Alice voglia inviare a Bob un semplice messaggio ASCII. 1. Alice invoca il proprio user agent per la posta elettronica, fornisce l’indirizzo di posta di Bob, compone il messaggio e dà istruzione allo user agent di inviarlo. 2. Lo user agent di Alice invia il messaggio al suo mail server dove è collocato in una coda di messaggi. 3. Il lato client di SMTP, eseguito sul server di Alice, vede il messaggio nella coda dei messaggi e apre una connessione TCP verso un server SMTP in esecuzione sul mail server di Bob. 4. Dopo un handshaking SMTP, il client SMTP invia il messaggio di Alice sulla connessione TCP. 5. Preso il mail server di Bob, il lato server di SMTP riceve il messaggio, che viene posizionato nella casella di Bob. 6. Bob, quando lo ritiene opportuno, invoca il proprio user agent per leggere il messaggio. È importante osservare che di solito SMTP non usa mail server intermedi per inviare la posta, anche quando sono collocati agli angoli opposti del mondo. Protocolli di accesso alla posta Nell’ipotesi in cui il destinatario esegua il proprio user agent sul proprio pc locale, verrebbe però naturale pensare alla collocazione di un mail server anch’esso sul pc locale. I due mail server parlerebbero direttamente ma esiste un problema per tale soluzione; infatti il pc destinatario dovrebbe rimanere sempre acceso. Piuttosto, un utente manda in esecuzione uno user agent sul pc locale ma accede alla propria casella memorizzata su un mail server condiviso con altri utenti e sempre attivo. Questo server è generalmente gestito dall’ISP dell’utente. Per accedere ai messaggi bisogna usare un protocollo speciale: Post office protocol-versione 3 (POP3) Internet mail access protocol (IMAP) POP3 POP3 è un protocollo di accesso alla posta estremamente semplice in quanto breve e di agevole lettura. Dato che il protocollo è tanto semplice, le sue funzionalità sono piuttosto limitate. POP3 entra in azione quando lo user agent (il client) apre una connessone TCP verso il mail server (server) sulla porta 110. Quando la connessione TCP è stabilita, POP3 procede in tre fasi: autorizzazione, transazione e aggiornamento. Durante la prima fase (autorizzazione) lo user agent invia nome utente e password (in chiaro) per autentificare l’utente. Durante la seconda fase (transazione) lo user agent recupera i messaggi; inoltre, durante questa fase, può marcare i messaggi per la cancellazione, rimuovere i marcatori di cancellazione e ottenere statistiche sulla posta. La fase di aggiornamento ha luogo dopo che il client ha inviato il comando quit, che conclude la sessione POP3; in questo istante, il server di posta rimuove i messaggi che sono stati marcati per la cancellazione. Purtroppo a causa del metodo “scarica e cancella” non si possono vedere le mail scaricare su un pc da un altro pc. IMAP Per risolvere il problema precedentemente esplicitato si implementa il protocollo IMAP. Molto più potente ma molto più complesso di POP3. Un server IMAP associa a una cartella ogni messaggio arrivato al server. Tali server conservano informazioni di stato sull’utente da una sessione all’altra. Abbiamo anche mail browser dove lo user agent è un semplice browser e l’utente comunica con la propria casella tramite HTTP. DNS I nomi degli host (hostname), i quali risultano abbastanza appropriati per l’uomo ma forniscono ben poca informazione sulla loro collocazione all’interno di Internet. Essendo costituiti da un numero variabile di caratteri alfanumerici, sarebbero difficilmente elaborati dai server. Per tali motivi, gli host vengono identificati anche dai cosiddetti indirizzi IP. Al fine di conciliare i due approcci è necessario un servizio in grado di tradurre i nomi degli host nei loro indirizzi IP. Si tratta del principale compito del domain name system (DNS) di Internet. DNS è un database distribuito implementato in una gerarchia di DNS server e un protocollo a livello di applicazione che consente agli host di interrogare il database. I DNS server sono generalmente macchine UNIX che eseguono un software chiamato BIND. Il protocollo DNS utilizza UDP e la porta 53. DNS viene comunemente utilizzato da altri protocolli a livello di applicazione per traduttore i nomi di host forniti dall’utente in indirizzi IP. Vediamo cosa succede affinché un host dell’utente sia in grado di inviare un messaggio di richiesta HTTP ad un web server. 1. La stessa macchina utente esegue il lato client dell’applicazione DNS. 2. Il browser estrae il nome dell’host dall’URL e lo passa al lato client dell’applicazione DNS. 3. Il client DNS invia una interrogazione (query) contenente l’hostname a un DNS server. 4. Il client DNS prima o poi riceve una risposta, che include l’indirizzo IP corrispondente all’hostname 5. Una volta ricevuto l’indirizzo IP dal DNS, il browser può dare inizio a una connessione TCP verso il processo server HTTP collegato alla porta 80 di quell’indirizzo IP. Vediamo quindi che il DNS introduce un ritardo aggiuntivo, talvolta sostanziale, alle applicazioni Internet che lo utilizzano. Oltre alla traduzione degli hostname in indirizzi IP, DNS mette a disposizione altri importanti servizi. Host aliasing: Un host dal nome complicato (hostname canonico) può avere uno o più sinonimi (alias). Il DNS può essere invocato da un’applicazione per ottenere l’hostname canonico di un sinonimo, così come l’indirizzo IP dell’host. Mail server aliasing: Un’applicazione di posta può invocare il DNS per ottenere il nome canonico di un sinonimo fornito, così come l’indirizzo IP dell’host. Infatti, il record MX permette al server di posta di una società e al web server di avere hostname (alias). Distribuzione del carico di rete: Il DNS viene anche utilizzato per distribuire il carico tra server replicati. I siti con molto traffico vengono replicati su più server, e ciascuno di questi viene eseguito su un host diverso e presenta un indirizzo IP differente. Nel caso di web server replicati, va dunque associato a ogni hostname canonico un insieme di indirizzi IP. Il database DNS contiene questo insieme di indirizzi. Quando i client effettuano una query DNS per un nome associato a un insieme di indirizzi, il server risponde con l’intero insieme di indirizzi, ma ne varia l’ordinamento a ogni risposta. La rotazione DNS distribuisce il traffico sui server replicati. Funzionamento dei DNS Un applicazione che deve tradurre un nome in un IP invocherà il lato client del DNS specificando l’hostname da tradurre. Su molte macchine basate su Linux, gesthostbyname() è la chiamata di funzione effettuata da un’applicazione per ottenere il servizio di traduzione. Il DNS sull’host prende poi il controllo, inviando un messaggio di richiesta sulla rete. Tutte le richieste DNS e i messaggi vengono inviati all’interno di datagrammi UDP diretti alla porta 53. Un primo approccio potrebbe essere quello di utilizzare un DNS server contenente tutte le corrispondenze. In questo schema centralizzato, i client dirigono semplicemente tutte le richieste al singolo server e quest’ultimo risponde loro direttamente. Sebbene tale semplicità progettuale sia attraente, sarebbe inappropriata per l’attuale Internet, dotata di un vasto e sempre crescere numero di host. Tra i problemi legati a uno schema centralizzato ricordiamo i seguenti. Un solo punto di fallimento: Se il DNS server si guasta, ne soffre l’intera Internet. Volume di traffico: Un singolo DNS server dovrebbe gestire tutte le richieste. Database centralizzato distante: Un singolo DNS server non può essere vicino a tutti i client; ciò può creare ritardi significativi. Manutenzione: Il singolo DNS server dovrebbe contenere record relativi a tutti gli host di Internet. Non solo tale database centralizzato sarebbe vasto, ma dovrebbe essere aggiornato frequentemente per tener conto di ogni nuovo host. In conclusione, un database centralizzato su un singolo DNS server non è in grado di adattarsi alla crescita esponenziale della rete (non è scalabile). Di conseguenza, il DNS è stato progettato in maniera distribuita. Per trattare il problema della scalabilità, il DNS utilizza un grande numero di server, organizzati in maniera gerarchica e distribuiti nel mondo. Nessun DNS server ha le corrispondenze per tutti gli host in Internet, che sono invece distribuite tra tutti i DNS server. In prima approssimazione, esistono tre classi di DNS server: i root server, i top-level domain (TLD) server e i server autoritativi, organizzati in una gerarchia. Root server: In Internet esistono 13 root server etichettati dalla A alla M. Ai fini di sicurezza e affidabilità ciascuno di essi è in realtà un cluster di server replicati. Top-level domain server: Questi server si occupano dei domini di primo livello (quali com, org, ecc.) e di tutti i domini di primo livello relativi ai vari paese. DNS server autoritativo: Ogni organizzazione dotata di host pubblicamente accessibili tramite Internet deve fornire record DNS pubblicamente accessibili che associno i nomi di tali host a indirizzi IP. Il DNS server dell’organizzazione ospita questi record. Un’organizzazione può scegliere di implementare il proprio server autoritativo o di pagare un fornitore di servizi per ospitare questi record su un suo server. Esiste un importante tipo di DNS, detto DNS server locale, che non appartiene strettamente alla gerarchia di server, ma che è comunque centrale nell’architettura DNS. Ciascun ISP ha un DNS server locale (default name server). Quando un host si connette a un ISP, quest’ultimo gli fornisce un indirizzo IP tratto da uno o più dei suoi DNS server locali, generalmente tramite DHCP. Un DNS server locale è solitamente vicino all’host. Quando un host effettua una richiesta DNS, la richiesta viene inviata al DNS server locale, che opera da proxy e inoltra la query alla gerarchia dei DNS server. L’host dapprima invia un messaggio di richiesta DNS al proprio server locale. Il messaggio contiene il nome da tradurre. Il server locale inoltra il messaggio di richiesta a un root server. Quest’ultimo prende nota del suffisso e restituisce al server locale un elenco di indirizzi IP per i TLD server responsabili del prefisso. Il server locale quindi invia il messaggio di richiesta a un TLD server. Il server TLD prende nota del suffisso (un punto in più) e risponde con l’indirizzo IP del server autoritario. Infine, il DNS locale manda direttamente il messaggio all’interessato che risponde con l’IP desiderato. Le richieste DNS possono essere di due tipologie. Ricorsiva: Se non si conosce la corrispondenza chiediamo ad un altro DNS server di ottenere l’associazione per conto del richiedente. Iterative: Se non si conosce la corrispondenza si invia la richiesta ad un altro DNS e tutte le risposte sono restituite direttamente dal richiedente. Usualmente le richieste seguono lo schema mostrato in figura in cui la richiesta dell’host iniziale al DNS server locale è ricorsiva, mentre le restanti sono iterative. DNS Caching L’idea alla base del DNS caching è molto semplice. In una concatenazione di richieste, il DNS server che riceve una risposta DNS può mettere in cache le informazioni ottenute. Se una coppia hostname/IP è presente nelle cache di un DNS server che riceve una richiesta con lo stesso hostname, il DNS server può fornire l’indirizzo IP desiderato, anche se non è autoritativo per tale indirizzo. I server che implementano il database distribuito di DNS memorizzano i cosiddetti record di risorsa, tra cui quelli che forniscono le corrispondenze tra nomi e indirizzi. Un record di risorsa contiene i seguenti campi: name, value, type e TLL. Il TTL è il time to live, ossia il tempo residuo di vita di un record e determina quando una risorsa deve essere rimossa dalle cache. Il significato di Name e Value dipende da Type. Se Type = A, allora Name è il nome dell’host e Value è il suo indirizzo IP. Pertanto un record di tipo A fornisce la corrispondenza tra hostname standard e indirizzo IP. Se Type = NS, allora Name è un dominio e Value è l’hostname del DNS server autoritativo che sa come ottenere gli indirizzi IP degli host nel dominio. Questo record viene usato per instradare le richieste DNS successive alla prima nella concatenazione delle query. Se Type = CNAME, allora Value rappresenta il nome canonico dell’host per il sinonimo Name. Se Type = MX, allora Value è il nome canonico di un mail server che ha il sinonimo Name. Possibili attacchi I DNS server possono essere attaccati Attacchi DDOS attraverso richieste iterative. Redirect Attacks intercettando le query ma si risolve con HTTPS DNS Poisoning: Chiedo qualcosa al DNS locale che aspetta risposta, ma se riceve una risposta da un DNS falso la salva in cache infettando molti altri host. Posso pure usare un DNS per effettuare un attacco DDOS in cui l’IP sorgente della query è della macchina da attaccare. Per evitare questo non si accettano richieste da utenti non autorizzati. Ogni dominio ha un DNS primario e uno secondario. Il primario si sincronizza con il secondario. Fatta una query, se il primario non risponde allora si contatta il secondario; tra i due vi è una zona di trasferimento in cui si può inserire un host che può far buttare giù il primario dal secondario. Quando un host contata il primario, essendo off contatterà il secondario che, essendo alterato, porterà in siti differenti da quelli richiesti dall’host. LIVELLO DI TRASPORTO I protocolli a livello di trasporto sono implementati nei sistemi periferici, ma non nei router della rete. Lato mittente, il livello di trasporto converte i messaggi che riceve da un processo applicativo in pacchetti a livello di trasporto, noti secondo la terminologia Internet come segmenti (transport- layer segment). Questo avviene spezzando (se necessario) i messaggi applicativi in parti più piccole e aggiungendo a ciascuna di essere un’intestazioni di trasporto per creare un segmento. Il livello di trasporto, quindi, passa il segmento al livello di rete, dove viene incapsulato all’interno di un pacchetto a livello di rete (datagramma) e inviato a destinazione. E’ importante notare che i router intermedi agiscono solo sui campi a livello di rete del datagramma, senza esaminare i campi del segmento incapsulato al suo interno. Internet, e più in generale una rete TCP/IP, mette a disposizione del livello di applicazione due diversi protocolli. Uno è UDP (user datagram protocol), che fornisce alle applicazioni un servizio non affidabile e non orientato alla connessione, l’altro è TCP (transmission control protocol), che offre un servizio affidabile e orientato alle connessione. Il protocollo a livello di rete di Internet ha un nome: IP (Internet protocol). Tale protocollo fornisce comunicazione logica tra host. Il suo modello di servizio prende il nome di best-effort delivery service o, più comunemente, best effort (massimo sforzo): questo significa che IP fa del suo meglio per consegnare i segmenti tra host comunicanti, ma non offre garanzie. Per questa ragione si dice che IP offre un servizio non affidabile. UDP costituisce un servizio inaffidabile: non garantisce che i dati inviati da un processo arrivino intatti (e neppure che arrivino) al processo destinatario. TCP, d’altra parte, offre alle applicazioni diversi servizi aggiuntivi. Innanzitutto, fornisce un trasferimento dati affidabile. Grazie al controllo di flusso, ai numeri di sequenza, agli ack e ai timer. Pertanto TCP converte il servizio inaffidabile tra sistemi periferici, tipico di IP, in un servizio affidabile di trasporto dati tra processi. TCP fornisce anche un controllo di congestione. Multiplexing e demultiplexing Vediamo come il servizio di trasporto da host a host fornito dal livello di rete possa diventare un servizio di trasporto da processo a processo per le applicazioni in esecuzione sugli host. Un processo può gestire una o più socket, attraverso le quali i dati fluiscono dalla rete al processo e viceversa. Di conseguenza il livello di trasporto nell’host di ricezione in realtà non trasferisce i dati direttamente a un processo, ma piuttosto a una socket che fa da intermediario. Siccome, a ogni dato istante, può esserci più di una socket nell’host di ricezione, ciascuna avrà un identificatore univoco il cui formato dipende dal fatto che si tratti di socket UDP o TCP. Il compito di trasportare i dati dei segmenti a livello di trasporto verso la giusta socket viene detto demultiplexing. Il compito di radunare frammenti di dati da diverse socket sull’host di origine e incapsulare ognuno con intestazioni a livello di trasporto per creare dei segmenti e passarli al livello di rete, viene detto multiplexing. Si noti che il livello di trasporto nell’host centrale deve effettuare il demultiplexing dal livello di rete di segmenti che possono arrivare sia per il processo P1 sia per P2, ciò avviene indirizzando i dati del segmento in ingresso alla giusta socket. Vediamo come vengono realizzati dagli host. Il multiplexing a livello di trasporto richiede che la socket abbiano identificatori unici e che ciascun segmento presenti un campo che indichi la socket a cui va consegnato il segmento. Questi sono il campo del numeri di porta di origine e il campo del numero di porta di destinazione. I segmenti UPD e TCP presentano anche altri campi. I numeri di porta sono di 16 bit e vanno da 0 a 65535, quelli che vanno da 0 a 1023 sono chiamati numeri di porta noti e sono riservati per essere usati da protocolli ben noti. Trasporto non orientato alla connessione: UDP Il livello di trasporto deve fornire un servizio di multiplexing/demultiplexing al fine di trasferire dati tra il livello di rete e il processo corretto al livello di applicazione. UDP, fa praticamente il minimo che un protocollo di trasporto debba fare. A parte la funzione di multiplexing/demultiplexing e una forma di controllo degli errori molto semplice, non aggiunge nulla a IP. Se, infatti, lo sviluppatore scegli UPD anziché TCP, allora l’applicazione dialoga quasi in modo diretto con IP. UDP prende i messaggi dal processo applicativo, aggiunge il numero di porta di origine e destinazione per il multiplexing/demultiplexing, aggiunge altri due piccoli campi e passa il segmento risultante al livello di rete. Questi incapsula il segmento in un datagramma IP e quindi effettua un tentativo di consegnarlo all’host di destinazione in modalità best-effort. Se il segmento arriva a destinazione, UDP utilizza il numero di porta di destinazione per consegnare i dati del segmento al processo applicativo corretto. Notiamo che in UDP non esiste handshaking tra le entità di invio e di ricezione a livello di trasporto. Per questo motivo, si dice che UDP sia non orientato alla connessione. DNS è un tipico esempio di protocollo a livello applicativo che utilizza UDP. Quando l’applicazione DNS in un host vuole effettuare una query, costruisce un messaggio di query DNS e lo passa a UDP. Senza effettuare alcun handshaking con l’entità UDP in esecuzione sul sistema di destinazione, il sistema aggiunge i campi d’intestazione al messaggio e trasferisce il segmento risultante al livello di rete. Quest’ultimo incapsula il segmento UDP in un datagramma e lo invia a un server DNS. L’applicazione DNS sull’host che ha effettuato la richiesta aspetta quindi una risposta. Se non ne riceve, l’applicazione tenta di inviare la richiesta a un altro DNS server oppure informa l’applicazione dell’impossibilità di ottenere una risposta. Vediamo alcuni motivi per scegliere UDP. Controllo più fine a livello di applicazione su quali dati sono inviati e quando: Non appena un processo applicativo passa dei dati a UDP, quest’ultimo li impacchetta in un segmento che trasferisce immediatamente al livello di rete. TCP, invece, dispone di un meccanismo di controllo della congestione che ritarda l’invio a livello di trasporto quando uno o più collegamenti tra l’origine e la destinazione diventano eccessivamente congestionati. TCP continua a inviare il segmento fino a quando viene notificata la sua ricezione da parte della destinazione, incurante del tempo richiesto per un trasporto affidabile. Dato che le applicazioni in tempo reale spesso richiedono una velocità minima di trasmissione e non sopportano ritardi eccessivi nella trasmissione dei pacchetti mentre tollerano una certa perdita di dati, il modello di servizio TCP non si adatta particolarmente bene a queste esigenze. Nessuna connessione stabilita: TCP utilizza un handshake a tre vie prima di iniziare il trasferimento dei dati. UDP invece spara dati a raffica senza alcun preliminare formale. Pertanto, UDP non introduce alcun ritardo nello stabilire una connessione. Questo è probabilmente il motivo principale per cui DNS utilizza UDP anziché TCP. Nessuno stato di connessione: TCO mantiene lo stato della connessione nei sistemi periferici. Questo stato include buffer di ricezione e di invio, parametri per il controllo della congestione e parametri sul numero di sequenza e di ack. UDP, invece, non conserva lo stato della connessione e non tiene traccia di questi parametri. Per questo motivo, un server dedicato a una particolare applicazione può generalmente supportare molti più client attivi quando l’applicazione utilizza UDP anziché TCP. Minor spazio usato per l’intestazione del pacchetto: L’intestazione dei pacchetti TCP aggiunge 20 byte, mentre UDP solo 8. Struttura dei segmenti UDP L’intestazione UDP presenta solo quattro campi di due byte ciascuno. I numeri di porta consentono all’host di destinazione di trasferire i dati applicativi al processo corretto. Il campo lunghezza specifica il numero di byte del segmento UDP. Un valore esplicito di lunghezza è necessario perché la grandezza del campo dati può essere diversa tra un segmento e quello successivo. L’host ricevente utilizza il checksum per verificare se sono avvenuti errori nel segmento, In realtà, oltre che sul segmento UDP, il checksum è calcolato anche su alcuni campi dell’intestazione IP. Il checksum UDP serve per il rilevamento degli errori. In altre parole, viene utilizzato per determinare se i bit del segmento UDP sono stati alterati durante il loro trasferimento da sorgente a destinazione. Lato mittente UDP effettua il complemento a 1 della somma di tutte le parole da 16 bit nel segmento, e l’eventuale riporto finale viene sommato al primo bit. Tale risultato viene posto nel campo checksum del segmento UDP. Il motivo della presenza del checksum è che non c’è garanzia che tutti i collegamenti tra origine e destinazione controllino gli errori. Inoltre, anche se i segmenti fossero trasferiti correttamente lungo un collegamento, si potrebbero verificare un errore mentre il segmento si trova nella memoria del router. Dato che non sono garantiti né l’affidabilità del singolo collegamento né il rilevamento di errori in memoria, UDP deve mettere a disposizione a livello di trasporto un meccanismo di verifica su base end-to-end se si vuole che il servizio di trasferimento dati sia in grado di rilevare eventuali errori. Questo è un esempio del celebrato principio end-to-end nella progettazione dei sistemi in base al quale, dato che determinate funzionalità devono essere implementate su base end-to-end, le funzionalità posizionate ai livelli inferiori possono diventare ridondanti o di scarso valore se confrontate con le stesse funzionalità offerte dai livelli superiori. Principi del trasferimento dati affidabile Considerando ora il problema del trasferimento dati affidabile in un contesto generale. Questa scelta è opportuna, dato che il problema dell’implementazione di un trasferimento dati affidabile si verifica non solo a livello di trasporto, ma anche a livello di collegamento e di applicazione. Il problema generale è, quindi, di fondamentale importanza nel campo del networking. L’astrazione del servizio offerta alle entità dei livelli superiori è quella di un canale affidabile tramite il quale si possono trasferire dati. Con un canale affidabile a disposizione nessun bit dei dati trasferiti è corrotto o va perduto e tutti i bit sono consegnati nell’ordine di invio. Si tratta precisamente del modello di servizio offerto da TCP alle applicazioni per Internet che ne fanno uso. Il compito dei protocolli di trasferimento dati affidabile è l’implementazione di questa astrazione del servizio. Ciò è reso difficile dalla possibile inaffidabilità del livello “al di sotto” del protocollo di trasferimento dati. Andiamo ad assumere che i pacchetti vengano consegnati nell’ordine con cui sono stati inviati, ma alcuni possono andare persi; vale a dire che il canale sottostante non riordina i pacchetti. La figura precedentemente vista mostra le interfacce per il nostro protocollo di trasferimento dati. Il lato mittente del protocollo di trasferimento dati sarà invocato tramite una chiamata rdt_send() e trasferirà i dati da consegnare al livello superiore sul lato ricevente. In questo caso rdt sta per “reliable data transfer” e _send indica la chiamata al lato mittente di rdt. Quando un pacchetto raggiunge il lato ricevente del canale, verrà chiamata rdt_rcv(). Nel momento in cui il protocollo rdt voglia consegnare i dati al livello superiore, lo farà chiamando deliver_data(). Andiamo a considerare solo il caso di trasferimento dati unidirezionale. Vedremo che i due lati di rdt necessiteranno anche del reciproco scambio di pacchetti di controllo: entrambi inviano pacchetti tramite una chiamata a udt_send() (unrealiable data transfer). Trasferimento dati affidabile su un canale perfettamente affidabile: rdt 1.0 Consideriamo il caso più semplice, in cui il canale sottostante è completamente affidabile. Il protocollo che chiameremo rdt 1.0 è banale. Le definizioni della macchina a stati finiti (FSM) del mittente e del destinatario sono: Dato che le FSM della figura hanno un unico stato, le transizioni (indicate dalle frecce) hanno luogo necessariamente tra quello stato e sé stesso. L’evento che causa la transizione è scritto sopra la linea orizzontale che la etichetta, e le azioni intraprese in seguito all’evento sono scritte sotto. Quando un evento non determina un’azione e quando viene intrapresa un’azione senza il verificarsi di un evento, useremo la lettera Ʌ rispettivamente sotto o sopra la linea orizzontale per denotare esplicitamente la mancanza di un’azione o di un evento. Lo stato iniziale della FSM è indicato dalle freccia tratteggiata. Il mittente di rdt accetta semplicemente dati dal livello superiore tramite l’evento rdt_send(data), crea un pacchetto contenente dati con l’azione make_pkt(data) e lo invio sul canale. In pratica, l’evento rdt_send(data) è il risultato di una chiamata a procedura. Lato ricevente, rdt raccoglie i pacchetti dal sottostante canale tramite l’evento rdt_rcv(packet), rimuove i dati dei pacchetti tramite l’azione extract(packet, data) e li passa al livello superiore con l’azione deliver_data(data). Trasferimento dati affidabile su un canale con errori sui bit: rdt 2.0 Un modello più realistico del canale sottostante è quello in cui i bit in un pacchetto possono essere corrotti. Tali errori si verificano nei componenti fisici delle reti quando il pacchetto viene trasmesso, propagato o inserito nei buffer. Continueremo ad assumere che tutti i pacchetti trasmessi vengano ricevuti nell’ordine di invio, anche se i loro bit possono essere corrotti. Per risolvere tale problema rinvieremo i messaggi corrotti, per sapere se il messaggio è corrotto si userà un protocollo di dettatura dei messaggi che usa notifiche (acknowledgement) positive e notifiche negative. Tali messaggi di controllo consentono al destinatario di far sapere al mittente che cosa sia stato ricevuto correttamente e che cosa no, chiedendone quindi la ripetizione. Nel contesto di una rete di calcolatori, i protocolli di trasferimento dati affidabili basati su ritrasmissioni sono noti come protocolli ARQ (automatic repeat request). Fondamentalmente, per gestire la presenza di errori nei bit, i protocolli ARQ devono avere tre funzionalità aggiuntive. Rilevamento dell’errore: Innanzitutto è richiesto un meccanismo che consenta al destinatario di rilevare gli errori sui bit. Feedback del destinatario: Dato che mittente e destinatario sono generalmente in esecuzione sui sistemi periferici diversi, magari separati da migliaia di chilometri, l’unico modo che ha il mittente per conoscere la “visione del mondo” del destinatario consiste nel feedback esplicito del destinatario. Il protocollo rdt 2.0 manderà pacchetti ACK e NAK dal del destinatario al mittente. Ritrasmissione: Un pacchetto ricevuto con errori sarà ritrasmesso dal mittente. Il lato mittente di rdt 2.0 presenta due stati. In quello di sinistra, il protocollo lato mittente sta attendendo i dati da raccogliere dal livello superiore. Quando si verifica l’evento rdt_send(data), il mittente crea un pacchetto (sndpkt) contenente i dati da inviare, insieme al checksum e infine spedisce il pacchetto tramite l’operazione udt_send(sndpkt). Nello stato di destra, il protocollo mittente è in attesa di un pacchetto ACK o NAK dal destinatario. Se riceve un ACK (evento denotato da rdt_rcv(rcvpkt) && isACK(rcvpkt), il mittente sa che il pacchetto trasmesso più di recente è stato ricevuto correttamente e pertanto il protocollo ritorna allo stato di attesa dei dati provenienti dal livello superiore. Invece, se riceve un NAK, il protocollo ritrasmette l’ultimo pacchetto e attente una risposta alla ritrasmissione. E’ importante notare che quando il mittente è nello stato di attesa di ACK o NAK, non può recepire dati dal livello superiore; in altre parole, non può aver luogo l’evento rdt_send(), che invece si verificherà solo dopo la ricezione di un ACK che permette al mittente di cambiare stato. Quindi, il mittente non invia nuovi dati finché non è certo che il destinatario abbia ricevuto correttamente il pacchetto corrente. E’ proprio per questo comportamento che i protocolli quali rdt 2.0 sono noti come protocolli stop-and-wait. La macchina a stati finiti lato ricevente di rdt 2.0 ha ancora un solo stato. All’arrivo del pacchetto, il destinatario risponde o con un ACK o con un NAK, a seconda che il pacchetto sia corrotto o meno. Il protocollo rdt 2.0 sembrerebbe funzionare ma, sfortunatamente, presenta un grave difetto; infatti non abbiamo tenuto conto della possibilità che i pacchetti ACK o NAK possano essere a loro volta alterati. Andiamo a considerare due possibilità per gestire gli ACK e i NACK corrotti. Aggiunta di bit di checksum sufficienti a consentire al mittente non solo di trovare, ma anche di correggere gli errori sui bit. Ciò risolve il problema ma solo per un canale che può danneggiare pacchetti, ma non perderli. Rinvio del pacchetto di dati corrente a seguito della ricezione di un ACK o NAK alterato. Questo approccio, tuttavia, introduce pacchetti duplicati nel canale. La fondamentale difficoltà insita nella duplicazione di pacchetti è che il destinatario non sa se l’ultimo ACK o NAK inviato sia stato ricevuto correttamente dal mittente. DI conseguenza, non può sapere “a priori” se un pacchetto in arrivo contenga dati nuovi o rappresenti una ritrasmissione. Una soluzione semplice a questo nuovo problema consiste nell’aggiungere un campo al pacchetto dati, obbligando il mittente a numerare i propri pacchetti dati con un numero di sequenza nel nuovo campo. AL destinatario sarà sufficiente controllare questo numero per sapere se il pacchetto ricevuto rappresenti o meno una ritrasmissione. Per questo semplice protocollo stop- and-wait, un numero di sequenza da 1 bit sarà sufficiente, dato che consentirà al destinatario di sapere se il mittente stia ritrasmettendo un pacchetto o inviandone uno già trasmesso. Nel primo caso il numero di sequenza del pacchetto ha lo stesso numero di sequenza del pacchetto appena ricevuto, nel secondo caso il numero di sequenza sarà diverso. Dato che stiamo ipotizzando che il canale non perda i pacchetti, i pacchetti ACK e NAK non devono indicare il numero di sequenza del pacchetto di cui rappresentano la notifica. Il mittente sa che un pacchetto ricevuto di tipo ACK o NACK (alterato o meno) è stato generato come rispsota al pacchetto dati trasmetto più di recente. La figura sovrastante mostra la FSM di rdt 2.1 (la versione corretta di 2.0). Le FSM di mittente e destinatario hanno ora il doppio degli stati precedenti. Questo avviene perché lo stato del protocollo deve riflettere il fatto che il pacchetto attualmente in invio o in ricezione abbia numero di sequenza 0 o 1. Notiamo che le azioni negli stati di invio e di attesa di un pacchetto numerato 0 sono immagini speculari delle azioni negli stati in cui viene spedito o si attende un pacchetto numero 1. L’unica differenza riguarda la gestione del numero di sequenza. Il protocollo rdt 2.1 usa ack positivi e negativi del destinatario verso il mittente. Il destinatario manda un ack positivo quando riceve un pacchetto fuori sequenza, e un ack negativo, quando riceve un pacchetto alterato. Possiamo ottenere lo stesso effetto di un NAK spendendo piuttosto un ACK per il più recente pacchetto ricevuto correttamente. Un mittente che ricev

Use Quizgecko on...
Browser
Browser