+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.
+
+
+\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 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
+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 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
+ 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} (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_first_code}.
+
+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 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,
+per evitare la creazione di zombie, riceverà il segnale \const{SIGCHLD}
+eseguendo il relativo gestore. Al ritorno del gestore però l'esecuzione nel
+padre ripartirà subito con il ritorno della funzione \func{accept} (a meno di
+un caso fortuito in cui il segnale arriva durante l'esecuzione del programma
+in risposta ad una connessione) con un errore di \errcode{EINTR}. Non avendo
+previsto questa eventualità il programma considera questo un errore fatale
+terminando a sua volta con un messaggio del tipo:
+\begin{verbatim}
+[root@gont sources]# ./echod -i
+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}\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
+ \begin{minipage}[c]{15.6cm}
+ \includecodesample{listati/SignalRestart.c}
+ \end{minipage}
+ \normalsize
+ \caption{La funzione \funcd{SignalRestart}, che installa un gestore di
+ segnali in semantica BSD per il riavvio automatico delle system call
+ interrotte.}
+ \label{fig:sig_SignalRestart_code}
+\end{figure}
+
+Come si può notare questa funzione è identica alla precedente \func{Signal},
+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
+questo corrisponda ad \errcode{EINTR}. Questa soluzione ha però il pregio
+della portabilità, infatti lo standard POSIX dice che la funzionalità di
+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}; 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}[!htb]
+ \footnotesize \centering
+ \begin{minipage}[c]{15.6cm}
+ \includecodesample{listati/TCP_echod_second.c}
+ \end{minipage}
+ \normalsize
+ \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}
+
+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.
+
+
+
+
+\section{I vari scenari critici}
+\label{sec:TCP_echo_critical}
+
+Con le modifiche viste in \secref{sec:TCP_child_hand} il nostro esempio
+diventa in grado di affrontare la gestione ordinaria delle connessioni, ma un
+server di rete deve tenere conto che, al contrario di quanto avviene per i
+server che operano nei confronti di processi presenti sulla stessa macchina,
+la rete è di sua natura inaffidabile, per cui è necessario essere in grado di
+gestire tutta una serie di situazioni critiche che non esistono per i processi
+locali.
+
+
+\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}. 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.
+
+È 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
+ \includegraphics[width=10cm]{img/tcp_client_early_abort}
+ \caption{Un possibile caso di terminazione precoce della connessione.}
+ \label{fig:TCP_early_abort}
+\end{figure}