Aggiornamento alla versione reale
[gapil.git] / elemtcp.tex
index 45584ea5abfda94052f09bf69721bea2f881e6dc..534dd398f18819943c1811ed5bbb63fcf5d556ab 100644 (file)
@@ -8,8 +8,8 @@
 %% license is included in the section entitled "GNU Free Documentation
 %% License".
 %%
-\chapter{Socket TCP elementari}
-\label{cha:elem_TCP_sock}
+\chapter{Socket TCP}
+\label{cha:TCP_socket}
 
 In questo capitolo iniziamo ad approfondire la conoscenza dei socket TCP,
 iniziando con una descrizione delle principali caratteristiche del
@@ -22,7 +22,7 @@ client, fornendo poi alcuni esempi di applicazione elementare.
 \section{Il funzionamento di una connessione TCP}
 \label{sec:TCP_connession}
 
-Prima di entrare nei dettagli delles singole funzioni usate nelle applicazioni
+Prima di entrare nei dettagli delle singole funzioni usate nelle applicazioni
 che utilizzano i socket TCP, è fondamentale spiegare alcune delle basi del
 funzionamento del protocollo, poiché questa conoscenza è essenziale per
 comprendere il comportamento di dette funzioni per questo tipo di socket, ed
@@ -48,7 +48,7 @@ Il processo che porta a creare una connessione TCP 
   serie di flag usati per gestire la connessione, come SYN, ACK, URG, FIN,
   alcuni di essi, come SYN (che sta per \textit{syncronize}) corrispondono a
   funzioni particolari del protocollo e danno il nome al segmento, (per
-  maggiori dettagli vedere \capref{cha:tcp_protocol}).}  di dati che vengono
+  maggiori dettagli vedere \secref{sec:tcp_protocol}).}  di dati che vengono
 scambiati) che porta alla creazione di una connessione è la seguente:
  
 \begin{enumerate}
@@ -133,7 +133,7 @@ regolare la connessione. Normalmente vengono usate le seguenti opzioni:
   connessione corrente. È possibile leggere e scrivere questo valore
   attraverso l'opzione del socket \const{TCP\_MAXSEG}.
   
-\item \textit{window scale option}, %come spiegato in \capref{cha:tcp_protocol}
+\item \textit{window scale option}, %come spiegato in \secref{sec:tcp_protocol}
   il protocollo TCP implementa il controllo di flusso attraverso una
   \textsl{finestra annunciata} (\textit{advertized window}) con la quale
   ciascun capo della comunicazione dichiara quanto spazio disponibile ha in
@@ -161,7 +161,8 @@ regolare la connessione. Normalmente vengono usate le seguenti opzioni:
 \end{itemize}
 
 La MSS è generalmente supportata da quasi tutte le implementazioni del
-protocollo, le ultime due opzioni (trattate nell'RFC~1323) sono meno comuni;
+protocollo, le ultime due opzioni (trattate
+nell'\href{http://www.ietf.org/rfc/rfc1323.txt}{RFC~1323}) sono meno comuni;
 vengono anche dette \textit{long fat pipe options} dato che questo è il nome
 che viene dato alle connessioni caratterizzate da alta velocità o da ritardi
 elevati. In ogni caso Linux supporta pienamente entrambe le opzioni.
@@ -171,9 +172,9 @@ elevati. In ogni caso Linux supporta pienamente entrambe le opzioni.
 
 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_cli_code} e
-\figref{fig:TCP_serv_code}, in questo caso la successione degli eventi è la
-seguente:
+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:
 
 \begin{enumerate}
 \item Un processo ad uno dei due capi chiama la funzione \func{close}, dando
@@ -182,7 +183,7 @@ seguente:
   significa che si è finito con l'invio dei dati sulla connessione.
   
 \item L'altro capo della connessione riceve il FIN ed esegue la
-  \textit{chiusura passiva} (o \textit{passive close}); al FIN, come ad ogni
+  \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
@@ -215,46 +216,45 @@ scambio dei segmenti che conclude la connessione.
 Come per il SYN anche il FIN occupa un byte nel numero di sequenza, per cui
 l'ACK riporterà un \textit{acknowledge number} incrementato di uno. 
 
-Si noti che nella sequenza di chiusura fra i passi 2 e 3 è in teoria possibile
-che si mantenga un flusso di dati dal capo della connessione che deve ancora
-eseguire la chiusura passiva a quello che sta eseguendo la chiusura attiva.
-Nella sequenza indicata i dati verrebbero persi, dato che si è chiuso il
-socket dal lato che esegue la chiusura attiva; esistono tuttavia situazioni in
-cui si vuole poter sfruttare questa possibilità, usando una procedura che è
-chiamata \textit{half-close}; torneremo su questo aspetto e su come
-utilizzarlo in \secref{xxx_shutdown}, quando parleremo della funzione
+Si noti che, nella sequenza di chiusura, fra i passi 2 e 3, è in teoria
+possibile che si mantenga un flusso di dati dal capo della connessione che
+deve ancora eseguire la chiusura passiva a quello che sta eseguendo la
+chiusura attiva.  Nella sequenza indicata i dati verrebbero persi, dato che si
+è chiuso il socket dal lato che esegue la chiusura attiva; esistono tuttavia
+situazioni in cui si vuole poter sfruttare questa possibilità, usando una
+procedura che è chiamata \textit{half-close}; torneremo su questo aspetto e su
+come utilizzarlo in \secref{xxx_shutdown}, quando parleremo della funzione
 \func{shutdown}.
 
 La emissione del FIN avviene quando il socket viene chiuso, questo però non
-avviene solo per la chiamata della funzione \func{close} (come faremo in
-\figref{fig:TCP_serv_code}), ma anche alla terminazione di un processo (come
-vedremo in \figref{fig:TCP_cli_code}). Questo vuol dire ad esempio che se un
-processo viene terminato da un segnale tutte le connessioni aperte verranno
-chiuse.
+avviene solo per la chiamata esplicita della funzione \func{close}, ma anche
+alla terminazione di un processo, quando tutti i file vengono chiusi.  Questo
+comporta ad esempio che se un processo viene terminato da un segnale tutte le
+connessioni aperte verranno chiuse.
 
 Infine occorre sottolineare che, benché nella figura (e nell'esempio che
-vedremo più avanti in \secref{sec:TCPsimp_echo}) sia stato il client ad
-eseguire la chiusura attiva, nella realtà questa può essere eseguita da uno
-qualunque dei due capi della comunicazione (come nell'esempio di
-\figref{fig:TCP_serv_code}), e anche se il caso più comune resta quello del
-client, ci sono alcuni servizi, il principale dei quali è l'HTTP, per i quali
-è il server ad effettuare la chiusura attiva.
+vedremo più avanti in \secref{sec:TCP_echo}) sia stato il client ad eseguire
+la chiusura attiva, nella realtà questa può essere eseguita da uno qualunque
+dei due capi della comunicazione (come nell'esempio di
+\figref{fig:TCP_daytime_iter_server_code}), e anche se il caso più comune
+resta quello del client, ci sono alcuni servizi, il principale dei quali è
+l'HTTP, per i quali è il server ad effettuare la chiusura attiva.
 
 
 \subsection{Un esempio di connessione}
 \label{sec:TCP_conn_dia}
 
-Le operazioni del TCP nella creazione e conclusione di una connessione sono
-specificate attraverso il diagramma di transizione degli stati riportato in
-\figref{fig:TCP_conn_example}. TCP prevede l'esistenza di 11 diversi stati
-per un socket ed un insieme di regole per le transizioni da uno stato
-all'altro basate sullo stato corrente e sul tipo di segmento ricevuto; i nomi
-degli stati sono gli stessi che vengono riportati del comando \cmd{netstat}
-nel campo \textit{State}.
+Come abbiamo visto le operazioni del TCP nella creazione e conclusione di una
+connessione sono piuttosto complesse, ed abbiamo esaminato soltanto quelle
+relative ad un andamento normale.  In \secref{sec:TCP_states} vedremo con
+maggiori dettagli che una connessione può assumere vari stati, che ne
+caratterizzano il funzionamento, e che sono quelli che vengono riportati dal
+comando \cmd{netstat}, per ciascun socket TCP aperto, nel campo
+\textit{State}.
 
-Non possiamo affrontare una descrizione completa del funzionamento del
+Non possiamo affrontare qui una descrizione completa del funzionamento del
 protocollo; un approfondimento sugli aspetti principali si trova in
-\capref{cha:tcp_protocol}, ma per una trattazione esauriente il miglior
+\secref{sec:tcp_protocol}, ma per una trattazione completa il miglior
 riferimento resta \cite{TCPIll1}. Qui ci limiteremo a descrivere brevemente un
 semplice esempio di connessione e le transizioni che avvengono nei due casi
 appena citati (creazione e terminazione della connessione).
@@ -348,10 +348,11 @@ pertanto anche se il TTL (da \textit{time to live}) non 
 limite sul tempo di vita, si stima che un pacchetto IP non possa restare nella
 rete per più di MSL secondi.
 
-Ogni implementazione del TCP deve scegliere un valore per la MSL (l'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.
+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:
@@ -444,7 +445,7 @@ 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 \texttt{ssh}) effettuati da appositi server che rispondono alle
+servizio \textit{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
@@ -455,8 +456,9 @@ creazione della connessione. Queste sono dette effimere in quanto vengono
 usate solo per la durata della connessione, e l'unico requisito che deve
 essere soddisfatto è che ognuna di esse sia assegnata in maniera univoca.
 
-La lista delle porte conosciute è definita dall'RFC~1700 che contiene l'elenco
-delle porte assegnate dalla IANA (la \textit{Internet Assigned Number
+La lista delle porte conosciute è definita
+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
 \texttt{ftp://ftp.isi.edu/in-notes/iana/assignements/port-numbers}); inoltre
@@ -483,8 +485,9 @@ nome simbolico del servizio.  I numeri sono divisi in tre intervalli:
   sono i candidati naturali ad essere usate come porte effimere.
 \end{enumerate}
 
-In realtà rispetto a quanto indicato nell'RFC~1700 i vari sistemi hanno fatto
-scelte diverse per le porte effimere, in particolare in
+In realtà rispetto a quanto indicato
+nell'\href{http://www.ietf.org/rfc/rfc1700.txt}{RFC~1700} i vari sistemi hanno
+fatto scelte diverse per le porte effimere, in particolare in
 \figref{fig:TCP_port_alloc} sono riportate quelle di BSD e Linux.  Nel caso di
 Linux poi la scelta fra i due intervalli possibili viene fatta dinamicamente a
 seconda della memoria a disposizione del kernel per gestire le relative
@@ -500,7 +503,7 @@ 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 root, per far si che solo
+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.
 
@@ -529,9 +532,10 @@ 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 quella che scriveremo in
-\secref{sec:TCP_cunc_daytime}) esamineremo cosa accade con le connessioni nel
-caso di un server TCP che deve gestire connessioni multiple.
+che fare con un'applicazione client/server (come quelle che scriveremo 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.
 
 Se eseguiamo un \cmd{netstat} su una macchina di prova (il cui indirizzo sia
 \texttt{195.110.112.152}) potremo avere un risultato del tipo:
@@ -694,8 +698,8 @@ l'indirizzo di destinazione specificato dal SYN del client.
 Per specificare un indirizzo generico, con IPv4 si usa il valore
 \const{INADDR\_ANY}, il cui valore, come accennato in
 \secref{sec:sock_sa_ipv4}, è pari a zero; nell'esempio
-\figref{fig:TCP_serv_code} si è usata un'assegnazione immediata del tipo:
-\includecodesnip{listati/serv_addr_sin_addr.c}
+\figref{fig:TCP_daytime_iter_server_code} si è usata un'assegnazione immediata
+del tipo: \includecodesnip{listati/serv_addr_sin_addr.c}
 
 Si noti che si è usato \func{htonl} per assegnare il valore
 \const{INADDR\_ANY}, anche se, essendo questo nullo, il riordinamento è
@@ -782,7 +786,7 @@ socket, gi
 
 La struttura dell'indirizzo deve essere inizializzata con l'indirizzo IP e il
 numero di porta del server a cui ci si vuole connettere, come mostrato
-nell'esempio \secref{sec:TCP_cli_sample} usando le funzioni illustrate in
+nell'esempio \secref{sec:TCP_daytime_client}, usando le funzioni illustrate in
 \secref{sec:sock_addr_func}.
 
 Nel caso di socket TCP la funzione \func{connect} avvia il \textit{three way
@@ -904,7 +908,7 @@ della prima connessione completa.
 
 \begin{figure}[htb]
   \centering
-  \includegraphics[width=10cm]{img/tcp_listen_backlog}  
+  \includegraphics[width=11cm]{img/tcp_listen_backlog}  
   \caption{Schema di funzionamento delle code delle connessioni complete ed
     incomplete.}
   \label{fig:TCP_listen_backlog}
@@ -920,7 +924,7 @@ implementazioni.
 In Linux il significato di questo valore è cambiato a partire dal kernel 2.2
 per prevenire l'attacco chiamato \textit{syn flood}. Questo si basa
 sull'emissione da parte dell'attaccante di un grande numero di pacchetti SYN
-indirizzati verso una porta forgiati con indirizzo IP fasullo\footnote{con la
+indirizzati verso una porta, forgiati con indirizzo IP fasullo\footnote{con la
   tecnica che viene detta \textit{ip spoofing}.} così che i SYN$+$ACK vanno
 perduti e la coda delle connessioni incomplete viene saturata, impedendo di
 fatto ulteriori connessioni.
@@ -937,14 +941,14 @@ ignorato e non esiste pi
 di \param{backlog} viene troncato ad un massimo di \const{SOMAXCONN} se è
 superiore a detta costante (che di default vale 128).
 
-La scelta storica per il valore di questo parametro è di 5, e alcuni vecchi
+La scelta storica per il valore di questo parametro era di 5, e alcuni vecchi
 kernel non supportavano neanche valori superiori, ma la situazione corrente è
 molto cambiata per via della presenza di server web che devono gestire un gran
 numero di connessioni per cui un tale valore non è più adeguato. Non esiste
 comunque una risposta univoca per la scelta del valore, per questo non
 conviene specificarlo con una costante (il cui cambiamento richiederebbe la
 ricompilazione del server) ma usare piuttosto una variabile di ambiente (vedi
-\secref{sec:proc_environ}).  
+\secref{sec:proc_environ}).
 
 Stevens tratta accuratamente questo argomento in \cite{UNP1}, con esempi presi
 da casi reali su web server, ed in particolare evidenzia come non sia più vero
@@ -1058,13 +1062,117 @@ 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
-ascolto, che resta per tutto il tempo nello stato \texttt{LISTEN}, mentre le
-connessioni vengono gestite dai nuovi socket ritornati da \func{accept}, che
+ascolto, detto per questo \textit{listening socket}, che resta per tutto il
+tempo nello stato \texttt{LISTEN}, mentre le connessioni vengono gestite dai
+nuovi socket, detti \textit{connected socket}, ritornati da \func{accept}, che
 si trovano automaticamente nello stato \texttt{ESTABLISHED}, e vengono
-utilizzati fino alla chiusura della connessione, che avviene su di essi.  Si
-può riconoscere questo schema anche nell'esempio elementare in
-\figref{fig:TCP_serv_code} dove per ogni connessione il socket creato da
-\func{accept} viene chiuso dopo l'invio dei dati.
+utilizzati per lo scambio dei dati, che avviene su di essi, fino alla chiusura
+della connessione.  Si può riconoscere questo schema anche nell'esempio
+elementare di \figref{fig:TCP_daytime_iter_server_code}, dove per ogni
+connessione il socket creato da \func{accept} viene chiuso dopo l'invio dei
+dati.
+
+
+\subsection{Le funzioni \func{getsockname} e \func{getpeername}}
+\label{sec:TCP_get_names}
+
+Oltre a tutte quelle viste finora, dedicate all'utilizzo dei socket, esistono
+alcune funzioni ausiliarie che possono essere usate per recuperare alcune
+informazioni relative ai socket ed alle connessioni ad essi associate. Le due
+funzioni più elementari sono queste, che vengono usate per ottenere i dati
+relativi alla socket pair associata ad un certo socket.
+
+La prima funzione è \funcd{getsockname} e serve ad ottenere l'indirizzo locale
+associato ad un socket; il suo prototipo è:
+\begin{prototype}{sys/socket.h}
+  {int getsockname(int sockfd, struct sockaddr * name, socklen\_t * namelen)}
+  Legge l'indirizzo locale di un socket.
+
+\bodydesc{La funzione restituisce 0 in caso di successo e -1 in caso di
+  errore. I codici di errore restituiti in \var{errno} sono i seguenti:
+  \begin{errlist}
+  \item[\errcode{EBADF}] l'argomento \param{sockfd} non è un file descriptor
+    valido.
+  \item[\errcode{ENOTSOCK}] l'argomento \param{sockfd} non è un socket.
+  \item[\errcode{ENOBUFS}] non ci sono risorse sufficienti nel sistema per
+    eseguire l'operazione.
+  \item[\errcode{EFAULT}] l'indirizzo \param{name} non è valido.
+  \end{errlist}}
+\end{prototype}
+
+La funzione restituisce la struttura degli indirizzi del socket \param{sockfd}
+nella struttura indicata dal puntatore \param{name} la cui lunghezza è
+specificata tramite l'argomento \param{namlen}. Quest'ultimo viene passato
+come indirizzo per avere indietro anche il numero di byte effettivamente
+scritti nella struttura puntata da \param{name}. Si tenga presente che se si è
+utilizzato un buffer troppo piccolo per \param{name} l'indirizzo risulterà
+troncato.
+
+La funzione si usa tutte le volte che si vuole avere l'indirizzo locale di un
+socket; ad esempio può essere usata da un client (che usualmente non chiama
+\func{bind}) per ottenere numero IP e porta locale associati al socket
+restituito da una \func{connect}, o da un server che ha chiamato \func{bind}
+su un socket usando 0 come porta locale per ottenere il numero di porta
+effimera assegnato dal kernel.
+
+Inoltre quando un server esegue una \func{bind} su un indirizzo generico, se
+chiamata dopo il completamento di una connessione sul socket restituito da
+\func{accept}, restituisce l'indirizzo locale che il kernel ha assegnato a
+quella connessione.
+
+Tutte le volte che si vuole avere l'indirizzo remoto di un socket si usa la
+funzione \funcd{getpeername}, il cui prototipo è:
+\begin{prototype}{sys/socket.h}
+  {int getpeername(int sockfd, struct sockaddr * name, socklen\_t * namelen)}
+  Legge l'indirizzo remoto di un socket.
+  
+  \bodydesc{La funzione restituisce 0 in caso di successo e -1 in caso di
+    errore. I codici di errore restituiti in \var{errno} sono i seguenti:
+  \begin{errlist}
+  \item[\errcode{EBADF}] l'argomento \param{sockfd} non è un file descriptor
+    valido.
+  \item[\errcode{ENOTSOCK}] l'argomento \param{sockfd} non è un socket.
+  \item[\errcode{ENOTCONN}] il socket non è connesso.
+  \item[\errcode{ENOBUFS}] non ci sono risorse sufficienti nel sistema per
+    eseguire l'operazione.
+  \item[\errcode{EFAULT}] l'argomento \param{name} punta al di fuori dello
+    spazio di indirizzi del processo.
+  \end{errlist}}
+\end{prototype}
+
+La funzione è identica a \func{getsockname}, ed usa la stessa sintassi, ma
+restituisce l'indirizzo remoto del socket, cioè quello associato all'altro
+capo della connessione.  Ci si può chiedere a cosa serva questa funzione dato
+che dal lato client l'indirizzo remoto è sempre noto quando si esegue la
+\func{connect} mentre dal lato server si possono usare, come vedremo in
+\figref{fig:TCP_daytime_cunc_server_code}, i valori di ritorno di
+\func{accept}.
+
+Il fatto è che in generale quest'ultimo caso non è sempre possibile.  In
+particolare questo avviene quando il server, invece di gestire la connessione
+direttamente in un processo figlio, come vedremo nell'esempio di server
+concorrente di \secref{sec:TCP_daytime_cunc_server}, lancia per ciascuna
+connessione un altro programma, usando \func{exec}.\footnote{questa ad esempio
+  è la modalità con cui opera il \textsl{super-server} \cmd{inetd}, che può
+  gestire tutta una serie di servizi diversi, eseguendo su ogni connessione
+  ricevuta sulle porte tenute sotto controllo, il relativo server.}
+
+In questo caso benché il processo figlio abbia una immagine della memoria che
+è copia di quella del processo padre (e contiene quindi anche la struttura
+ritornata da \func{accept}), all'esecuzione di \func{exec} verrà caricata in
+memoria l'immagine del programma eseguito, che a questo punto perde ogni
+riferimento ai valori tornati da \func{accept}.  Il socket descriptor però
+resta aperto, e se si è seguita una opportuna convenzione per rendere noto al
+programma eseguito qual'è il socket connesso, \footnote{ad esempio il solito
+  \cmd{inetd} fa sempre in modo che i file descriptor 0, 1 e 2 corrispondano
+  al socket connesso.} quest'ultimo potrà usare la funzione \func{getpeername}
+per determinare l'indirizzo remoto del client.
+
+Infine è da chiarire (si legga la pagina di manuale) che, come per
+\func{accept}, il terzo parametro, che è specificato dallo standard POSIX.1g
+come di tipo \code{socklen\_t *} in realtà deve sempre corrispondere ad un
+\ctyp{int *} come prima dello standard perché tutte le implementazioni dei
+socket BSD fanno questa assunzione.
 
 
 \subsection{La funzione \func{close}}
@@ -1099,16 +1207,19 @@ descritta in \secref{sec:TCP_conn_term}, si pu
 
 
 
-\section{Un esempio di applicazione}
-\label{sec:TCP_application}
+\section{Un esempio elementare: il servizio \textit{daytime}}
+\label{sec:TCP_daytime_application}
 
 Avendo introdotto le funzioni di base per la gestione dei socket, potremo
-vedere in questa sezione un esempio di applicazione elementare.  Prima di
-passare agli esempi del client e del server, inizieremo riprendendo con
-maggiori dettagli una caratteristica delle funzioni di I/O, già accennata in
+vedere in questa sezione un primo esempio di applicazione elementare che
+implementa il servizio \textit{daytime} su TCP, secondo quanto specificato
+dall'\href{http://www.ietf.org/rfc/rfc0867.txt}{RFC~867}.  Prima di passare
+agli esempi del client e del server, inizieremo riesaminando con maggiori
+dettagli una peculiarità delle funzioni di I/O, già accennata in
 \secref{sec:file_read} e \secref{sec:file_write}, che nel caso dei socket è
-particolarmente rilevante, per poi passare agli esempi, sia di server
-iterativo, che di server concorrente.
+particolarmente rilevante.  Passeremo poi ad illustrare gli esempi
+dell'implementazione, sia dal lato client, che dal lato server, che si è
+realizzato sia in forma iterativa che concorrente.
 
 
 \subsection{Il comportamento delle funzioni di I/O}
@@ -1123,15 +1234,9 @@ Infatti con i socket 
 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
+problema si avverte solo quando si incontra la fine del file. In generale non
 è così, e con i socket questo è particolarmente evidente.
 
-Quando ci si trova ad affrontare questo comportamento tutto quello che si deve
-fare è semplicemente ripetere la lettura (o la scrittura) per la quantità di
-byte restanti, tenendo conto che le funzioni si possono bloccare se i dati non
-sono disponibili: è lo stesso comportamento che si può avere scrivendo più di
-\const{PIPE\_BUF} byte in una pipe (si riveda quanto detto in
-\secref{sec:ipc_pipes}).
 
 \begin{figure}[htb]
   \footnotesize \centering
@@ -1144,10 +1249,17 @@ sono disponibili: 
   \label{fig:sock_FullRead_code}
 \end{figure}
 
+Quando ci si trova ad affrontare questo comportamento tutto quello che si deve
+fare è semplicemente ripetere la lettura (o la scrittura) per la quantità di
+byte restanti, tenendo conto che le funzioni si possono bloccare se i dati non
+sono disponibili: è lo stesso comportamento che si può avere scrivendo più di
+\const{PIPE\_BUF} byte in una pipe (si riveda quanto detto in
+\secref{sec:ipc_pipes}).
+
 Per questo motivo, seguendo l'esempio di R. W. Stevens in \cite{UNP1}, si sono
 definite due funzioni, \func{FullRead} e \func{FullWrite}, che eseguono
 lettura e scrittura tenendo conto di questa caratteristica, ed in grado di
-ritornare dopo avere letto o scritto esattamente il numero di byte
+ritornare solo dopo avere letto o scritto esattamente il numero di byte
 specificato; il sorgente è riportato rispettivamente in
 \figref{fig:sock_FullRead_code} e \figref{fig:sock_FullWrite_code} ed è
 disponibile fra i sorgenti allegati alla guida nei file \file{FullRead.c} e
@@ -1173,53 +1285,55 @@ 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 non è quindi più possibile leggere niente) e
+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.
 
 
-\subsection{Un primo esempio di client}
-\label{sec:TCP_cli_sample}
+\subsection{Il client \textit{daytime}}
+\label{sec:TCP_daytime_client}
 
-Il primo esempio di applicazione delle funzioni viste finora (sia in
-\capref{cha:socket_intro} che in \secref{sec:TCP_functions}) è relativo alla
-creazione di un client elementare per il servizio \textit{daytime}, un
-servizio standard che restituisce l'ora locale della macchina a cui si
-effettua la richiesta, e che è assegnato alla porta 13. 
+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
+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.
 
-In \figref{fig:TCP_cli_code} è riportata la sezione principale del codice del
-nostro client. Il sorgente completo del programma
-(\file{ElemDaytimeTCPClient.c}, che comprende il trattamento delle opzioni e
-una funzione per stampare un messaggio di aiuto) è allegato alla guida nella
+In \figref{fig:TCP_daytime_client_code} è riportata la sezione principale del
+codice del nostro client. Il sorgente completo del programma
+(\file{TCP\_daytime.c}, che comprende il trattamento delle opzioni ed una
+funzione per stampare un messaggio di aiuto) è allegato alla guida nella
 sezione dei codici sorgente e può essere compilato su una qualunque macchina
 GNU/Linux.
 
 \begin{figure}[!htb]
   \footnotesize \centering
   \begin{minipage}[c]{15cm}
-    \includecodesample{listati/ElemDaytimeTCPClient.c}
+    \includecodesample{listati/TCP_daytime.c}
   \end{minipage} 
   \normalsize
-  \caption{Esempio di codice di un client elementare per il servizio daytime.}
-  \label{fig:TCP_cli_code}
+  \caption{Esempio di codice di un client elementare per il servizio
+    \textit{daytime}.} 
+  \label{fig:TCP_daytime_client_code}
 \end{figure}
 
 Il programma anzitutto (\texttt{\small 1--5}) include gli header necessari;
 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 funzioni illustrate in
-\capref{sec:proc_opt_handling}).
+\secref{sec:proc_opt_handling}).
 
-Il primo passo (\texttt{\small 14--18}) è creare un \textit{socket} TCP
-(quindi di famiglia \const{AF\_INET} e di tipo \const{SOCK\_STREAM}). La
-funzione \func{socket} ritorna il descrittore che viene usato per identificare
-il socket in tutte le chiamate successive. Nel caso la chiamata fallisca si
+Il primo passo (\texttt{\small 14--18}) è creare un socket TCP (quindi di tipo
+\const{SOCK\_STREAM} e di famiglia \const{AF\_INET}). La funzione
+\func{socket} ritorna il descrittore che viene usato per identificare il
+socket in tutte le chiamate successive. Nel caso la chiamata fallisca si
 stampa un errore (\texttt{\small 16}) con la funzione \func{perror} e si esce
 (\texttt{\small 16}) con un codice di errore.
 
 Il passo seguente (\texttt{\small 19--27}) è quello di costruire un'apposita
 struttura \struct{sockaddr\_in} in cui sarà inserito l'indirizzo del server ed
 il numero della porta del servizio. Il primo passo (\texttt{\small 20}) è
-inizializzare tutto a zero, per poi inserire il tipo di protocollo
+inizializzare tutto a zero, per poi inserire il tipo di indirizzo
 (\texttt{\small 21}) e la porta (\texttt{\small 22}), usando per quest'ultima
 la funzione \func{htons} per convertire il formato dell'intero usato dal
 computer a quello usato nella rete, infine \texttt{\small 23--27} si può
@@ -1237,9 +1351,10 @@ ritorna (\texttt{\small 31}).
 
 Completata con successo la connessione il passo successivo (\texttt{\small
   34--40}) è leggere la data dal socket; il protocollo prevede che il server
-invii sempre una stringa alfanumerica di 26 caratteri, nella forma giorno
-della settimana, mese, ora minuto e secondo, anno, seguita dai caratteri di
-teminazione \verb|\r\n|, cioè qualcosa del tipo:
+invii sempre una stringa alfanumerica, il formato della stringa non è
+specificato dallo standard, per cui noi useremo il formato usato dalla
+funzione \func{ctime}, seguito dai caratteri di terminazione \verb|\r\n|, cioè
+qualcosa del tipo:
 \begin{verbatim}
 Wed Apr 4 00:53:00 2001\r\n
 \end{verbatim}
@@ -1278,39 +1393,38 @@ Mon Apr 21 20:46:11 2003
 e come si vede tutto funziona regolarmente.
 
 
-\subsection{Un primo esempio di server}
-\label{sec:TCP_serv_sample}
+\subsection{Un server \textit{daytime} iterativo}
+\label{sec:TCP_daytime_iter_server}
 
 Dopo aver illustrato il client daremo anche un esempio di un server
 elementare, che sia anche in grado di rispondere al precedente client. Come
 primo esempio realizzeremo un server iterativo, in grado di fornire una sola
 risposta alla volta. Il codice del programma è nuovamente mostrato in
-\figref{fig:TCP_serv_code}, il sorgente completo
-(\file{ElemDaytimeTCPServer.c}) è allegato insieme agli altri file degli
-esempi.
+\figref{fig:TCP_daytime_iter_server_code}, il sorgente completo
+(\file{TCP\_iter\_daytimed.c}) è allegato insieme agli altri file degli esempi.
 
 \begin{figure}[!htbp]
   \footnotesize \centering
   \begin{minipage}[c]{15cm}
-    \includecodesample{listati/ElemDaytimeTCPServer.c}
+    \includecodesample{listati/TCP_iter_daytimed.c}
   \end{minipage} 
   \normalsize
   \caption{Esempio di codice di un semplice server per il servizio daytime.}
-  \label{fig:TCP_serv_code}
+  \label{fig:TCP_daytime_iter_server_code}
 \end{figure}
 
 Come per il client si includono (\texttt{\small 1--9}) gli header necessari a
 cui è aggiunto quello per trattare i tempi, e si definiscono (\texttt{\small
-  14--18}) alcune costanti e le variabili necessarie in seguito, come nel caso
+  14--18}) alcune costanti e le variabili necessarie in seguito. Come nel caso
 precedente si sono omesse le parti relative al trattamento delle opzioni da
 riga di comando.
 
 La creazione del socket (\texttt{\small 20--24}) è analoga al caso precedente,
 come pure l'inizializzazione (\texttt{\small 25--29}) della struttura
-\struct{sockaddr\_in}, anche in questo caso (\texttt{\small 28}) si usa la
+\struct{sockaddr\_in}.  Anche in questo caso (\texttt{\small 28}) si usa la
 porta standard del servizio daytime, ma come indirizzo IP si usa
 (\texttt{\small 27}) il valore predefinito \const{INET\_ANY}, che corrisponde
-ad un indirizzo generico.
+all'indirizzo generico.
 
 Si effettua poi (\texttt{\small 30--34}) la chiamata alla funzione \func{bind}
 che permette di associare la precedente struttura al socket, in modo che
@@ -1322,24 +1436,24 @@ programma.
 Il passo successivo (\texttt{\small 35--39}) è quello di mettere ``in
 ascolto'' il socket; questo viene fatto (\texttt{\small 36}) con la funzione
 \func{listen} che dice al kernel di accettare connessioni per il socket che
-abbiamo creatp; la funzione indica inoltre, con il secondo parametro, il
+abbiamo creato; 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. Di nuovo in caso di errore si stampa (\texttt{\small 37})
 un messaggio, e si esce (\texttt{\small 38}) immediatamente.
 
 La chiamata a \func{listen} completa la preparazione del socket per l'ascolto
 (che viene chiamato anche \textit{listening descriptor}) a questo punto si può
-procedere con il ciclo (\texttt{\small 40--53}) principale che viene eseguito
-indefinitamente. Il primo passo è porsi (\texttt{\small 42}) in attesa di
+procedere con il ciclo principale (\texttt{\small 40--53}) che viene eseguito
+indefinitamente. Il primo passo (\texttt{\small 42}) è porsi in attesa di
 connessioni con la chiamata alla funzione \func{accept}, come in precedenza in
 caso di errore si stampa (\texttt{\small 43}) un messaggio, e si esce
 (\texttt{\small 44}).
 
-Il provesso resterà in stato di \textit{sleep} fin quando non arriva e viene
+Il processo resterà in stato di \textit{sleep} fin quando non arriva e viene
 accettata una connessione da un client; quando questo avviene \func{accept}
-ritorna un secondo descrittore di socket, che viene chiamato \textit{connected
-  descriptor}, e che è quello che verrà usato dalla successiva chiamata alla
-\func{write} per scrivere la risposta al client.
+ritorna, restituendo un secondo descrittore, che viene chiamato
+\textit{connected descriptor}, e che è quello che verrà usato dalla successiva
+chiamata alla \func{write} per scrivere la risposta al client.
 
 Il ciclo quindi proseguirà determinando (\texttt{\small 46}) il tempo corrente
 con una chiamata a \texttt{time}, con il quale si potrà opportunamente
@@ -1349,198 +1463,554 @@ trasmissione il nuovo socket viene chiuso (\texttt{\small 52}).  A questo
 punto il ciclo si chiude ricominciando da capo in modo da poter ripetere
 l'invio della data in risposta ad una successiva connessione.
 
-È importante notare che questo server è estremamente elementare, infatti a
+È importante notare che questo server è estremamente elementare, infatti, a
 parte il fatto di poter essere usato solo con indirizzi IPv4, esso è in grado
 di rispondere ad un solo un client alla volta: è cioè, come dicevamo, un
-\textsl{server iterativo}. Inoltre esso è scritto per essere lanciato da linea
-di comando, se lo si volesse utilizzare come demone occorrerebbero le
-opportune modifiche\footnote{come una chiamata a \func{daemon} prima
-  dell'inizio del ciclo principale.} per tener conto di quanto illustrato in
+\textsl{server iterativo}. Inoltre è scritto per essere lanciato da linea di
+comando, se lo si volesse utilizzare come demone occorrerebbero le opportune
+modifiche\footnote{come una chiamata a \func{daemon} prima dell'inizio del
+  ciclo principale.} per tener conto di quanto illustrato in
 \secref{sec:sess_daemon}. Si noti anche che non si è inserita nessuna forma di
 gestione della terminazione del processo, dato che tutti i file descriptor
 vengono chiusi automaticamente alla sua uscita, e che, non generando figli,
 non è necessario preoccuparsi di gestire la loro terminazione.
 
 
-\subsection{Un esempio di server \textit{daytime} concorrente}
-\label{sec:TCP_cunc_daytime}
+\subsection{Un server \textit{daytime} concorrente}
+\label{sec:TCP_daytime_cunc_server}
 
-Il server \texttt{daytime} dell'esempio in \secref{sec:TCP_cli_sample} è un
-tipico esempio di server iterativo, in cui viene servita una richiesta alla
-volta; in generale però, specie se il servizio è più complesso e comporta uno
-scambio di dati più sostanzioso di quello in questione, non è opportuno
-bloccare un server nel servizio di un client per volta; per questo si ricorre
-alle capacità di multitasking del sistema.
+Il server \texttt{daytime} dell'esempio in
+\secref{sec:TCP_daytime_iter_server} è un tipico esempio di server iterativo,
+in cui viene servita una richiesta alla volta; in generale però, specie se il
+servizio è più complesso e comporta uno scambio di dati più sostanzioso di
+quello in questione, non è opportuno bloccare un server nel servizio di un
+client per volta; per questo si ricorre alle capacità di multitasking del
+sistema.
 
-Come già visto per i server basati sui meccanismi di intercomunicazione locale
-visti in \capref{cha:IPC}, il modo più immediato per creare un server
-concorrente è quello di usare la funzione \func{fork} per creare ad ogni
-richiesta da parte di un client un processo figlio che si incarichi della
-gestione della comunicazione. Si è allora riscritto il server \texttt{daytime}
-dell'esempio precedente in forma concorrente, inserendo anche una opzione per
-la stampa degli indirizzi delle connessioni ricevute.
+Come accennato anche in \secref{sec:proc_gen} una delle modalità più comuni di
+funzionamento da parte dei server è quella di usare la funzione \func{fork}
+per creare, ad ogni richiesta da parte di un client, un processo figlio che si
+incarichi della gestione della comunicazione.  Si è allora riscritto il server
+\textit{daytime} dell'esempio precedente in forma concorrente, inserendo anche
+una opzione per la stampa degli indirizzi delle connessioni ricevute.
 
-In \figref{fig:TCP_serv_code} è mostrato un estratto del codice, in cui si
-sono tralasciati il trattamento delle opzioni e le parti rimaste invariate
-rispetto al precedente esempio (cioè tutta la parte riguardante l'apertura
-passiva del socket). Al solito il sorgente completo del server
-\file{ElemDaytimeTCPCuncServ.c} è allegato insieme ai sorgenti degli altri
-esempi.
+In \figref{fig:TCP_daytime_cunc_server_code} è mostrato un estratto del
+codice, in cui si sono tralasciati il trattamento delle opzioni e le parti
+rimaste invariate rispetto al precedente esempio (cioè tutta la parte
+riguardante l'apertura passiva del socket). Al solito il sorgente completo del
+server, nel file \file{TCP\_cunc\_daytimed.c}, è allegato insieme ai sorgenti
+degli altri esempi.
 
 \begin{figure}[!htb]
   \footnotesize \centering
   \begin{minipage}[c]{15cm}
-    \includecodesample{listati/ElemDaytimeTCPCuncServ.c}
+    \includecodesample{listati/TCP_cunc_daytimed.c}
   \end{minipage} 
   \normalsize
   \caption{Esempio di codice di un server concorrente elementare per il 
     servizio daytime.}
-  \label{fig:TCP_serv_code}
+  \label{fig:TCP_daytime_cunc_server_code}
 \end{figure}
 
 Stavolta (\texttt{\small 21--25}) la funzione \func{accept} è chiamata
 fornendo una struttura di indirizzi in cui saranno ritornati l'indirizzo IP e
-la porta da cui il client effettua la connessione, che più avanti
+la porta da cui il client effettua la connessione, che in un secondo tempo,
 (\texttt{\small 39--43}), se il logging è abilitato, stamperemo sullo standard
 output.
 
 Quando \func{accept} ritorna il server chiama la funzione \func{fork}
 (\texttt{\small 26--30}) per creare il processo figlio che effettuerà
 (\texttt{\small 31--45}) tutte le operazioni relative a quella connessione,
-mentre il padre resterà in attesa di ulteriori connessioni.
+mentre il padre proseguirà l'esecuzione del ciclo principale in attesa di
+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 \var{sock\_fd} dopo
-(\texttt{\small 47}) ciascuna \func{accept}. Per quanto abbiamo detto in
-\secref{sec:TCP_func_close} queste due chiusure non causano l'innesco della
-sequenza di chiusura perché il numero di riferimenti al file descriptor non si
-è annullato.
+continua ad operare solo sul socket in ascolto chiudendo (\texttt{\small 47})
+\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
+descriptor non si è annullato.
 
 Infatti subito dopo la creazione del socket \var{list\_fd} ha una referenza, e
 lo stesso vale per \var{sock\_fd} dopo il ritorno di \func{accept}, ma dopo la
-fork i descrittori vengono duplicati nel padre e nel figlio per cui entrambi i
-socket si trovano con due referenze. Questo fa si che quando il padre chiude
-\var{sock\_fd} esso resta con una referenza da parte del figlio, e sarà
-definitivamente chiuso solo quando quest'ultimo, dopo aver completato le sue
-operazioni, chiamerà la funzione \func{close}.
-
-In realtà per il figlio non sarebbero necessarie nessuna delle due chiamate a
-\func{close} in quanto nella \func{exit} tutti i file ed i socket vengono
-chiusi. Tuttavia si è preferito effettuare la chiusura esplicitamente per
-avere una maggiore chiarezza del codice ed evitare possibili errori.
-
-Si noti come sia essenziale che il padre chiuda ogni volta il socket connesso
-dopo la \func{accept}; se così non fosse nessuno di questi socket sarebbe
-effettivamente chiuso dato che alla chiusura da parte del figlio resterebbe
-ancora un riferimento. Si avrebbero così due effetti, il padre potrebbe
-esaurire i descrittori disponibili (che sono un numero limitato per ogni
-processo) e soprattutto nessuna delle connessioni con i client verrebbe
-chiusa.
-
-Si noti come anche in questo caso non si sia gestita né la terminazione del
-processo né il suo uso come demone, che tra l'altro sarenne stato
-incompatibile con l'uso della opzione di logging che stampa gli indirizzi
-delle connessioni sullo standard output. Un altro aspetto tralasciato è la
-gestione della terminazione dei processi figli, torneremo su questo più avanti
-quando tratteremo alcuni esempi di server più complessi.
+\func{fork} i descrittori vengono duplicati nel padre e nel figlio per cui
+entrambi i socket si trovano con due referenze. Questo fa si che quando il
+padre chiude \var{sock\_fd} esso resta con una referenza da parte del figlio,
+e sarà definitivamente chiuso solo quando quest'ultimo, dopo aver completato
+le sue operazioni, chiamerà (\texttt{\small 44}) la funzione \func{close}.
+
+In realtà per il figlio non sarebbe necessaria nessuna chiamata a
+\func{close}, in quanto con la \func{exit} finale (\texttt{\small 45}) tutti i
+file descriptor, quindi anche quelli associati ai socket, vengono
+automaticamente chiusi.  Tuttavia si è preferito effettuare esplicitamente le
+chiusure per avere una maggiore chiarezza del codice, e per evitare eventuali
+errori, prevenendo ad esempio un uso involontario del \textit{listening
+  descriptor}.
+
+Si noti invece come sia essenziale che il padre chiuda ogni volta il socket
+connesso dopo la \func{fork}; se così non fosse nessuno di questi socket
+sarebbe effettivamente chiuso dato che alla chiusura da parte del figlio
+resterebbe ancora un riferimento nel padre. Si avrebbero così due effetti: il
+padre potrebbe esaurire i descrittori disponibili (che sono un numero limitato
+per ogni processo) e soprattutto nessuna delle connessioni con i client
+verrebbe chiusa.
+
+Come per ogni server iterativo il lavoro di risposta viene eseguito
+interamente dal processo figlio. Questo si incarica (\texttt{\small 33}) di
+chiamare \func{time} per leggere il tempo corrente, e di stamparlo
+(\texttt{\small 34}) sulla stringa contenuta in \var{buffer} con l'uso di
+\func{snprintf} e \func{ctime}. Poi la stringa viene scritta (\texttt{\small
+  35--38}) sul socket, controllando che non ci siano errori. Anche in questo
+caso si è evitato il ricorso a \func{FullWrite} in quanto la stringa è
+estremamente breve e verrà senz'altro scritta in un singolo segmento.
+
+Inoltre nel caso sia stato abilitato il \textit{logging} delle connessioni, si
+provvede anche (\texttt{\small 39--42}) a stampare sullo standard output
+l'indirizzo e la porta da cui il client ha effettuato la connessione, usando
+i valori contenuti nelle strutture restituite da \func{accept}, eseguendo le
+opportune conversioni con \func{inet\_ntop} e \func{atohs}.
+
+Ancora una volta l'esempio è estremamente semplificato, si noti come di nuovo
+non si sia gestita né la terminazione del processo né il suo uso come demone,
+che tra l'altro sarebbe stato incompatibile con l'uso della opzione di logging
+che stampa gli indirizzi delle connessioni sullo standard output. Un altro
+aspetto tralasciato è la gestione della terminazione dei processi figli,
+torneremo su questo più avanti quando tratteremo alcuni esempi di server più
+complessi.
+
+
+
+\section{Un esempio più completo: il servizio \textit{echo}}
+\label{sec:TCP_echo_application}
+
+L'esempio precedente, basato sul servizio \textit{daytime}, è un esempio molto
+elementare, in cui il flusso dei dati va solo nella direzione dal server al
+client. In questa sezione esamineremo un esempio di applicazione client/server
+un po' più complessa, che usi i socket TCP per una comunicazione in entrambe
+le direzioni.
+
+Ci limiteremo a fornire una implementazione elementare, che usi solo le
+funzioni di base viste finora, ma prenderemo in esame, oltre al comportamento
+in condizioni normali, anche tutti i possibili scenari particolari (errori,
+sconnessione della rete, crash del client o del server durante la connessione)
+che possono avere luogo durante l'impiego di un'applicazione di rete, partendo
+da una versione primitiva che dovrà essere rimaneggiata di volta in volta per
+poter tenere conto di tutte le evenienze che si possono manifestare nella vita
+reale di un'applicazione di rete, fino ad arrivare ad un'implementazione
+completa.
+
+
+\subsection{Il servizio \textit{echo}}
+\label{sec:TCP_echo}
+
+
+Nella ricerca di un servizio che potesse fare da esempio per una comunicazione
+bidirezionale, si è deciso, seguendo la scelta di Stevens in \cite{UNP1}, di
+usare il servizio \textit{echo}, che si limita a restituire in uscita quanto
+immesso in ingresso. Infatti, nonostante la sua estrema semplicità, questo
+servizio costituisce il prototipo ideale per una generica applicazione di rete
+in cui un server risponde alle richieste di un client.  Nel caso di una
+applicazione più complessa quello che si potrà avere in più è una elaborazione
+dell'input del client, che in molti casi viene interpretato come un comando,
+da parte di un server che risponde fornendo altri dati in uscita.
+
+Il servizio \textit{echo} è uno dei servizi standard solitamente provvisti
+direttamente dal superserver \cmd{inetd}, ed è definito
+dall'\href{http://www.ietf.org/rfc/rfc0862.txt}{RFC~862}. Come dice il nome il
+servizio deve riscrivere indietro sul socket i dati che gli vengono inviati in
+ingresso. L'RFC descrive le specifiche del servizio sia per TCP che UDP, e per
+il primo stabilisce che una volta stabilita la connessione ogni dato in
+ingresso deve essere rimandato in uscita fintanto che il chiamante non ha
+chiude la connessione. Al servizio è assegnata la porta riservata 7.
+
+Nel nostro caso l'esempio sarà costituito da un client che legge una linea di
+caratteri dallo standard input e la scrive sul server. A sua volta il server
+leggerà la linea dalla connessione e la riscriverà immutata all'indietro. Sarà
+compito del client leggere la risposta del server e stamparla sullo standard
+output.
 
 
-\subsection{Le funzioni \func{getsockname} e \func{getpeername}}
-\label{sec:TCP_get_names}
+\subsection{Il client: prima versione}
+\label{sec:TCP_echo_client}
 
-Queste due funzioni vengono usate per ottenere i dati relativi alla socket
-pair associata ad un certo socket; la prima è \funcd{getsockname} e
-restituisce l'indirizzo locale; il suo prototipo è:
-\begin{prototype}{sys/socket.h}
-  {int getsockname(int sockfd, struct sockaddr * name, socklen\_t * namelen)}
-  Legge l'indirizzo locale del socket \param{sockfd} nella struttura
-  \param{name}.
+Il codice della prima versione del client per il servizio \textit{echo},
+disponibile nel file \file{TCP\_echo1.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}) è
+sostanzialmente identica, a parte l'uso di una porta diversa.
 
-\bodydesc{La funzione restituisce 0 in caso di successo e -1 in caso di
-  errore. I codici di errore restituiti in \var{errno} sono i seguenti:
-  \begin{errlist}
-  \item[\errcode{EBADF}] l'argomento \param{sockfd} non è un file descriptor
-    valido.
-  \item[\errcode{ENOTSOCK}] l'argomento \param{sockfd} non è un socket.
-  \item[\errcode{ENOBUFS}] non ci sono risorse sufficienti nel sistema per
-    eseguire l'operazione.
-  \item[\errcode{EFAULT}] l'argomento \param{name} punta al di fuori dello
-    spazio di indirizzi del processo.
-  \end{errlist}}
-\end{prototype}
+\begin{figure}[!htb]
+  \footnotesize \centering
+  \begin{minipage}[c]{15.6 cm}
+    \includecodesample{listati/TCP_echo1.c}
+  \end{minipage} 
+  \normalsize
+  \caption{Codice della prima versione del client \textit{echo}.}
+  \label{fig:TCP_echo_client_1}
+\end{figure}
 
-La funzione si usa tutte le volte che si vuole avere l'indirizzo locale di un
-socket; ad esempio può essere usata da un client (che usualmente non chiama
-\func{bind}) per ottenere numero IP e porta locale associati al socket
-restituito da una \func{connect}, o da un server che ha chiamato \func{bind}
-su un socket usando 0 come porta locale per ottenere il numero di porta
-effimera assegnato dal kernel.
+Al solito si è tralasciata la sezione relativa alla gestione delle opzioni a
+riga di comando.  Una volta dichiarate le variabili, si prosegue
+(\texttt{\small 10--13}) con della creazione del socket con l'usuale controllo
+degli errori, alla preparazione (\texttt{\small 14--17}) della struttura
+dell'indirizzo, che stavolta usa la porta 7 riservata al servizio
+\textit{echo}, infine si converte (\texttt{\small 18--22}) l'indirizzo
+specificato a riga di comando.  A questo punto (\texttt{\small 23--27}) si può
+eseguire la connessione al server secondo la stessa modalità usata in
+\secref{sec:TCP_daytime_client}.
+
+Completata la connessione, per gestire il funzionamento del protocollo si usa
+la funzione \code{ClientEcho}, il cui codice si è riportato a parte in
+\figref{fig:TCP_client_echo_sub}. Questa si preoccupa di gestire tutta la
+comunicazione, leggendo una riga alla volta dallo standard input \file{stdin},
+scrivendola sul socket e ristampando su \file{stdout} quanto ricevuto in
+risposta dal server. Al ritorno dalla funzione (\texttt{\small 30--31}) anche
+il programma termina.
+
+La funzione \code{ClientEcho} utilizza due buffer (\texttt{\small 3}) per
+gestire i dati inviati e letti sul socket.  La comunicazione viene gestita
+all'interno di un ciclo (\texttt{\small 5--10}), i dati da inviare sulla
+connessione vengono presi dallo \file{stdin} usando la funzione \func{fgets},
+che legge una linea di testo (terminata da un \texttt{CR} e fino al massimo di
+\const{MAXLINE} caratteri) e la salva sul buffer di invio.
+
+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}.
 
-Inoltre quando un server esegue una \func{bind} su un indirizzo generico, se
-chiamata dopo il completamento di una connessione sul socket restituito da
-\func{accept}, restituisce l'indirizzo locale che il kernel ha assegnato a
-quella connessione.
+\begin{figure}[!htb]
+  \footnotesize \centering
+  \begin{minipage}[c]{15.6cm}
+    \includecodesample{listati/ClientEcho.c}
+  \end{minipage} 
+  \normalsize
+  \caption{Codice della prima versione della funzione \texttt{ClientEcho} per 
+    la gestione del servizio \textit{echo}.}
+  \label{fig:TCP_client_echo_sub}
+\end{figure}
 
-Tutte le volte che si vuole avere l'indirizzo remoto di un socket si usa la
-funzione \funcd{getpeername}, il cui prototipo è:
-\begin{prototype}{sys/socket.h}
-  {int getpeername(int sockfd, struct sockaddr * name, socklen\_t * namelen)}
-  Legge l'indirizzo remoto del socket \param{sockfd} nella struttura
-  \param{name}.
-  
-  \bodydesc{La funzione restituisce 0 in caso di successo e -1 in caso di
-    errore. I codici di errore restituiti in \var{errno} sono i seguenti:
-  \begin{errlist}
-  \item[\errcode{EBADF}] l'argomento \param{sockfd} non è un file descriptor
-    valido.
-  \item[\errcode{ENOTSOCK}] l'argomento \param{sockfd} non è un socket.
-  \item[\errcode{ENOTCONN}] il socket non è connesso.
-  \item[\errcode{ENOBUFS}] non ci sono risorse sufficienti nel sistema per
-    eseguire l'operazione.
-  \item[\errcode{EFAULT}] l'argomento \param{name} punta al di fuori dello
-    spazio di indirizzi del processo.
-  \end{errlist}}
-\end{prototype}
+Quando si concluderà l'invio di dati mandando un end-of-file sullo standard
+input si avrà il ritorno di \func{fgets} con un puntatore nullo (si riveda
+quanto spiegato in \secref{sec:file_line_io}) e la conseguente uscita dal
+ciclo; al che la subroutine ritorna ed il nostro programma client termina.
 
-Ci si può chiedere a cosa serva questa funzione dato che dal lato client
-l'indirizzo remoto è sempre noto quando si esegue la \func{connect} mentre
-dal lato server si possono usare, come si è fatto nell'esempio precedente, i
-valori di ritorno di \func{accept}.
+Si può effettuare una verifica del funzionamento del client abilitando il
+servizio \textit{echo} nella configurazione di \cmd{initd} sulla propria
+macchina ed usandolo direttamente verso di esso in locale, vedremo in
+dettaglio più avanti (in \secref{sec:TCP_echo_startup}) il funzionamento del
+programma, usato però con la nostra versione del server \textit{echo}, che
+illustriamo immediatamente.
 
-In generale però questa ultima possibilità è sempre possibile. In particolare
-questo avviene quando il server invece di far gestire la connessione
-direttamente a un processo figlio, come nell'esempio precedente, lancia un
-opportuno programma per ciascuna connessione usando \func{exec} (questa ad
-esempio è la modalità con cui opera il \textsl{super-server} \cmd{inetd}
-che gestisce tutta una serie di servizi lanciando per ogni connessione
-l'opportuno server).
 
-In questo caso benché il processo figlio abbia una immagine della memoria che
-è copia di quella del processo padre (e contiene quindi anche la struttura
-ritornata da \func{accept}), all'esecuzione di \func{exec} viene caricata
-in memoria l'immagine del programma eseguito che a questo punto perde ogni
-riferimento. Il socket descriptor però resta aperto. Allora se una opportuna
-convenzione è seguita per rendere noto al programma eseguito qual'è il socket
-connesso (\cmd{inetd} ad esempio fa sempre in modo che i file descriptor 0,
-1 e 2 corrispondano al socket connesso) quest'ultimo potrà usare la funzione
-\func{getpeername} per determinare l'indirizzo remoto del client.
+\subsection{Il server: prima versione}
+\label{sec:TCPsimp_server_main}
 
-Infine è da chiarire (si legga la pagina di manuale) che, come per
-\func{accept}, il terzo parametro, che è specificato dallo standard POSIX.1g
-come di tipo \code{socklen\_t *} in realtà deve sempre corrispondere ad un
-\ctyp{int *} come prima dello standard perché tutte le implementazioni dei
-socket BSD fanno questa assunzione.
+La prima versione del server, contenuta nel file \file{TCP\_echod.c}, è
+riportata in \figref{fig:TCP_echo_server_code}. Come abbiamo fatto per il
+client anche il server è stato diviso in un corpo principale, costituito dalla
+funzione \code{main}, che è molto simile a quello visto nel precedente esempio
+per il server del servizio \textit{daytime} di
+\secref{sec:TCP_daytime_cunc_server}, e da una funzione ausiliaria
+\code{ServEcho} che si cura della gestione del servizio.
+
+\begin{figure}[!htbp]
+  \footnotesize \centering
+  \begin{minipage}[c]{15.6cm}
+    \includecodesample{listati/TCP_echod.c}
+  \end{minipage} 
+  \normalsize
+  \caption{Codice del corpo principale della prima versione del server
+    per il servizio \textit{echo}.}
+  \label{fig:TCP_echo_server_code}
+\end{figure}
+
+In questo caso però, rispetto a quanto visto nell'esempio di
+\figref{fig:TCP_daytime_cunc_server_code} si è preferito scrivere il server
+curando maggiormente alcuni dettagli, per tenere conto anche di alcune
+esigenze generali (che non riguardano direttamente la rete), come la
+possibilità di lanciare il server anche in modalità interattiva e la cessione
+dei privilegi di amministratore non appena questi non sono più necessari.
+
+La sezione iniziale del programma (\texttt{\small 8--21}) è la stessa del
+server di \secref{sec:TCP_daytime_cunc_server}, ed ivi descritta in dettaglio:
+crea il socket, inizializza l'indirizzo e esegue \func{bind}; dato che
+quest'ultima funzione viene usata su una porta riservata, il server dovrà
+essere eseguito da un processo con i privilegi di amministratore, pena il
+fallimento della chiamata.
+
+Una volta eseguita la funzione \func{bind} però i privilegi di amministratore
+non sono più necessari, per questo è sempre opportuno rilasciarli, in modo da
+evitare problemi in caso di eventuali vulnerabilità del server.  Per questo
+prima (\texttt{\small 22--26}) si esegue \func{setgid} per assegnare il
+processo ad un gruppo senza privilegi,\footnote{si è usato il valore 65534,
+  ovvero -1 per il formato \ctyp{short}, che di norma in tutte le
+  distribuzioni viene usato per identificare il gruppo \texttt{nogroup} e
+  l'utente \texttt{nobody}, usati appunto per eseguire programmi che non
+  richiedono nessun privilegio particolare.} e poi si ripete (\texttt{\small
+  27--30}) l'operazione usando \func{setuid} per cambiare anche
+l'utente.\footnote{si tenga presente che l'ordine in cui si eseguono queste
+  due operazioni è importante, infatti solo avendo i privilegi di
+  amministratore si può cambiare il gruppo di un processo ad un'altro di cui
+  non si fa parte, per cui chiamare prima \func{setuid} farebbe fallire una
+  successiva chiamata a \func{setgid}.  Inoltre si ricordi (si riveda quanto
+  esposto in \secref{sec:proc_perms}) che usando queste due funzioni il
+  rilascio dei privilegi è irreversibile.}  Infine (\texttt{\small 30--36}),
+qualora sia impostata la variabile \var{demonize}, prima (\texttt{\small 31})
+si apre il sistema di logging per la stampa degli errori, e poi
+(\texttt{\small 32--35}) si invoca \func{daemon} per eseguire in background il
+processo come demone.
+
+A questo punto il programma riprende di nuovo lo schema già visto usato dal
+server per il servizio \textit{daytime}, con l'unica differenza della chiamata
+alla funzione \code{PrintErr}, riportata in \figref{fig:TCP_PrintErr}, al
+posto di \func{perror} per la stampa degli errori. 
+
+Si inizia con il porre (\texttt{\small 37--41}) in ascolto il socket, e poi si
+esegue indefinitamente il ciclo principale (\texttt{\small 42--58}).
+All'interno di questo si ricevono (\texttt{\small 43--46}) le connessioni,
+creando (\texttt{\small 47--50}) un processo figlio per ciascuna di esse.
+Quest'ultimo (\texttt{\small 51--55}), chiuso (\texttt{\small 52}) il
+\textit{listening socket}, esegue (\texttt{\small 53}) la funzione di gestione
+del servizio \code{ServEcho}, ed al ritorno di questa (\texttt{\small 54})
+esce.
+
+Il padre invece si limita (\texttt{\small 56}) a chiudere il \textit{connected
+  socket} per ricominciare da capo il ciclo in attesa di nuove connessioni. In
+questo modo si ha un server concorrente. La terminazione del padre non è
+gestita esplicitamente, e deve essere effettuata inviando un segnale al
+processo.
+
+Avendo trattato direttamente la gestione del programma come demone, si è
+dovuto anche provvedere alla necessità di poter stampare eventuali messaggi di
+errore attraverso il sistema del \textit{syslog} trattato in
+\secref{sec:sess_daemon}. Come accennato questo è stato fatto utilizzando come
+\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.
+
+
+\begin{figure}[!htb]
+  \footnotesize \centering
+  \begin{minipage}[c]{15.6cm}
+    \includecodesample{listati/PrintErr.c}
+  \end{minipage} 
+  \normalsize
+  \caption{Codice della funzione \code{PrintErr} per la
+    generalizzazione della stampa degli errori sullo standard input o
+    attraverso il \texttt{syslog}.}
+  \label{fig:TCP_PrintErr}
+\end{figure}
 
+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}.
+
+\begin{figure}[!htb] 
+  \footnotesize \centering
+  \begin{minipage}[c]{15.6cm}
+    \includecodesample{listati/ServEcho.c}
+  \end{minipage} 
+  \normalsize
+  \caption{Codice della prima versione della funzione \code{ServEcho} per la
+    gestione del servizio \textit{echo}.}
+  \label{fig:TCP_ServEcho}
+\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
+processo figlio.
+
+
+\subsection{L'avvio e il funzionamento normale}
+\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
+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
+la comprensione del protocollo TCP/IP e dall'altra ricavare le indicazioni
+necessarie per essere in grado di scrivere applicazioni robuste, in grado di
+gestire anche i casi limite.
+
+Il primo passo è compilare e lanciare il server (da root, per poter usare la
+porta 7 che è riservata), alla partenza esso eseguirà l'apertura passiva con
+la sequenza delle chiamate a \func{socket}, \func{bind}, \func{listen} e poi
+si bloccherà nella \func{accept}. A questo punto si potrà controllarne lo
+stato con \cmd{netstat}:
+\begin{verbatim}
+[piccardi@roke piccardi]$ netstat -at
+Active Internet connections (servers and established)
+Proto Recv-Q Send-Q Local Address           Foreign Address         State 
+...
+tcp        0      0 *:echo                  *:*                     LISTEN
+...
+\end{verbatim} %$
+che ci mostra come il socket sia in ascolto sulla porta richiesta, accettando
+connessioni da qualunque indirizzo e da qualunque porta e su qualunque
+interfaccia locale.
+
+A questo punto si può lanciare il client, esso chiamerà \func{socket} e
+\func{connect}; una volta completato il three way handshake la connessione è
+stabilita; la \func{connect} ritornerà nel client\footnote{si noti che è
+  sempre la \func{connect} del client a ritornare per prima, in quanto
+  questo avviene alla ricezione del secondo segmento (l'ACK del server) del
+  three way handshake, la \func{accept} del server ritorna solo dopo
+  un altro mezzo RTT quando il terzo segmento (l'ACK del client) viene
+  ricevuto.} e la \func{accept} nel server, ed usando di nuovo
+\cmd{netstat} otterremmo che:
+\begin{verbatim}
+Active Internet connections (servers and established)
+Proto Recv-Q Send-Q Local Address           Foreign Address         State
+tcp        0      0 *:echo                  *:*                     LISTEN
+tcp        0      0 roke:echo               gont:32981              ESTABLISHED
+\end{verbatim}
+mentre per quanto riguarda l'esecuzione dei programmi avremo che:
+\begin{itemize}
+\item il client chiama la funzione \code{ClientEcho} che si blocca sulla
+  \func{fgets} dato che non si è ancora scritto nulla sul terminale.
+\item il server eseguirà una \func{fork} facendo chiamare al processo figlio
+  la funzione \code{ServEcho}, quest'ultima si bloccherà sulla \func{read}
+  dal socket sul quale ancora non sono presenti dati.
+\item il processo padre del server chiamerà di nuovo \func{accept}
+  bloccandosi fino all'arrivo di un'altra connessione.
+\end{itemize}
+e se usiamo il comando \cmd{ps} per esaminare lo stato dei processi otterremo
+un risultato del tipo:
+\begin{verbatim}
+[piccardi@roke piccardi]$ ps ax
+  PID TTY      STAT   TIME COMMAND
+ ...  ...      ...    ...  ...
+ 2356 pts/0    S      0:00 ./echod
+ 2358 pts/1    S      0:00 ./echo 127.0.0.1
+ 2359 pts/0    S      0:00 ./echod
+\end{verbatim} %$
+(dove si sono cancellate le righe inutili) da cui si evidenzia la presenza di
+tre processi, tutti in stato di \textit{sleep} (vedi
+\tabref{tab:proc_proc_states}).
+
+Se a questo punto si inizia a scrivere qualcosa sul client non sarà trasmesso
+niente fin tanto che non si prema il tasto di a capo (si ricordi quanto detto
+in \secref{sec:file_line_io} a proposito dell'I/O su terminale), solo allora
+\func{fgets} ritornerà ed il client scriverà quanto immesso sul socket, per
+poi passare a rileggere quanto gli viene inviato all'indietro dal server, che
+a sua volta sarà inviato sullo standard output, che nel caso ne provoca
+l'immediatamente stampa a video.
+
+
+\subsection{La conclusione normale}
+\label{sec:TCP_echo_conclusion}
+
+Tutto quello che scriveremo sul client sarà rimandato indietro dal server e
+ristampato a video fintanto che non concluderemo l'immissione dei dati; una
+sessione tipica sarà allora del tipo: 
+\begin{verbatim}
+[piccardi@roke sources]$ ./echo 127.0.0.1
+Questa e` una prova
+Questa e` una prova
+Ho finito
+Ho finito
+\end{verbatim} %$
+che termineremo inviando un EOF dal terminale (usando la combinazione di tasti
+ctrl-D, che non compare a schermo); se eseguiamo un \cmd{netstat} a questo
+punto avremo:
+\begin{verbatim}
+[piccardi@roke piccardi]$ netstat -at 
+tcp        0      0 *:echo                  *:*                     LISTEN
+tcp        0      0 localhost:33032         localhost:echo          TIME_WAIT
+\end{verbatim} %$
+con il client che entra in \texttt{TIME\_WAIT}.
+
+Esaminiamo allora in dettaglio la sequenza di eventi che porta alla
+terminazione normale della connessione, che ci servirà poi da riferimento
+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.
+\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
+  la chiusura del socket di comunicazione; il client allora invierà un FIN al
+  server a cui questo risponderà con un ACK.  A questo punto il client verrà a
+  trovarsi nello stato \texttt{FIN\_WAIT\_2} ed il server nello stato
+  \texttt{CLOSE\_WAIT} (si riveda quanto spiegato in
+  \secref{sec:TCP_conn_term}).
+\item quando il server riceve il FIN la \func{read} del processo figlio che
+  gestisce la connessione ritorna restituendo 0 causando così l'uscita dal
+  ciclo e il ritorno di \code{ServEcho}, a questo punto il processo figlio
+  termina chiamando \func{exit}.
+\item all'uscita del figlio tutti i file descriptor vengono chiusi, la
+  chiusura del socket connesso fa sì che venga effettuata la sequenza finale
+  di chiusura della connessione, viene emesso un FIN dal server che riceverà
+  un ACK dal client, a questo punto la connessione è conclusa e il client
+  resta nello stato \texttt{TIME\_WAIT}.
+\end{enumerate}
 
 
+\subsection{La gestione dei processi figli}
+\label{sec:TCP_child_hand}
 
+Tutto questo riguarda la connessione, c'è però da tenere conto dell'effetto
+del procedimento di chiusura del processo figlio nel server (si veda quanto
+esaminato in \secref{sec:proc_termination}). In questo caso avremo l'invio del
+segnale \const{SIGCHLD} al padre, ma dato che non si è installato un
+gestore e che l'azione predefinita per questo segnale è quella di essere
+ignorato, non avendo predisposto la ricezione dello stato di terminazione,
+otterremo che il processo figlio entrerà nello stato di zombie\index{zombie}
+(si riveda quanto illustrato in \secref{sec:sig_sigchld}), come risulterà
+ripetendo il comando \cmd{ps}:
+\begin{verbatim}
+ 2356 pts/0    S      0:00 ./echod
+ 2359 pts/0    Z      0:00 [echod <defunct>]
+\end{verbatim}
 
+Dato che non è il caso di lasciare processi zombie\index{zombie}, occorrerà
+ricevere opportunamente lo stato di terminazione del processo (si veda
+\secref{sec:proc_wait}), cosa che faremo utilizzando \const{SIGCHLD} secondo
+quanto illustrato in \secref{sec:sig_sigchld}. Una prima modifica al nostro
+server è pertanto quella di inserire la gestione della terminazione dei
+processi figli attraverso l'uso di un gestore.  Per questo useremo la funzione
+\code{Signal} della nostra libreria personale, che abbiamo illustrato in
+\figref{fig:sig_Signal_code}, per installare il gestore che riceve i segnali
+dei processi figli terminati già visto in \figref{fig:sig_sigchld_handl}.
+Basterà allora aggiungere il seguente codice:
+\includecodesnip{listati/sigchildhand.c}
+\noindent
+all'esempio illustrato in \figref{fig:TCP_echo_server_code}.
 
+In questo modo però si introduce un altro problema, 
 
 
 
+\subsection{I vari scenari critici}
+\label{sec:TCP_echo_critical}