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
+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.
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
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.
le direzioni.
Ci limiteremo a fornire una implementazione elementare, che usi solo le
-funzioni di base viste finore, ma prenderemo in esame, oltre al comportamento
+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
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 rimandare indietro sulla connessione i dati che gli vengono
-inviati; l'RFC descrive le specifiche 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; il servizio opera sulla porta 7.
+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
\subsection{Il client: prima versione}
\label{sec:TCP_echo_client}
-Il codice della prima versione client per il servizio \textit{echo},
-diponibile nel file \file{TCP_echo1.c}, è riportato in
+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}) è
\begin{figure}[!htb]
\footnotesize \centering
\begin{minipage}[c]{15.6 cm}
- \includecodesample{listati/TCP_echo_client.c}
+ \includecodesample{listati/TCP_echo1.c}
\end{minipage}
\normalsize
\caption{Codice della prima versione del client \textit{echo}.}
\end{figure}
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, la preparazione (\texttt{\small 14--17}) della
-struttura dell'indirizzo, che usa la porta 7 riservata al servizio
-\textit{echo}, l'indirizzo specificato a riga di comando appositamente
-convertito (\texttt{\small 18--22}). Una volta inizializzato l'indirizzo si si
-può eseguire (\texttt{\small 23--27}) la connessione al server secondo la
-stessa modalità usata in \secref{sec:TCP_daytime_client}.
-
-Completata la connessione, al ritorno di \func{connect}, per gestire il
-funzionamento del protocollo si usa la funzione \code{ClientEcho}, il cui
-codice si è riportato a parte in \figref{fig:TCPsimpl_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.
+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
\normalsize
\caption{Codice della prima versione della funzione \texttt{ClientEcho} per
la gestione del servizio \textit{echo}.}
- \label{fig:TCPsimpl_client_echo_sub}
+ \label{fig:TCP_client_echo_sub}
\end{figure}
-Quando si conluderà l'invio di dati mandando un end-of-file sullo standard
-inputo (ad esempio con la pressione di \texttt{C-d}) 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.
+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.
+
+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.
\subsection{Il server: prima versione}
\label{sec:TCPsimp_server_main}
-La prima versione del server, \file{TCP_echod.c}, si compone di un
-corpo principale, costituito dalla funzione \code{main}. Questa si incarica
-di creare il socket, metterlo in ascolto di connessioni in arrivo e creare un
-processo figlio a cui delegare la gestione di ciascuna connessione. Questa
-parte, riportata in \figref{fig:TCPsimpl_serv_code}, è analoga a quella vista
-nel precedente esempio esaminato in \secref{sec:TCP_daytime_cunc_server}.
+La prima versione del server, contenuta nel file \file{TCP\_echod\_first.c}, è
+riportata in \figref{fig:TCP_echo_server_first_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}[!htb]
+\begin{figure}[!htbp]
\footnotesize \centering
\begin{minipage}[c]{15.6cm}
- \includecodesample{listati/ElemEchoTCPServer.c}
+ \includecodesample{listati/TCP_echod_first.c}
\end{minipage}
\normalsize
- \caption{Codice della funzione \code{main} della prima versione del server
+ \caption{Codice del corpo principale della prima versione del server
per il servizio \textit{echo}.}
- \label{fig:TCPsimpl_serv_code}
+ \label{fig:TCP_echo_server_first_code}
\end{figure}
-La struttura di questa prima versione del server è sostanzialmente identica a
-quella dell'esempio citato, ed ad esso si applicano le considerazioni fatte in
-\secref{sec:TCP_daytime_cunc_server}. Le uniche differenze rispetto
-all'esempio in \figref{fig:TCP_daytime_cunc_server_code} sono che in questo
-caso per il socket in ascolto viene usata la porta 7 e che tutta la gestione
-della comunicazione è delegata alla funzione \code{ServEcho}.
-% Per ogni connessione viene creato un
-% processo figlio, il quale si incarica di lanciare la funzione
-% \texttt{SockEcho}.
-
-Il codice della funzione \code{ServEcho} è invece mostrata in
-\figref{fig:TCPsimpl_server_elem_sub}, la comunicazione viene gestita
-all'interno del ciclo (linee \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}.
+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}
\normalsize
\caption{Codice della prima versione della funzione \code{ServEcho} per la
gestione del servizio \textit{echo}.}
- \label{fig:TCPsimpl_server_elem_sub}
+ \label{fig:TCP_ServEcho}
\end{figure}
-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.
-
+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:TCPsimpl_startup}
+\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
\subsection{La conclusione normale}
-\label{sec:TCPsimpl_conclusion}
+\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
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:TCPsimpl_child_hand}
+\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
2359 pts/0 Z 0:00 [echod <defunct>]
\end{verbatim}
-Poiché non è possibile lasciare processi zombie\index{zombie} che pur inattivi
-occupano spazio nella tabella dei processi e a lungo andare saturerebbero le
-risorse del kernel, 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}.
-
-La 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}, illustrata in
-\figref{fig:sig_Signal_code}, per installare il semplice gestore che
-riceve i segnali dei processi figli terminati già visto in
-\figref{fig:sig_sigchld_handl}; aggiungendo il seguente codice:
-\includecodesnip{listati/sigchildhand.c}
+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:TCPsimpl_serv_code}, e linkando il tutto
-alla funzione \code{sigchld\_hand}, si risolverà completamente il problema
-degli zombie\index{zombie}.
+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 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} 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},
+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}, 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}.
+
+\begin{figure}[!htbp]
+ \footnotesize \centering
+ \begin{minipage}[c]{15.6cm}
+ \includecodesample{listati/TCP_echod.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}
+\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.
+
+
+
+
+\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.
+
+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}; questo significa che, oltre al caso di interruzione
+da parte di un segnale, esistono altri errori non fatali che necessitano
+semplicemente la ripetizione della chiamata senza che si debba uscire dal
+programma. Un esempio possibile è quello mostrato in
+\figref{fig:TCP_early_abort}, in cui la connessione viene abortita dal client
+con l'invio di un segmento RST prima che 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}