Riorganizzate varie parti, rimetto in linea la nuova versione
[gapil.git] / network.tex
index 80d37ebad9a5bd76f3290f8f92c1969a16bd6618..de8376f830c29db41bae36c0b933a046d434bbca 100644 (file)
@@ -1,17 +1,16 @@
 \chapter{Introduzione alla programmazione di rete}
 \label{cha:network}
 
-In questo capitolo sarà fatta un'introduzione ai contetti generali che servono
-come prerequisiti per capire la programmazione di rete, partiremo con due
-semplici esempi per poi passare ad un esame a grandi linee dei protocolli di
-rete e di come questi sono organizzati e interagiscono.
+In questo capitolo sarà fatta un'introduzione ai concetti generali che servono
+come prerequisiti per capire la programmazione di rete, non tratteremo quindi
+aspetti specifici ma faremo una breve introduzione al modello più comune usato
+nella programmazione di rete, per poi passare ad un esame a grandi linee dei
+protocolli di rete e di come questi sono organizzati e interagiscono. 
 
 In particolare, avendo assunto l'ottica di un'introduzione mirata alla
-programmazione, ci concentreremo sul protocollo più diffuso, TCP/IP, che è
-quello che sta alla base di internet, ed in particolare prenderemo in esame in
-questa introduzione i concetti più importanti da conoscere ai fini della
-programmazione.
-
+programmazione, ci concentreremo sul protocollo più diffuso, il TCP/IP, che è
+quello che sta alla base di internet, avendo cura di sottolineare i concetti
+più importanti da conoscere per la scrittura dei programmi.
 
 \section{Il modello client-server}
 \label{sec:net_cliserv}
@@ -36,268 +35,20 @@ generale anche per programmi che non fanno necessariamente uso della rete,
 come il sistema a finestre.
 
 Normalmente si dividono i server in due categorie principali, e vengono detti
-\textit{concorrenti} o \textit{iterativi}, sulla base del loro comportamento.
+\textsl{concorrenti} o \textsl{iterativi}, sulla base del loro comportamento.
 
-Un server iterativo risponde alla richiesta inviando i dati e resta occupato
-(non rispondendo ad ulteriori richieste) fintanto che non ha concluso la
-richiesta. Una volta completata la richiesta il server diventa di nuovo
+Un \textsl{server iterativo} risponde alla richiesta inviando i dati e resta
+occupato (non rispondendo ad ulteriori richieste) fintanto che non ha concluso
+la richiesta. Una volta completata la richiesta il server diventa di nuovo
 disponibile.
 
-Un server concorrente al momento di trattare la richiesta crea un processo
-figlio incaricato di fornire i servizi richiesti, per poi porsi in attesa di
-ulteriori richieste. In questo modo più richieste possono essere soddisfatte
-contemporaneamente; una volta che il processo figlio ha concluso il suo lavoro
-viene terminato, mentre il server originale resta sempre attivo.
-
-
-\subsection{Un primo esempio di client}
-\label{sec:net_cli_sample}
-
-Per evitare di rendere l'esposizione dei concetti generali sulla rete
-puramente teorica iniziamo con il mostrare un semplice esempio di client TCP.
-In \nfig\ è riportata la sezione principale del codice del nostro client
-elementare per il servizio \textit{daytime}, un servizio standard che
-restituisce l'ora locale della macchina a cui si effettua la richesta.
-
-\begin{figure}[!htbp]
-  \footnotesize
-  \begin{lstlisting}{}
-#include <sys/types.h>   /* predefined types */
-#include <unistd.h>      /* include unix standard library */
-#include <arpa/inet.h>   /* IP addresses conversion utiliites */
-#include <sys/socket.h>  /* socket library */
-#include <stdio.h>       /* include standard I/O library */
-
-int main(int argc, char *argv[])
-{
-    int sock_fd;
-    int i, nread;
-    struct sockaddr_in serv_add;
-    char buffer[MAXLINE];
-     ...
-    /* create socket */
-    if ( (sock_fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
-        perror("Socket creation error");
-        return -1;
-    }
-    /* initialize address */
-    memset((void *) &serv_add, 0, sizeof(serv_add)); /* clear server address */
-    serv_add.sin_family = AF_INET;                   /* address type is INET */
-    serv_add.sin_port = htons(13);                   /* daytime post is 13 */
-    /* build address using inet_pton */
-    if ( (inet_pton(AF_INET, argv[optind], &serv_add.sin_addr)) <= 0) {
-        perror("Address creation error");
-        return -1;
-    }
-    /* extablish connection */
-    if (connect(sock_fd, (struct sockaddr *)&serv_add, sizeof(serv_add)) < 0) {
-        perror("Connection error");
-        return -1;
-    }
-    /* read daytime from server */
-    while ( (nread = read(sock_fd, buffer, MAXLINE)) > 0) {
-        buffer[nread]=0;
-        if (fputs(buffer, stdout) == EOF) {          /* write daytime */
-            perror("fputs error");
-            return -1;
-        }
-    }
-    /* error on read */
-    if (nread < 0) {
-        perror("Read error");
-        return -1;
-    }
-    /* normal exit */
-    return 0;
-}
-  \end{lstlisting}
-  \caption{Esempio di codice di un client elementare per il servizio daytime.}
-  \label{fig:net_cli_code}
-\end{figure}
-
-Scopo di questo esempio è fornire un primo approccio alla programmazione di
-rete, per questo motivo non ci dilungheremo nel trattare il significato dei
-termini o il funzionamento delle varie funzioni utilizzate. Tutto questo sarà
-esaminato in dettaglio nel seguito, per cui qui ci limiteremo a citarli senza
-ulteriori spiegazioni.
-
-Il sorgente completo del programma (\texttt{SimpleDaytimeTCPClient.c}, che
-comprende il trattamento delle opzioni e una funzione per stampare un
-messaggio di aiuto) è allegato alla guida nella sezione dei codici sorgente e
-può essere compilato su una qualunque macchina linux.
-
-Il programma anzitutto include gli header necessari (\texttt{\small 1--5});
-dopo la dichiarazione delle variabili (\texttt{\small 9--12}) si è omessa
-tutta la parte relativa al trattamento degli argomenti passati dalla linea di
-comando (effettuata con le apposite routines illustrate in
-\ref{cha:parameter_options}).
-
-Il primo passo (\texttt{\small 14--18}) è creare un \textit{socket} IPv4
-(\texttt{AF\_INET}), di tipo TCP \texttt{SOCK\_STREAM} (in sostanza un canale
-di comunicazione attraverso internet, questi termini verranno spiegati con
-precisione più avanti). La funzione \texttt{socket} ritorna un descrittore,
-analogo a quello dei file, che viene usato per identificare il socket in tutte
-le chiamate successive. Nel caso la chiamata fallisca si stampa un errore con
-la relativa routine e si esce.
-
-Il passo seguente (\texttt{\small 19--27}) è quello di costruire una apposita
-struttura \texttt{sockaddr\_in} in cui sarà inserito l'indirizzo del server ed
-il numero della porta del servizio. Il primo passo è inizializzare tutto a
-zero, per poi inserire il tipo di protocollo e la porta (usando per
-quest'ultima la funzione \texttt{htons} per convertire il formato dell'intero
-usato dal computer a quello usato nella rete), infine si utilizza la funzione
-\texttt{inet\_pton} per convertire l'indirizzo numerico passato dalla linea di
-comando.
-
-Usando la funzione \texttt{connect} sul socket creato in precedenza
-(\texttt{\small 28--32}) si provvede poi a stabilire la connessione con il
-server specificato dall'indirizzo immesso nella struttura possata come secondo
-argomento, il terzo argomento è la dimensione di detta struttura. Dato che
-esistono diversi tipi di socket, si è dovuto effettuare un cast della
-struttura inizializzata in precedenza, che è specifica per i socket IPv4.  Un
-valore di ritorno negativo implica il fallimento della connessione.
-
-Completata con successo la connessione il passo successivo (\texttt{\small
-  34--40}) è leggere la data dal socket; il server invierà sempre una stringa
-di 26 caratteri della forma \verb|Wed Apr 4 00:53:00 2001\r\n|, che viene
-letta dalla funzione \texttt{read} e scritta su \texttt{stdout}.
-
-Dato il funzionamento di TCP la risposta potrà tornare in un unico pacchetto
-di 26 byte (come avverrà senz'altro nel caso in questione) ma potrebbe anche
-arrivare in 26 pacchetti di un byte.  Per questo nel caso generale non si può
-mai assumere che tutti i dati arrivino con una singola lettura, pertanto
-quest'ultima deve essere effettuata in un loop in cui si continui a leggere
-fintanto che la funzione \texttt{read} non ritorni uno zero (che significa che
-l'altro capo ha chiuso la connessione) o un numero minore di zero (che
-significa un errore nella connessione).
-
-Si noti come in questo caso la fine dei dati sia specificata dal server che
-chiude la connessione; questa è una delle tecniche possibili (è quella usata
-pure dal protocollo HTTP), ma ce ne possono essere altre, ad esempio FTP marca
-la conclusione di un blocco di dati con la sequenza ASCII \verb|\r\n|
-(carriage return e line feed), mentre il DNS mette la lunghezza in testa ad
-ogni blocco che trasmette. Il punto essenziale è che TCP non provvede nessuna
-indicazione che permetta di marcare dei blocchi di dati, per cui se questo è
-necessario deve provvedere il programma stesso.
-
-\subsection{Un primo esempio di server}
-\label{sec:net_serv_sample}
-
-Dopo aver illustrato il client daremo anche un esempio di un server
-elementare, in grado di rispondere al precedente client. Il listato è
-nuovamente mostrato in \nfig, il sorgente completo
-(\texttt{SimpleDaytimeTCPServer.c}) è allegato insieme agli altri file nella
-directory \texttt{sources}.
+Un \textsl{server concorrente} al momento di trattare la richiesta crea un
+processo figlio incaricato di fornire i servizi richiesti, per poi porsi in
+attesa di ulteriori richieste. In questo modo più richieste possono essere
+soddisfatte contemporaneamente; una volta che il processo figlio ha concluso
+il suo lavoro viene terminato, mentre il server originale resta sempre attivo.
 
-\begin{figure}[!htbp]
-  \footnotesize
-  \begin{lstlisting}{}
-#include <sys/types.h>   /* predefined types */
-#include <unistd.h>      /* include unix standard library */
-#include <arpa/inet.h>   /* IP addresses conversion utiliites */
-#include <sys/socket.h>  /* socket library */
-#include <stdio.h>       /* include standard I/O library */
-#include <time.h>
-#define MAXLINE 80
-#define BACKLOG 10
-int main(int argc, char *argv[])
-{
-/* 
- * Variables definition  
- */
-    int list_fd, conn_fd;
-    int i;
-    struct sockaddr_in serv_add;
-    char buffer[MAXLINE];
-    time_t timeval;
-
-    ...
-
-    /* create socket */
-    if ( (list_fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
-        perror("Socket creation error");
-        exit(-1);
-    }
-    /* initialize address */
-    memset((void *)&serv_add, 0, sizeof(serv_add)); /* clear server address */
-    serv_add.sin_family = AF_INET;                  /* address type is INET */
-    serv_add.sin_port = htons(13);                  /* daytime port is 13 */
-    serv_add.sin_addr.s_addr = htonl(INADDR_ANY);   /* connect from anywhere */
-    /* bind socket */
-    if (bind(list_fd, (struct sockaddr *)&serv_add, sizeof(serv_add)) < 0) {
-        perror("bind error");
-        exit(-1);
-    }
-    /* listen on socket */
-    if (listen(list_fd, BACKLOG) < 0 ) {
-        perror("listen error");
-        exit(-1);
-    }
-    /* write daytime to client */
-    while (1) {
-        if ( (conn_fd = accept(list_fd, (struct sockaddr *) NULL, NULL)) <0 ) {
-            perror("accept error");
-            exit(-1);
-        }
-        timeval = time(NULL);
-        snprintf(buffer, sizeof(buffer), "%.24s\r\n", ctime(&timeval));
-        if ( (write(conn_fd, buffer, strlen(buffer))) < 0 ) {
-            perror("write error");
-            exit(-1);
-        }
-        close(conn_fd);
-    }
-    /* normal exit */
-    exit(0);
-}
-  \end{lstlisting}
-  \caption{Esempio di codice di un semplice server per il servizio daytime.}
-  \label{fig:net_serv_code}
-\end{figure}
 
-Come per il client si includono gli header necessari a cui è aggiunto quello
-per trattare i tempi, e si definiscono alcune costanti e le variabili
-necessarie in seguito (\texttt{\small 1--18}), come nel caso precedente si
-sono omesse le parti relative al trattamento delle opzioni da riga di comando.
-
-La creazione del socket (\texttt{\small 22--26}) è analoga al caso precedente,
-come pure l'inizializzazione della struttura \texttt{sockaddr\_in}, anche in
-questo caso si usa la porta standard del servizio daytime, ma come indirizzo
-IP si il valore predefinito \texttt{INET\_ANY} che corrisponde ad un indirizzo
-generico (\texttt{\small 27--31}).
-
-Si effettua poi (\texttt{\small 32--36}) la chiamata alla funzione
-\texttt{bind} che permette di associare la precedente struttura al socket, in
-modo che quest'ultimo possa essere usato per accettare connessioni su una
-qualunque delle interfacce di rete locali.
-
-Il passo successivo (\texttt{\small 37--41}) è mettere ``in ascolto'' il
-socket, questo viene effettuato con la funzione \texttt{listen} che dice al
-kernel di accettare connessioni per il socket specificato, la funzione indica
-inoltre, con il secondo parametro, il numero massimo di connessioni che il
-kernel accetterà di mettere in coda per il suddetto socket.
-
-Questa ultima chiamata completa la preparazione del socket per l'ascolto (che
-viene chiamato anche \textit{listening descriptor}) a questo punto il processo
-è mandato in sleep (\texttt{\small 44--47}) con la successiva chiamata alla
-funzione \texttt{accept}, fin quando non arriva e viene accettata una
-connessione da un client.
-
-Quando questo avviene \texttt{accept} ritorna un secondo descrittore di
-socket, che viene chiamato \textit{connected descriptor} che è quello che
-viene usato dalla successiva chiamata alla \texttt{write} per scrivere la
-risposta al client, una volta che si è opportunamente (\texttt{\small 48--49})
-costruita la stringa con la data da trasmettere. Completata la trasmissione il
-nuovo socket viene chiuso (\texttt{\small 54}).
-Il tutto è inserito in un loop infinito (\texttt{\small 42--55}) in modo da
-poter ripetere l'invio della data ad una successiva connessione.
-
-È impostante notare che questo server è estremamente elementare, infatti a
-parte il fatto di essere dipendente da IPv4, esso è in grado di servire solo
-un client alla volta, è cioè un \textsl{server iterativo}, inoltre esso è
-scritto per essere lanciato da linea di comando, se lo si volesse utilizzare
-come demone di sistema (che è in esecuzione anche quando non c'è nessuna shell
-attiva), occorrerebbero delle opportune modifiche.
 
 \section{I protocolli di rete}
 \label{sec:net_protocols}
@@ -319,7 +70,7 @@ macchine diverse conversano tramite lo stesso protocollo. Questo modello di
 funzionamento è stato stato standardizzato dalla \textit{International
   Standards Organization} (ISO) che ha preparato fin dal 1984 il Modello di
 Riferimento \textit{Open Systems Interconnection} (OSI), strutturato in sette
-livelli, secondo la tabella in \ntab.
+livelli, secondo quanto riportato in \ntab.
 
 \begin{table}[htb]
   \centering
@@ -348,15 +99,24 @@ quest'ultimo viene comunemente chiamato modello DoD (\textit{Department of
   Defense}), dato che fu sviluppato dall'agenzia ARPA per il Dipartimento
 della Difesa Americano.
 
+\begin{figure}[!htbp]
+  \centering
+  \includegraphics[width=8cm]{img/iso_tcp_comp.eps}
+  \caption{Struttura a livelli dei protocolli OSI e TCP/IP, con la  
+    relative corrispondenze e la divisione fra kernel e user space.}
+  \label{fig:net_osi_tcpip_comp}
+\end{figure}
+
+
 \subsection{Il modello DoD (TCP/IP)}
 \label{sec:net_tcpip_overview}
 
 Così come ISO/OSI anche TCP/IP è stato strutturato in livelli (riassunti in
-\ntab); un confronto fra i due è riportato in \nfig\ dove viene evidenziata
+\ntab); un confronto fra i due è riportato in \curfig\ dove viene evidenziata
 anche la corrispondenza fra i rispettivi livelli (che comunque è
 approssimativa) e su come essi vanno ad inserirsi all'interno del sistema
 operativo rispetto alla divisione fra user space e kernel space spiegata in
-\ref{sec:intro_unix_struct}.
+\secref{sec:intro_unix_struct}.
 
 \begin{table}[htb]
   \centering
@@ -371,11 +131,10 @@ operativo rispetto alla divisione fra user space e kernel space spiegata in
     device driver \& scheda di interfaccia  \\
     \hline
 \end{tabular}
-\caption{I quattro livelli del protocollo TPC/IP.}
+\caption{I quattro livelli del protocollo TCP/IP.}
 \label{tab:net_layers}
 \end{table}
 
-
 Come si può notare TCP/IP è più semplice del modello ISO/OSI e strutturato in
 soli quattro livelli. Il suo nome deriva dai due principali protocolli che lo
 compongono, il TCP \textit{Trasmission Control Protocol} e l'IP
@@ -383,8 +142,8 @@ compongono, il TCP \textit{Trasmission Control Protocol} e l'IP
 
 \begin{description}
 \item \textbf{Applicazione} É relativo ai programmi di interfaccia utente, in
-  genere questi vengono realizzati secondo il modello Client-Server (vedi
-  \ref{sec:net_cliserv}.
+  genere questi vengono realizzati secondo il modello client-server (vedi
+  \secref{sec:net_cliserv}.
 \item \textbf{Trasporto} Fornisce la comunicazione tra le due stazioni
   terminali su cui girano gli applicativi, regola il flusso delle
   informazioni, e può fornire un trasporto affidabile, cioè con recupero
@@ -401,32 +160,40 @@ compongono, il TCP \textit{Trasmission Control Protocol} e l'IP
 \end{description}
 
 
-La comunicazione fra due stazioni avviene pertanto secondo le modalità
-illustrate in \nfig. 
-
-Le singole applicazioni si scambieranno i dati secondo un loro formato
-specifico, implementando un protocollo di applicazione (esempi possono essere
-HTTP, POP, telnet, SMTP, etc). 
-
-Questi dati vengono inviati al livello di trasporto usando un'interfaccia
-opportuna (i \textit{socket}, che esamineremo in dettaglio in seguito), i
-quali li spezzerà in pacchetti di dimensione opportuna e li incapsulerà
-all'interno del suo protocollo di trasporto aggiungendo ad ogni pacchetto le
-informazioni necessarie alla gestione di quest'ultimo. Questo processo viene
-svolto dirattamente nel kernel ad esempio dallo stack TCP nel caso il
-protocollo di trasporto sia questo.
-
-Una volta composto il pacchetto nel formato adatto al protocollo di trasporto
-usato questo sarà passato al successivo livello, quello del collegamento che
-si occupa di inserire le opportune informazioni per poter effettuare
-l'instradamento nella rete ed il recapito alla destinazione finale. In genere
-questo è il livello di IP (Internet Protocol), a cui vengono inseriti i numeri
-IP che identificano i computer su internet.
+La comunicazione fra due stazioni avviene secondo le modalità illustrate in
+\nfig, dove si è riportato il flusso dei dati reali e i protocolli usati per
+lo scambio di informazione su ciascuno livello.
+\begin{figure}[!htb]
+  \centering
+  \includegraphics[width=6cm]{img/tcp_data_flux.eps}  
+  \caption{Strutturazione del flusso dei dati nella comunicazione fra due
+    applicazioni attraverso i protocolli della suite TCP/IP.}
+  \label{fig:net_tcpip_data_flux}
+\end{figure}
 
-L'ultimo passo è il trasferimento del pacchetto al driver della interfaccia di
-trasmissione che si incarica di incapsularlo nel relativo protocollo di
-trasmissione fisica usato dall'hardware usato per la comunicazione (ad esempio
-ethernet per una scheda di rete).
+La struttura della comuniczione pertanto si può riassumere nei seguenti passi:
+\begin{itemize}
+\item Le singole applicazioni si scambieranno i dati secondo un loro formato
+  specifico, implementando un protocollo di applicazione (esempi possono
+  essere HTTP, POP, telnet, SMTP, etc).
+\item Questi dati vengono inviati al livello di trasporto usando
+  un'interfaccia opportuna (i \textit{socket}, che esamineremo in dettaglio in
+  seguito). Qui verranno spezzati in pacchetti di dimensione opportuna e
+  incapsulati nel protocollo di trasporto, aggiungendo ad ogni pacchetto le
+  informazioni necessarie per la sua gestione. Questo processo viene
+  svolto direttamente nel kernel ad esempio dallo stack TCP nel caso il
+  protocollo di trasporto sia questo.
+\item Una volta composto il pacchetto nel formato adatto al protocollo di
+  trasporto usato questo sarà passato al successivo livello, quello del
+  collegamento che si occupa di inserire le opportune informazioni per poter
+  effettuare l'instradamento nella rete ed il recapito alla destinazione
+  finale. In genere questo è il livello di IP (Internet Protocol), a cui
+  vengono inseriti i numeri IP che identificano i computer su internet.
+\item L'ultimo passo è il trasferimento del pacchetto al driver della
+  interfaccia di trasmissione che si incarica di incapsularlo nel relativo
+  protocollo di trasmissione fisica usato dall'hardware usato per la
+  comunicazione (ad esempio ethernet per una scheda di rete).
+\end{itemize}
 
 
 \subsection{Criteri generali del design di TCP/IP}
@@ -466,39 +233,52 @@ trattato uniformemente da tutti i nodi della rete.
 \section{Il protocollo TCP/IP}
 \label{sec:net_tpcip}
 
-Come già affermato il protocollo TCP/IP è un insieme di protocolli diversi,
+Come appena mostrato il protocollo TCP/IP è un insieme di protocolli diversi,
 che operano su 4 livelli diversi. Per gli interessi della programmazione di
 rete però sono importanti principalmente i due livelli centrali, e soprattutto
-quello di trasporto, su cui è innestata l'interfaccia fra kernel space e user
-space. 
-
-Il livello 4 infatti è normalmente gestito dal kernel, e si accede ad esso
-solo quando si vogliono fare applicazioni di sistema per il controllo della
-rete (locale) a basso livello, un uso quindi molto specialistico. Il livello 1
-invece dipende dalle singole applicazioni ed è di nuovo troppo specifico per
-essere affrontato qui.
+quello di trasporto. 
+
+La principale interfaccia di programmazione di rete, quella dei socket, è
+infatti un'interfaccia nei confronti di quest'ultimo. Questo avviene perché al
+di sopra del livello di trasporto i programmi hanno a che fare solo con
+dettagli specifici delle applicazioni, mentre al di sotto vengono curati tutti
+i dettagli relativi alla comunicazione. È pertanto naturale definire una API
+su questo confine tanto più che è proprio li (come evidenziato in \pfig) che
+nei sistemi unix (e non solo) viene inserita la divisione fra kernel space e
+user space.
+
+In realtà in un sistema unix è possibile accedere anche agli altri livelli
+inferiori (e non solo a quello di trasporto) con opportune interfacce (la cosa
+è indicata in \pfig\ lasciando uno spazio fra UDP e TCP), ma queste vengono
+usate solo quando si vogliono fare applicazioni di sistema per il controllo
+della rete a basso livello, un uso quindi molto specialistico, e che non
+rientra in quanto trattato qui.
 
 In questa sezione daremo una breve descrizione dei vari protocolli di TCP/IP,
-ma ci concentreremo principalmente sul livello di trasposto e in particolare
-sul protocollo TCP sia per il ruolo centrale che esso svolge nella maggior
-parte delle applciazioni, sia per la sua complessità che necessita di maggiori
-spiegazioni.
+concentrandoci per le ragioni esposte sul livello di trasporto. All'interno di
+questo privilegeremo poi il protocollo TCP, per il ruolo centrale che svolge
+nella maggior parte delle applicazioni.
 
 \subsection{Il quadro generale}
 
 Benché si parli di TCP/IP questa famiglia di protocolli è composta anche da
-altri membri. In \nfig\ si è riportato una figura di quadro che mostra un
-panorama sull'intera famiglia, e di come i vari protocolli vengano usati dalle
-applicazioni.
+altri membri. In \nfig\ si è riportato uno schema che mostra un panorama sui
+vari protocolli della famiglia, e delle loro relazioni reciproche e con
+alcune dalle principali applicazioni che li usano.
 
-La figura è da fare  ...
+\begin{figure}[!htbp]
+  \centering
+  \includegraphics[width=10cm]{img/tcpip_overview.eps}  
+  \caption{Panoramica sui vari protocolli che compongono la suite TCP/IP.}
+  \label{fig:net_tcpip_overview}
+\end{figure}
 
 I vari protocolli mostrati in figura sono i seguenti:
 
 \begin{list}{}{}
 \item \textsl{IPv4} \textit{Internet Protocol version 4}. È quello che
   comunemente si chiama IP. Ha origine negli anni '80 e da allora è la base su
-  cui è cotriuta internet. Usa indirizzi a 32 bit e provvede la trasmissione
+  cui è costruita internet. Usa indirizzi a 32 bit e provvede la trasmissione
   dei pacchetti TCP, UDP, ICMP e IGMP.
 \item \textsl{IPv6} \textit{Internet Protocol version 6}. È stato progettato a
   metà degli anni '90 per rimpiazzare IPv4. Ha indirizzi a 128 bit e effettua
@@ -507,9 +287,9 @@ I vari protocolli mostrati in figura sono i seguenti:
   orientato alla connessione che provvede un trasporto affidabile e
   bidirezionale di un flusso di dati. I socket TCP sono esempi di
   \textit{stream socket}. Il protocollo ha cura di tutti gli aspetti del
-  trasporto, come l'acknoweledgment, i timout, la ritrasmissione, etc. È usato
-  dalla maggior parte delle applicazioni. Può essere usato sia con IPv4 che
-  con IPv6.
+  trasporto, come l'acknoweledgment, i timeout, la ritrasmissione, etc. È 
+  usato dalla maggior parte delle applicazioni. Può essere usato sia con IPv4
+  che con IPv6.
 \item \textsl{UDP} \textit{User Datagram Protocol}. È un protocollo senza
   connessione a pacchetti. I socket UDP sono esempi di \textit{datagram
     socket}. Contrariamente al TCP in protocollo non è affidabile e non c'è
@@ -517,13 +297,14 @@ I vari protocolli mostrati in figura sono i seguenti:
   ordine di arrivo. Può essere usato sia con IPv4 che con IPv6.
 \item \textsl{ICMP} \textit{Internet Control Message Protocol}. Gestisce gli
   errori e trasporta l'informazione di controllo fra stazioni remote e
-  instradatori (\textit{router} e \textit{host}). I messaggi sono normalmente
+  instradatori (\textit{host} e \textit{router}). I messaggi sono normalmente
   generati dal software del kernel che gestisce la comunicazione TCP/IP, anche
-  se può venire usato direttamente da alcuni programmi come \texttt{ping}. A
-  volte ci si riferisce ad esso come ICPMv4 per distinguerlo da ICMPv6.
-\item \textsl{ICMP} \textit{Internet Group Management Protocol}. É un
+  se ICMP può venire usato direttamente da alcuni programmi come
+  \texttt{ping}. A volte ci si riferisce ad esso come ICPMv4 per distinguerlo
+  da ICMPv6.
+\item \textsl{IGMP} \textit{Internet Group Management Protocol}. É un
   protocollo usato per il \textit{multicasting} (vedi
-  \ref{sec:xxx_multicast}), che è opzionale in IPv4.
+  \secref{sec:xxx_multicast}), che è opzionale in IPv4.
 \item \textsl{ARP} \textit{Address Resolution Protocol}. È il protocollo che
   mappa un indirizzo IP in un indirizzo hardware (come un indirizzo
   internet). È usato in reti di tipo broadcast come ethernet, token ring o
@@ -552,7 +333,7 @@ Quando si parla di IP ci si riferisce in genere alla versione attualmente in
 uso che è la versione 4 (e viene pertanto chiamato IPv4). Questa versione
 venne standardizzata nel 1981 dall'RFC~719.
 
-Internet protocol nasce per disaccoppiare le applicazioni della struttura
+Internet Protocol nasce per disaccoppiare le applicazioni della struttura
 hardware delle reti di trasmissione, e creare una interfaccia di trasmissione
 dei dati indipendente dal sottostante substrato di rete, che può essere
 realizzato con le tecnologie più disparate (Ethernet, Token Ring, FDDI, etc.).
@@ -584,38 +365,38 @@ grandi linee nei seguenti punti:
   supportare una gerarchia con più livelli di indirizzamento, un numero di
   nodi indirizzabili molto maggiore e una autoconfigurazione degli indirizzi
 \item l'introduzione un nuovo tipo di indirizzamento, l'\textit{anycast} che
-  si aggiungono agli usuali \textit{unycast} e \textit{multicast}
+  si aggiunge agli usuali \textit{unycast} e \textit{multicast}
 \item la semplificazione del formato della testata, eliminando o rendendo
   opzionali alcuni dei campi di IPv4, per eliminare la necessità di
   riprocessamento della stessa da parte dei router e contenere l'aumento di
-  dimensione dovuto ai nuovi indirizzi
+  dimensione dovuto all'ampliamento degli indirizzi
 \item un supporto per le opzioni migliorato, per garantire una trasmissione
   più efficiente del traffico normale, limiti meno stringenti sulle dimensioni
   delle opzioni, e la flessibilità necessaria per introdurne di nuove in
   futuro
-\item il supporto per delle capacità di qualità di servizio (QoS) che permetta
-  di identificare gruppi di dati per i quali si può provvedere un trattamento
-  speciale (in vista dell'uso di internet per applicazioni multimediali e/o
-  ``real-time'')
+\item il supporto per delle capacità di qualità di servizio (QoS) che
+  permettano di identificare gruppi di dati per i quali si può provvedere un
+  trattamento speciale (in vista dell'uso di internet per applicazioni
+  multimediali e/o ``real-time'')
 \end{itemize}
 
-Per maggiori dettagli riguardo al protocollo si può consultare
-\ref{sec:appA_ip}.
+Maggiori dettagli riguardo a caratteristiche, notazioni e funzionamento del
+protocollo IP sono forniti nell'appendice \capref{cha:ip_protocol}.
 
  
 \subsection{UDP: User Datagram Protocol)}
 \label{sec:net_udp}
 
-UDP è un protocollo di trasporto molto semplice, la sua descizione completa è
-contenuta dell'RFC~768, ma in sostanza esso è una semplice interfaccia a IP dal
-livello di trasporto. Quando un'applicazione usa UDP essa scrive un pacchetto
-di dati (il cosiddetto \textit{datagram} che da il nome al protocollo) su un
-socket, al pacchetto viene aggiunto un header molto semplice (per una
-descrizione più accurata vedi \ref{sec:appA_udp}), e poi viene passato al
-livello superiore (IPv4 o IPv6 che sia) che lo spedisce verso la destinazione.
-Dato che né IPv4 né IPv6 garantiscono l'affidabilità niente assicura che il
-pacchetto arrivi a destinazione, né che più pacchetti arrivino nello stesso
-ordine in cui sono stati spediti.
+UDP è un protocollo di trasporto molto semplice, la sua descrizione completa è
+contenuta dell'RFC~768, ma in sostanza esso è una semplice interfaccia a IP
+dal livello di trasporto. Quando un'applicazione usa UDP essa scrive un
+pacchetto di dati (il cosiddetto \textit{datagram} che da il nome al
+protocollo) su un socket, al pacchetto viene aggiunto un header molto semplice
+(per una descrizione più accurata vedi \secref{sec:xxx_udp}), e poi viene
+passato al livello superiore (IPv4 o IPv6 che sia) che lo spedisce verso la
+destinazione.  Dato che né IPv4 né IPv6 garantiscono l'affidabilità niente
+assicura che il pacchetto arrivi a destinazione, né che più pacchetti arrivino
+nello stesso ordine in cui sono stati spediti.
 
 Pertanto il problema principale che si affronta quando si usa UDP è la
 mancanza di affidabilità, se si vuole essere sicuri che i pacchetti arrivino a
@@ -637,7 +418,7 @@ Infine UDP 
 (\textit{connectionless}) in quanto non è necessario stabilire nessun tipo di
 relazione tra origine e destinazione dei pacchetti. Si hanno così situazioni
 in cui un client può scrivere su uno stesso socket pacchetti destinati a
-server diversi, o un server ricevere su un socket paccetti provenienti da
+server diversi, o un server ricevere su un socket pacchetti provenienti da
 client diversi.  Il modo più semplice di immaginarsi il funzionamento di UDP è
 quello della radio, in cui si può ``trasmettere a'' e ``ricevere da'' più
 stazioni usando la stessa frequenza.
@@ -646,7 +427,7 @@ Nonostante gli evidenti svantaggi comportati dall'inaffidabilit
 grande pregio della velocità che in certi casi è essenziale; inoltre si presta
 bene per le applicazioni in cui la connessione non è necessaria e
 costituirebbe solo un peso di prestazioni mentre una perdita di pacchetti può
-essere tollerata, come quelle che usano il multicasting.
+essere tollerata, ad esempio quelle che usano il multicasting.
 
 \subsection{TCP: Transport Control Protocol)}
 \label{sec:net_tcp}
@@ -656,19 +437,20 @@ diverso da UDP; alla base del suo design infatti non stanno semplicit
 velocità, ma la ricerca della massima affidabilità possibile nella
 trasmissione dei dati.
 
-La prima differenza con UDP è che TCP provvede sempre una conessione diretta
+La prima differenza con UDP è che TCP provvede sempre una connessione diretta
 fra un client e un server, attraverso la quale essi possono comunicare; per
 questo il paragone più appropriato per questo protocollo è quello del
 collegamento telefonico, in quanto prima viene stabilita una connessione fra
-due stazioni su cui poi viene effettuata una comunicazione diretta.
+due i due capi della comunicazione su cui poi viene quest'ultima viene
+effettuata.
 
 Caratteristica fondamentale di TCP è l'affidabilità; quando i dati vengono
 inviati attraverso una connessione ne viene richiesto un ``ricevuto''
 (il cosiddetto \textit{acknowlegment}), se questo non arriva essi verranno
-ritrasmessi facendo un determinato numero di tentativi intervallati da un
-periodo di tempo crescente, fintanto che la connessione sarà considerata
-fallita o caduta la connessione (con un errore di \textit{time-out}), dopo un
-periodo di tempo che dipende dall'implementazione e che può variare far i
+ritrasmessi per un determinato numero di tentativi, intervallati da un
+periodo di tempo crescente, fino a che sarà considerata fallita o caduta la
+connessione (e generato un errore di \textit{time-out}), dopo un periodo di
+tempo che dipende dall'implementazione e che può variare far i
 quattro e i dieci minuti.
 
 Inoltre per tenere conto delle diverse condizioni in cui può trovarsi la linea
@@ -692,7 +474,7 @@ Il protocollo provvede anche un controllo di flusso (\textit{flow control}),
 cioè specifica sempre all'altro capo della trasmissione quanti dati può
 ricevere tramite una \textit{advertised window} (letteralmente finestra
 annunciata), che indica lo spazio disponibile nel buffer di ricezione,
-cosicchè nella trasmissione non vengano inviati più dati di quelli che possono
+cosicché nella trasmissione non vengano inviati più dati di quelli che possono
 essere ricevuti. 
 
 Questa finestra cambia dinamicamente diminuendo con la ricezione dei dati dal
@@ -708,18 +490,108 @@ stesso tempo, il che poi comporta che quanto dicevamo a proposito del
 controllo di flusso e della gestione della sequenzialità dei dati viene
 effettuato per entrambe le direzioni di comunicazione.
 
+Una descrizione più accurata del protocollo è fornita in appendice
+\capref{cha:tcp_protocol}.
 
+\subsection{Limiti e dimensioni riguardanti la trasmissione dei dati}
+\label{sec:net_lim_dim}
 
-\subsection{Creazione e terminazione della connessione TCP}
-
-Per capire il funzionamento delle funzioni della interfaccia dei socket che
-operano con TCP (come \texttt{connect}, \texttt{accept} e \texttt{close} che
-vedremo più avanti) è fodamentale capire come funziona la creazione e la
-conclusione di una connessione TCP.
-
-
+Un aspetto di cui bisogna tenere conto, e che ritornerà in seguito, è che ci
+sono una serie di limiti a cui la trasmissione dei dati attraverso i vari
+livelli del protocollo deve sottostare, limiti che è opportuno tenere presente
+perché in certi casi si possono avere delle conseguenze sul comportamento
+delle applicazioni.
 
+Un elenco di questi limiti è il seguente, insieme ad un breve accenno alle
+loro origini ed alle eventuali implicazioni che possono avere:
+\begin{itemize}
+\item La dimensione massima di un pacchetti IP è di 65535 bytes, compreso
+  l'header. Questo è dovuto al fatto che la dimensione è indicata da un campo
+  apposito nell'header di IP che è lungo 16 bit (vedi
+  \tabref{tab:IP_ipv4head}).
+\item La dimensione massima di un pacchetto normale di IPv6 è di 65575 bytes,
+  il campo apposito nell'header infatti è sempre a 16 bit, ma la dimensione
+  dell'header è fissa e di 40 byte e non è compresa nel valore indicato dal
+  suddetto campo. Inoltre IPv6 ha la possibilità di estendere la dimensione di
+  un pacchetto usando la \textit{jumbo payload option}.
+\item Molte reti fisiche hanno un MTU (\textit{maximum tranfer unit}) che
+  dipende dal protocollo specifico usato al livello di link. Il più comune è
+  quello dell'ethernet che è pari a 1500 bytes, una serie di valori possibili
+  sono riportati in \ntab.
+\end{itemize}
 
-\subsection{Le porte}
+Quando un pacchetto IP viene inviato su una interfaccia di rete e le sue
+dimensioni eccedono la MTU viene eseguita la cosiddetta
+\textit{frammentazione}, i pacchetti cioè vengono spezzati (sia da IPv4 che da
+IPv6, anche se i pacchetti frammentati sono gestiti con modalità
+diverse\footnote{il primo usa un flag nell'header, il secondo una opportuna
+  opzione, si veda \secref{cha:ip_protocol}}), in blocchi più piccoli che
+possono essere trasmessi attraverso l'interfaccia.
 
+\begin{table}[!htb]
+  \centering
+  \begin{tabular}[c]{|l|c|}
+    \hline
+    \textbf{Rete} & \textbf{MTU} \\
+    \hline
+    \hline
+    Hyperlink & 65535 \\
+    Token Ring IBM (16 Mbit/sec) & 17914 \\
+    Token Ring IEEE 802.5 (4 Mbit/sec) & 4464 \\
+    FDDI & 4532 \\
+    Ethernet & 1500 \\
+    X.25 & 576 \\
+    \hline
+  \end{tabular}
+  \caption{Valori della MTU (\textit{maximum tranfer unit}) per una serie di
+    reti diverse.}
+  \label{tab:net_mtu_values}
+\end{table}
 
+La MTU più piccola fra due stazioni viene in genere chiamata \textit{path
+  MTU}, che dice qual'è la lunghezza massima oltre la quale un pacchetto
+inviato da una stazione ad un'altra verrebbe senz'altro frammentato. Si tenga
+conto che non è affatto detto che la \textit{path MTU} sia la stessa in
+entrambe le direzioni, perché l'instradamento può essere diverso nei due
+sensi, con diverse tipologie di rete coinvolte.
+
+Una delle differenze fra IPv4 e IPv6 é che per IPv6 la frammentazione può
+essere eseguita solo alla sorgente, questo vuol dire che i router IPv6 non
+frammentano i pacchetti che trasmettono (anche se possono frammentare i
+pacchetti che generano loro stessi), mentre i router IPv4 si. In ogni caso una
+volta frammentati i pacchetti possono essere riassemblati solo alla
+destinazione.
+
+Nell'header di IPv4 è previsto il flag \texttt{DF} che specifica che il
+pacchetto non deve essere frammentato; un router che riceva un pacchetto le
+cui dimensioni eccedano quelle dell'MTU della rete di destinazione genererà un
+messaggio di errore ICMPv4 di tipo \textit{destination unreachable,
+  fragentation needed but DF bit set}.
+
+Dato che i router IPv6 non possono effettuare la frammentazione la ricezione
+di un pacchetto di dimensione eccessiva per la ritrasmissione genererà sempre
+un messaggio di errore ICMPv6 di tipo \textit{packet too big}.
+
+Dato che il meccanismo di frammentazione e riassemblaggio comporta
+inefficienza normalmente viene utilizzato il procedimento della \textit{path
+  MTU discover} (vedi RFC~1191 per IPv4 e RFC~1981 per IPv6) che permette di
+trovare il \textit{path MTU} fra due stazioni; per la realizzazione del
+procedimento si usa il flag DF di IPv4 e il comportamento normale di IPv6
+inviando delle opportune serie di pacchetti (per i dettagli vedere l'RFC~1191
+per IPv4 e l'RFC~1981 per IPv6) fintanto che non si hanno più errori. 
+
+Il TCP usa sempre questo meccanismo, che per le implementazioni di IPv4 è
+opzionale, mentre diventa obbligatorio per IPv6.  Per IPv6 infatti, non
+potendo i router frammentare i pacchetti, è necessario, per poter comunicare,
+conoscere il \textit{path MTU}.
+
+
+Infine TCP definisce una \textit{maximum segment size} MSS che annuncia
+all'altro capo la dimensione massima del segmento di dati.
+
+
+\subsection{Il passaggio dei dati in TCP}
+\label{sec:net_tcp_pass}
+
+\subsection{Il passaggio dei dati in UDP}
+\label{sec:net_udp_pass}