Reti
Reti
https://github.com/TendTo/Tutorato-Reti-di-Calcolatori?tab=readme-ov-file
Lezione 1: Introduzione alle Reti di Calcolatori
Le reti di calcolatori sono sistemi che collegano vari dispositivi, consentendo loro di comunicare e
scambiare dati. Questi collegamenti permettono di accedere a risorse condivise e di trasmettere
informazioni in modo rapido e coordinato tra diversi dispositivi.
Architettura a livelli
L’architettura a livelli è una struttura organizzativa delle reti che separa le varie funzioni della rete
in livelli gerarchici. Ogni livello ha responsabilità specifiche e collabora con i livelli adiacenti
(quello immediatamente sopra e quello immediatamente sotto) per offrire servizi agli utenti finali.
**Se mandiamo più segnali contemporaneamente, c’è il rischio che questi si vadano a sovrapporre e
dunque andiamo ad avere segnali compromessi. Nel caso in cui il segnale che arriva non è
comprensibile, parleremo di collisione. Quando parleremo di segnali, parleremo chiaramente di
segnali radio.
Multicast
Interprocessor distance: distanza tra i processori (dispositivi di rete: computer, server, router, ecc)
Processors located in same: area in cui sono collocati, o in cui è definita la rete
DMI LAN
UNICTMAN
Commutazione
La commutazione è il processo di stabilire un percorso attraverso il quale i dati possono essere
inviati da un punto a un altro all'interno di una rete. Ci sono 2 principali tipi di
commutazione: commutazione a livello di circuito, commutazione a livello di pacchetto.
2.Commutazione a livello di pacchetto: i dati vengono suddivisi in pacchetti, che sono unità più
piccole di informazioni. L’idea è quella di usare un grafo, così facendo se salta una strada possiamo
usare una strada secondaria per arrivarci.
I pacchetti vengono instradati in modo indipendente attraverso la rete. Ogni pacchetto contiene le
informazioni necessarie per raggiungere la sua destinazione, cioè mittente, destinazione e payload.
Una volta arrivati, vengono riassemblati per formare il messaggio originale.
Vantaggi: Dato che ogni pacchetto viene instradato singolarmente, la rete può̀ utilizzare più̀
percorsi e risorse di rete in modo efficiente (un arco diverso del grafo). Inoltre, se un percorso
diventa congestionato o si verifica un guasto nella rete, i pacchetti possono essere instradati su
percorsi alternativi per evitare ritardi o perdite di dati.
Svantaggi: dato che i pacchetti possono viaggiare percorsi diversi e arrivare in ordine diverso
rispetto a quello in cui sono stati inviati, può introdurre latenza variabile. Poiché́ i pacchetti sono
elaborati individualmente, la commutazione a livello di pacchetto può̀ richiedere maggiori risorse di
elaborazione. Per gestire il traffico si può pensare a delle code.
ARPANET (Advanced Research Projects Agency Network) è stata la prima rete a commutazione
di pacchetto, realizzata alla fine degli anni ’60 e sviluppata dall'ARPA (oggi DARPA), l'agenzia del
Dipartimento della Difesa degli Stati Uniti dedicata a progetti di ricerca avanzata. Quando
ARPANET fu sviluppata, il metodo dominante di trasmissione dati nelle telecomunicazioni era
la commutazione di circuito (usata, ad esempio, nelle telefonate).
ARPANET rappresenta quindi il precursore di Internet: molti dei protocolli e dei principi di base su
cui si basa oggi Internet (come il protocollo TCP/IP) furono sperimentati e sviluppati proprio su
questa rete.
Reti a commutazione di pacchetto: è il metodo in cui, i dati vengono suddivisi in pacchetti
indipendenti attraverso la rete. È un’idea generale che include sia le reti datagram che quelle a
circuito virtuale.
Reti a circuito virtualei pacchetti seguono un percorso predefinito (circuito logico)
Reti datagramogni pacchetto è trattato indipendentemente.
**latenza = parametro che misura il ritardo nella trasmissione dei dati in una rete.
Reti Datagram: In queste reti, ogni pacchetto è indipendente dagli altri e può seguire percorsi
diversi per arrivare a destinazione. Non c'è un percorso prestabilito per la comunicazione, e i
pacchetti possono arrivare in ordine diverso da quello di invio. Ogni pacchetto contiene le
informazioni necessarie per arrivare alla destinazione. Questo è il modello tipico di Internet, basato
sul protocollo IP.
Abbiamo client P1 e P2 (nella stessa macchina) che mandano entrambi delle richieste ai server p3 e
p4. Come facciamo a capire a chi va la risposta se queste si trovano nella stessa macchina e quindi
hanno lo stesso IP?
Multiplexing e del demultiplexing sono due tecniche che vanno effettuate tra i due host per far sì
di capire a chi va quale pacchetto. Infatti, il multiplexing serve a radunare i frammenti di dati da
diverse socket sull’host di origine e incapsulare ognuno con header a livello di trasporto per creare
dei segmenti e passarli a livello di rete. Invece il demultiplexing ha il compito di trasportare i dati
dei segmenti a livello di trasporto verso la giusta socket.
Una cosa molto importante è che il multiplexing, richiede il campo del numero di porta di origine e
il campo del numero di porta di destinazione.
ESEMPIO CONDOMINIO
Anna effettua un’operazione di multiplexing quando raccoglie le lettere dai mittenti e le imbuca.
Nel momento in cui Andrea riceve le lettere dal postino, effettua un’operazione di demultiplexing
leggendo il nome riportato sopra la busta e consegnando ciascuna missiva al rispettivo destinatario.
Abbiamo visto come i processi di rete comunichino tra loro inviando messaggi tra socket. Ma come
sono strutturati questi messaggi? Qual è il significato dei loro campi? Quando vengono inviati?
Queste domande ci conducono nel campo dei protocolli a livello di applicazione.
Un protocollo per la parte applicativa definisce:
- Tipi di messaggi che si scambiano (richieste, risposte)
- Sintassi dei messaggi
- Semantica dei messaggi
- Regole per come e quando mandare e rispondere
- Il protocollo stesso e a chi appartiene
Le porte di rete sono numeri a 16 bit che identificano le connessioni tra applicazioni su dispositivi
diversi in rete. Classifichiamo le porte:
1. Well-known ports (Porte ben note)
Range: da 0 a 1023: porte sono essenziali per identificare i protocolli standard e i più
comuni usati dai servizi di rete.
- FTP (File Transfer Protocol) - Utilizza le porte 20 e 21. È un protocollo per trasferire file
tra client e server su una rete, molto usato per caricare e scaricare file da server remoti.
- SSH (Secure Shell) - Usa la porta 22. SSH è un protocollo per la connessione remota sicura
a un altro dispositivo, criptando i dati trasmessi per garantire privacy e sicurezza.
- Telnet - Usa la porta 23. È un protocollo di accesso remoto simile a SSH ma senza
crittografia, quindi meno sicuro.
- SMTP (Simple Mail Transfer Protocol) - Usa la porta 25. Viene utilizzato per l’invio di e-
mail dai client ai server di posta e per il trasferimento tra server.
- DNS (Domain Name System) - Usa la porta 53. È un protocollo che trasforma i nomi di
dominio (come example.com) in indirizzi IP comprensibili dalla rete, permettendo ai client
di accedere a risorse Internet.
- HTTP (Hypertext Transfer Protocol) - Usa la porta 80. Protocollo principale per la
trasmissione di pagine web non criptate.
- HTTPS (Hypertext Transfer Protocol Secure) - Usa la porta 443. È la versione sicura e
crittografata di HTTP, utilizzata per la trasmissione di dati sensibili su Internet, come per siti
di e-commerce o banking online.
- POP3 (Post Office Protocol 3) - Usa la porta 110. Protocollo per scaricare e-mail dai server
di posta ai client locali, solitamente rimuovendole dal server.
- IMAP (Internet Message Access Protocol) - Usa la porta 143. Un protocollo per gestire le
e-mail da un server senza rimuoverle, permettendo l’accesso da diversi dispositivi.
Telnet
è utilizzato per creare una connessione remota con un server o un dispositivo su una rete,
impiegando la porta 23. Esso permette a un client di inviare comandi a un dispositivo remoto e
riceverne le risposte, simulando un'interazione diretta (cioè come se fosse fisicamente di fronte ad
esso). La comunicazione avviene tramite un semplice formato basato su testo, in cui i comandi e le
risposte sono trasmessi come stringhe ASCII.
Uno dei principali problemi di Telnet è la mancanza di crittografia: tutti i dati, incluse le
credenziali (username e password), vengono trasmessi in chiaro. Questo rende Telnet vulnerabile
agli attacchi di tipo man-in-the-middle, in cui un malintenzionato potrebbe intercettare e leggere il
traffico. Per questo motivo, Telnet viene generalmente sostituito da SSH (Secure Shell).
Altro limite: solo con le intestazioni IP (20 byte) e TCP (20 byte), un pacchetto "vuoto" ha già 40
byte di overhead. Questo significa che, se voglio inviare un solo byte di dati (ad esempio, un
singolo carattere), il pacchetto complessivo peserà 41 byte, con 40 byte spesi solo per le
intestazioni. Questo è uno spreco enorme, poiché la maggior parte del pacchetto è occupata da
informazioni di controllo piuttosto che dal contenuto effettivo.
Nonostante i problemi di sicurezza, Telnet è ancora utile in reti chiuse e ambienti controllati per
testare la connettività di rete o per la configurazione di dispositivi su reti locali (come switch e
router) che utilizzano solo Telnet per la gestione e non SSH.
HTTP
HTTP, o Hypertext Transfer Protocol, è un protocollo utilizzato per il trasferimento di pagine web.
Funziona secondo un modello Client-Server, dove il client (solitamente un browser) invia richieste
a un server che ospita le informazioni desiderate. La connessione HTTP è tipicamente stabilita su
una connessione TCP attraverso la porta 80, mentre la versione sicura, HTTPS, usa la porta 443.
Quando un client desidera accedere a una risorsa web, invia una richiesta HTTP al server. Questa
richiesta contiene un metodo, che specifica l'azione da compiere. Una volta ricevuta la richiesta, il
server risponde con una risposta HTTP, che include uno stato (come 200 OK per una richiesta
andata a buon fine) e i dati richiesti.
Un aspetto importante, soprattutto nella sua versione 1.0, è la sua natura stateless**.
Una pagina web è composta da vari oggetti, ciascuno dei quali può risiedere su server diversi. Le
URL forniscono l'indirizzo completo per individuare e accedere a ciascun oggetto. Questo sistema
consente al browser di raccogliere gli elementi da più fonti e visualizzare la pagina in modo
completo per l'utente. La struttura di una URL tipica è simile a questa:
https://www.esempio.com/categoria/immagine.jpg
il server è "www.esempio.com"
/categoria/immagine.jpg: Specifica la posizione esatta dell'oggetto sul server, indicando la
"cartella" e il nome del file tramite percorso
HTTP 1.1: Introduce la persistenza delle connessioni, permettendo di inviare più richieste
attraverso la stessa connessione TCP, riducendo così il tempo di latenza. Rimane stateless, ma
introduce l'uso dei cookies** per mantenere lo stato dell'utente tra le richieste. Supporta il
pipelining (È possibile inviare più richieste in parallelo sulla stessa connessione senza aspettare le
risposte una per una.) e offre migliori meccanismi per la gestione della cache e della compressione
dei dati (come gzip).
Pipelining soffre del "blocco di testa" (head-of-line blocking o HOLblocking): una richiesta lenta
blocca tutte quelle successive.
HTTP 3.0: HTTP/3 abbandona TCP a favore di QUIC, un protocollo basato su UDP che è più
veloce e resiliente; è un protocollo di trasporto sviluppato da Google e progettato per migliorare la
velocità e l'efficienza della trasmissione dei dati su Internet, specialmente per le applicazioni web.
Elimina il problema del blocco delle richieste di testa e migliora la resilienza alle perdite di
pacchetti, permettendo al protocollo di riprendersi più velocemente. HTTP/3 integra la crittografia
TLS (Transport Layer Security) direttamente nel protocollo, garantendo una connessione più sicura.
QUIC è progettato per essere più resiliente rispetto a TCP, poiché può recuperare più rapidamente
da perdite di pacchetti senza interrompere la connessione, migliorando l'esperienza utente durante il
caricamento delle pagine web.
**COOKIES
I Cookies sono piccoli file di testo che i siti web memorizzano sul dispositivo dell'utente quando
visita una pagina. Servono principalmente a mantenere lo stato della sessione e a personalizzare
l’esperienza di navigazione, rendendo in qualche modo HTTP, che è per natura stateless, un
protocollo parzialmente stateful a livello logico.
Come funzionano? Quando un utente accede a un sito web, il server può assegnargli un ID
unico tramite un cookie. Questo ID viene memorizzato sul dispositivo dell'utente e inviato al server
con ogni richiesta successiva, permettendo al server di identificare l'utente e di mantenere la
continuità della sessione. Ad esempio, se un utente aggiunge articoli al carrello di un negozio
online, i cookie permettono al server di ricordare questi elementi anche quando l'utente naviga tra
diverse pagine del sito.
Il server invia il cookie come parte della risposta HTTP al browser dell'utente. Il browser include il
cookie in ogni richiesta successiva, permettendo al server di identificare l'utente. I cookie sono
memorizzati nel dispositivo dell’utente e sono gestiti dal browser, che li conserva secondo le
impostazioni e le politiche specifiche. Il sito web può conservare le informazioni relative ai cookie
nel proprio database, così da riconoscere e associare correttamente i dati agli utenti.
Classificazione in base alla durata
di sessione: sono temporanei e vengono eliminati quando il browser viene chiuso. Sono usati per
memorizzare informazioni sulla sessione corrente, come gli articoli di un carrello degli acquisti.
persistenti: Rimangono sul dispositivo dell’utente anche dopo la chiusura del browser. Hanno una
data di scadenza e possono essere utilizzati per ricordare informazioni utili nelle visite future,
permettendo ad esempio l’accesso automatico a un sito.
Classificazione in base alla finalità
tecnici: Essenziali per il funzionamento del sito, come la gestione del login o del carrello della
spesa, infatti non chiedono il consenso dell’utente. Se invece di profilazione: Tracciano il
comportamento dell’utente per personalizzare contenuti e pubblicità in base alle preferenze. Ad
esempio, possono registrare le pagine visitate e il tempo trascorso su ciascuna di esse, aiutando gli
inserzionisti a mostrare annunci più mirati.
Sicurezza e Privacy
Poiché i cookie memorizzano informazioni in chiaro, inclusi ID di sessione e preferenze, essi
possono essere utilizzati per tracciare il comportamento degli utenti. Tuttavia, questa caratteristica li
rende vulnerabili a possibili attacchi, come l'intercettazione se la connessione non è sicura. Per
proteggere la privacy, molte versioni aggiornate dei browser richiedono il consenso dell’utente.
Request Body (Body della richiesta): Questa parte è opzionale e viene utilizzata principalmente
nei metodi che inviano dati al server, come POST o PUT. Ad esempio, in una richiesta di
registrazione, il body potrebbe contenere i dati dell'utente.
HTTP response
Status Line (Riga di stato): La prima riga della risposta che contiene:
1. La versione di HTTP utilizzata.
2. Un codice di stato a tre cifre che indica l'esito della richiesta (ad esempio, 200 per
OK, 404 per Not Found).
3. Un messaggio di stato che descrive il codice (ad esempio, 200 OK).
HTTP Headers (Header HTTP): Questi header forniscono informazioni aggiuntive sulla risposta.
Esempi comuni includono: Content-Type: Indica il tipo di contenuto restituito (text/html per una
pagina web). Date: La data e l'ora in cui è stata generata la risposta. Content-Length: La
dimensione del contenuto restituito in byte.
Response Body (Body della risposta): Questa parte contiene i dati restituiti dal server. Può
includere il contenuto di una pagina web, un file JSON ecc.
Ciao Bob,
Come stai? Questo è un messaggio di prova.
SMTP è un protocollo affidabile ma non cifrato. È importante notare che SMTP si occupa solo
dell'invio di e-mail e non della ricezione. Per la ricezione di e-mail, viene invece utilizzato un
protocollo differente, come ad esempio POP3 o IMAP.
POP3 (Post Office Protocol 3) e IMAP (Internet Message Access Protocol) sono entrambi
protocolli utilizzati per la ricezione delle e-mail, ma funzionano in modo diverso.
POP3
è un protocollo di tipo "pull", ovvero il client si connette al server e "tira giù" le e-mail,
scaricandole completamente sul dispositivo locale. Una volta scaricate le e-mail, queste vengono
generalmente rimosse dal server. POP3, quindi, rende il client l’unica posizione in cui i messaggi
restano accessibili. Con POP3, le e-mail scaricate non sono disponibili su altri dispositivi, a meno
che non siano state salvate manualmente su più dispositivi.
In questo modo, POP3 si comporta come un "postino" che raccoglie e consegna le e-mail al
destinatario, rendendo l'accesso alle e-mail disponibile solo sul dispositivo da cui sono state
scaricate.
IMAP
IMAP è un protocollo di posta elettronica basato sul modello Client-Server, che consente ai client di
posta elettronica di selezionare e visualizzare i messaggi di posta elettronica presenti sul server
senza doverli scaricare e archiviare localmente sul dispositivo client.
In sintesi:
POP3 scarica le e-mail e le elimina dal server.
IMAP mantiene le e-mail sul server, sincronizzandole su tutti i dispositivi connessi.
Dominio
Quando ci colleghiamo a un servizio, come la posta elettronica, l’indirizzo e-mail è strutturato come
"nomeutente@dominio". In questa struttura:
"nomeutente" identifica l’utente specifico.
"dominio" rappresenta l'insieme di server che gestiscono e forniscono il servizio di posta
per quell’organizzazione.
Questo meccanismo consente di evitare di specificare un server specifico, poiché il dominio
rappresenta un pool di server (macchine equivalenti) che condividono risorse, servizi e regole
comuni, in grado di rispondere a ogni richiesta. Così, se uno dei server ha un guasto, altri server
all'interno del dominio possono subentrare per gestire le richieste, garantendo continuità del servizio
e l’affidabilità dei messaggi.
Blacklist e Sicurezza del Dominio
Le blacklist (liste nere) sono elenchi di mittenti considerati non affidabili o potenzialmente dannosi,
come fonti di spam o contenuti pericolosi. Ogni server può utilizzare una propria blacklist per
filtrare le e-mail indesiderate, evitando che raggiungano gli utenti. L’amministratore di sistema deve
vigilare affinché i propri server non finiscano in queste liste nere, cosa che potrebbe accadere se
venissero usati per inviare spam o altre comunicazioni non sicure.
DNS
Gli host di internet possono essere identificati da un Hostname es www.google.com e da un
Indirizzo IP. Un indirizzo IP consiste in 4 byte e rappresenta una struttura gerarchica
(192.164.54.101). Un DNS ha il compito di trasformare l’Hostname in IP. Il DNS è un database
implementato in una gerarchia di DNS server e un protocollo che gli permette di interrogare il
server. Quello che succede è che la macchina utente esegue il lato client del DNS, il browser estrae
il nome dell’host dall’URL e lo passa al DNS. Il DNS comincia l’interrogazione del DNS server e
prima o poi riceverà una risposta contenente l’indirizzo IP relativo all’hostname. Una volta ottenuto
l’IP possiamo cominciare una connessione TCP con il processo server http relativo all’IP trovato. Il
DNS introduce un ritardo aggiuntivo, talvolta sostanziale, alle applicazioni Internet che lo utilizzano
a causa di questa ricerca ma spesso ciò non accade grazie alla cache del server. Il DNS fornisce
anche:
Host aliasing: Un host dal nome complicato può avere uno o più alias, ad esempio
relay1.west-coast.enterprise.com potrebbe avere, diciamo, due sinonimi quali enterprise.com
o www.entrprise.com.
Mail server aliasing: Per ovvi motivi è fortemente auspicabile che gli indirizzi di posta
elettronica siano facili da ricordare. Per esempio, se Bob ha un account Hotmail, il suo
indirizzo di posta elettronica potrebbe essere semplicemente [email protected]. Tuttavia,
l’hostname del server di posta Hotmail è molto più complicato e assai meno facile da
ricordare rispetto a yahoo.com.
Load distribution: Il DNS viene anche utilizzato per distribuire il carico tra server replicati
in modo da gestire al meglio il carico di utenti e di non avere sovraccarichi del server dato
che spesso un sito ha più server.
Come Funziona il DNS su Internet
Quando un utente inserisce un nome di dominio nel browser, il computer invia una query DNS per
cercare l’indirizzo IP corrispondente a quel nome di dominio. Ecco come funziona il processo:
1. Query iniziale: La richiesta parte dal computer dell'utente e viene inviata a un DNS
Locale (resolver DNS), generalmente gestito dal provider Internet (ISP).
2. DNS Locale (Resolver): Questo server DNS cerca prima nei suoi dati di cache. Se ha già
l'informazione, restituisce subito l’IP. Altrimenti, inoltra la richiesta attraverso la gerarchia
DNS.
3. DNS Root Server: Se il DNS Locale non trova una risposta, la query arriva ai DNS Root
Server. I Root Server contengono informazioni sui Top-Level Domain
(TLD) come .com, .org, .net, etc. e rispondono indirizzando la query al server DNS che
gestisce il TLD appropriato.
4. Top-Level Domain (TLD) Server: Il server TLD indirizza la query verso il DNS
Autoritativo del dominio richiesto.
5. DNS Autoritativo: Questo server DNS detiene le informazioni ufficiali sui nomi di dominio
specifici. Risponde alla query con l’indirizzo IP associato al dominio, che viene quindi
inviato al resolver DNS e infine al browser dell'utente, permettendo la connessione al sito
web.
La struttura del DNS si può vedere come una gerarchia ad albero che parte dai Root Server e
scende lungo vari livelli, fino a raggiungere i server specifici che contengono i dettagli di un
dominio. Tuttavia, la struttura reale non è un albero perfetto, ma ha anche collegamenti
trasversali che rendono il sistema più simile a un grafo orientato, dove le query possono viaggiare
anche attraverso percorsi alternativi, seguendo cache locali o indirizzamenti veloci, senza risalire
sempre fino ai Root Server.
I provider di servizi Internet (ISP) possono modificare dinamicamente l'indirizzo IP dei clienti per
evitare che questi impostino facilmente un server pubblico (pratica spesso non consentita ai privati
senza autorizzazione specifica). Servizi di DNS dinamico permettono agli utenti di aggiornare
automaticamente la coppia client-IP tramite un login. Ad esempio, un dispositivo con IP dinamico
può mantenere l’associazione a un nome di dominio aggiornato in tempo reale. Un’alternativa per
mantenere accesso costante, sebbene con IP dinamico, è l’utilizzo di un dispositivo (come un router
o un firmware) che si colleghi regolarmente a un server web esterno con un IP fisso. Questo server
centrale può ricevere informazioni dal dispositivo e renderle disponibili ad altri utenti, mantenendo
un punto di contatto stabile e fisso.
SNMP
l Simple Network Management Protocol (SNMP) è un protocollo progettato per monitorare e
gestire dispositivi su una rete (come router, switch, server e stampanti) da un'unica postazione
centrale. SNMP consente agli amministratori di rete di raccogliere informazioni sulle prestazioni
della rete, monitorare eventuali problemi e configurare dispositivi in remoto (quindi eventualmente
eseguire dei comandi su di essi).
L’Agente SNMP è un software che gira su ciascun dispositivo di rete gestito e ha i permessi di
amministrazione per accedere a dati specifici del sistema operativo e dell’hardware. L’agente
raccoglie e gestisce i dati riguardanti lo stato e le prestazioni del dispositivo. I dati raccolti sono
organizzati all'interno di una struttura ad albero chiamata Management Information Base (MIB),
che agisce come un database standardizzato per l’organizzazione delle informazioni. Ogni dato nel
MIB è rappresentato da un identificatore univoco chiamato OID (Object Identifier) che ne specifica
la posizione all’interno della struttura ad albero.
Tre Versioni di SNMP: La prima versione, semplice ma con scarsa sicurezza, permette la gestione
di base tramite semplici comandi. SNMPv2: Introdotta con alcune migliorie di performance e
funzionalità, ma ancora limitata in termini di sicurezza. SNMPv3: La versione più recente, che
include miglioramenti significativi sulla sicurezza, come autenticazione e crittografia, per evitare
accessi non autorizzati.
Modalità Operative:
Polling: Il gestore (manager) invia periodicamente query agli agenti per aggiornare i dati. (GET o
SET)
Traps: Gli agenti inviano notifiche al gestore SNMP per segnalare eventi importanti.
Lezione 5: livello di trasporto
Un protocollo a livello di trasporto mette a disposizione una comunicazione logica tra processi
applicativi di host differenti, senza preoccuparsi dei dettagli dell’infrastruttura fisica utilizzata per
trasportarli. Per comunicazione logica si intende, dal punto di vista dell’applicazione, che tutto
proceda come se gli host che eseguono i processi fossero direttamente connessi; in realtà, non deve
essere necessariamente così. Il termine end-to-end indica che i protocolli di trasporto gestiscono la
comunicazione direttamente tra i host finali, senza che dispositivi intermedi (come router)
intervengano nel processo di trasferimento dei dati. Grazie ai suoi meccanismi di controllo del
flusso e di controllo della congestione, TCP garantisce una trasmissione affidabile e ordinata dei
dati su una rete IP. Tuttavia, in alcune situazioni, come quelle in cui è necessaria una bassa latenza,
UDP può essere preferibile per la sua maggiore leggerezza e velocità.
Internet, e più in generale una rete TCP/IP, mette a disposizione del livello di applicazione due
diversi protocolli. Ricordiamo, che la letteratura su Internet definisce segmento un pacchetto a
livello di trasporto per TCP, ma molte volte definisce datagramma un pacchetto per UDP.
RDT 2.2
RDT 2.2 elimina l’uso del NAK, riducendo la complessità: quando il destinatario rileva un
pacchetto danneggiato o fuori sequenza, invia semplicemente un ACK duplicato riferito all'ultimo
pacchetto valido ricevuto. Il mittente interpreta due ACK identici come segnale che il destinatario
non ha ricevuto correttamente il pacchetto successivo, e provvede a ritrasmetterlo.
Figura C: abbiamo la situazione in cui perdiamo un ACK e dunque, scaduto il timer, il sender
reinvia il messaggio e il receiver, notando che è un duplicato lo ignora e reinvia ACK.
Figura D: Qui invece abbiamo ancora un altro problema che è causato dal fatto che i pacchetti non
viaggiano sempre alla stessa velocità e possono dunque succedere che un ACK è riferito ad un
pacchetto diverso da quello a cui si riferisce il programma.
Errore dal canale Errore dal canale del ACK/ NACK Pacchetti persi
del sender reciever
RDT 1.0 no no - no
RDT 2.0 si no ACK/ NACK no
RDT 2.1 si si ACK/ NACK no
RDT 2.2 si si ACK no
RDT 3.0 si si ACK si
Il throughput (cioè la quantità di dati trasmessi per unità di tempo) nello stop-and-wait, è limitato
perché il mittente deve attendere l’ACK di ogni pacchetto prima di inviarne un altro. Questo crea
molti tempi morti, soprattutto per connessioni a lunga distanza, e impedisce di sfruttare appieno la
banda disponibile. Questo processo implica che, per ogni pacchetto trasmesso, ci sia un ritardo
totale definito da vari elementi del viaggio e dell’elaborazione, che possiamo esprimere con la
formula seguente: (indica il tempo totale di trasmissione per un singolo pacchetto)
Go-Back-N
Il mittente può trasmettere più pacchetti senza dover attendere gli ACK ma non può aver mandato
più di N pacchetti senza che questi abbiano ricevuto un ACK. Questo numero N viene definito
come finestra di trasmissione.
Ogni pacchetto inviato viene numerato sequenzialmente, e il destinatario invia un ACK cumulativo
che indica l’ultimo pacchetto ricevuto correttamente. Ad esempio, se il mittente invia i pacchetti 0,
1, 2 e 3, ma il pacchetto 2 viene perso, il destinatario invierà un ACK per il pacchetto 1 e scarterà
tutti quelli successivi. Il mittente, scaduto il timer, alla ricezione di questo ACK, sa che deve
riprendere da 2 e ritrasmettere il pacchetto 2 e tutti quelli successivi (3 e oltre). Questo richiede
meno buffer (memoria) sul destinatario, perché gestisce solo i pacchetti in ordine e usa un singolo
timer per tutta la finestra, semplificando il controllo.
Presenta l’inconveniente che tutti i pacchetti dopo il primo perso devono essere ritrasmessi, anche
se alcuni di essi sono stati ricevuti correttamente. Questo può portare a un uso inefficiente della
larghezza di banda, specialmente in caso di perdite frequenti.
Quelli gialli sono i pacchetti mandati e non confermati, quelli verdi sono quelli confermati (quindi
non si considerano) e quelli blu sono quelli che potrei ancora spedire.
Ripetizione Selettiva (Selective Repeat)
Il Selective Repeat è progettato per migliorare l’efficienza rispetto al Go-Back-N, permettendo di
gestire i pacchetti ricevuti fuori ordine e ritrasmettendo solo quelli che sono stati persi o
danneggiati. Il mittente mantiene una finestra di trasmissione che rappresenta i pacchetti che può
trasmettere senza aspettare ACK. Il destinatario ha una finestra di ricezione che rappresenta i
pacchetti che può accettare, anche se non sono nell’ordine giusto. Se un pacchetto arriva
correttamente (anche fuori ordine), il destinatario lo memorizza in un buffer. Se un pacchetto è
perso o danneggiato, il destinatario segnala solo quel pacchetto specifico come mancante (ad
esempio con un NACK o tramite numeri di ACK). Il mittente ritrasmette solo il pacchetto perso o
danneggiato, senza dover ritrasmettere tutti i pacchetti successivi come accade nel Go-Back-N.
Una volta ricevuti tutti i pacchetti mancanti, il destinatario ricostruisce i dati nell’ordine corretto
utilizzando il buffer.
Sintesi
In sintesi, il pipelining, attraverso i protocolli Go-Back-N e Ripetizione Selettiva, consente di
superare le inefficienze del metodo stop-and-wait. Se io perdo tanti pacchetti assieme, go back N
conviene perché si aspetta un solo timer. Mentre la ripetizione selettiva fa perdere molto più tempo.
Dipende dunque tutto da quanti pacchetti perdo e da come li perdo.
In generale per quanto riguarda i pacchetti che arrivano in maniera disordinata, il protocollo lascia
tutto nelle mani di chi l’ha implemento, senza dare particolari indicazioni. Di fatto, abbiamo
principalmente due approcci: il primo consiste nel buttare tutti i pacchetti arrivati in maniera
disordinata, mentre il secondo consiste nel mantenere in un buffer i pacchetti non arrivati in ordine
e quindi reinserirli una volta arrivati i pacchetti che mancano.
Definiamo inoltre come Error rate del canale il numero di bit errati per ogni tot. Per la fibra ottica
è 1 bit errato ogni 10^14.
TCP IPv4
TCP è un protocollo a livello di trasporto che offre alle applicazioni, un servizio di comunicazione
affidabile e orientato alla connessione (perché prima di scambiare dati, TCP stabilisce un
collegamento attraverso un processo noto come handshake a tre vie (three-way handshake)).
Questo processo coinvolge l'invio di pacchetti SYN e ACK per sincronizzare i numeri di sequenza
tra mittente e destinatario, assicurando che entrambi siano pronti a comunicare. La “connessione”
TCP non è un circuito fisico TDM o FDM, come in una rete a commutazione di circuito, in quanto
lo stato della connessione risiede completamente nei due sistemi periferici. Nel modello end-to-end,
la comunicazione avviene esclusivamente tra i due host finali, senza che i router intermedi
partecipino alla gestione della connessione. Ciò significa che TCP si occupa della gestione della
comunicazione, mentre i router si limitano a inoltrare i pacchetti, senza alcuna consapevolezza della
connessione TCP stessa (vedono solo datagrammi non connessioni). TCP offre una connessione di
tipo full-duplex in quanto i dati possono fluire da mittente a destinatario e viceversa. TCP sfrutta
l’architettura peer-to-peer. Una connessione TCP è anche punto a punto, ossia ha luogo tra un
singolo mittente e un singolo destinatario. (il Multicast non è ottenibile)
L’MSS, o Maximum Segment Size, definisce la quantità massima di dati (payload) che può essere
inserita in un segmento TCP. L’Header TCP ha dimensione fissa di 20 byte.
Per garantire che il segmento TCP possa essere trasmesso senza frammentazione, la somma
dell'MSS e della dimensione dell’header deve essere inferiore al Maximum Transmission Unit
(MTU). Se un segmento TCP supera l'MTU, il pacchetto sarà frammentato, il che può comportare
inefficienze e complicazioni nel processo di riassemblaggio dei pacchetti al destinatario.
Struttura di un pacchetto TCP
Un segmento TCP è composto da un header e da un payload.
Il numero di sequenza per un segmento è il numero nel flusso di byte del primo byte del segmento.
Per esempio, se A vuole inviare a B in una connessione TCP 500.000 byte con un MSS di 1000
byte, allora troveremo che il numero di sequenza nel primo segmento è 0, poi 1000, poi 2000 ecc.
fino ad arrivare a 500.000.
Invece il numero di conferma corrisponde al numero di sequenze del byte successivo che la
macchina attende dall’altra. Quindi se ad esempio a B è arrivato il primo segmento con numero di
sequenza 1000, questo manderà un ACK con numero 1001 per confermare che ha ricevuto tutti i
pacchetti fino al 1000 e che adesso attende il 1001. Ricordiamo che TCP utilizza ACK
CUMULATIVI, dunque mandare un ACK 1000 conferma tutti i pacchetti con numero precedente.
Questa strategia ha diversi vantaggi: 1. Riduce il numero di pacchetti di ACK inviati sulla rete,
minimizzando il sovraccarico. 2. Facilita la gestione delle ritrasmissioni di pacchetti persi, in quanto
il mittente può determinare facilmente quale pacchetto deve essere inviato nuovamente in base
all'ACK ricevuto.
Piggybacking: inviare ACK insieme ai dati
Nella comunicazione TELNET, spesso succede che un ACK non venga inviato come pacchetto
separato, ma sia "accompagnato" da dati che devono essere trasmessi nella stessa direzione. Questo
processo è chiamato piggybacking, che possiamo tradurre in italiano come "A cavallo di". Quando
una macchina deve inviare un ACK (per confermare la ricezione di un pacchetto), invece di
mandarlo subito, aspetta di avere dei dati da inviare nella stessa direzione.
L’ACK viene "incluso" nel pacchetto con i dati, riducendo il numero totale di pacchetti trasmessi.
Mi serve un modo per capire quanto tempo aspettare prima che l’host B mandi un pacchetto e
questo voglio ritardarlo il più possibile perché voglio che B abbia comunque qualcosa da mandare,
ma non troppo perché altrimenti rischio che scada il timer dell’altra macchina.
Time-out TCP
TCP usa un timer per far fronte alla possibile perdita di pacchetti.
Se il mittente non riceve un ACK entro il tempo di time-out, assume che il pacchetto sia stato perso
e attiva il meccanismo di ritrasmissione. Questo meccanismo è essenziale per mantenere la
comunicazione fluida e garantire che i dati vengano effettivamente consegnati.
La misurazione accurata del RTT (round trip time) è cruciale per determinare un time-out
appropriato. Abbiamo però un problema, noi l’RTT, quindi tempo di andata e ritorno non lo
conosciamo a prescindere e anche se lo conoscessimo, non sarebbe comunque sempre lo stesso
perché non sempre abbiamo lo stesso traffico nella rete. Serve dunque fare una media tramite il
Sample RTT.
In questa formula:
RTT è il valore attuale del Round Trip Time calcolato. (è Estimated_RTT che mi servirà
dopo)
SampleRTT è il tempo effettivo impiegato per ricevere l'ACK del pacchetto più recente.
α è un fattore di peso, comunemente impostato a 0.125 (o 1/8), che determina quanto peso
assegnare al valore campionato più recente (SampleRTT) rispetto alla media storica (RTT).
Il fattore α consente di dare più peso ai tempi recenti, rendendo il calcolo più sensibile ai
cambiamenti.
L’EMWA non basta da sola però, abbiamo bisogno anche della deviazione standard perché i valori
possono variare molto tra l’uno e l’altro.
DevRTT
La DevRTT misura la variazione del RTT, fornendo una stima della sua instabilità. A differenza
dell'EWMA, che calcola una media del RTT, la DevRTT tiene conto delle fluttuazioni del RTT
stesso. Questo è particolarmente utile in reti con condizioni variabili, dove i tempi di risposta
possono cambiare a causa di congestioni o variazioni nella latenza.
La formula per calcolare la DevRTT utilizzando l'algoritmo EWMA è la seguente:
In questa formula:
DevRTT è il valore attuale della deviazione media ponderata del RTT.
DevRTT_precedente è il valore calcolato di DevRTT al momento precedente.
β è un parametro di smoothing, solitamente impostato a 0.25 (o 1/4), che determina il peso
relativo dei valori passati rispetto a quelli presenti nel calcolo della media mobile.
RTT è il valore reale dell’RTT cioè il tempo impiegato per inviare un pacchetto di dati e
ricevere la risposta.
Estimated_RTT è la stima dell’RTT calcolato precedentemente con la media ponderata.
Una volta che la DevRTT è stata calcolata, viene utilizzata per determinare il valore del RTO
secondo la seguente formula:
In questo contesto:
RTO rappresenta il tempo massimo di attesa per una risposta prima di considerare un
pacchetto come perso.
Estimated_RTT è la stima attuale del RTT, calcolata in precedenza con la EWMA.
DevRTT è la deviazione calcolata, moltiplicata per 4 per fornire un'ampiezza di banda di
sicurezza, riducendo il rischio di ritrasmissioni non necessarie.
In questo modo, RTO viene impostato in modo che la probabilità di perdere un pacchetto sia
inferiore all’1%.
Implicazioni Pratiche
Un RTO troppo breve può portare a ritrasmissioni eccessive, mentre un RTO troppo lungo può
causare ritardi nella correzione degli errori, portando a una scarsa esperienza utente. Pertanto, un
corretto bilanciamento tra i valori di RTT e DevRTT è essenziale per ottimizzare la comunicazione
attraverso la rete.
Fast Retransmit
Come possiamo vedere da questo grafico, spesso andiamo ad esagerare anche di molto l’RTO
(timer) nel TCP; tuttavia, per compensare a questo scompenso andiamo ad utilizzare la
Ritrasmissione rapida. Quando il mittente riceve tre ACK duplicati, considera che il pacchetto a cui
si riferisce l'ACK duplicato sia andato perso e procede a ritrasmetterlo immediatamente, prima della
scadenza del timer di ritrasmissione.
Esempio
Immaginiamo che il pacchetto 4 sia andato perso. Il destinatario riceve i pacchetti 5, 6 e 7 e invia tre
ACK duplicati per il pacchetto 3, indicando che si aspetta ancora il pacchetto 4. Il mittente, alla
ricezione del terzo ACK duplicato, interpreta questo segnale come un'indicazione di perdita e invia
immediatamente il pacchetto 4 senza attendere il timer.
Questo approccio riduce i tempi di attesa per la ritrasmissione e migliora l'efficienza complessiva
della comunicazione TCP.
TCP non usa un timer per ogni pacchetto, ma usa un solo timer per tutti pacchetti e questo timer
viene resettato ogni volta che arriva un ACK di conferma. Per quanto riguarda gli ACK non ci
preoccupiamo molto della loro perdita, dato che sono cumulativi, basta che arrivino quelli dopo
abbiamo la conferma anche per i precedenti.
Dove:
RcvBuffer: Dimensione totale del buffer del ricevente.
lastbytercvd: L'ultimo byte dei dati ricevuti dal buffer (ma non necessariamente ancora
elaborato).
lastbyteread: L'ultimo byte dei dati che l'applicazione del ricevente ha letto ed elaborato.
Il ricevente comunica periodicamente il valore di rwnd al mittente attraverso i pacchetti ACK.
Il mittente, da parte sua, tiene traccia di 2 variabili: lastbytesent cioè 'ultimo byte dei dati inviati dal
mittente e lastbyteacket, cioè l'ultimo byte per cui ha ricevuto un ACK dal ricevente. Per garantire
che non vengano inviati più dati di quanti il buffer del ricevente possa gestire, il mittente deve
rispettare la condizione: lastbytesent – lastbyteacked ≤ rwnd
Se questa condizione non è rispettata, il mittente deve interrompere temporaneamente l'invio dei
dati fino a che non riceve un aggiornamento del valore di rwnd. La finestra di ricezione è dinamica
perché se l'applicazione del ricevente legge ed elabora rapidamente i dati dal buffer, rwnd aumenta,
permettendo al mittente di inviare più dati; se l'applicazione del ricevente non riesce a leggere
velocemente, il buffer si riempie, e rwnd diminuisce, bloccando temporaneamente il mittente.
Algoritmo di Nagle
L'algoritmo di Nagle è una soluzione ideata per migliorare l'efficienza della comunicazione TCP.
TCP utilizza un meccanismo chiamato sliding window: il destinatario gestisce una finestra di
dimensione variabile alla destinazione, che rappresenta la quantità di dati che può ricevere senza
inviare un ACK. Quando questa finestra si chiude, il mittente è costretto a interrompere
temporaneamente l'invio di dati e attendere che la finestra si riapra. Tuttavia, una volta che si apre,
c'è il rischio che i dati vengano inviati immediatamente in piccole quantità, ossia inviando anche la
quantità minima consentita di byte, causando un sovraccarico della rete. Questo comportamento è
noto come silly window syndrome e porta a un aumento del numero di pacchetti trasmessi, con
conseguente spreco di risorse.
L'algoritmo di Nagle affronta questo problema adottando una strategia basata sull'accumulo dei
dati e sull'ottimizzazione dei tempi di invio. Quando un'applicazione genera dati, anziché inviare
immediatamente ogni byte o piccolo gruppo di byte, il mittente accumula i dati fino a raggiungere
una dimensione sufficiente per formare un pacchetto più grande. Questo riduce il numero
complessivo di pacchetti inviati e quindi il traffico sulla rete.
Il funzionamento dell'algoritmo si basa su due scenari principali:
1. Quando arriva un ACK per il pacchetto precedente, il mittente invia immediatamente il
nuovo pacchetto, garantendo che la trasmissione continui senza ritardi significativi.
2. Quando non arriva un ACK per il pacchetto precedente, il mittente aspetta un breve
intervallo di tempo (detto "ritardo di Nagle", solitamente di circa 200 millisecondi) prima di
inviare un nuovo pacchetto. Durante questo intervallo, possono accumularsi ulteriori dati,
aumentando la probabilità che il prossimo pacchetto inviato sia di dimensioni maggiori.
I due passaggi bilanciano il procedimento nel senso che se da un lato riduce il numero di pacchetti
piccoli inviati, dall'altro evita di introdurre ritardi significativi, assicurandosi che i dati siano inviati
quando necessario.
Lezione 6: livello di trasporto – continuo
TCP, essendo un protocollo orientato alla connessione, richiede che i dispositivi coinvolti nella
comunicazione stabiliscano prima una connessione, la quale verrà poi chiusa in modo esplicito una
volta completato lo scambio di dati. Per questo scopo, TCP utilizza procedure specifiche per
l'apertura e la chiusura della connessione.
Concetto di Sfida
Il "concetto di sfida" in TCP serve a verificare che entrambi gli host siano realmente presenti e
intenzionati a stabilire una connessione. Host 1 vuole aprire una connessione con Host 2. E Host 2
risponde. Dato che Host 1 non vede l'Host 2 e Host 2 non vede l'Host 1, ma semplicemente possono
scambiarsi il messaggio; chi c'è dall'altra parte? Ci sono messaggi vecchi provenienti da Host 2 che
si sono persi? Che spuntano improvvisamente senza motivo? Oppure c'è un reale tentativo di aprire
la connessione? Dato che non si vedono, la sfida è "io ti mando un numero, se tu ora sei presente,
sei online, allora mi devi rispondere con un valore legato al numero che ti sto mandando". Poi la
sfida viene invertita. L'Host 2 sfida l'Host 1 a fare la stessa operazione. Qui non è un problema di
sicurezza, è un problema solo per garantire che vecchi messaggi che circolano nella rete per
qualunque motivo, che non ci interessa, non vadano ad aprire connessioni, quindi a occupare risorse
in maniera inutile. Host 2 apre la connessione solamente se la sua sfida, quella che manda verso
Host 1, ha successo.
L'utilizzo di numeri di sequenza iniziali pseudocasuali serve a distinguere le varie connessioni TCP.
Di solito, questi numeri sono calcolati in base all'ora corrente, prendendo le cifre meno significative
della rappresentazione binaria del tempo, in modo da evitare conflitti con connessioni precedenti.
Il bit SYN viene posto a 1 per i primi due pacchetti inviati. Il mittente invia il primo pacchetto ed
avvia un timer. Non avendo campioni su cui basarmi imposto un timer molto grande per essere
sicuro di coprire il tempo di risposta.
Tuttavia, l’approccio di inizializzare un timer lungo per il primo pacchetto SYN può creare un
problema di sicurezza noto come SYN flood attack. In questo attacco, un malintenzionato invia
continuamente pacchetti SYN a un server, simulando richieste di connessione senza mai completare
l’handshake a tre vie. Ogni pacchetto SYN ricevuto induce il server a riservare risorse e avviare un
nuovo timer.
Dato che le risorse sono bloccate per tutta la durata del timer, il server può rapidamente esaurire il
suo buffer di richieste, causando una saturazione della tabella delle connessioni.
Di conseguenza, il server non può più accettare nuove connessioni legittime, bloccando il servizio
per gli utenti reali.
Il SYN Flood è un tipo di attacco DoS/DDoS che usa proprio la tecnica di flooding per bloccare la
connessione. Può essere eseguito da un singolo attaccante e prende il nome di DoS (Denial of
Service), oppure, se viene effettuato da molti dispositivi coordinati, si parla di DDoS (Distributed
Denial of Service).
Se un segmento di ACK viene perso, TCP utilizza un meccanismo di time-out per la ritrasmissione,
garantendo che entrambi gli host abbiano conferma della chiusura. Tuttavia, se anche dopo i
ritentativi l'ACK non viene ricevuto, l'host chiuderà la connessione in modo forzato per evitare il
blocco, rilasciando le risorse legate alla connessione.
Questo processo è unidirezionale perché una macchina chiude il flusso di dati da un lato, ma l'altro
lato può ancora essere aperto fino a quando non invia il proprio FIN. Quindi, il flusso di dati viene
fermato prima da una parte, ma la chiusura della connessione avviene in due fasi: una per ogni
direzione del flusso di dati. La chiusura finale di entrambi i flussi avviene solo dopo che entrambe
le macchine hanno inviato il proprio FIN e ricevuto l'ACK finale.
**congestione
La congestione di rete si verifica quando il volume di pacchetti che attraversano una rete supera la
capacità di trasmissione della rete stessa. Questo può accadere quando più pacchetti vengono inviati
contemporaneamente, ma la rete (specialmente i router e i dispositivi intermedi) non è in grado di
gestirli tutti. Sebbene i canali di comunicazione abbiano una certa capacità massima, è la gestione
dei pacchetti attraverso la rete, in particolare da parte dei router, che può causare congestionamento.
Andiamo ad esaminare vari scenari che ci mostreranno al meglio i motivi che portano alla
congestione:
SCENARIO 1: Due mittenti, un router con buffer illimitato
Abbiamo un host A e un host B che mandano dati ad una certa frequenza media di in byte/s dove
questi dati sono solo dati originali (niente ritrasmissioni ecc.). Questi dati viaggiano su un canale
condiviso con capacità massima R. Ora, quello che succede è che avremo R/2 per il canale A-
Router e R/2 per il canale Router-B. Supponiamo inoltre che il router che ci sia in mezzo abbia un
buffer illimitato.
Fino a quando inviamo dati con un valore che non supera R/2, naturalmente questi arrivano senza
alcun tipo di problema ma, se il tasso supera R/2, il router non può trasmettere i dati in tempo
reale; quindi, i pacchetti si accumulano nel buffer a un ritmo sempre maggiore, causando ritardi.
Di fatto, più ci avviciniamo a R/2 di throughput, maggiore sarà il ritardo che andrà al limite a
tendere ad infinito. Avere dunque un throughput vicino a R/2, per quanto possa sembrare una cosa
conveniente, porterebbe a maggiori ritardi di accodamento.
Secondo caso: A ritrasmette i messaggi, solo quando è sicuro che un pacchetto si è perso.
Consideriamo che il carico offerto valga R/2. Con questo valore di carico effettivo, abbiamo che i
dati consegnati a destinazione non sono più di R/2, bensì di R/3. Dunque, possiamo anche rilevare
un altro costo legato alla congestione di rete, cioè, che il mittente deve andare a ritrasmette i
pacchetti perduti a causa del buffer.
Terzo caso: sia il pacchetto originale che la ritrasmissione arrivano al destinatario. Ovviamente al
destinatario servirà solo un pacchetto e scarterà quindi i duplicati arrivati inutilmente. Dunque,
abbiamo che il router ha sprecato del tempo a indirizzare i pacchetti copia che alla fine non
servivano, avrebbe potuto infatti utilizzare meglio questo tempo per instradare altri pacchetti nuovi.
SCENARIO 3: Quattro mittenti, router con buffer limitati e percorsi composti da più
collegamenti
Supponiamo che in questo caso i pacchetti trasmessi dai quattro host viaggino su percorsi composti
da due collegamenti sovrapposti tra loro. Inoltre, ciascun Host implementa una connessione
affidabile e tutte le relative conseguenze di ritrasmissioni ecc.
Prendiamo la connessione A-C che passa per i router R1 e R2. Questa connessione condivide il
router R1 con la connessione D-B e stessa cosa fa il Router R2 con la connessione B-D. Per in
molto piccoli, gli overflow dei buffer saranno molto rari e il throughput sarà uguale al traffico di
rete.
Consideriamo invece in più grandi, immaginiamo che A voglia comunicare con C e manda un
pacchetto che passa prima da R1 senza alcun problema, ma che poi su R2 viene scartato a causa del
buffer pieno per i messaggi che ci sono da B verso D. E così via, più aumenta il traffico di dati tra B
e D, maggiore sarà la competizione per accaparrarsi lo spazio nel buffer di R2 creando così
congestione nel canale che potrebbe portare a throughput 0 nella connessione A-C su R2. Notiamo
quindi un grave spreco perché i pacchetti inviati nel primo R1, verranno poi buttati da R2 e quindi
avremo creato traffico inutile sulla rete causando congestione.
Evento 3 ACK duplicati: la risposta a questa situazione è diversa rispetto a TCP Tahoe:
Applica il Fast Retransmit: Non bisogna aspettare che scada il timer per ritrasmettere il pacchetto
perso. Quando il mittente riceve tre ACK duplicati (cioè, il destinatario ha ricevuto dei pacchetti
ma uno non è stato ancora riconosciuto), TCP considera che il pacchetto indicato è stato perso. A
questo punto, TCP ritrasmette subito il pacchetto senza attendere.
Fast Recovery (è raccomandata ma non obbligatoria): Dopo il Fast Retransmit, non torna a 1 MSS
come avviene con un time-out. Invece, TCP Reno continua la trasmissione con una finestra di
congestione ridotta, ma non riparte dalla fase Slow Start. La finestra di congestione ridotta
permette di recuperare il flusso senza resettare completamente il processo di trasmissione. La
riduzione della finestra avviene linearmente, e si entra nella fase AIMD per controllare la crescita
della finestra.
Possiamo avere un throughput maggiore di R quindi? Teoricamente no, ma... invece sì. Come?
Consideriamo il fatto che nei router ci siano dei buffer che possono accumulare pacchetti. Questo
significa che, anche se il link ha una capacità R, il sistema potrebbe inviare pacchetti più
rapidamente per un breve periodo, esaurendo i pacchetti in coda. È questa accumulazione che porta
il throughput oltre R per un istante. Quindi, può capitare di arrivare nella zona oltre il segmento R1
R2. Però arrivare in questa zona del grafico, e quindi di avere un punto in questa zona oltre il max
throughput, vuol dire che i pacchetti si stanno accumulando e quindi le code si riempiono e prima o
poi si arriva alla perdita di qualche pacchetto per time-out o triplo ACK duplicato.
Conclusione: L'accumulo nei buffer è solo un fenomeno temporaneo. Non può sostenere un
throughput maggiore di R per un lungo periodo. Superare R significa che il sistema sta operando in
modo instabile, e prima o poi si verificano perdite di pacchetti o rallentamenti.
Il Data Plane, noto anche come piano dati o piano di inoltro, è la parte operativa che si occupa di
leggere i pacchetti, analizzarne l’intestazione e inoltrarli al nodo successivo secondo le indicazioni
contenute nella tabella di routing operando a livello locale, nodo per nodo.
Il Control Plane, noto come piano di controllo o piano di instradamento, gestisce invece la parte
"intelligente" della rete, ossia la configurazione e la scelta dei percorsi migliori per i pacchetti
attraverso la rete.
In questo modo, il Control Plane stabilisce le regole e le configurazioni che il Data Plane segue per
gestire il traffico dati (esegue il lavoro fisico). I due piani collaborano strettamente per garantire il
corretto funzionamento della rete.
Abbiamo due approcci al control plane per la gestione della rete:
1. Approccio Distribuito Tradizionale (Control Plane Distribuito)
Ogni router possiede un control plane integrato. In pratica, ogni router ha un algoritmo di routing
incorporato che gli consente di prendere decisioni di instradamento del traffico in modo autonomo e
decentralizzato. Ogni router adatta le proprie decisioni di routing in tempo reale, aggiornando la
propria tabella di routing basata sulle nuove informazioni ricevute da altri dispositivi.
Vantaggi: se un dispositivo fallisce, la rete si riorganizza autonomamente; buona scalabilità in reti
grandi e complesse.
Svantaggi: Maggiore complessità di configurazione e aggiornamento
1. Porte di ingresso
Svolgono le funzioni (a livello fisico) di terminazione di un collegamento in ingresso di un router e
di indirizzamento verso la porta d’uscita (funzione di forwarding= inoltro).
Nelle porte di input di un router, si ha un componente che lavora a livello fisico e che si occupa di
ricevere i pacchetti di dati provenienti dalle diverse interfacce di rete. Successivamente, i dati
ricevuti vengono bufferizzati per consentire una gestione efficiente del traffico, in quanto non è
detto che i pacchetti vengano inoltrati con la stessa velocità con cui vengono ricevuti.
Per assegnare un'uscita a un pacchetto in ingresso, si cerca una voce della tabella di inoltro
con il prefisso di indirizzo più lungo che matcha all'indirizzo di destinazione.
Abbiamo due tipi di inoltro: destination based e generalized. Quello destination based si basa
unicamente sull’indirizzo IP di destinazione ed è quello tipicamente utilizzato mentre quello
generalized si basa su alcuni valori nel campo dell’header.
Una tabella di inoltro contiene dei range degli indirizzi di destinazione alle quali corrispondono
delle interfacce (uscite).
Questi possono anche essere indicati diversamente specificando solo la maschera che consiste nei
primi X bit, questa ci va ad indicare che quei X bit devono essere fissi mentre gli altri possono
essere variabili (quelli indicati con *).
In questo caso possiamo notare che l’interfaccia 1 e la 2 hanno maschere “simili”, nel caso in cui
abbiamo un indirizzo che combacia con entrambe, utilizziamo la regola del prefisso più lungo cioè
lo indirizziamo in base al prefisso più lungo che combacia, in questo caso l’interfaccia 1.
Abbiamo bisogno che la ricerca venga effettuata in nanosecondi, per fare ciò ricorriamo alle
memorie TCAM che per un IP a 32 bit, riescono ad effettuare le ricerca in un tempo costante,
indipendentemente dal numero di voci presenti nelle tabelle.
CAM e TCAM
Le memorie associative CAM e TCAM (Content-Addressable Memory e Ternary Content-
Addressable Memory) rendono estremamente veloce la ricerca nelle tabelle di routing.
La CAM è una memoria che permette di effettuare ricerche basate su corrispondenze esatte. In
altre parole, con la CAM si può cercare un dato specifico (come un indirizzo IP) e ottenere
immediatamente il corrispondente valore associato (come la porta di uscita), se presente.
Utilizza la ricerca esatta, ovvero confronta l'indirizzo del pacchetto con quelli memorizzati e
restituisce il risultato solo se trova una corrispondenza completa. Esegue la ricerca simultaneamente
su tutti gli indirizzi memorizzati, offrendo così un tempo di ricerca molto veloce. La CAM viene
spesso usata per compiti di ricerca come quelli nelle tabelle ARP.
La TCAM è un’evoluzione della CAM, che aggiunge la capacità di effettuare ricerche parziali. A
differenza della CAM, che confronta solo valori binari (0 e 1), la TCAM permette di avere tre
stati: 0, 1 e "don't care" (X). Questo significa che può effettuare ricerche con maschere di bit,
permettendo di identificare in modo flessibile indirizzi parziali o più indirizzi contemporaneamente.
La X rappresenta una posizione in cui il bit può essere ignorato, rendendo la TCAM ideale per
l’utilizzo di maschere di rete e prefissi IP.
2. Struttura di commutazione
È un meccanismo che permette di trasferire i pacchetti di dati dalle porte di ingresso alle porte di
uscita, dove vengono instradati verso la destinazione. Questa struttura può essere implementata con
diverse architetture, ognuna con vantaggi e svantaggi in termini di velocità, complessità e costo.
1. Architettura della Memoria Condivisa: I primi router utilizzavano le porte come dei semplici
dispositivi I/O. Questi ricevevano i pacchetti, li mettevano nella memoria del processore di
instradamento che trovava l’indirizzo di destinazione e copiava il pacchetto nella memoria del
buffer d’uscita. Naturalmente questo approccio era piuttosto semplice e parecchio economico visto
che non richiedeva un particolare tipo di processore personalizzato a questo scopo. Lo svantaggio è
che richiede molti accessi alla memoria, che possono rappresentare un collo di bottiglia; per grandi
volumi di traffico, questa architettura risulta lenta e non scalabile.
2. Architettura del Bus Condiviso: le porte d’ingresso sono collegate a quelle d’uscita tramite un
bus unico e inviano il pacchetto lì, senza l’intervento del processore d’instradamento. Per fare ciò le
porte d’ingresso mettono un flag che indica in quale porta d’uscita deve andare e, una volta arrivato
a destinazione, questo flag viene tolto e il pacchetto spedito. Naturalmente consideriamo che la
larghezza di banda della commutazione è limitata a quella del bus in questo caso. Abbiamo una
maggiore velocità rispetto alla memoria condivisa, poiché elimina l’accesso ripetuto alla memoria
centrale, ma il bus diventa un collo di bottiglia quando il traffico è elevato, poiché può gestire un
solo trasferimento alla volta.
3. Architettura della Rete di Interconnessione
Un modo per superare la limitazione di banda di un singolo bus condiviso è l’utilizzo di una rete di
interconnessione più sofisticata, quale quella usata in passato nelle architetture multicore. Questa
architettura permette di gestire flussi di traffico simultanei da diverse porte di ingresso a diverse
porte di uscita. È usata nei router ad alte prestazioni, dove è fondamentale gestire un alto volume di
traffico in modo efficiente.
In base alle tempistiche del router, potremmo avere degli accodamenti in vari luoghi: in particolare
se il tempo di commutazione è più lento di quello d’arrivo dei pacchetti, allora naturalmente avremo
una coda nelle porte d’ingresso e si creerà un HOL blocking**. Se invece sono lente le porte di
output rispetto al tempo di commutazione allora quei buffer si andranno man mano riempiendo
creando degli accodamenti anche nelle porte d’ingresso.
**L'HOL blocking (Head-of-Line blocking) si verifica quando un pacchetto bloccato in una coda
d'ingresso impedisce il trasferimento di altri pacchetti che si trovano dietro di esso, anche se questi
ultimi potrebbero essere instradati verso destinazioni differenti.
3. Porte di Uscita
Le porte di uscita memorizzano i pacchetti provenienti dalla struttura di commutazione e li
trasmettono sui link di uscita. Oltre alla trasmissione, le porte di uscita svolgono anche operazioni
del livello data-link e del livello fisico, come il controllo degli errori e la codifica/decodifica del
segnale.
Le porte di uscita hanno delle code di uscita che gestiscono i pacchetti in attesa di essere trasmessi.
In caso di congestione, le code possono temporaneamente bufferizzare i pacchetti o, in casi estremi,
scartarli per evitare il sovraccarico.
Il buffering nei router è essenziale per gestire in modo efficiente il traffico di rete, evitando la
perdita di pacchetti in condizioni di congestione. Tuttavia, la quantità di memoria da allocare per il
buffering deve essere calcolata attentamente per bilanciare tra la capacità di gestire picchi di traffico
e la necessità di evitare ritardi eccessivi, soprattutto per le applicazioni in tempo reale.
La formula per determinare la capacità di buffering ottimale in un router è:
Dove:
RTT (Round Trip Time) è il tempo di andata e ritorno, cioè il tempo necessario perché un
pacchetto viaggi dalla sorgente alla destinazione e ritorni alla sorgente.
C è la capacità del link di rete, ossia la massima quantità di dati che il link può trasferire in
un’unità di tempo (ad esempio, in bit per secondo).
N è il numero di flussi di dati presenti nella rete.
Interpretazione della Formula
Prodotto RTT e C: Il buffering necessario aumenta proporzionalmente all’aumento del
RTT e della capacità del link. Questo significa che se il tempo di viaggio dei pacchetti o la
velocità del link sono alti, il router avrà bisogno di un buffer maggiore per contenere i
pacchetti in attesa di essere instradati.
Radice quadrata del numero di flussi N: Aumentando il numero di flussi di dati nella rete,
il buffering necessario diminuisce in proporzione alla radice quadrata di N. L'idea è che
aumentando il numero di flussi di dati (N), il traffico diventa più equilibrato. Questo accade
perché avere più flussi distribuisce meglio i pacchetti, riducendo la probabilità di
congestione concentrata sul singolo flusso.
Considerazioni sul Buffering
Un buffering eccessivo può aumentare il tempo di attesa per i pacchetti, con il rischio di ritardi
elevati, soprattutto per le applicazioni in tempo reale. Quando il buffer è troppo grande, i pacchetti
si accumulano e possono subire ritardi significativi, generando fenomeni di bufferbloat (eccessivo
ritardo a causa del buffering).
Per le applicazioni che non sono sensibili alla latenza, come il trasferimento di file, un buffer più
grande potrebbe non causare problemi significativi. Tuttavia, per applicazioni interattive, un
buffering eccessivo può degradare l’esperienza dell’utente.
La quantità di buffering deve essere determinata in base alle caratteristiche del traffico di rete e al
carico previsto. Se la rete ha molte connessioni (alto valore di N), il buffer può essere ridotto.
Viceversa, per reti con pochi flussi di dati e tempi di andata e ritorno elevati, il buffering deve
essere maggiore per evitare perdite di pacchetti.
- Classe B è destinata a reti di medie dimensioni, come reti aziendali; i primi due ottetti (16
bit) identificano la rete, e i successivi due (16 bit) identificano l'host, permettendo circa
65.000 host per rete.
- Classe C: 24 bit (3 byte) per la rete e lasciava solo 8 bit per gli host, permettendo fino a 254
host per rete. La classe C è usata per reti di piccole dimensioni, come reti domestiche o
piccoli uffici.
La classe D Utilizzata per il Multicast, ovvero per inviare pacchetti a un gruppo di dispositivi
piuttosto che a uno specifico destinatario; Non ha una suddivisione tra parte di rete e parte di host.
La classe E è riservata per scopi sperimentali o di ricerca; anche questa non ha una suddivisione
tra parte di rete e parte di host e generalmente non è utilizzata in reti pubbliche.
All'interno delle classi A, B e C, ci sono anche indirizzi riservati per uso privato (non instradabili
su Internet), come:
Classe A: 10.0.0.0 – 10.255.255.255
Classe B: 172.16.0.0 – 172.31.255.255
Classe C: 192.168.0.0 – 192.168.255.255
Questi indirizzi sono utilizzati in reti locali e permettono di risparmiare indirizzi pubblici, grazie
all'uso di tecniche come il NAT (Network Address Translation).
Header IPv4
I pacchetti IPv4 vengono trasmessi attraverso la rete in modo indipendente, ovvero ogni pacchetto
può seguire percorsi diversi fino alla destinazione. I router utilizzano le informazioni
nell'intestazione, come l’indirizzo di destinazione, per determinare la rotta migliore per il pacchetto.
Basandosi sul campo "lunghezza dell'intestazione" e sugli indirizzi IP contenuti nell’intestazione, la
TCAM consente di confrontare l’indirizzo di destinazione con gli indirizzi presenti nelle tabelle di
routing in modo molto rapido e parallelo.
Indirizzamenti
l’interfaccia è il punto di contatto tra un dispositivo e il collegamento fisico a una rete.
Un host ha in genere un solo collegamento fisico alla rete, quindi una sola interfaccia, che
rappresenta il punto di connessione tra il dispositivo e la rete. Quando l'host deve inviare o ricevere
dati, lo fa tramite questa interfaccia. I router devono avere almeno due collegamenti per ricevere
dati da una rete e inoltrarli su un'altra. Ogni collegamento a una rete, come per l'host, è
un'interfaccia.
Ogni interfaccia deve avere un indirizzo IP univoco (escluso nel caso di NAT), che permette di
identificare la connessione del dispositivo su una determinata rete.
L'indirizzo IP è, quindi, associato all'interfaccia, non all'host o al router in sé. Questo perché ogni
interfaccia può essere considerata come una "uscita" o "entrata" della rete e deve avere un proprio
identificativo.
Indirizzi flat
Gli indirizzi flat non seguono una struttura gerarchica; non includono informazioni su reti o
posizioni geografiche. Ogni indirizzo è univoco ma autonomo, senza alcun indizio su una possibile
gerarchia. Gli indirizzi flat sono comuni nelle reti locali, dove la necessità di instradare pacchetti su
vaste aree geografiche non è rilevante. Ad esempio: Gli indirizzi MAC (Media Access Control),
usati per identificare le schede di rete in reti locali, sono flat. Ogni scheda di rete ha un indirizzo
MAC unico, ma non fornisce informazioni geografiche o di rete.
Subnetting
Il Subnetting è una tecnica utilizzata per suddividere una rete IP in sottoreti più piccole, che
permette una gestione più efficiente degli indirizzi IP e facilita il controllo del traffico di rete.
Esempio di subnetting
Consideriamo l'indirizzo 192.168.1.7/24:
Indirizzo IP: 192.168.1.7 → in binario 11000000.10101000.00000001.00000111
Subnet Mask: /24, che corrisponde a 255.255.255.0 in decimale e
11111111.11111111.11111111.00000000 in binario.
Parte di rete: I primi 24 bit
dell’indirizzo 192.168.1.7 sono 11000000.10101000.00000001 (ovvero 192.168.1 in decimale).
Questa parte identifica la rete di appartenenza.
Parte di host: Gli ultimi 8 bit 00000111 (ovvero 7 in decimale) identificano il dispositivo specifico
(host) all’interno di quella rete.
In questo esempio, la rete 192.168.1.0/24 può contenere fino a 254 host
(da 192.168.1.1 a 192.168.1.254), poiché i due indirizzi (192.168.1.0 e 192.168.1.255) sono
riservati per la rete e il broadcast, rispettivamente.
Indirizzi speciali
Alcuni indirizzi speciali non possono essere utilizzati per configurare host all’interno di una rete:
L'indirizzo 0.0.0.0 viene utilizzato come indirizzo di default o indirizzo di "tutti gli indirizzi" in
alcune situazioni. Ad esempio, un dispositivo potrebbe utilizzarlo come indirizzo IP sorgente
quando invia pacchetto su un una rete se non ha ancora un indirizzo IP assegnato.
L'indirizzo 255.255.255.255, noto anche come indirizzo di broadcast limitato, viene utilizzato per
inviare pacchetti di broadcast a tutti i dispositivi nella stessa rete locale. Quando un dispositivo
invia un pacchetto a questo indirizzo, il pacchetto viene trasmesso a tutti i dispositivi nella LAN.
La subnet mask con prefisso /31 viene utilizzata quando sono presenti solo due router agli estremi
di un collegamento senza alcuna macchina intermedia. In condizioni normali, per una sottorete con
2 indirizzi IP (come in una subnet /30), uno degli indirizzi sarebbe riservato per la rete e l'altro per il
broadcast, rendendo inutilizzabili entrambi per gli host. Con una subnet /31, invece: Non ci sono
indirizzi per rete e broadcast. Entrambi gli indirizzi sono usati per i due dispositivi del collegamento
punto-punto.
Il MAC Andress (Media Access Control) è un identificatore unico assegnato a ciascuna scheda di
rete da parte del produttore e rimane generalmente invariato per tutta la vita del dispositivo,
utilizzato per identificare i dispositivi all'interno di una LAN.
È suddiviso in due parti: Organizationally Unique Identifier (OUI): I primi 3 byte identificano il
produttore (es. 00:1A:2B). Gli ultimi 3 byte sono assegnati in modo univoco dal produttore per
distinguere i dispositivi prodotti.
Come fa una macchina a capire che la macchina a cui vuole inviare il messaggio non si trova nella
sua rete? Ogni macchina conosce il suo IP e da questo ricava la sua subnet mask. Dopodiché,
trovata la propria subnet, effettua un AND tra la sua maschera e la maschera di destinazione, se
questa corrisponde allora sa che la macchina è nella sua sottorete e dunque la invia nella subnet,
altrimenti invia il frame all’interfaccia del router che si occuperà di inviare il pacchetto.
Tuttavia, è importante sottolineare che l'indirizzo MAC non cambia casualmente, ma viene
sostituito da una macchina intermedia solo durante il passaggio del pacchetto attraverso quella
macchina. L'indirizzo MAC originale del mittente e della destinazione viene preservato all'interno
del pacchetto stesso.
Se la destinazione del pacchetto si trova fuori della LAN, allora il pacchetto deve essere inviato al
router di rete. Il router funge da gateway predefinito per la rete e viene utilizzato per instradare i
pacchetti di dati tra le diverse reti. Il router analizza l’indirizzo IP di destinazione del pacchetto e lo
inoltra alla rete corretta fino a quando non raggiuge la destinazione finale. A livello di Data Link
Layer, il dispositivo sorgente invia il pacchetto al MAC address del router. Un router spesso ha più
interfacce di rete: una per la connessione alla rete locale (LAN) e una per la connessione alla rete
esterna (internet, WAN). Ogni interfaccia avrà un proprio MAC address univoco.
Discussione d’esame
Abbiamo due LAN separate da un Router (Livello 3 quindi) di mezzo. Ha infatti sia indirizzi IP che
MAC per ogni interfaccia. Analizziamo 2 casi: supponiamo che una macchina abbia necessità di
parlare con un’altra macchina, che potrebbe trovarsi sia nella sua stessa LAN che in una LAN
differente, anche attraversando più router.
Stessa LAN:
Il mittente deve solo scoprire che il destinatario appartiene alla stessa LAN; quindi, può preparare
un frame Ethernet (ricordiamo che la comunicazione avviene a livello DLL, non IP, perché il
datagramma IP è incapsulato nella frame Ethernet). Deve solo scoprire il MAC Address del
destinatario, cosa che può fare con ARP mandando in broadcast la richiesta. Questa macchina potrà
rispondere tranquillamente alla richiesta broadcast in quanto si trova sulla stessa LAN.
Questo processo funziona perché entrambe le macchine sono raggiungibili direttamente a livello
di Data Link Layer.
LAN Differenti:
Se il destinatario è fuori dalla sua LAN non può usare ARP per scoprire il MAC address della
destinazione, per due motivi:
a Il router è come una barriera tra le due LAN: ha due interfacce separate per ciascuna LAN
(quella rossa e quella verde); quindi, ciascuna interfaccia lavora su una rete di
collegamento separata. Quando un pacchetto IP deve attraversare il router per andare da
una LAN all'altra, il router “scarta” l’intestazione Ethernet del pacchetto (contenente il
MAC address del mittente e destinatario). Una volta raggiunto il router, quindi, l'indirizzo
MAC originale non serve più, perché il router rielabora il pacchetto, ricreando una nuova
intestazione Ethernet per la LAN di destinazione con il MAC address della sua interfaccia di
uscita verso la rete di destinazione.
b Non esiste solo Ethernet: Ci sono reti DLL che non hanno il MAC Address (per esempio
tante macchine collegate tutte punto a punto), quindi semplicemente dire che il mittente
vuole conoscere il MAC Address della destinazione è inutile, perché potrebbe anche non
esistere.
Soluzione: Quando il mittente vuole inviare un pacchetto a un dispositivo fuori dalla propria LAN,
deve inviare il pacchetto al router. Il router riceve il pacchetto, spacchetta il frame Ethernet
originale (leggendo solo il pacchetto IP), e poi crea un nuovo frame Ethernet per la LAN di
destinazione, che conterrà i MAC address della LAN di destinazione (se Ethernet è supportato su
quella LAN).
Quando una macchina deve inviare un pacchetto di dati, consulta la tabella di routing per
determinare il percorso migliore per la destinazione. Se la destinazione si trova sulla stessa subnet,
la macchina invia il pacchetto direttamente alla destinazione. In caso contrario, cerca il router di
rete predefinito (gateway predefinito) e invia il pacchetto a questo router per l'instradamento verso
la destinazione.
DHCPv4 (Dynamic Host Configuration Protocol versione 4)
Il protocollo DHCPv4 è un protocollo di rete utilizzato per l'assegnazione dinamica degli indirizzi
IP alle macchine sulla rete, apprendere informazioni sulla propria maschera di sottorete, l’indirizzo
del router per uscire dalla sottorete e in fine l’indirizzo del DNS server locale. DHCPv4 consente
alle macchine di ottenere un indirizzo IP valido in modo automatico, senza la necessità di
assegnarlo manualmente, per questo si dice plug&play.
Supporta sia l’assegnazione di indirizzi statici, ma anche quella di indirizzi IP temporanei (o
dinamici), noti come indirizzi IP "leasing". Nel primo caso, un server DHCP può essere configurato
per assegnare sempre lo stesso indirizzo IP a un dispositivo in base al suo MAC address. Nel
secondo caso, l'indirizzo IP viene assegnato alla macchina solo per un periodo di tempo limitato
(lease time). Prima che il lease scada, il client deve inviare una richiesta di rinnovo al server per
continuare a utilizzare lo stesso indirizzo. Se il client non rinnova il lease, l'indirizzo IP viene
restituito al pool di indirizzi disponibili e può essere assegnato ad altri dispositivi. Questo consente
di gestire in modo più efficiente gli indirizzi IP disponibili sulla rete. Il protocollo DHCPv4 è
Client-Server e prevede quattro fasi principali per l'assegnazione dell'indirizzo IP:
1. Scoperta (DHCP discover): inizia quando il client DHCP si connette alla rete e
invia un messaggio di scoperta in broadcast sulla rete locale alla ricerca di un server
DHCP disponibile. Il messaggio contiene informazioni come l'identificatore del
client, il tipo di hardware utilizzato e le opzioni di configurazione richieste.
2. Offerta (DHCP offer): il server DHCP riceve il messaggio di scoperta e invia un
messaggio di offerta al client. In questo messaggio, il server offre un indirizzo IP
disponibile al client DHCP, la durata della concessione dell’indirizzo e altre
informazioni di configurazione come subnet mask e l'indirizzo del gateway e i server
DNS.
3. Richiesta (DHCP request): il client DHCP riceve il messaggio di offerta dal server
e invia un messaggio di richiesta per confermare l'assegnazione dell'indirizzo IP
offerto dal server. In questo messaggio, il client DHCP richiede l'assegnazione
dell'indirizzo IP offerto dal server. Se il client riceve più offerte da diversi server,
sceglie una e la comunica esplicitamente agli altri server per informare che non
devono assegnare quell'indirizzo IP.
4. Conferma (DHCP Ack): il server DHCP riceve il messaggio di richiesta e invia un
messaggio di ACK al client per confermare l'assegnazione dell'indirizzo IP richiesto
e ora può utilizzarlo. Il messaggio ACK contiene l'indirizzo IP assegnato al client,
insieme alle altre informazioni di configurazione richieste.
Il server DHCP mantiene un registro dello stato delle assegnazioni degli indirizzi IP ai client
(stateful), però non prevede l'autenticazione.
Perché sono necessari 4 passaggi? Per prevenire conflitti di indirizzi IP.
Immaginiamo che più di un server DHCP esista nella rete e che ogni server stia cercando di
assegnare indirizzi IP. Se un client ricevesse un indirizzo IP senza conferma, ci sarebbe il rischio
che un altro server DHCP possa assegnare lo stesso indirizzo IP a un altro dispositivo, creando
un conflitto di indirizzi IP. La sequenza di REQUEST e ACK serve proprio a: Confermare che il
server che ha fatto l'offerta è l'unico responsabile di quel determinato indirizzo IP. Escludere
conflitti nel caso in cui più server DHCP rispondano a una richiesta di un client. In pratica, il client
invia la REQUEST per dichiarare esplicitamente al server quale indirizzo IP vuole. Il server,
quindi, riserva l'indirizzo e lo "blocca" per quel client.
I router abilitati al NAT non appaiono come router al mondo esterno, ma si comportano come un
unico dispositivo con un unico indirizzo IP.
Quindi per la comunicazione gli utenti della sottorete avranno tutti l’indirizzo IP del router a cui
sono collegati ma saranno anche identificati tra loro con un indirizzo IP privato che avrà senso solo
lì. Tutti i datagrammi arrivati al router, avranno sempre lo stesso IP e dunque, per distinguere i vari
client connessi alla rete utilizziamo una tabella di traduzione NAT.
Esempio: Un client con IP 192.168.56.100 fa richiesta di una pagina server (porta 80) e così manda
la richiesta al suo router partendo con una porta 1234. Il router NAT che riceve il datagramma
cambia la porta sostituendola con un’altra 5580 e sostituisce l’indirizzo IP sorgente con il proprio
indirizzo pubblico. Poi registra questa associazione nella tabella. Quando il datagramma di risposta
arriva all'indirizzo IP pubblico e alla porta pubblica, il NAT consulta la tabella. Trova l'associazione
originale e modifica il pacchetto sostituendo l'indirizzo IP pubblico e la porta pubblica con
l'indirizzo IP privato e la porta privata corrispondenti. Il pacchetto viene quindi inviato al
dispositivo interno. Se una connessione rimane inattiva per troppo tempo, il NAT elimina la voce
corrispondente dalla tabella, liberando risorse.
Abbiamo però delle pecche, infatti il NAT usa le porte per identificare gli host, cosa per cui questi
non erano progettati (ambiguità). Le porte TCP/UDP, progettate originariamente per distinguere
processi di un singolo host, vengono sfruttate dal NAT per identificare gli host stessi nella rete
privata. L'uso intensivo delle porte può portare a esaurimento in scenari con un elevato numero di
connessioni simultanee.
Inoltre, il NAT viola il principio end to end che prevede che i dispositivi di origine e destinazione
possano comunicare direttamente senza modifiche ai pacchetti in transito, dovuto alla netta
separazione tra spazi di indirizzamenti pubblici e privati.
La distinzione netta tra indirizzi pubblici e privati crea uno scenario in cui gli indirizzi privati
possono riutilizzarsi in reti diverse, ma ciò introduce ambiguità nelle connessioni in alcuni scenari
complessi (es., VPN o reti sovrapposte).
Inoltre, protocolli che crittografano l'intestazione IP possono non funzionare correttamente con
NAT, poiché il NAT non può modificare i dati crittografati.
NB. Il server NAT non necessariamente è un router ma potrebbe essere una macchina sulla rete in
grado di gestire pacchetti IP e svolgere traduzioni di indirizzi. Il NAT è stateful per definizione e
funziona registrando una connessione solo quando il primo pacchetto parte dalla rete interna.
Mantiene uno stato attivo per ogni connessione registrata. Questo stato è rappresentato dalla tabella
di traduzione.
Questo impedisce a dispositivi esterni di avviare connessioni con dispositivi interni. Protegge la rete
privata, ma introduce problemi per servizi che richiedono connessioni in ingresso non previste.
Sicurezza: Il livello di sicurezza di IPv4, posto dopo il livello di trasporto, tiene in chiaro tutti i dati
successivi, inclusi gli indirizzi IP e le porte.
Questi dati sensibili vengono trasmessi in chiaro, rendendoli vulnerabili agli attacchi di spoofing
degli indirizzi IP. IPv6 invece supporta la crittografia e la sicurezza dei pacchetti attraverso
l'utilizzo di IPsec, un insieme di protocolli di sicurezza che forniscono autenticazione, integrità dei
dati e crittografia per i pacchetti IP.
Gestione della qualità del servizio (QoS): consente di garantire determinati livelli di servizio per
le applicazioni. In IPv4, la QoS è gestita mediante il campo Type of Service (ToS) nell'header IP
ma non viene mai sfruttato.
IPv6 il bit Flow Label (etichetta di flusso) consente di fornire un livello di servizio differenziato per
flussi di traffico specifici sulla rete.
Questo metodo semplifica la configurazione automatica degli indirizzi IPv6 per le interfacce di rete,
garantendo anche l'unicità degli identificatori.
L'indirizzo IPv6 completo viene generato combinando:
I primi 64 bit dal prefisso della rete (dato dal router).
I secondi 64 bit calcolati con l'EUI-64.
Un router IPv6 pubblica periodicamente informazioni sulla rete tramite i messaggi ICMPv6 Router
Advertisement, che includono il prefisso della rete (es. 2001:db8::/64). (L'EUI-64 non è
l'autoconfigurazione completa di IPv6, ma è una parte fondamentale del processo.)
Algoritmi di Routing
Gli algoritmi di Routing sono algoritmi utilizzati dai router per determinare il percorso ottimale per
instradare i pacchetti attraverso una rete. Quando si parla di Routing distribuito si fa riferimento ad
un approccio nel quale l'algoritmo di Routing è in esecuzione in ogni nodo della rete in modo
distribuito ed indipendente dagli altri nodi. Ogni nodo utilizza le informazioni locali per
determinare il percorso migliore per instradare i pacchetti. In un approccio distribuito, bisogna che
risulti chiaro quando l'algoritmo inizia la propria esecuzione e quando l'algoritmo si conclude.
Gli algoritmi di instradamento hanno lo scopo di determinare i percorsi o cammini tra le sorgenti e i
destinatari attraverso i router. Il percorso migliore è quello che ha costo minimo. Per dimostrare gli
algoritmi di instradamento faremo utilizzo di un grafo che è un insieme di N nodi e un insieme di E
di archi. Un percorso è una sequenza di nodi.
Distinguiamo gli algoritmi di Routing in statici/dinamici e globali/locali. Un algoritmo di Routing
si definisce statico se non implementa una tecnica adattiva alle congestioni o i vari guasti, un
algoritmo dinamico è invece responsivo ai rallentamenti e ai problemi della rete. Inoltre, gli
algoritmi globali (link-state) per funzionare necessitano di conoscere tutta la topologia della rete
mentre in quelli locali nessun nodo possiede informazioni complete sul costo di tutti i collegamenti
se non quelli adiacenti. Tramite un processo iterativo ottiene le informazioni sulla rete dai nodi
adiacenti.
Flooding: è un algoritmo di Routing distribuito locale. Come funziona? ogni nodo inoltra il
pacchetto ricevuto (detto di Hello) a tutti i nodi ad esso adiacenti, che a loro volta lo inoltrano ai
propri vicini, e così via, fino a quando il pacchetto raggiunge la destinazione finale. L'algoritmo di
flooding è molto semplice da implementare e non richiede conoscenza della topologia della rete. In
tali reti, l'algoritmo di flooding può garantire una maggiore resilienza alla rete, poiché ogni nodo ha
la possibilità di inoltrare il pacchetto a tutti i nodi vicini, indipendentemente dalla loro posizione o
dal loro stato di connessione.
Questo algoritmo non viene utilizzato in Internet perché può causare una congestione di rete e
perché non fornisce un percorso ottimale per il pacchetto.
Si necessita di un modo per bloccare il flooding in quanto la ritrasmissione continua di pacchetti su
tutti i link provoca una congestione dovuta al fatto che molti pacchetti vengono rispediti molte
volte sugli stessi link. A tal proposito sono state proposte diverse soluzioni:
• Usare un ID per i pacchetti: così da poter tenere conto di tutti i pacchetti di cui si fa forwarding,
in modo da non ritrasmettere duplicati.
Questo approccio risolve la congestione ma sorge il problema della dimensione della tabella che
tiene conto di tutti i pacchetti inoltrati e diventa difficoltoso memorizzarla a meno che il passaggio
di un pacchetto per un link non sia sporadico.
• TTL limite: Se si possono fare assunzioni sulla rete si può invece pensare di stabilire un TTL
limite pari al diametro del grafo, ovvero la distanza massima tra una coppia di nodi del grafo.
(diametro: massimo valore tra tutti i percorsi minimi che coinvolgono tutte le coppie di nodi)
Il valore limite di TTL viene utilizzato come meccanismo di sicurezza per prevenire il loop infinito
dei pacchetti in una rete. Ogni volta che il pacchetto viene inoltrato a un nodo, il valore di TTL
viene decrementato di uno. Se il valore di TTL raggiunge lo zero, il pacchetto viene scartato. Il
problema è che spesso non è possibile fare assunzioni sulla rete.
• Spanning tree protocol: L'obiettivo è creare un albero di copertura minimo, (cioè tagliamo i rami
del grafo) ovvero un sottografo dell'intera topologia di rete che contiene tutti i nodi e che non ha
cicli ed elimina gli archi che portano a nodi già raggiungibili.
Si elegge un nodo radice sulla base dei confronti tra i vari MAC address dei nodi, in particolare la
radice è costituita dal dispositivo che ha il MAC address minore e si effettua una visita in
ampiezza (BFS) a partire da quel nodo.
Tuttavia, il protocollo STP riscontra problemi di applicabilità in quanto richiede la conoscenza
completa della topologia di rete e può causare ritardi nella convergenza della rete in caso di
cambiamenti nella topologia di rete.
Passo1: Inizialmente, ogni nodo conosce solo i costi per raggiungere i suoi vicini diretti:
X conosce che raggiungere Y costa 2 e Z costa 7.
Y conosce che raggiungere X costa 2 e Z costa 1.
Z conosce che raggiungere X costa 7 e Y costa 1.
Tutti gli altri valori sono impostati a infinito (∞), perché il nodo non conosce ancora un percorso per
quelle destinazioni.
Passo 4: Convergenza
Questo processo di scambio e aggiornamento continua finché tutte le tabelle di Routing si
stabilizzano, cioè non ci sono ulteriori aggiornamenti perché tutti i percorsi minimi sono stati
trovati. A questo punto, ogni nodo ha una visione "ottimale" dei percorsi minimi verso ogni altro
nodo.
Supponiamo che adesso all’improvviso abbiamo un miglioramento in un canale passando da 10 a 1.
Prima di tutto ad accorgersi di questo cambiamento sono i vicini X e Y che cambieranno il loro
valore da 10 a 1. Avvenuto questo cambiamento quello che succederà è che Z andrà così ad
aggiornare la sua tabella una volta ottenuta l’informazione di cambio da parte di X e Y. E così via
ottenuto il cambio da parte di Z, a loro volta X e Y aggiorneranno la loro tabella.
Questo sistema dunque sembra funzionare correttamente, ma troviamo in realtà una falla nel
momento in cui abbiamo dei peggioramenti nella rete. Distance vector risponde male al
peggioramento delle condizioni di rete.
Se ritornassimo ad avere 10 al posto di 1 tra X e Y, questi aggiorneranno la loro tabella e, una volta
spediti i loro vettori ci troveremmo nella situazione in cui X e Y avranno segnato il peggioramento
della rete ma Z, non sapendo nulla del cambiamento, continuerà a dire di avere un percorso con
costo inferiore a quello degli altri due senza però specificare che questo percorso passi proprio dal
canale che ha subito il peggioramento, di fatto mandando avanti una fake news all’inizio (il nodo
avrà una stima fittizia). Il router non riesce a raggiungere la destinazione con quella stima e ritorna
al mittente la propria tabella d'inoltro ed il pacchetto rimbalzerà continuamente creando un grosso
ritardo.
La tabella di inoltro dice quale è il prossimo passo da seguire nel cammino, quella di Routing
fornisce il quadro generale della rete. L'output dell'algoritmo distance vector è la tabella di inoltro.
Si nota che questo algoritmo non implica la conoscenza a priori del grafo; quindi, ogni nodo si
affida alle informazioni ricevute dai nodi ad esso adiacenti.
Questo implica un forte problema di sicurezza dovuto al fatto che un nodo malevolo potrebbe
dirottare il traffico destinato ad altri nodi. Non c'è soluzione a questo problema e si necessita di
fidarsi. La terminazione dell'algoritmo avviene anch'essa in modo distribuito. Questo è stato il
primo algoritmo ad essere utilizzato su Internet seppur con delle precisazioni da stabilire, come il
concetto di infinito uguale a 15, peso unitario dei link ecc...
RIP v1: ogni router mantiene una tabella di Routing che indica il numero di hop necessari per
raggiungere ogni nodo nella rete. Si fissa il numero massimo di salti a 15 per prevenire ritardi nella
convergenza dell'algoritmo dovuti ad eccessive distanze tra nodi. Un router sceglierà il percorso più
breve in termini di numero di hop per raggiungere la destinazione.
Con RIP ogni router in una rete, trasmette periodicamente (ogni 30 secondi) le proprie informazioni
di Routing agli altri router tramite messaggi di aggiornamento e se un percorso per un router non
viene aggiornato per 180 secondi, la sua distanza viene impostata a infinito.
Il protocollo RIP sfrutta un garbage-collection timer (120 secondi) per rimuovere dalla tabella di
Routing, i router che non sono più raggiungibili.
Nel pacchetto RIPvl non è specificata una maschera in quanto opera utilizzando le classi di
indirizzi.
RIP V2
- dimensione del grafo, infatti il flooding causa una forte congestione all'aumentare del
numero di nodi. Inoltre, considerare porzioni troppo grandi del grafo comporta ricoprire AS
differenti, il che non interessa i link considerati.
Algoritmo Dijkstra
Percorsi minimi a partire da un Nodo. Prende in considerazione il nodo con costo più basso. Da B
conosce C E ed F e di questi blocca nuovamente il più piccolo e prende C. Da C conosce di nuovo E
F D ecc. Piano piano blocca i pesi per ogni nodo e ne scopre anche i percorsi. Si può dimostrare che
vengono trovati i percorsi minimi. E abbiamo trovato un albero di copertura minima. Se ci sono dei
nodi con lo stesso peso minimo, potremmo avere più alberi di copertura minima.
Dopo questo passo, visto che C è il minore dopo B, si prende in considerazione C e si continua.
Per applicare Dijkstra dobbiamo già conoscere il grafo. Per farlo A manda un pacchetto Hello ai
vicini e così, in base ai tempi di risposta mappa i costi (tutti fanno la stessa cosa). Le tabelle fatte da
ogni nodo vanno a comporre un grafo sottoforma di matrice. Per mandare le tabelle utilizziamo il
flooding, una volta ogni tanto in modo da non intasare la rete. Da queste tabelle abbiamo un double
check dove A dice di conoscere B ad un certo peso ma anche B dovrebbe dire lo stesso.
Fatto ciò, possiamo paragonare i due algoritmi:
Per quanto riguarda Internet, questo è organizzato in autonomous system AS, che hanno il compito
di gestire le politiche di Routing in una singola rete o gruppi di reti.
Internet Routing
Un Autonomous System (AS) è un insieme di reti interconnesse gestite da un unico amministratore
che utilizza un protocollo di Routing comune. In altre parole, un AS è un sistema autonomo e
indipendente che si occupa di instradare il traffico Internet all'interno della propria rete e verso altre
reti.
Distinguiamo due tipologie di protocolli di Routing
- Interior gateways protocol (IGP): consente ai router all'interno dello stesso AS di scambiare
informazioni sulle rotte disponibili e di selezionare il percorso migliore per instradare i
pacchetti all'interno dell'AS. Alcuni esempi di protocolli IGP includono RIP e OSPF.
- Exterior gateways protocol (EGP): sono utilizzati per il Routing tra diverse AS e
consentono ai router di scambiare informazioni sulle rotte disponibili tra AS differenti e di
condividere informazioni sulla raggiungibilità delle destinazioni. BGP (Border Gateway
Protocol) è un esempio di protocollo EGP.
BGP-4 ad esempio, ha il compito di fare Routing solo su dei router scelti magari dal gestore
(esempio TIM fa passare la sua rete solo tramite router TIM e “salta” i router VODAFONE)
Canali a 3 Stati
Se invece il canale avesse 3 stati distinti (ad esempio: basso, medio, alto), possiamo:
Utilizzare i due stati estremi (basso e alto) per trasmettere dati.
Riservare il livello medio per indicare assenza di comunicazione.
Questa soluzione elimina l'ambiguità, ma introduce un problema: uno dei tre stati è ridondante cioè
viene lasciato inutilizzato per la trasmissione di dati; quindi, il sistema non è ottimale in termini di
utilizzo delle risorse disponibili.
Codifica 4B5B
La codifica 4B5B serve per trasmettere dati in modo più sicuro su un canale che supporta solo 2
stati (0 e 1). Funziona così:
1. Ogni sequenza di 4 bit di dati viene codificata in 5 bit di trasmissione.
2. Sono possibili 25=32 combinazioni di bit:
o 16 combinazioni vengono mappate direttamente sui dati (4 bit).
o Le altre 16 combinazioni sono riservate per il controllo e per evitare errori.
Questa codifica introduce una ridondanza, aumentando la probabilità di rilevare errori:
Se riceviamo una combinazione non valida, sappiamo che c'è stato un errore.
Però non possiamo rilevare errori se una combinazione valida viene trasformata in un'altra
valida.
Lo svantaggio è che per ogni 5 bit trasmessi, solo 4 contengono dati utili. C'è quindi uno "spreco"
del 20% della capacità.
Codifica 8B10B
La codifica 8B10B è un'estensione della 4B5B e viene usata in sistemi come HDMI:
1. Ogni 8 bit di dati viene codificato in 10 bit di trasmissione.
2. Questa tecnica garantisce:
o Bilanciamento energetico: il numero di 0 e 1 trasmessi è uguale, eliminando problemi
di polarizzazione del segnale.
o Rilevamento degli errori: grazie a combinazioni riservate.
Supponiamo di avere un canale con 3 stati (L = basso, M = medio, H = alto) e un baud rate di 12
simboli al secondo. Se codifichiamo più stati in un singolo simbolo:
Due simboli alla volta: 32=9 combinazioni. Questo corrisponde a circa log2(9) =3.17 bit
per simbolo, arrotondati a 3.
Tre simboli alla volta: 33=27 combinazioni. Questo corrisponde a log2(27) =4.75 bit,
arrotondati a 4.
Bit rate massimo: aumentando il numero di stati utilizzati per simbolo, possiamo trasmettere più
bit senza aumentare il baud rate. Ad esempio, con 3 simboli si hanno alto-alto-alto, alto-alto-medio,
ecc. Non c’è una reale corrispondenza biunivoca tra i simboli a livello fisico e i simboli a livello
DLL; infatti, con strategie software si possono raggruppare i simboli al fine di ottenere una
maggiore velocità di trasmissione in bps
Controllo di parità
La forma più semplice di controllo degli errori è il bit di parità. Supponiamo di avere D
informazioni da inviare con d bit. In uno schema di parità pari il mittente aggiunge ai d bit un bit in
più per far sì che i bit a 1 siano una quantità pari, cosicché il ricevente non deve far altro che contare
quanti bit a 1 ci sono e se sono un numero pari allora è tutto okay, se sono dispari c’è stato un
errore. Questo sistema funziona dal momento in cui siamo sicuri che c’è stato un solo errore o
comunque un numero dispari di errori, se invece vengono cambiati un numero pari di bit questo non
funziona.
Presupponendo che ci sia un solo errore è stato ideato un sistema chiamato parità (a due
dimensioni) che permette anche la risoluzione degli errori.
In questo caso, i d bit del dato D sono suddivisi in i righe e j colonne per ognuna delle quali è stato
calcolato un valore di parità. I risultanti i + j + 1 bit di parità contengono bit per la rilevazione
dell’errore nei frame a livello di collegamento.
La capacità del ricevente sia di rilevare sia di correggere gli errori è conosciuta come forward
error correction.
Ricorda: il numero di 1 per la riga (e colonna) deve essere pari quindi aggiungo come bit 0 o 1 per
mantenere la parità.
Tuttavia, la correzione degli errori si basa sulla probabilità che l'errore sia solo uno, pertanto si
necessita di massimizzare la probabilità che ci sia un solo errore.
Consideriamo ora l’invio di dati D con d bit. Questi bit li vediamo come se fossero un polinomio e
dove abbiamo 1 mettiamo x^posizione in cui si trova.
La tecnica CRC prevede la generazione di un polinomio di grado n+1, dove n è il numero di bit di
controllo da aggiungere. Si prende il polinomio M(x) ottenuto dalla sequenza m da trasmettere che
presenta una ridondanza di r bit. Si prende il resto della divisione tra il polinomio M(x) ed un
generatore G(x) di grado r+1, noto a mittente e destinatario.
Il generatore G(x) deve avere alcune caratteristiche, ovvero deve avere il primo e l'ultimo bit posti
ad 1 e non deve essere ottenibile come prodotto di altri polinomi.
Durante la trasmissione, il generatore del CRC viene trasmesso insieme ai dati. Il destinatario riceve
i dati e il valore di controllo CRC e utilizza lo stesso polinomio generato dal mittente per calcolare
il valore di controllo CRC sui dati ricevuti. Se il valore di controllo CRC calcolato dal destinatario
(applicando M(x) mod G(x)) corrisponde al valore trasmesso dal mittente, allora i dati sono stati
trasmessi correttamente. In caso contrario, significa che si è verificato un errore di trasmissione.
Il CRC è un controllo semplice da implementare ed efficace dal punto di vista della rilevazione.
Aggiunti r bit, inizialmente li impostiamo a 0 e poi facciamo la divisione. Dopodiché una volta
raggiunto il massimo che possiamo fare ci basta sostituire R al posto di quei bit prima a 0.
Ci basta quindi implementare una specie di finestra a scorrimento che effettua il controllo XOR.
Hamming
Cominciamo innanzitutto definendo la distanza di hamming su due codewords come il numero di
bit che sono differenti tra loro.
Definiamo inoltre un vocabolario come un set di codewords e diciamo che questo è completo se
contiene 2n codewords dove n sono il numero di bit che ci sono nelle parole del vocabolario. Infatti,
in un vocabolario le codewords hanno una lunghezza e una distanza fissa.
Prendiamo un vocabolario di 3 di 6 bit con distanza 3 e con solo 4 codewords.
Guardando questo vocabolario con 10 bit, ci rendiamo facilmente conto che buttare 1020
combinazioni sia un po’ uno spreco e dunque ci domandiamo, come possiamo fare di meglio?
Grazie a queste 8 codewords potremmo avere 3 bit che possiamo utilizzare per mandare i dati e 7
bit che controllano questi 3. Ma la domanda è dunque, quanta ridondanza r dobbiamo aggiunge
se vogliamo mandare m bit di dati? Una volta ottenuto questo valore, come costruiamo il
vocabolario adatto a correggere gli errori?
In questo grafico, le palline verdi sono le codeword del nostro vocabolario mentre le rosse sono
tutte le altre codeword non valide.
Ricordiamoci che se vogliamo correggere 1 bit errato, abbiamo bisogno di un vocabolario con
distanza 3.
Possiamo dire inoltre che se tutti i gruppi sono separati. L’unico modo per ottenere tutti i gruppi
separati è proprio quello di scegliere dei vocabolari con distanza dispari. Altrimenti quando
andremmo a effettuare il controllo, rischieremmo di avere che le distanze più basse sono due e
quindi non riusciremmo a correggere l’errore.
Questo scenario può infatti accadere solo se abbiamo delle codewords che hanno una distanza pari.
Ci rendiamo subito conto che in n non troviamo mai le potenze di 2 e di base questa cosa ci piace.
Infatti, andremo a posizionare i bit di controllo nelle posizioni delle potenze di 2, così facendo
riusciamo a costruire il codice così:
Andiamo a posizionare i bit di controllo nelle posizioni delle potenze di 2 perché così facendo
riusciamo a identificare in maniera univoca quali bit controllano quale posizione. Il bit 9 verrà
controllato dal bit 1+8 e così via…
Nel caso di un errore notiamo subito che
Potremmo per esempio prima di inviare i dati insieme alle codewords, anziché mandarle per riga,
mandarle per colonne in modo da avere tutti i bit di controllo vicini. Può tornare comodo, ad
esempio, se abbiamo un canale che sbaglia poco ma quando lo fa genera molti errori.
Qui il bit alla posizione 10 è stato alterato (da 0 a 1).
Ora, ricontrollando i bit di controllo: b1, b2 e b4 risultano 1. b8 risulta 0.
La combinazione dei bit di controllo b1=1, b2=1, b4=1, e b8=0 ci fornisce il numero
binario 1010, che è il numero 10 in decimale. Questo ci indica che l'errore si trova alla
posizione 10. Ora che abbiamo identificato la posizione dell'errore (posizione 10), possiamo
correggerlo invertendo il bit in quella posizione (da 1 a 0 in questo caso).
Questo algoritmo viene utilizzato nelle ECC RAM (error connection code RAM)
Collegamenti Broadcast
Il collegamento broadcast può avere nodi sia trasmittenti che riceventi, connessi allo stesso canale
broadcast condiviso. In questo tipo di collegamenti, quando un nodo trasmette un frame, quello che
succede è che il canale lo diffonde a tutti gli altri nodi. Il problema di questi tipi di canali è che se
due frame si incrociano per strada, abbiamo delle collisioni che fanno perdere i frame inviati,
dunque abbiamo il problema dell’accesso multiplo. I nodi naturalmente nei canali broadcast
possono sia trasmettere che ricevere. Abbiamo diversi tipi di protocolli di accesso multiplo:
FDMA (divisione delle frequenze), TDMA (divisione del tempo), CDMA (divisione a code).
Inoltre, possiamo fare una suddivisione tra protocolli a suddivisione del canale (FDMA e TDMA),
accesso casuale (Aloha) e a rotazione (ticket).
In genere da un canale broadcast ci aspettiamo che:
- Quando un solo nodo deve inviare dati, questo dispone di un throughput pari a R.
- Quando M nodi devono inviare dati, questi dispongono di un throughput pari a R/M.
- Il protocollo è decentralizzato; non ci sono nodi principali che se smettessero di funzionare
potrebbero bloccare il sistema
- Il protocollo deve essere semplice
Un terzo protocollo di suddivisione del canale è l’accesso multiplo a divisione di codice. CDMA
assegna un codice a ogni nodo e quando questo deve inviare dati, utilizza il proprio codice univoco
per codificarli. Se i codici sono scelti in maniera corretta, CDMA consentirà a nodi differenti di
trasmettere simultaneamente e ai rispettivi destinatari di ricevere correttamente i bit dei dati
codificati (assumendo che il ricevente conosca il codice) nonostante le interferenze derivanti dalle
trasmissioni degli altri nodi.
Protocolli ad accesso casuale
Ogni nodo è indipendente dagli altri e tenta di trasmettere i propri dati non appena ne ha bisogno,
senza accordarsi preventivamente con gli altri nodi. Se due o più nodi trasmettono nello stesso
momento, si verifica una collisione: i dati si sovrappongono e risultano incomprensibili. Quando
avviene una collisione, i nodi coinvolti aspettano un intervallo di tempo casuale (random delay)
prima di ritrasmettere. Questo aiuta a ridurre la probabilità che le collisioni si ripetano.
Utilizza un metodo semplice, decentralizzato e adatto a reti con nodi che trasmettono dati in modo
sporadico. La particolarità di questi protocolli è che non ci sono regole rigide che decidono quale
nodo può trasmettere in un dato momento.
Slotted Aloha
Assumiamo che tutti i frame consistano in L bit, il tempo sia diviso in slot di L/R secondi (uno slot
= una trasmissione di un pacchetto), i nodi comincino la trasmissione dei frame solo all’inizio degli
slot, i nodi sono tutti sincronizzati con gli slot e se due frame collidono tutti i nodi rilevano l’evento
prima del termine dello slot.
Con Aloha abbiamo che:
• Quando un nodo ha un nuovo frame da spedire, attende fino all’inizio dello slot successivo e poi
trasmette l’intero frame.
• Se non si verifica una collisione, l’operazione ha avuto successo; quindi, non occorre effettuare
una ritrasmissione e il nodo può predisporre l’invio di un nuovo frame.
• Se si verifica una collisione, il nodo la rileva prima del termine dello slot e ritrasmette con
probabilità p il suo frame durante gli slot successivi, fino a quando l’operazione non ha successo.
La ritrasmissione con probabilità p indica che il nodo lancia una moneta dove testa indica la
ritrasmissione e croce indica il rilancio della moneta nello slot successivo. Questo metodo ci
permette di usare a pieno il canale ed inoltre è decentralizzato. Tuttavia, se abbiamo più nodi che
devono agire contemporaneamente cominciano ad accadere due particolari problemi. In primo
luogo, in alcuni slot troveremo delle collisioni e quindi avremo di fatto sprecato tempo. In secondo
luogo, molti slot rimarranno vuoti a causa del tipo di politica applicata da Aloha. Uno slot in cui un
solo nodo riesce a trasmettere è detto slot riuscito.
In genere con questo approccio il canale sarà utilizzato per circa il 18.4% della sua potenzialità a
causa delle varie collisioni e slot inutilizzati.
Non si può evitare la collisione quindi si sfrutta il fatto che statisticamente pochi utenti hanno
necessità di iniziare la trasmissione contemporaneamente e quindi si ha bassa probabilità di
sovrapposizione di slot. Più si richiede al canale e più si abbassa il throughput ottenibile.
Pure Aloha
Il primo protocollo Aloha era privo di slot e non era sincronizzato. Appena arriva un frame, questo
viene trasmesso immediatamente. Se un frame va in collisione, allora questo verrà ritrasmesso
immediatamente con probabilità p. Inoltre, visto che gli slot non sono sincronizzati, abbiamo molta
più probabilità di avere delle collisioni. Le collisioni possono avvenire in due modi:
Sovrapposizione Totale: Un nodo trasmette mentre un altro sta già trasmettendo.
Sovrapposizione Parziale: Anche se le trasmissioni iniziano in momenti diversi, una trasmissione
in corso può essere "tagliata" dall'inizio di un'altra trasmissione.
Nodo A inizia a trasmettere al tempo t0 e termina al tempo t0+1 (dove 1 è il tempo di trasmissione
del frame). Qualsiasi nodo che inizia a trasmettere tra t0−1 e t0+1 causerà una collisione, perché i
frame si sovrapporranno in parte o totalmente.
CSMA
In generale esistono due regole importanti per quanto riguarda questi tipi di protocolli:
- Ascolta prima di parlare. Se qualcuno sta parlando, si aspetta che abbia finito. Questa è
chiamata rilevamento della portante.
- Se qualcuno comincia a parlare insieme a te, smetti di parlare. Questo è conosciuto in reti
come rilevamento della collisione.
Da qui leggi quello di alfio
Queste due regole sono alla base del CSMA e del CSMA/CD (aggiunta del rilevamento della
collisione).
Capiamo innanzitutto perché si verificano lo stesso le collisioni. In teoria se un nodo si accorge che
c’è qualcuno che sta parlando, allora non dovrebbe mandare nulla. Il problema sta proprio nel
quando si accorge che un altro nodo sta parlando. Infatti, quando un nodo B supponiamo trasmette
qualcosa, ci metterà un certo tempo (ritardo di propagazione) prima di arrivare a D il segnale.
Dunque, se D si accorge del segnale solo dopo che ha già trasmesso qualcosa, avviene comunque
una collisione.
Per quanto riguarda però CSMA base, B e D continuano a trasmettere i loro pacchetti anche se c’è
una collisione.
In CSMA/CD quando un nodo rileva la collisione, cessa immediatamente la trasmissione. Evitiamo
quindi l’inutile trasmissione dell’intero frame danneggiato. CSMA/CD dunque opera così:
1. La scheda ottiene direttamente un datagramma dal livello di rete, prepara un frame a livello
di collegamento e lo sistema in un suo buffer.
2. Quando riscontra che il canale è libero (cioè, non vi è energia di segnale che entri nella
scheda dal canale), inizia la trasmissione del frame. Se il canale risulta occupato, resta in
attesa sino al momento in cui non rileva più il segnale e solo allora inizia l’invio del frame.
3. Durante la trasmissione verifica la presenza di eventuali segnali provenienti da altre schede
di rete sul canale broadcast.
4. La scheda di rete, se trasmette l’intero frame senza rilevare energia di segnale proveniente
da altre schede, ha finito il suo lavoro; altrimenti, se riscontra energia di segnale durante la
trasmissione, interrompe immediatamente la trasmissione del frame.
5. Dopo aver annullato la trasmissione, la scheda di rete aspetta per un tempo casuale e poi
ritorna al passo 2
Chiaramente non potremmo mai aspettare un tempo fissato, se facessimo così, quando due frame
sono inviate allo stesso istante, allora avremo che i due nodi si bloccheranno ogni volta dato che
rimanderanno contemporaneamente il pacchetto. Quanto deve essere l’intervallo di scelta del tempo
casuale (tempo di backoff)? Se l’intervallo è grande e il numero di nodi che collidono è piccolo, i
nodi probabilmente aspetteranno per un lungo intervallo di tempo prima di riprovare. Se l’intervallo
è piccolo e il numero di nodi che collidono è grande, sarà probabile che valori scelti casualmente
siano simili e che quindi i nodi trasmittenti tornino a collidere.
Vogliamo un tempo piccolo con poche collisioni e un tempo grande con tante collisioni.
L’algoritmo di binary exponential backoff, quando il trasmettitore riscontra l’n-esima collisione
durante la trasmissione di un dato frame, stabilisce casualmente un valore K nell’insieme {0, 1,
2, ..., 2^n – 1} (attesa binaria esponenziale). Quindi più alto è il numero di collisioni, più grande
sarà l’intervallo da cui K.
Protocolli a rotazione
Da un protocollo di accesso multiplo ci aspettiamo che quando un solo nodo è attivo il suo
throughput debba essere di R bps mentre quando ci sono M nodi attivi ci dobbiamo avvicinare a
R/M bps. I protocolli precedenti hanno la prima caratteristica ma non la seconda. Per questo ci sono
i protocolli a rotazione.
Primo tra tutti abbiamo il protocollo di polling nel quale uno dei nodi designato come master
interpella a turno tutti gli altri dicendogli quanto possono inviare sul canale. Dopo il nodo 1 verrà
interpellato il 2 e così via.
Questo protocollo dispone delle caratteristiche elencate precedentemente ma è fortemente
centralizzato, il che lo rende facilmente suscettibile ai guasti e immettiamo una sorta di ritardo sul
canale dovuto al polling.
Il secondo protocollo di questo genere è il protocollo token-passing dove abbiamo un token che
viene passato tra i vari nodi seguendo un certo ordine prefissato. Quando un nodo ha un token può
parlare. Questo non è centralizzato ed è fortemente efficiente, tuttavia un guasto ad un nodo può
bloccare tutto il canale.
Ethernet
Ethernet domina per quanto riguarda il mercato delle reti globali, soprattutto per quanto riguarda le
tecnologie LAN. Ethernet è stata la prima LAN ad alta velocità con vasta diffusione. Quindi, gli
amministratori di rete, dopo aver acquisito familiarità con Ethernet, si dimostrarono riluttanti al
cambiamento quando apparvero sulla scena altre tecnologie. Inoltre, se Ethernet continua ad essere
utilizzato il motivo è proprio perché riesce a fornire versioni sempre più veloci.
Il meccanismo Ethernet utilizza quello che è l’algoritmo CSMA/CD. Riceve un datagramma dal
livello network e con questo ne crea un frame, dopodiché si mette in ascolto: se il canale è libero
allora trasmetta il frame, altrimenti aspetta che il canale si liberi. Se la trasmissione del frame
avviene senza collisione, allora il gioco è fatto, altrimenti se rileva una collisione smette di
trasmettere e aspetta un numero randomico di tempo definito nell’intervallo {0,1, 2, …, (2^m) - 1}
dove m rappresenta il numero di collisioni già avvenute. Come dicevamo già prima, questo è
definito come binary exponential backoff.
All’inizio di Ethernet veniva utilizzato un cablaggio di tipo 10base5. Innanzitutto, definiamo cosa
vogliono dire questi nomi. La prima parte fa riferimento alla velocità standard (10,100,1000 o 10G),
Base si riferisce a Ethernet in banda base cioè che quel cavo trasferisce solo Ethernet e in fine
l’ultima parte si riferisce al “mezzo fisico” cioè al tipo di cavo che si utilizza.
Le prime tipologie di Ethernet utilizzavano dei cavi di tipo coassiali che, nella loro versione
“Thick” erano molto spessi e potevano raggiungere all’incirca 500 metri. Questo metraggio poteva
essere allungato tramite un particolare ripetitore che al tempo veniva chiamato vampiro. Quello che
faceva questo vampiro era bucare in un certo punto i due cavi da sopra di fatto ricevendo un segnale
in entrate e trasmettendolo in uscita. Oltre che a ritrasmettere il segnale, il vampiro aveva anche la
funzione di uditore per evitare le collisioni. Questo genere di cavo si preferisce non tagliarlo perché
causerebbe una perdita di segnale. Nella versione “Thin”, questi tipi di cavi erano molto più
morbidi e flessibili e potevano essere tagliati, tuttavia alla fine trovavamo un connettore. A causa di
ciò però la portata di questi cavi è di molto diminuita. Naturalmente questi cavi sono schermati in
modo che nessun segnale da fuori li possa disturbare.
Ethernet fu successivamente migliorato con 100Mbps utilizzando cavi in rame 100Base -T e in fibra
ottica 100 Base FX/SX/BX.
La maggior parte delle strutture odierne utilizza una struttura con uno switch e con segmenti punto a
punto.
Questo è il tipico frame Ethernet. Ricordiamo che a livello ethernet lavoriamo solo con indirizzi
MAC. Dunque, troviamo gli indirizzi di destinazione e il sorgente a cui siamo già abituati, il tipo
che sta ad indicare quale protocollo di rete utilizziamo, il campo di dati contiene il datagramma IP.
Dato che l’unità massima di trasmissione per Ethernet è di 1500 byte, se questi vengono superati
dobbiamo frammentare il frame. Altrimenti se non rappresenta il minimo di 46 byte, abbiamo la
necessità di riempirlo. Infine, troviamo il CRC e il preambolo che è un campo di 8 byte i cui i sette
hanno i bit 10101010 e l’ultimo è 10101011. I primi servono a far sì che i due host si sincronizzino
e l’ultimo serve ad indicare che sta per arrivare a tutti gli effetti il carico.
Codifica Manchester
Avevamo all’inizio il problema di identificare gli 1 e gli 0, per fare ciò utilizziamo la codifica
Manchester. Qui utilizziamo il clock in modo da identificare il segnale correttamente, leggendo i
dati la codifica di Manchester utilizza il cambio di segnale verso l’alto per identificare i bit 1 e il
cambio verso il basso per i bit a 0.
Fast Ethernet
Fast ethernet è una evoluzione di ethernet implementata utilizzando i doppini (filo di rame) o fibra
ottica.
Gigabit Ethernet
Questa versione rimuove 4B5B e usa 4 coppie di fili UTP assieme. Implementa inoltre un canale
full duplex e usa 5 livelli per simbolo anziché 3. Implementa inoltre FEC che gli permette di
correggere molti errori.
Quello che facciamo è utilizzare una macchina a stati finiti costruita così.
In base allo stato in cui ci troviamo, mandiamo dei segnali diversi per mandare o 0 o 1. Questa
macchina a stati finiti è fatta in modo tale che ogni destinazione possa essere raggiunta in due step.
Inoltre, la distanza di hamming tra i bit mandati sarà sempre massima (es da 2 per mandare 0
abbiamo 10 mentre per mandare 1 abbiamo 01.
Cosa succede se abbiamo un errore? Innanzitutto, se abbiamo un solo errore su 4 bit riusciamo ad
identificarlo e correggerlo (su base statistica) senza problemi, se sono due non riusciamo.
Quello che succede è che se abbiamo una collisione, questa verrà replicata a tutta la rete. Dunque,
l’hub è diciamo un qualcosa di “stupido”.
Il bridge Ethernet sfrutta invece gli switch al posto degli hub che riescono quindi a eliminare le
collisioni.
Se A vuole comunicare con H, manda un frame a B1 e B1 si segna che da quel lato ha visto A,
dopodiché ritrasmette a tutte le uscite il segnale. Allo stesso modo di B1 agiscono B2 e B3. B3
riuscirà a raggiungere H e H per rispondere ripercorrerà la strada per arrivare ad A all’indietro.
Queste informazioni che i router si salvano vengono eliminate dopo un tot. In questi grafi non ci
sono solitamente cicli, tuttavia se ci sono dobbiamo dichiararli e potrebbero essere usati in vari
modi.
Ciò che facciamo per evitare i cicli è utilizzare lo Spanning tree protocol che mantiene inattive
alcune interfacce in modo da garantire che la rete rimanga connessa, ma priva di loop.
VLAN
Le VLAN separano a livello logico le LAN che sono costruite a livello fisico. Può capitare di dover
separare due settori di LAN esempio il settore economico dalla LAN degli studenti e questo viene
fatto attraverso le Virtual LAN.
Gli obbiettivi delle VLAN sono:
- Risparmio: Evitiamo di dover creare altre LAN fisiche
- Flessibilità: I movimenti fisici dell’utente sono facilitati
- Miglioramento delle performance: Il traffico Broadcast è confinato
- Sicurezza: Gli utenti di due VLAN diverse non vedono gli uni le frame degli altri
Assegniamo quindi una porta ad una VLAN. Ma come facciamo a far comunicare due switch tra di
loro? Un modo sarebbe quello di connettere una porta dello switch VLAN a un router esterno e
configurarla in modo che appartenga a entrambe le VLAN. Un altro approccio potrebbe essere
quello di far in modo che una porta faccia parte di entrambe le VLAN; tuttavia, in questo caso se ci
fossero N LAN, avremmo bisogno di N porte e questo è poco fattibile. Un approccio più comodo
può essere quello di utilizzare la tagged VLAN. Nel pratico assegniamo una porta speciale di
trunking che percorre i due switch VLAN e appartiene a tutte le VLAN. In pratica utilizziamo delle
etichette VLAN di 4 byte che contengono i campi TPID di due byte e un campo tag control di
altrettanti 2 byte.