Sistemati i riferimenti
[gapil.git] / network.tex
index ba0e7d32084f5904121a0a61fc9eea6e63a7ff7a..879f9708bda4d2ccc59f534e7806865604d9aaab 100644 (file)
-\chapter{Introduzione alla rete}
+\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 ed esamineremo a grandi
-linee i protocolli di rete e 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, per evitare un
+capitolo puramente teorico 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 particolare, avendo assunto l'ottica di un'introduzione mirata alla
-programmazione di rete, ci concentreremo sul protocollo più diffuso che è
-quello che sta alla base di internet, ed in particolare sulle parti più
-importanti ai fini della programmazione.  
+programmazione, ci concentreremo sul protocollo più diffuso, il TCP/IP, che è
+quello che sta alla base di internet, con un'ottica improntata a sottolineare
+i concetti più importanti da conoscere ai fini della programmazione.
 
+\section{Il modello client-server}
+\label{sec:net_cliserv}
+
+La differenza principale fra un'applicazione di rete e un programma normale è
+che quest'ultima per definizione concerne la comunicazione fra ``processi''
+diversi (che in generale non girano neanche sulla stessa macchina). Questo già
+prefigura un cambiamento completo rispetto all'ottica del ``programma''
+monolitico all'interno del quale vengono eseguite tutte le istruzioni, e
+presuppone un sistema operativo ``multitasking'' in grado di eseguire processi
+diversi.
+
+Il concetto fondamentale si basa la programmazione di rete sotto Linux (e
+sotto Unix in generale) è il modello \textit{client-server} in cui un
+programma di servizio, il \textit{server} riceve un connessione e risponde a
+un programma di utilizzo, il \textit{client}, provvedendo a quest'ultimo un
+definito insieme di servizi.
+
+Esempi di questo modello sono il WEB, ftp, telnet, ssh e praticamente ogni
+servizio che viene fornito tramite la rete, ma il modello è utilizzato in
+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
+\textsl{concorrenti} o \textsl{iterativi}, sulla base del loro comportamento.
+
+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 \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.
+
+
+\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 esempio di un client TCP
+elementare.  Scopo di questo esempio è fornire un primo approccio alla
+programmazione di rete, tutto questo sarà esaminato in dettaglio nei capitoli
+successivo; qui ci limiteremo a introdurre la nomenclatura senza fornire
+definizioni precise e dettagli di funzionamento che saranno trattati
+estensivamente più avanti.
+
+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 richiesta.
+
+
+\begin{figure}[!htb]
+  \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}
+
+Il sorgente completo del programma (\texttt{ElemDaytimeTCPClient.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
+\capref{sec:proc_opt_handling}).
+
+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 passata 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{ElemDaytimeTCPServer.c}) è allegato insieme agli altri file nella
+directory \texttt{sources}.
+
+\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.
+
+È importante 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 e il terminale da cui lo si è lanciato è stato sconnesso),
+occorrerebbero delle opportune modifiche.
 
 \section{I protocolli di rete}
 \label{sec:net_protocols}
 
+Visto un primo esempio di programmazione, passiamo ora ad una introduzione più
+dettagliata del funzionamento delle reti e dei relativi protocolli.
+
 Parlando di reti di computer si parla in genere di un insieme molto vasto ed
 eterogeneo di mezzi di comunicazione che vanno dal cavo telefonico, alla fibra
 ottica, alle comunicazioni via satellite; per rendere possibile la
 comunicazione attraverso un così variegato insieme di mezzi sono stati
 adottati una serie di protocolli, il più famoso dei quali, quello alla base
-del funzionamento di internet, è il cosiddetto TCP/IP.
+del funzionamento di internet, è il protocollo TCP/IP.
 
 \subsection{Il modello ISO/OSI}
 \label{sec:net_iso_osi}
@@ -31,7 +321,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
@@ -60,15 +350,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
@@ -83,11 +382,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
@@ -95,8 +393,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
@@ -113,32 +411,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}
@@ -178,33 +484,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,
+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
@@ -213,9 +538,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'è
@@ -223,13 +548,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.
+  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{ICMP} \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
@@ -258,7 +584,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.).
@@ -280,8 +606,8 @@ internet ha iniziato a far emergere i vari limiti di IPv4, per risolverne i
 problemi si è perciò definita una nuova versione del protocollo, che (saltando
 un numero) è diventata la versione 6. IPv6 nasce quindi come evoluzione di
 IPv4, mantendone inalterate le funzioni che si sono dimostrate valide,
-eliminando quelle inutili e aggiungendone poche altre ponendo al contempo una
-grande attenzione a mantenere il protocollo il più snello e veloce possibile.
+eliminando quelle inutili e aggiungendone poche altre per mantenere il
+protocollo il più snello e veloce possibile.
 
 I cambiamenti apportati sono comunque notevoli e si possono essere riassunti a
 grandi linee nei seguenti punti:
@@ -290,80 +616,233 @@ 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'RFC768, 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
-(\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 
-
+mancanza di affidabilità, se si vuole essere sicuri che i pacchetti arrivino a
+destinazione occorrerà provvedere con l'applicazione all'interno della quale
+si dovrà inserire tutto quanto necessario a gestire la notifica di
+ricevimento, la ritrasmissione, il timeout. 
+
+Si tenga conto poi che in UDP niente garantisce che i pacchetti arrivino nello
+stesso ordine in cui sono stati trasmessi, e può anche accadere che i
+pacchetti vengano duplicati nella trasmissione, e non solo perduti. Di tutto
+questo di nuovo deve tenere conto l'applicazione.
+
+Un'altro aspetto di UDP è che se un pacchetto raggiunge correttamente la
+destinazione esso viene passato all'applicazione ricevente in tutta la sua
+lunghezza, la trasmissione avviene perciò per \textit{record} la cui lunghezza
+viene anche essa trasmessa all'applicazione all'atto del ricevimento.
+
+Infine UDP è un protocollo che opera senza connessione
+(\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 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.
+
+Nonostante gli evidenti svantaggi comportati dall'inaffidabilità UDP ha il
+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, ad esempio quelle che usano il multicasting.
 
 \subsection{TCP: Transport Control Protocol)}
 \label{sec:net_tcp}
 
+Il TCP è un protocollo molto complesso, definito nell'RFC~739 e completamente
+diverso da UDP; alla base del suo design infatti non stanno semplicità e
+velocità, ma la ricerca della massima affidabilità possibile nella
+trasmissione dei dati.
+
+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 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 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
+di comunicazione TCP comprende anche un algoritmo di calcolo dinamico del
+tempo di andata e ritorno dei pacchetti (il cosiddetto RTT, 
+\textit{round-trip time}) fra un client e un server che lo rende in grado di
+adattarsi alle condizioni della rete per non generare inutili ritrasmissioni o
+cadere facilmente in timeout.
+
+Inoltre TCP è in grado di preservare l'ordine dei dati assegnando un numero di
+sequenza ad ogni byte che trasmette. Ad esempio se un'applicazione scrive 3000
+bytes su un socket TCP, questi potranno essere spezzati dal protocollo in due
+segmenti (le unità di dati passate da TCP a IP vengono chiamate
+\textit{segment}) di 1500 bytes, di cui il primo conterrà il numero di
+sequenza $1-1500$ e il secondo il numero $1501-3000$. In questo modo anche se
+i segmenti arrivano a destinazione in un ordine diverso, o se alcuni arrivano
+più volte a causa di ritrasmissioni dovute alla perdita dei ricevuto,
+all'arrivo sarà comunque possibile riordinare i dati e scartare i duplicati.
+
+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
+essere ricevuti. 
+
+Questa finestra cambia dinamicamente diminuendo con la ricezione dei dati dal
+socket ed aumentando con la lettura di quest'ultimo da parte
+dell'applicazione, se diventa nulla il buffer di ricezione è pieno e non
+verranno accettati altri dati.  Si noti che UDP non provvede niente di tutto
+ciò per cui nulla impedisce che vengano trasmessi pacchetti ad un rate che il
+ricevitore non può sostenere.
+
+Infine attraverso TCP la trasmissione è sempre bidirezionale (in inglese
+\textit{full-duplex}), è cioè possibile sia trasmettere che ricevere allo
+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}
+
+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}
 
+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.
 
-\section{Il modello client-server}
-\label{sec:net_cliserv}.
-
-La differenza principale fra un'applicazione di rete e un programma normale
-è che quest'ultima per definizione concerne la comunicazione fra
-``processi'' diversi (che in generale non girano neanche sulla stessa
-macchina). Questo già prefigura un cambiamento completo rispetto all'ottica
-del ``programma'' monolitico all'interno del quale vengono eseguite tutte le
-istruzioni, e presuppone un sistema operativo ``multitasking'' in grado di
-eseguire processi diversi.
-
-Il concetto fondamentale si basa la programmazione di rete sotto Linux (e
-sotto Unix in generale) è il modello \textit{client-server} in cui un
-programma di servizio, il \textit{server} riceve un connessione e risponde a
-un programma di utilizzo, il \textit{client}, provvedendo a quest'ultimo un
-definito insieme di servizi.
-
-Esempi di questo modello sono il WEB, ftp, telnet, ssh e praticamente ogni
-servizio che viene fornito tramite la rete, ma il modello è utilizzato in
-generale anche per programmi di uso locale.
-
-Normalmente si dividono i server in due categorie principali,
-\textit{concorrenti} e \textit{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
-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.
+\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}