Prova di endianess
[gapil.git] / elemtcp.tex
index cfc4c8530540a00cd5f686f80614fbd13fbbdbf4..a49c48c5d0dbd8a5354cbc1cd7512eb3b3f2ecd8 100644 (file)
@@ -1,6 +1,6 @@
 %% elemtcp.tex
 %%
-%% Copyright (C) 2000-2002 Simone Piccardi.  Permission is granted to
+%% Copyright (C) 2000-2003 Simone Piccardi.  Permission is granted to
 %% copy, distribute and/or modify this document under the terms of the GNU Free
 %% Documentation License, Version 1.1 or any later version published by the
 %% Free Software Foundation; with the Invariant Sections being "Prefazione",
@@ -71,7 +71,7 @@ scambiati) che porta alla creazione di una connessione 
   client, inoltre anche il server deve inviare il suo SYN al client (e
   trasmettere il suo numero di sequenza iniziale) questo viene fatto
   ritrasmettendo un singolo segmento in cui sono impostati entrambi i flag SYN
-  ACK.
+  ACK.
   
 \item una volta che il client ha ricevuto l'acknowledge dal server la funzione
   \func{connect} ritorna, l'ultimo passo è dare dare il ricevuto del SYN del
@@ -101,7 +101,7 @@ stabilisce la connessione.
 \end{figure}
 
 Si è accennato in precedenza ai \textsl{numeri di sequenza} (che sono anche
-riportati in \figref{fig:TCP_TWH}); per gestire una connessione affidabile
+riportati in \figref{fig:TCP_TWH}): per gestire una connessione affidabile
 infatti il protocollo TCP prevede nell'header la presenza di un numero a 32
 bit (chiamato appunto \textit{sequence number}) che identifica a quale byte
 nella sequenza del flusso corrisponde il primo byte della sezione dati
@@ -170,29 +170,27 @@ elevati. In ogni caso Linux supporta pienamente entrambe le opzioni.
 \subsection{La terminazione della connessione}
 \label{sec:TCP_conn_term}
 
-Mentre per creare una connessione occorre un interscambio di tre segmenti, la
-procedura di chiusura ne richiede quattro; ancora una volta si può fare
-riferimento al codice degli esempi \figref{fig:TCP_daytime_client_code} e
-\figref{fig:TCP_daytime_iter_server_code}, in questo caso la successione degli
-eventi è la seguente:
+Mentre per la creazione di una connessione occorre un interscambio di tre
+segmenti, la procedura di chiusura ne richiede normalmente quattro. In questo
+caso la successione degli eventi è la seguente:
 
 \begin{enumerate}
 \item Un processo ad uno dei due capi chiama la funzione \func{close}, dando
   l'avvio a quella che viene chiamata \textsl{chiusura attiva} (o
   \textit{active close}). Questo comporta l'emissione di un segmento FIN, che
-  significa che si è finito con l'invio dei dati sulla connessione.
+  serve ad indicare che si è finito con l'invio dei dati sulla connessione.
   
-\item L'altro capo della connessione riceve il FIN ed esegue la
-  \textsl{chiusura passiva} (o \textit{passive close}); al FIN, come ad ogni
-  altro pacchetto, viene risposto con un ACK. Inoltre il ricevimento del FIN
+\item L'altro capo della connessione riceve il FIN e dovrà eseguire la
+  \textsl{chiusura passiva} (o \textit{passive close}). Al FIN, come ad ogni
+  altro pacchetto, viene risposto con un ACK, inoltre il ricevimento del FIN
   viene segnalato al processo che ha aperto il socket (dopo che ogni altro
   eventuale dato rimasto in coda è stato ricevuto) come un end-of-file sulla
-  lettura, questo perché il ricevimento di un FIN significa che non si
+  lettura: questo perché il ricevimento di un FIN significa che non si
   riceveranno altri dati sulla connessione.
-
-\item Dopo un certo tempo anche il secondo processo chiamerà la funzione
-  \func{close} sul proprio socket, causando l'emissione di un altro segmento
-  FIN. 
+  
+\item Una volta rilevata l'end-of-file anche il secondo processo chiamerà la
+  funzione \func{close} sul proprio socket, causando l'emissione di un altro
+  segmento FIN.
 
 \item L'altro capo della connessione riceverà il FIN conclusivo e risponderà
   con un ACK.
@@ -352,10 +350,8 @@ Ogni implementazione del TCP deve scegliere un valore per la MSL
 (l'\href{http://www.ietf.org/rfc/rfc1122.txt}{RFC~1122} raccomanda 2 minuti,
 Linux usa 30 secondi), questo comporta una durata dello stato
 \texttt{TIME\_WAIT} che a seconda delle implementazioni può variare fra 1 a 4
-minuti.
-
-Lo stato \texttt{TIME\_WAIT} viene utilizzato dal protocollo per due motivi
-principali:
+minuti.  Lo stato \texttt{TIME\_WAIT} viene utilizzato dal protocollo per due
+motivi principali:
 \begin{enumerate}
 \item implementare in maniera affidabile la terminazione della connessione
   in entrambe le direzioni.
@@ -379,13 +375,13 @@ verrebbe interpretato come un errore.
 Se il TCP deve poter chiudere in maniera pulita entrambe le direzioni della
 connessione allora deve essere in grado di affrontare la perdita di uno
 qualunque dei quattro segmenti che costituiscono la chiusura. Per questo
-motivo lo stato \texttt{TIME\_WAIT} deve essere mantenuto anche dopo l'invio
-dell'ultimo ACK per poter essere in grado di poterne gestire l'eventuale
-ritrasmissione in caso di perdita.
+motivo un socket deve rimanere attivo nello stato \texttt{TIME\_WAIT} anche
+dopo l'invio dell'ultimo ACK, per potere essere in grado di gestirne
+l'eventuale ritrasmissione, in caso esso venga perduto.
 
 Il secondo motivo è più complesso da capire, e necessita di una spiegazione
-degli scenari in cui accade che i pacchetti si possano perdere nella rete o
-restare intrappolati, per poi riemergere in un secondo tempo.
+degli scenari in cui può accadere che i pacchetti TCP si possano perdere nella
+rete o restare intrappolati, per poi riemergere in un secondo tempo.
 
 Il caso più comune in cui questo avviene è quello di anomalie
 nell'instradamento; può accadere cioè che un router smetta di funzionare o che
@@ -397,13 +393,13 @@ pacchetti verso un'altro e quest'ultimo li rispedisce indietro, o li manda ad
 un terzo router che li rispedisce al primo, si creano cioè dei circoli (i
 cosiddetti \textit{routing loop}) in cui restano intrappolati i pacchetti.
 
-Se uno di questi pacchetti intrappolati è un segmento TCP chi l'ha inviato,
+Se uno di questi pacchetti intrappolati è un segmento TCP, chi l'ha inviato,
 non ricevendo un ACK in risposta, provvederà alla ritrasmissione e se nel
 frattempo sarà stata stabilita una strada alternativa il pacchetto ritrasmesso
 giungerà a destinazione.
 
 Ma se dopo un po' di tempo (che non supera il limite dell'MSL, dato che
-altrimenti verrebbe ecceduto il TTL) l'anomalia viene a cessare il circolo di
+altrimenti verrebbe ecceduto il TTL) l'anomalia viene a cessare, il circolo di
 instradamento viene spezzato i pacchetti intrappolati potranno essere inviati
 alla destinazione finale, con la conseguenza di avere dei pacchetti duplicati;
 questo è un caso che il TCP deve essere in grado di gestire.
@@ -411,7 +407,8 @@ questo 
 Allora per capire la seconda ragione per l'esistenza dello stato
 \texttt{TIME\_WAIT} si consideri il caso seguente: si supponga di avere una
 connessione fra l'IP \texttt{195.110.112.236} porta 1550 e l'IP
-\texttt{192.84.145.100} porta 22, che questa venga chiusa e che poco dopo si
+\texttt{192.84.145.100} porta 22 (affronteremo il significato delle porte
+nella prossima sezione), che questa venga chiusa e che poco dopo si
 ristabilisca la stessa connessione fra gli stessi IP sulle stesse porte
 (quella che viene detta, essendo gli stessi porte e numeri IP, una nuova
 \textsl{incarnazione} della connessione precedente); in questo caso ci si
@@ -445,8 +442,8 @@ Quando un client contatta un server deve poter identificare con quale dei vari
 possibili server attivi intende parlare. Sia TCP che UDP definiscono un gruppo
 di \textsl{porte conosciute} (le cosiddette \textit{well-known port}) che
 identificano una serie di servizi noti (ad esempio la porta 22 identifica il
-servizio \textit{ssh}) effettuati da appositi server che rispondono alle
-connessioni verso tali porte.
+servizio SSH) effettuati da appositi server che rispondono alle connessioni
+verso tali porte.
 
 D'altra parte un client non ha necessità di usare un numero di porta
 specifico, per cui in genere vengono usate le cosiddette \textsl{porte
@@ -460,7 +457,7 @@ La lista delle porte conosciute 
 dall'\href{http://www.ietf.org/rfc/rfc1700.txt}{RFC~1700} che contiene
 l'elenco delle porte assegnate dalla IANA (la \textit{Internet Assigned Number
   Authority}) ma l'elenco viene costantemente aggiornato e pubblicato su
-internet (una versione corrente si può trovare all'indirizzo
+internet (una versione aggiornata si può trovare all'indirizzo
 \texttt{ftp://ftp.isi.edu/in-notes/iana/assignements/port-numbers}); inoltre
 in un sistema unix-like un analogo elenco viene mantenuto nel file
 \file{/etc/services}, con la corrispondenza fra i vari numeri di porta ed il
@@ -470,7 +467,7 @@ nome simbolico del servizio.  I numeri sono divisi in tre intervalli:
 \item \textsl{le porte conosciute}. I numeri da 0 a 1023. Queste sono
   controllate e assegnate dalla IANA. Se è possibile la stessa porta è
   assegnata allo stesso servizio sia su UDP che su TCP (ad esempio la porta 22
-  è assegnata a ssh su entrambi i protocolli, anche se viene usata solo dal
+  è assegnata a SSH su entrambi i protocolli, anche se viene usata solo dal
   TCP).
   
 \item \textsl{le porte registrate}. I numeri da 1024 a 49151. Queste porte non
@@ -503,15 +500,16 @@ tabelle.
 I sistemi Unix hanno inoltre il concetto di \textsl{porte riservate} (che
 corrispondono alle porte con numero minore di 1024 e coincidono quindi con le
 porte conosciute). La loro caratteristica è che possono essere assegnate a un
-socket solo da un processo con i privilegi di amministratore, per far si che solo
-l'amministratore possa allocare queste porte per far partire i relativi
+socket solo da un processo con i privilegi di amministratore, per far si che
+solo l'amministratore possa allocare queste porte per far partire i relativi
 servizi.
 
-Si tenga conto poi che ci sono alcuni client (in particolare \cmd{rsh} e
-\cmd{rlogin}) che richiedono una connessione su una porta riservata anche
-dal lato client come parte dell'autenticazione. Questo viene fatto tramite la
-funzione \func{rresvport} assegnando al socket una porta libera
-nell'intervallo fra 512 e 1023.
+Si tenga conto poi che ci sono alcuni client, in particolare \cmd{rsh} e
+\cmd{rlogin}, che richiedono una connessione su una porta riservata anche dal
+lato client come parte dell'autenticazione, contando appunto sul fatto che
+solo l'amministratore può usare queste porte. Data l'assoluta inconsistenza in
+termini di sicurezza di un tale metodo, al giorno d'oggi esso è in completo
+disuso.
 
 Data una connessione TCP si suole chiamare \textit{socket pair}\footnote{da
   non confondere con la coppia di socket della omonima funzione
@@ -532,7 +530,7 @@ queste informazioni nei campi \textit{Local Address} e \textit{Foreing
 \label{sec:TCP_port_cliserv}
 
 Per capire meglio l'uso delle porte e come vengono utilizzate quando si ha a
-che fare con un'applicazione client/server (come quelle che scriveremo in
+che fare con un'applicazione client/server (come quelle che descriveremo in
 \secref{sec:TCP_daytime_application} e \secref{sec:TCP_echo_application})
 esamineremo cosa accade con le connessioni nel caso di un server TCP che deve
 gestire connessioni multiple.
@@ -546,10 +544,10 @@ tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN
 tcp        0      0 0.0.0.0:25              0.0.0.0:*               LISTEN
 tcp        0      0 127.0.0.1:53            0.0.0.0:*               LISTEN
 \end{verbatim}
-essendo presenti e attivi un server ssh, un server di posta e un DNS per il
+essendo presenti e attivi un server SSH, un server di posta e un DNS per il
 caching locale.
 
-Questo ci mostra ad esempio che il server ssh ha compiuto un'apertura passiva,
+Questo ci mostra ad esempio che il server SSH ha compiuto un'apertura passiva,
 mettendosi in ascolto sulla porta 22 riservata a questo servizio, e che si è
 posto in ascolto per connessioni provenienti da uno qualunque degli indirizzi
 associati alle interfacce locali. La notazione \texttt{0.0.0.0} usata da
@@ -625,13 +623,13 @@ dalla porta remota 21100 vanno al primo figlio e quelli che arrivano alla
 porta 21101 al secondo.
 
 
-\section{Le funzioni dei socket TCP}
+\section{Le funzioni di base per la gestione dei socket}
 \label{sec:TCP_functions}
 
-In questa sezione descriveremo in dettaglio le varie funzioni necessarie per
-l'uso dei socket TCP, con l'eccezione della funzione \func{socket} che è già
-stata esaminata in dettaglio nel capitolo precedente in
-\secref{sec:sock_socket}. 
+In questa sezione descriveremo in maggior dettaglio le varie funzioni che
+vengono usate per la gestione di base dei socket TCP, non torneremo però sulla
+funzione \func{socket}, che è già stata esaminata accuratamente nel capitolo
+precedente in \secref{sec:sock_socket}.
 
 
 \subsection{La funzione \func{bind}}
@@ -669,8 +667,8 @@ Il primo argomento 
 l'indirizzo (locale) del socket e la dimensione della struttura che lo
 contiene, secondo quanto già trattato in \secref{sec:sock_sockaddr}. 
 
-Con il TCP la chiamata \func{bind} permette di specificare l'indirizzo, la
-porta, entrambi o nessuno dei due. In genere i server utilizzano una porta
+Con i socket TCP la chiamata \func{bind} permette di specificare l'indirizzo,
+la porta, entrambi o nessuno dei due. In genere i server utilizzano una porta
 nota che assegnano all'avvio, se questo non viene fatto è il kernel a
 scegliere una porta effimera quando vengono eseguite la funzioni
 \func{connect} o \func{listen}, ma se questo è normale per il client non lo è
@@ -690,7 +688,7 @@ alle connessioni che arrivano verso tale indirizzo.
 
 Normalmente un client non specifica mai l'indirizzo di un socket, ed il kernel
 sceglie l'indirizzo di origine quando viene effettuata la connessione, sulla
-base dell'interfaccia usata per trasmettere i pacchetti, (che dipende dalle
+base dell'interfaccia usata per trasmettere i pacchetti, (che dipende dalle
 regole di instradamento usate per raggiungere il server).  Se un server non
 specifica il suo indirizzo locale il kernel userà come indirizzo di origine
 l'indirizzo di destinazione specificato dal SYN del client.
@@ -755,7 +753,7 @@ connessione con un server TCP, il prototipo della funzione 
   Stabilisce una connessione fra due socket.
   
   \bodydesc{La funzione restituisce zero in caso di successo e -1 per un
-    errore, in caso di errore \var{errno} assumerà i valori:
+    errore, nel qual caso \var{errno} assumerà i valori:
   \begin{errlist}
   \item[\errcode{ECONNREFUSED}] non c'è nessuno in ascolto sull'indirizzo
     remoto.
@@ -1053,12 +1051,12 @@ errori rispetto ad altre implementazioni dei socket BSD, infatti la funzione
 \func{accept} passa gli errori di rete pendenti sul nuovo socket come codici
 di errore per \func{accept}, per cui l'applicazione deve tenerne conto ed
 eventualmente ripetere la chiamata alla funzione come per l'errore di
-\errcode{EAGAIN}. Un'altra differenza con BSD è che la funzione non fa
-ereditare al nuovo socket i flag del socket originale, come
-\const{O\_NONBLOCK},\footnote{ed in generale tutti quelli che si possono
-  impostare con \func{fcntl}, vedi \secref{sec:file_fcntl}.} che devono essere
-rispecificati ogni volta. Tutto questo deve essere tenuto in conto se si
-devono scrivere programmi portabili.
+\errcode{EAGAIN} (torneremo su questo in \secref{sec:TCP_echo_critical}).
+Un'altra differenza con BSD è che la funzione non fa ereditare al nuovo socket
+i flag del socket originale, come \const{O\_NONBLOCK},\footnote{ed in generale
+  tutti quelli che si possono impostare con \func{fcntl}, vedi
+  \secref{sec:file_fcntl}.} che devono essere rispecificati ogni volta. Tutto
+questo deve essere tenuto in conto se si devono scrivere programmi portabili.
 
 Il meccanismo di funzionamento di \func{accept} è essenziale per capire il
 funzionamento di un server: in generale infatti c'è sempre un solo socket in
@@ -1233,9 +1231,9 @@ socket di tipo stream).
 Infatti con i socket è comune che funzioni come \func{read} o \func{write}
 possano restituire in input o scrivere in output un numero di byte minore di
 quello richiesto. Come già accennato in \secref{sec:file_read} questo è un
-comportamento normale per l'I/O su file, ma con i normali file di dati il
-problema si avverte solo quando si incontra la fine del file. In generale non
-è così, e con i socket questo è particolarmente evidente.
+comportamento normale per le funzioni di I/O, ma con i normali file di dati il
+problema si avverte solo in lettura, quando si incontra la fine del file. In
+generale non è così, e con i socket questo è particolarmente evidente.
 
 
 \begin{figure}[htb]
@@ -1286,15 +1284,18 @@ l'errore viene ritornato al programma chiamante, interrompendo il ciclo.
 Nel caso della lettura, se il numero di byte letti è zero, significa che si è
 arrivati alla fine del file (per i socket questo significa in genere che
 l'altro capo è stato chiuso, e quindi non sarà più possibile leggere niente) e
-pertanto si ritorna senza aver concluso la lettura di tutti i byte richiesti.
+pertanto si ritorna senza aver concluso la lettura di tutti i byte
+richiesti. Entrambe le funzioni restituiscono 0 in caso di successo, ed un
+valore negativo in caso di errore, \texttt{FullRead} restituisce il numero di
+byte non letti in caso di end-of-file prematuro.
 
 
 \subsection{Il client \textit{daytime}}
 \label{sec:TCP_daytime_client}
 
 Il primo esempio di applicazione delle funzioni di base illustrate in
-precedenza è relativo alla creazione di un client elementare per il servizio
-\textit{daytime}, un servizio elementare, definito
+\secref{sec:TCP_functions} è relativo alla creazione di un client elementare
+per il servizio \textit{daytime}, un servizio elementare, definito
 nell'\href{http://www.ietf.org/rfc/rfc0867.txt}{RFC~867}, che restituisce
 l'ora locale della macchina a cui si effettua la richiesta, e che è assegnato
 alla porta 13.
@@ -1526,7 +1527,7 @@ ulteriori connessioni.
 
 Si noti come il figlio operi solo sul socket connesso, chiudendo
 immediatamente (\texttt{\small 32}) il socket \var{list\_fd}; mentre il padre
-continua ad operare solo sul socket in ascolto chiudendo (\texttt{\small 47})
+continua ad operare (\texttt{\small 47}) solo sul socket in ascolto chiudendo
 \var{sock\_fd} al ritorno dalla \func{fork}. Per quanto abbiamo detto in
 \secref{sec:TCP_func_close} nessuna delle due chiamate a \func{close} causa
 l'innesco della sequenza di chiusura perché il numero di riferimenti al file
@@ -1635,7 +1636,7 @@ output.
 \label{sec:TCP_echo_client}
 
 Il codice della prima versione del client per il servizio \textit{echo},
-disponibile nel file \file{TCP\_echo1.c}, è riportato in
+disponibile nel file \file{TCP\_echo\_first.c}, è riportato in
 \figref{fig:TCP_echo_client_1}. Esso ricalca la struttura del precedente
 client per il servizio \textit{daytime} (vedi
 \secref{sec:TCP_daytime_client}), e la prima parte (\texttt{\small 10--27}) è
@@ -1644,7 +1645,7 @@ sostanzialmente identica, a parte l'uso di una porta diversa.
 \begin{figure}[!htb]
   \footnotesize \centering
   \begin{minipage}[c]{15.6 cm}
-    \includecodesample{listati/TCP_echo1.c}
+    \includecodesample{listati/TCP_echo_first.c}
   \end{minipage} 
   \normalsize
   \caption{Codice della prima versione del client \textit{echo}.}
@@ -1680,9 +1681,14 @@ Si usa poi (\texttt{\small 6}) la funzione \func{FullWrite}, vista in
 \secref{sec:sock_io_behav}, per scrivere i dati sul socket, gestendo
 automaticamente l'invio multiplo qualora una singola \func{write} non sia
 sufficiente.  I dati vengono riletti indietro (\texttt{\small 7}) con una
-\func{FullRead} sul buffer di ricezione e viene inserita (\texttt{\small 8})
-la terminazione della stringa e per poter usare (\texttt{\small 9}) la
-funzione \func{fputs} per scriverli su \file{stdout}.
+\func{read}\footnote{si è fatta l'assunzione implicita che i dati siano
+  contenuti tutti in un solo segmento, così che la chiamata a \texttt{read} li
+  restituisca sempre tutti; avendo scelto una dimensione ridotta per il buffer
+  questo sarà sempre vero, vedremo più avanti come superare il problema di
+  rileggere indietro tutti e soli i dati disponibili, senza bloccarsi.} sul
+buffer di ricezione e viene inserita (\texttt{\small 8}) la terminazione della
+stringa e per poter usare (\texttt{\small 9}) la funzione \func{fputs} per
+scriverli su \file{stdout}.
 
 \begin{figure}[!htb]
   \footnotesize \centering
@@ -1793,13 +1799,13 @@ errore attraverso il sistema del \textit{syslog} trattato in
 \textit{wrapper} la funzione \code{PrintErr}, il cui codice è riportato in
 \figref{fig:TCP_PrintErr}. 
 
-In essa ci si limita a controllare se è stato impostato (valore attivo per
-default) l'uso come demone, nel qual caso (\texttt{\small 3}) si usa
-\func{syslog} per stampare il messaggio di errore fornito come argomento sui
-log di sistema. Se invece si è in modalità interattiva (attivabile con
-l'opzione \texttt{-i}) si usa semplicemente la funzione \func{perror} per
-stampare sullo standard error.
-
+In essa ci si limita a controllare (\texttt{\small 2}) se è stato impostato
+(valore attivo per default) l'uso come demone, nel qual caso (\texttt{\small
+  3}) si usa \func{syslog} (vedi \secref{sec:sess_daemon}) per stampare il
+messaggio di errore fornito come argomento sui log di sistema. Se invece si è
+in modalità interattiva (attivabile con l'opzione \texttt{-i}) si usa
+(\texttt{\small 5}) semplicemente la funzione \func{perror} per stampare sullo
+standard error.
 
 \begin{figure}[!htb]
   \footnotesize \centering
@@ -1815,34 +1821,33 @@ stampare sullo standard error.
 
 La gestione del servizio \textit{echo} viene effettuata interamente nella
 funzione \code{ServEcho}, il cui codice è mostrato in
-\figref{fig:TCP_ServEcho}, la comunicazione viene gestita all'interno del
-ciclo (\texttt{\small 6--8}).  I dati inviati dal client vengono letti dal
-socket con una semplice \func{read} (che ritorna solo in presenza di dati in
-arrivo), la riscrittura viene invece gestita dalla funzione \func{FullWrite}
-(descritta in \figref{fig:sock_FullWrite_code}) che si incarica di tenere
-conto automaticamente della possibilità che non tutti i dati di cui è
-richiesta la scrittura vengano trasmessi con una singola \func{write}.
+\figref{fig:TCP_ServEcho_first}, e la comunicazione viene gestita all'interno
+di un ciclo (\texttt{\small 6--13}).  I dati inviati dal client vengono letti
+(\texttt{\small 6}) dal socket con una semplice \func{read}, di cui non si
+controlla lo stato di uscita, assumendo che ritorni solo in presenza di dati
+in arrivo. La riscrittura (\texttt{\small 7}) viene invece gestita dalla
+funzione \func{FullWrite} (descritta in \figref{fig:sock_FullWrite_code}) che
+si incarica di tenere conto automaticamente della possibilità che non tutti i
+dati di cui è richiesta la scrittura vengano trasmessi con una singola
+\func{write}.
 
 \begin{figure}[!htb] 
   \footnotesize \centering
   \begin{minipage}[c]{15.6cm}
-    \includecodesample{listati/ServEcho.c}
+    \includecodesample{listati/ServEcho_first.c}
   \end{minipage} 
   \normalsize
   \caption{Codice della prima versione della funzione \code{ServEcho} per la
     gestione del servizio \textit{echo}.}
-  \label{fig:TCP_ServEcho}
+  \label{fig:TCP_ServEcho_first}
 \end{figure}
 
-Nella funzione si è anche inserita la possibilità (\texttt{\small 7--14}) di
-inviare dei messaggi di debug (abilitabile con l'uso dell'opzione \texttt{-d}
-che imposta opportunamente \var{debugging}), gestendo entrambi i casi in cui
-la stampa deve essere effettuata tramite \func{syslog} (\texttt{\small 11}) o
-direttamente sullo standard output (\texttt{\small 13}).
-
-Quando il client chiude la connessione il ricevimento del FIN fa ritornare la
-\func{read} con un numero di byte letti pari a zero, il che causa l'uscita dal
-ciclo e il ritorno della funzione, che a sua volta causa la terminazione del
+In caso di errore di scrittura (si ricordi che \func{FullWrite} restituisce un
+valore nullo in caso di successo) si provvede (\texttt{\small 8--10}) a
+stampare il relativo messaggio con \func{PrintErr}.  Quando il client chiude
+la connessione il ricevimento del FIN fa ritornare la \func{read} con un
+numero di byte letti pari a zero, il che causa l'uscita dal ciclo e il ritorno
+(\texttt{\small 12}) della funzione, che a sua volta causa la terminazione del
 processo figlio.
 
 
@@ -1850,7 +1855,7 @@ processo figlio.
 \label{sec:TCP_echo_startup}
 
 Benché il codice dell'esempio precedente sia molto ridotto, esso ci permetterà
-di considerare in dettaglio tutte le problematiche che si possono incontrare
+di considerare in dettaglio le varie problematiche che si possono incontrare
 nello scrivere un'applicazione di rete. Infatti attraverso l'esame delle sue
 modalità di funzionamento normali, all'avvio e alla terminazione, e di quello
 che avviene nelle varie situazioni limite, da una parte potremo approfondire
@@ -1952,8 +1957,8 @@ quando affronteremo il comportamento in caso di conclusioni anomale:
 
 \begin{enumerate}
 \item inviando un carattere di EOF da terminale la \func{fgets} ritorna
-  restituendo un puntatore nullo che causa l'uscita dal ciclo di
-  \code{while}, così la \code{ClientEcho} ritorna.
+  restituendo un puntatore nullo che causa l'uscita dal ciclo di \code{while},
+  così la funzione \code{ClientEcho} ritorna.
 \item al ritorno di \code{ClientEcho} ritorna anche la funzione \code{main}, e
   come parte del processo terminazione tutti i file descriptor vengono chiusi
   (si ricordi quanto detto in \secref{sec:proc_term_conclusion}); questo causa
@@ -2004,13 +2009,13 @@ seguente codice: \includecodesnip{listati/sigchildhand.c}
 \noindent
 all'esempio illustrato in \figref{fig:TCP_echo_server_first_code}.
 
-In questo modo però si introduce un altro problema, si ricordi infatti che,
+In questo modo però si introduce un altro problema. Si ricordi infatti che,
 come spiegato in \secref{sec:sig_gen_beha}, quando un programma si trova in
 stato di \texttt{sleep} durante l'esecuzione di una system call, questa viene
 interrotta alla ricezione di un segnale. Per questo motivo, alla fine
 dell'esecuzione del gestore del segnale, se questo ritorna, il programma
-riprenderà l'esecuzione ritornando dalla system call con un errore di
-\errcode{EINTR}.
+riprenderà l'esecuzione ritornando dalla system call interrotta con un errore
+di \errcode{EINTR}.
 
 Vediamo allora cosa comporta tutto questo nel nostro caso: quando si chiude il
 client, il processo figlio che gestisce la connessione terminerà, ed il padre,
@@ -2026,16 +2031,17 @@ terminando a sua volta con un messaggio del tipo:
 accept error: Interrupted system call
 \end{verbatim}%#
 
-
 Come accennato in \secref{sec:sig_gen_beha} le conseguenze di questo
 comportamento delle system call possono essere superate in due modi diversi,
 il più semplice è quello di modificare il codice di \func{Signal} per
 richiedere il riavvio automatico delle system call interrotte secondo la
 semantica di BSD, usando l'opzione \const{SA\_RESTART} di \func{sigaction};
 rispetto a quanto visto in \figref{fig:sig_Signal_code}. Definiremo allora la
-nuova funzione \func{SignalRestart} come mostrato in
-\figref{fig:sig_SignalRestart_code}, ed installeremo il gestore usando
-quest'ultima.
+nuova funzione \func{SignalRestart}\footnote{anche questa è definita, insieme
+  alle altre funzioni riguardanti la gestione dei segnali, nel file
+  \file{SigHand.c}, il cui contento completo può essere trovato negli esempi
+  allegati.} come mostrato in \figref{fig:sig_SignalRestart_code}, ed
+installeremo il gestore usando quest'ultima.
 
 \begin{figure}[!htb]
   \footnotesize  \centering
@@ -2050,12 +2056,12 @@ quest'ultima.
 \end{figure}
 
 Come si può notare questa funzione è identica alla precedente \func{Signal},
-solo che in questo caso invece di inizializzare a zero il campo
-\var{sa\_flags} di \struct{sigaction}, lo si inizializza (\texttt{\small 5})
-al valore \const{SA\_RESTART}. Usando questa funzione al posto di
-\func{Signal} nel server non è necessaria nessuna altra modifica: le system
-call interrotte saranno automaticamente riavviate, e l'errore \errcode{EINTR}
-non si manifesterà più.
+illustrata in \figref{fig:sig_Signal_code}, solo che in questo caso invece di
+inizializzare a zero il campo \var{sa\_flags} di \struct{sigaction}, lo si
+inizializza (\texttt{\small 5}) al valore \const{SA\_RESTART}. Usando questa
+funzione al posto di \func{Signal} nel server non è necessaria nessuna altra
+modifica: le system call interrotte saranno automaticamente riavviate, e
+l'errore \errcode{EINTR} non si manifesterà più.
 
 La seconda soluzione è più invasiva e richiede di controllare tutte le volte
 l'errore restituito dalle varie system call, ripetendo la chiamata qualora
@@ -2064,41 +2070,97 @@ della portabilit
 riavvio automatico delle system call, fornita da \const{SA\_RESTART}, è
 opzionale, per cui non è detto che essa sia disponibile su qualunque sistema.
 Inoltre in certi casi,\footnote{Stevens in \cite{UNP1} accenna che la maggior
-  parte degli Unix derivati da BSD non fanno ripartire \func{select}, ed
-  alcuni non fanno ripartire neanche \func{accept} e \func{recvfrom}; nel caso
-  di Linux questa è disponibile.} anche quando questa è presente, non è detto
-possa essere usata con \func{accept}. La portabilità però viene al costo di
-una riscrittura parziale del server, secondo quanto mostrato in
-\figref{fig:TCP_echo_server_code}.
+  parte degli Unix derivati da BSD non fanno ripartire \func{select}; altri
+  non riavviano neanche \func{accept} e \func{recvfrom}, cosa che invece nel
+  caso di Linux viene sempre fatta.} anche quando questa è presente, non è
+detto possa essere usata con \func{accept}. 
+
+
+La portabilità nella gestione dei segnali però viene al costo di una
+riscrittura parziale del server, la nuova versione di questo, in cui si sono
+introdotte una serie di nuove opzioni che ci saranno utili per il debug, è
+mostrata in \figref{fig:TCP_echo_server_code_second}, dove si sono riportate
+la sezioni di codice modificate nella seconda versione del programma, il
+sorgente completo di quest'ultimo si trova nel file
+\file{TCP\_echod\_second.c} dei sorgenti allegati alla guida.
+
+La prima modifica effettuata è stata quella di introdurre una nuova opzione a
+riga di comando, \texttt{-c}, che permette di richiedere il comportamento
+compatibile nella gestione di \const{SIGCHLD} al posto della semantica BSD
+impostando la variabile \var{compat} ad un valore non nullo. Questa è
+preimpostata al valore nullo, cosicché se non si usa questa opzione il
+comportamento di default del server è di usare la semantica BSD. 
+
+Una seconda opzione aggiunta è quella di inserire un tempo di attesa fisso
+specificato in secondi fra il ritorno della funzione \func{listen} e la
+chiamata di \func{accept}, specificabile con l'opzione \texttt{-w}, che
+permette di impostare la variabile \var{waiting}.  Infine si è introdotta una
+opzione \texttt{-d} per abilitare il debugging che imposta ad un valore non
+nullo la variabile \var{debugging}. Al solito si è omessa da
+\figref{fig:TCP_echo_server_code_second} la sezione di codice relativa alla
+gestione di tutte queste opzioni, che può essere trovata nel sorgente del
+programma.
 
-\begin{figure}[!htbp]
+\begin{figure}[!htb]
   \footnotesize \centering
   \begin{minipage}[c]{15.6cm}
-    \includecodesample{listati/TCP_echod.c}
+    \includecodesample{listati/TCP_echod_second.c}
   \end{minipage} 
   \normalsize
-  \caption{Codice del corpo principale della seconda versione del server
-    per il servizio \textit{echo}.}
-  \label{fig:TCP_echo_server_code}
+  \caption{La sezione nel codice della seconda versione del server
+    per il servizio \textit{echo} modificata per tener conto dell'interruzione
+    delle system call.}
+  \label{fig:TCP_echo_server_code_second}
 \end{figure}
 
-In realtà l'unica chiamata critica che può essere interrotta nel server è
-quella ad \func{accept}, dato che questa è l'unica che può mettere il processo
-padre in stato di sleep.\footnote{si noti infatti che le altre \textit{slow
-    system call} o sono chiamate prima di entrare nel ciclo principale, quando
-  ancora non esistono processi figli, o sono chiamate dai figli stessi.}  Per
-questo l'unica modifica nella nuova versione del server, rispetto alla
-versione precedente vista in \figref{fig:TCP_ServEcho}, è nella sezione
-(\texttt{\small 43--48}) in cui si effettua la chiamata di \func{accept}.
-Quest'ultima allora viene effettuata (\texttt{\small 43--44}) all'interno di
-un ciclo di \code{while}\footnote{la sintassi del C relativa a questo ciclo
-  può non essere del tutto chiara. In questo caso infatti si è usato un ciclo
-  vuoto che non esegue nessuna istruzione, in questo modo quello che viene
-  ripetuto con il ciclo è soltanto il codice che esprime la condizione
-  all'interno del \code{while}.}  che la ripete indefinitamente qualora in
-caso di errore il valore di \var{errno} sia \errcode{EINTR}. Negli altri casi
-si esce in caso di errore effettivo (\texttt{\small 45--48}), altrimenti il
-programma prosegue esattamente allo stesso modo del precedente.
+Vediamo allora come è cambiato il nostro server; una volta definite le
+variabili e trattate le opzioni il primo passo (\texttt{\small 9--13}) è
+verificare la semantica scelta per la gestione di \const{SIGCHLD}, a seconda
+del valore di \var{compat} (\texttt{\small 9}) si installa il gestore con la
+funzione \func{Signal} (\texttt{\small 10}) o con \texttt{SignalRestart}
+(\texttt{\small 12}), essendo quest'ultimo il valore di default.
+
+Tutta la sezione seguente, che crea il socket, cede i privilegi di
+amministratore ed eventualmente lancia il programma come demone, è rimasta
+invariata e pertanto è stata omessa in
+\figref{fig:TCP_echo_server_code_second}; l'unica modifica effettuata prima
+dell'entrata nel ciclo principale è stata quella di aver introdotto, subito
+dopo la chiamata (\texttt{\small 17--20}) alla funzione \func{listen}, una
+eventuale pausa con una condizione (\texttt{\small 21}) sulla variabile
+\var{waiting}, che viene inizializzata, con l'opzione \code{-w Nsec}, al
+numero di secondi da aspettare (il valore preimpostato è nullo).
+
+Si è potuto lasciare inalterata tutta la sezione di creazione del socket
+perché nel server l'unica chiamata ad una system call critica, che può essere
+interrotta dall'arrivo di \const{SIGCHLD}, è quella ad \func{accept}, che è
+l'unica funzione che può mettere il processo padre in stato di sleep nel
+periodo in cui un figlio può terminare; si noti infatti come le altre
+\textit{slow system call}\footnote{si ricordi la distinzione fatta in
+  \secref{sec:sig_gen_beha}.} o sono chiamate prima di entrare nel ciclo
+principale, quando ancora non esistono processi figli, o sono chiamate dai
+figli stessi e non risentono di \const{SIGCHLD}.
+
+Per questo l'unica modifica sostanziale nel ciclo principale (\texttt{\small
+  23--42}), rispetto precedente versione di \figref{fig:TCP_ServEcho_first}, è
+nella sezione (\texttt{\small 26--30}) in cui si effettua la chiamata di
+\func{accept}.  Quest'ultima viene effettuata (\texttt{\small 26--27})
+all'interno di un ciclo di \code{while}\footnote{la sintassi del C relativa a
+  questo ciclo può non essere del tutto chiara. In questo caso infatti si è
+  usato un ciclo vuoto che non esegue nessuna istruzione, in questo modo
+  quello che viene ripetuto con il ciclo è soltanto il codice che esprime la
+  condizione all'interno del \code{while}.}  che la ripete indefinitamente
+qualora in caso di errore il valore di \var{errno} sia \errcode{EINTR}. Negli
+altri casi si esce in caso di errore effettivo (\texttt{\small 27--29}),
+altrimenti il programma prosegue.
+
+Si noti che in questa nuova versione si è aggiunta una ulteriore sezione
+(\texttt{\small 31--39}) di aiuto per il debug del programma, che eseguita con
+un controllo (\texttt{\small 31}) sul valore della variabile \var{debugging}
+impostato dall'opzione \texttt{-d}. Qualora questo sia nullo, come
+preimpostato, non accade nulla. altrimenti (\texttt{\small 32}) l'indirizzo
+ricevuto da \var{accept} viene convertito in una stringa che poi
+(\texttt{\small 33--38}) viene opportunamente stampata o sullo schermo o nei
+log.
 
 
 
@@ -2114,20 +2176,24 @@ la rete 
 gestire tutta una serie di situazioni critiche che non esistono per i processi
 locali.
 
-La prima situazione critica è quella della terminazione precoce, per via di un
-qualche errore di rete, della connessione effettuata da un client. Come
+
+\subsection{La terminazione precoce della connessione}
+\label{sec:TCP_conn_early_abort}
+
+La prima situazione critica è quella della terminazione precoce, causata da un
+qualche errore sulla rete, della connessione effettuata da un client. Come
 accennato in \secref{sec:TCP_func_accept} la funzione \func{accept} riporta
 tutti gli eventuali errori di rete pendenti su una connessione sul
-\textit{connected socket}. 
+\textit{connected socket}. Di norma questo non è un problema, in quanto non
+appena completata la connessione, \func{accept} ritorna e l'errore sarà
+rilevato in seguito, dal processo che gestisce la connessione, alla prima
+chiamata di una funzione che opera sul socket.
 
-Questo significa che, oltre alla interruzione da parte di un segnale, che
-abbiamo trattato in \secref{sec:TCP_child_hand} nel caso particolare di
-\const{SIGCHLD}, si possono avere altri errori non fatali all'uscita di
-\func{accept}, che necessitano semplicemente la ripetizione della chiamata
-senza che si debba uscire dal programma. Uno scenario tipo è quello mostrato
-in \figref{fig:TCP_early_abort}, in cui la connessione viene abortita sul lato
-client con l'invio di un segmento RST, prima che nel server sia stata chiamata
-la funzione \func{accept}.
+È però possibile, dal punto di vista teorico, incorrere anche in uno scenario
+del tipo di quello mostrato in \figref{fig:TCP_early_abort}, in cui la
+connessione viene abortita sul lato client per un qualche errore di rete con
+l'invio di un segmento RST, prima che nel server sia stata chiamata la
+funzione \func{accept}.
 
 \begin{figure}[htb]
   \centering
@@ -2136,29 +2202,57 @@ la funzione \func{accept}.
   \label{fig:TCP_early_abort}
 \end{figure}
 
-Benché questo non sia un fatto comune un evento simile può essere osservato
-con dei server molto occupati. In tal caso, in una struttura del server simile
-a quella del nostro esempio, in cui la gestione delle singole connessioni è
-demandata a processi figli, può accadere che il three way handshake venga
-completato e la relativa connessione abortita subito dopo, prima che il padre,
-per via del carico della macchina abbia fatto in tempo a rieseguire la
-chiamata \func{accept}. In questo caso si ha una situazione analoga a quella
-illustrata in \figref{fig:TCP_early_abort}, la connessione viene stabilita, ma
-subito dopo si ha una condizione 
-
-
-che, come nell'esempio in figura, ritornerebbe
-immediatamente con un errore relativo alla connessione abortita.
+Benché questo non sia un fatto comune, un evento simile può essere osservato
+con dei server molto occupati. In tal caso, con una struttura del server
+simile a quella del nostro esempio, in cui la gestione delle singole
+connessioni è demandata a processi figli, può accadere che il three way
+handshake venga completato e la relativa connessione abortita subito dopo,
+prima che il padre, per via del carico della macchina, abbia fatto in tempo ad
+eseguire la chiamata ad \func{accept}. Di nuovo si ha una situazione analoga
+a quella illustrata in \figref{fig:TCP_early_abort}, in cui la connessione
+viene stabilita, ma subito dopo si ha una condizione di errore che la chiude
+prima che essa sia stata accettata dal programma.
 
+Questo significa che, oltre alla interruzione da parte di un segnale, che
+abbiamo trattato in \secref{sec:TCP_child_hand} nel caso particolare di
+\const{SIGCHLD}, si possono ricevere altri errori non fatali all'uscita di
+\func{accept}, che come nel caso precedente, necessitano semplicemente la
+ripetizione della chiamata senza che si debba uscire dal programma. In questo
+caso anche la versione modificata del nostro server non sarebbe adatta, in
+quanto uno di questi errori causerebbe la terminazione dello stesso. In Linux
+i possibili errori di rete non fatali, riportati sul socket connesso al
+ritorno di \func{accept}, sono \errcode{ENETDOWN}, \errcode{EPROTO},
+\errcode{ENOPROTOOPT}, \errcode{EHOSTDOWN}, \errcode{ENONET},
+\errcode{EHOSTUNREACH}, \errcode{EOPNOTSUPP} e \errcode{ENETUNREACH}.
 
 Si tenga presente che questo tipo di terminazione non è riproducibile
-terminando il client prima della chiamata ad \func{accept}; in tal caso
-infatti il socket associato alla connessione viene semplicemente chiuso,
+terminando il client prima della chiamata ad \func{accept}, come si potrebbe
+fare usando l'opzione \texttt{-w} per introdurre una pausa dopo il lancio del
+demone, in modo da poter avere il tempo per lanciare e terminare una
+connessione usando il programma client. In tal caso infatti, alla terminazione
+del client, il socket associato alla connessione viene semplicemente chiuso,
 attraverso la sequenza vista in \secref{sec:TCP_conn_term}, per cui la
 \func{accept} ritornerà senza errori, e si avrà semplicemente un end-of-file
-al primo accesso al socket.
+al primo accesso al socket. Nel caso di Linux inoltre, anche qualora si
+modifichi il client per fargli gestire l'invio di un segmento di RST alla
+chiusura dal socket (come suggerito da Stevens in \cite{UNP1}), non si ha
+nessun errore al ritorno di \funcd{accept} quanto un errore di
+\errcode{ECONNRESET} al primo tentativo di accesso al socket.
+
+
+
+\subsection{Il crollo del server}
+\label{sec:TCP_server_crash}
+
+Un secondo caso critico è quello in cui si ha il crollo del server. In tal
+caso si suppone che il processo del server termini per un errore fatale, cosa
+che potremo simulare inviandogli un segnale di terminazione. La conclusione
+del processo comporta la chiusura di tutti i file aperti, compresi tutti i
+socket relativi a connessioni stabilite; questo significa che al momento del
+crollo del servizio il client riceverà un FIN dal server in corrispondenza
+della chiusura del socket.
+
 
-In questo caso