Modifiche varie per i test delle situazioni limite
[gapil.git] / elemtcp.tex
index 70caf59463babdf922a02ac50eeca7eb94622cbe..1ae67f4a24b6bc29b1806b2b3e737b08ac5c01dc 100644 (file)
@@ -1053,12 +1053,12 @@ errori rispetto ad altre implementazioni dei socket BSD, infatti la funzione
 \func{accept} passa gli errori di rete pendenti sul nuovo socket come codici
 di errore per \func{accept}, per cui l'applicazione deve tenerne conto ed
 eventualmente ripetere la chiamata alla funzione come per l'errore di
 \func{accept} passa gli errori di rete pendenti sul nuovo socket come codici
 di errore per \func{accept}, per cui l'applicazione deve tenerne conto ed
 eventualmente ripetere la chiamata alla funzione come per l'errore di
-\errcode{EAGAIN}. Un'altra differenza con BSD è che la funzione non fa
-ereditare al nuovo socket i flag del socket originale, come
-\const{O\_NONBLOCK},\footnote{ed in generale tutti quelli che si possono
-  impostare con \func{fcntl}, vedi \secref{sec:file_fcntl}.} che devono essere
-rispecificati ogni volta. Tutto questo deve essere tenuto in conto se si
-devono scrivere programmi portabili.
+\errcode{EAGAIN} (torneremo su questo in \secref{sec:TCP_echo_critical}).
+Un'altra differenza con BSD è che la funzione non fa ereditare al nuovo socket
+i flag del socket originale, come \const{O\_NONBLOCK},\footnote{ed in generale
+  tutti quelli che si possono impostare con \func{fcntl}, vedi
+  \secref{sec:file_fcntl}.} che devono essere rispecificati ogni volta. Tutto
+questo deve essere tenuto in conto se si devono scrivere programmi portabili.
 
 Il meccanismo di funzionamento di \func{accept} è essenziale per capire il
 funzionamento di un server: in generale infatti c'è sempre un solo socket in
 
 Il meccanismo di funzionamento di \func{accept} è essenziale per capire il
 funzionamento di un server: in generale infatti c'è sempre un solo socket in
@@ -2078,8 +2078,9 @@ modificata per la seconda versione del programma.
     \includecodesample{listati/TCP_echod.c}
   \end{minipage} 
   \normalsize
     \includecodesample{listati/TCP_echod.c}
   \end{minipage} 
   \normalsize
-  \caption{Sezione del codice seconda versione del server
-    per il servizio \textit{echo} modificate rispetto alla prima.}
+  \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}
 \end{figure}
 
   \label{fig:TCP_echo_server_code}
 \end{figure}
 
@@ -2122,19 +2123,24 @@ la rete 
 gestire tutta una serie di situazioni critiche che non esistono per i processi
 locali.
 
 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à
 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..
+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
 
 È 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 con l'invio di un segmento RST,
-prima che nel server sia stata chiamata la funzione \func{accept}.
+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
 
 \begin{figure}[htb]
   \centering
@@ -2148,8 +2154,8 @@ con dei server molto occupati. In tal caso, con una struttura del server
 simile a quella del nostro esempio, in cui la gestione delle singole
 connessioni è demandata a processi figli, può accadere che il three way
 handshake venga completato e la relativa connessione abortita subito dopo,
 simile a quella del nostro esempio, in cui la gestione delle singole
 connessioni è demandata a processi figli, può accadere che il three way
 handshake venga completato e la relativa connessione abortita subito dopo,
-prima che il padre, per via del carico della macchina, abbia fatto in tempo a
-rieseguire la chiamata ad \func{accept}. Di nuovo si ha una situazione analoga
+prima che il padre, per via del carico della macchina, abbia fatto in tempo ad
+eseguire la chiamata ad \func{accept}. Di nuovo si ha una situazione analoga
 a quella illustrata in \figref{fig:TCP_early_abort}, in cui la connessione
 viene stabilita, ma subito dopo si ha una condizione di errore che la chiude
 prima che essa sia stata accettata dal programma.
 a quella illustrata in \figref{fig:TCP_early_abort}, in cui la connessione
 viene stabilita, ma subito dopo si ha una condizione di errore che la chiude
 prima che essa sia stata accettata dal programma.
@@ -2160,17 +2166,34 @@ abbiamo trattato in \secref{sec:TCP_child_hand} nel caso particolare di
 \func{accept}, che come nel caso precedente, necessitano semplicemente la
 ripetizione della chiamata senza che si debba uscire dal programma. In questo
 caso anche la versione modificata del nostro server non sarebbe adatta, in
 \func{accept}, che come nel caso precedente, necessitano semplicemente la
 ripetizione della chiamata senza che si debba uscire dal programma. In questo
 caso anche la versione modificata del nostro server non sarebbe adatta, in
-quanto uno di questi errori causerebbe la terminazione dello stesso.
+quanto uno di questi errori causerebbe la terminazione dello stesso. In Linux
+i possibili errori di rete non fatali, riportati sul socket connesso al
+ritorno di \func{accept}, sono \errcode{ENETDOWN}, \errcode{EPROTO},
+\errcode{ENOPROTOOPT}, \errcode{EHOSTDOWN}, \errcode{ENONET},
+\errcode{EHOSTUNREACH}, \errcode{EOPNOTSUPP} e \errcode{ENETUNREACH}.
 
 Si tenga presente che questo tipo di terminazione non è riproducibile
 terminando il client prima della chiamata ad \func{accept}; in tal caso
 infatti il socket associato alla connessione viene semplicemente chiuso,
 attraverso la sequenza vista in \secref{sec:TCP_conn_term}, per cui la
 \func{accept} ritornerà senza errori, e si avrà semplicemente un end-of-file
 
 Si tenga presente che questo tipo di terminazione non è riproducibile
 terminando il client prima della chiamata ad \func{accept}; in tal caso
 infatti il socket associato alla connessione viene semplicemente chiuso,
 attraverso la sequenza vista in \secref{sec:TCP_conn_term}, per cui la
 \func{accept} ritornerà senza errori, e si avrà semplicemente un end-of-file
-al primo accesso al socket. Per riprodurre l'errore occorrerebbe usare
-l'opzione \const{SO\_LINGER} (vedi \secref{sec:xxx}) per chiedere al client di
-chiudere il socket con un segmento RST, invece che con la normale sequenza di
-chiusura.
+al primo accesso al socket. Nel caso di Linux inoltre anche l'invio da parte
+del client di un segmento di RST non provoca nessun errore al ritorno di
+\funcd{accept} quanto un errore di \errcode{ECONNRESET} al primo tentativo di
+accesso al socket.
+
+
+
+\subsection{Il crollo del server}
+\label{sec:TCP_server_crash}
+
+Un secondo caso critico è quello in cui si ha il crollo del server. In tal
+caso si suppone che il processo del server termini per un errore fatale, cosa
+che potremo simulare inviandogli un segnale di terminazione. La conclusione
+del processo comporta la chiusura di tutti i file aperti, compresi tutti i
+socket relativi a connessioni stabilite; questo significa che al momento del
+crollo del servizio il client riceverà un FIN dal server in corrispondenza
+della chiusura del socket.