Completata e rivista la trattazione di SO_LINGER.
[gapil.git] / sockctrl.tex
index 7e8a5b611baff469dd1c6aaf389b0ed783d03603..b0cc66c6b02f34a8a346a30865f74858a5742ca5 100644 (file)
@@ -1370,8 +1370,8 @@ verr
   argument}) i propri risultati. La funzione infatti è rientrante, ed alloca
 autonomamente tutta la memoria necessaria in cui verranno riportati i
 risultati della risoluzione.  La funzione scriverà in \param{res} il puntatore
-iniziale ad una \textit{linked list} di strutture di tipo \struct{addrinfo}
-contenenti tutte le informazioni ottenute.
+iniziale ad una \index{\textit{linked~list}}\textit{linked list} di strutture
+di tipo \struct{addrinfo} contenenti tutte le informazioni ottenute.
 
 La funzione restituisce un valore nullo in caso di successo, o un codice in
 caso di errore. I valori usati come codice di errore sono riportati in
@@ -1461,8 +1461,8 @@ lista illustrata in fig.~\ref{fig:sock_addrinfo_list}.
 \begin{figure}[!htb]
   \centering
   \includegraphics[width=10cm]{img/addrinfo_list}
-  \caption{La \textit{linked list} delle strutture \struct{addrinfo}
-    restituite da \func{getaddrinfo}.}
+  \caption{La \index{\textit{linked~list}}\textit{linked list} delle strutture
+    \struct{addrinfo} restituite da \func{getaddrinfo}.}
   \label{fig:sock_addrinfo_list}
 \end{figure}
 
@@ -1558,10 +1558,11 @@ IPv4 address:
 \end{Verbatim}
 %$
 
-Una volta estratti i risultati dalla \textit{linked list} puntata da
-\param{res} se questa non viene più utilizzata si dovrà avere cura di
-disallocare opportunamente tutta la memoria, per questo viene fornita
-l'apposita funzione \funcd{freeaddrinfo}, il cui prototipo è:
+Una volta estratti i risultati dalla
+\index{\textit{linked~list}}\textit{linked list} puntata da \param{res} se
+questa non viene più utilizzata si dovrà avere cura di disallocare
+opportunamente tutta la memoria, per questo viene fornita l'apposita funzione
+\funcd{freeaddrinfo}, il cui prototipo è:
 \begin{functions}
   \headdecl{netdb.h} 
 
@@ -2065,22 +2066,15 @@ un valore logico. Si 
 usato per \param{optval} ed una breve descrizione del significato delle
 singole opzioni sulla sesta.
 
-
-Questo ci consentirà anche
-di trattare approfonditamente alcune opzioni che, nonostante siano
-classificate fra quelle generiche, hanno un significato effettivo solo per
-alcuni tipi di socket.TCP/IP.  L'elenco dettagliato del significato delle
-opzioni generiche dei socket è allora il seguente:
-
-
 Le descrizioni delle opzioni presenti in tab.~\ref{tab:sock_opt_socklevel}
 sono estremamente sommarie, è perciò necessario fornire un po' più di
-informazioni; alcune opzioni comunque hanno una notevole rilevanza nella
+informazioni. Alcune opzioni inoltre hanno una notevole rilevanza nella
 gestione dei socket, e pertanto il loro utilizzo sarà approfondito
-separatamente in sez.~\ref{sec:sock_options_main}. Quello che segue pertanto è
-soltanto un elenco più dettagliato di quanto scritto in
+separatamente in sez.~\ref{sec:sock_options_main}. Quello che segue è quindi
+soltanto un elenco più dettagliato della breve descrizione di
 tab.~\ref{tab:sock_opt_socklevel} sul significato delle varie opzioni:
 \begin{basedescript}{\desclabelwidth{2.5cm}\desclabelstyle{\nextlinelabel}}
+
 \item[\const{SO\_KEEPALIVE}] questa opzione abilita un meccanismo di verifica
   della persistenza di una connessione associata al socket (ed è pertanto
   effettiva solo sui socket che supportano le connessioni, ed è usata
@@ -2097,7 +2091,6 @@ tab.~\ref{tab:sock_opt_socklevel} sul significato delle varie opzioni:
   supportino i dati \textit{out-of-band} (non ha senso per socket UDP ad
   esempio), ed utilizza per \param{optval} un intero usato come valore logico.
 
-
 \item[\const{SO\_RCVLOWAT}] questa opzione imposta il valore che indica il
   numero minimo di byte che devono essere presenti nel buffer di ricezione
   perché il kernel passi i dati all'utente, restituendoli ad una \func{read} o
@@ -2107,7 +2100,6 @@ tab.~\ref{tab:sock_opt_socklevel} sul significato delle varie opzioni:
   essere cambiato; \func{getsockopt} leggerà questo valore mentre
   \func{setsockopt} darà un errore di \errcode{ENOPROTOOPT}. 
 
-
 \item[\const{SO\_SNDLOWAT}] questa opzione imposta il valore che indica il
   numero minimo di byte che devono essere presenti nel buffer di scrittura
   perché il kernel li invii al protocollo successivo, consentendo ad una
@@ -2118,7 +2110,6 @@ tab.~\ref{tab:sock_opt_socklevel} sul significato delle varie opzioni:
   sempre 1 e non può essere cambiato; \func{getsockopt} leggerà questo valore
   mentre \func{setsockopt} darà un errore di \errcode{ENOPROTOOPT}.
 
-
 \item[\const{SO\_RCVTIMEO}] l'opzione permette di impostare un tempo massimo
   sulle operazioni di lettura da un socket, e prende per \param{optval} una
   struttura di tipo \struct{timeval} (vedi fig.~\ref{fig:sys_timeval_struct})
@@ -2151,7 +2142,7 @@ tab.~\ref{tab:sock_opt_socklevel} sul significato delle varie opzioni:
   sulle operazioni di scrittura su un socket, ed usa gli stessi valori di
   \const{SO\_RCVTIMEO}.  In questo caso però si avrà un errore di
   \errcode{EAGAIN} o \errcode{EWOULDBLOCK} per le funzioni di scrittura
-  \func{write}, \func{writev}, \func{send}, \func{sendfrom} e \func{sendmsg}
+  \func{write}, \func{writev}, \func{send}, \func{sendto} e \func{sendmsg}
   qualora queste restino bloccate per un tempo maggiore di quello specificato. 
 
 \item[\const{SO\_BSDCOMPAT}] questa opzione abilita la compatibilità con il
@@ -2219,7 +2210,6 @@ tab.~\ref{tab:sock_opt_socklevel} sul significato delle varie opzioni:
   socket.  Maggiori dettagli sul suo funzionamento sono forniti in
   sez.~\ref{sec:sock_options_main}.
 
-
 \item[\const{SO\_TYPE}] questa opzione permette di leggere il tipo di socket
   su cui si opera; funziona solo con \func{getsockopt}, ed utilizza per
   \param{optval} un intero in cui verrà restituto il valore numerico che lo
@@ -2242,20 +2232,17 @@ tab.~\ref{tab:sock_opt_socklevel} sul significato delle varie opzioni:
   su tale indirizzo.  Prende per \param{optval} un intero usato come valore
   logico. L'opzione non ha effetti su un socket di tipo \const{SOCK\_STREAM}.
 
-
 \item[\const{SO\_SNDBUF}] questa opzione imposta la dimenzione del buffer di
   uscita del socket. Prende per \param{optval} un intero indicante il numero
   di byte. Il valore di default ed il valore massimo che si può specificare
   come argomento per questa opzione sono impostabili tramiti gli opportuni
   valori di \func{sysctl} (vedi sez.~\ref{sec:sock_sysctl}).
 
-
 \item[\const{SO\_RCVBUF}] questa opzione imposta la dimenzione del buffer di
   ingresso del socket. Prende per \param{optval} un intero indicante il numero
   di byte. Il valore di default ed il valore massimo che si può specificare
   come argomento per questa opzione sono impostabili tramiti gli opportuni
   valori di \func{sysctl} (vedi sez.~\ref{sec:sock_sysctl}).
-   
 
 \item[\const{SO\_LINGER}] questa opzione controlla le modalità con cui viene
   chiuso un socket quando si utilizza un protocollo che supporta le
@@ -2288,32 +2275,38 @@ tab.~\ref{tab:sock_opt_socklevel} sul significato delle varie opzioni:
 \subsection{Le uso delle principali opzioni dei socket}
 \label{sec:sock_options_main}
 
-L'elenco sintetico delle caratteristiche delle opzioni dei socket riportato in
-sez.~\ref{sec:sock_generic_options} non è sufficientemente dettagliato per
-permetterci di approfondire il significato di alcune di esse, che assumono
-grande importanza nella programmazione dei socket. Per questo motivo
-tratteremo ulteriormente l'uso di alcune di esse in questa sezione.
-
-\index{\texttt{SO\_KEEPALIVE} (costante)|(}
-La prima opzione da approfondire è \const{SO\_KEEPALIVE}, che come accennato
-permette di controllare automaticamente lo stato di una connessione.  Una
-connessione infatti può restare attiva anche se non viene effettuato alcun
-traffico su di essa, ma in certi casi però può essere utile controllarne lo
-stato per accorgersi di eventuali problemi. 
-
-Per questo, se si imposta questa opzione, è cura del kernel inviare degli
-appositi messaggi sulla rete (detti appunto \textit{keep-alive}) per
-verificare se la connessione è attiva.  L'opzione funziona soltanto con socket
-che supportino le connessioni (non ha senso per socket UDP ad esempio), ed
-utilizza per \param{optval} un intero usato come valore logico.
-
-L'opzione si applica principalmente ai socket TCP.  Con le impostazioni di
-default (che sono riprese da BSD) Linux emette un messaggio di
-\textit{keep-alive} verso l'altro capo della connessione se questa è rimasta
-senza traffico per più di due ore. Se è tutto a posto il messaggio viene
-ricevuto e verrà emesso un segmento ACK di risposta, alla cui ricezione
-ripartirà un'altro ciclo di attesa per altre due ore di inattività; tutto ciò
-viene effettuato dal kernel e le applicazioni non riceveranno nessun dato.
+La descrizione sintetica del significato delle opzioni generiche dei socket,
+riportata nell'elenco in sez.~\ref{sec:sock_generic_options}, non è
+sufficientemente dettagliata per permetterci di approfondire tutti le
+funzionalità che alcune di esse possono controllare, alcune delle quali hanno
+un rilevanza notevole nella programmazione dei socket. Per questo motivo
+tratteremo nei dettagli le principali opzioni in questa sezione.
+
+
+\index{\texttt{SO\_KEEPALIVE} (costante)|(} 
+\subsubsection{L'opzione \const{SO\_KEEPALIVE}}
+
+La prima opzione da approfondire è \const{SO\_KEEPALIVE} che permette di
+tenere sotto controllo lo stato di una connessione. Una connessione infatti
+resta attiva anche quando non viene effettuato alcun traffico su di essa,
+questo può comportare che un crollo della connessione, qualora avvenisse ad
+esempio in conseguenza di una interruzione completa della rete, potrebbe
+passare inosservato.
+
+Se si imposta questa opzione, è invece cura del kernel inviare degli appositi
+messaggi sulla rete, detti appunto \textit{keep-alive}, per verificare se la
+connessione è attiva.  L'opzione funziona soltanto con socket che supportino
+le connessioni (non ha senso per socket UDP ad esempio) e si applica
+principalmente ai socket TCP.
+
+Con le impostazioni di default (che sono riprese da BSD) Linux emette un
+messaggio di \textit{keep-alive}\footnote{in sostanza un segmento ACK vuoto,
+  cui sarà risposto con un altro segmento ACK vuoto.} verso l'altro capo della
+connessione se questa è rimasta senza traffico per più di due ore. Se è tutto
+a posto il messaggio viene ricevuto e verrà emesso un segmento ACK di
+risposta, alla cui ricezione ripartirà un'altro ciclo di attesa per altre due
+ore di inattività; il tutto avviene all'interno del kernel e le applicazioni
+non riceveranno nessun dato.
 
 In caso di problemi invece si possono avere i due casi già illustrati in
 sez.~\ref{sec:TCP_conn_crash} per il caso di terminazione prococe del server:
@@ -2321,56 +2314,111 @@ il primo 
 cui dopo il riavvio la connessione non viene più riconosciuta,\footnote{si
   ricordi che un normale riavvio non ha questo effetto, in quanto si passa per
   la chiusura del processo, che chiude anche il socket inviando un segmento
-  FIN all'altro capo della connessione.} e si otterrà come risposta un RST. In
+  FIN all'altro capo della connessione.} in questo caso all'invio del
+messaggio di \textit{keep-alive} si otterrà come risposta un segmento RST che
+indica che l'altro capo non riconosce più l'esistenza della connessione. In
 tal caso il socket viene chiuso dopo aver impostato un errore
 \errcode{ECONNRESET}.
 
 Se invece non viene ricevuta nessuna risposta (indice che la macchina non è
 più raggiungibile) l'emissione dei messaggi viene ripetuta ad intervalli di 75
-secondi ad un massimo di 9 volte\footnote{entrambi questi valori possono
+secondi per un massimo di 9 volte\footnote{entrambi questi valori possono
   essere opportunamente modificati con gli opportuni parametri illustrati in
   sez.~\ref{sec:sock_sysctl}, si tenga presente che però questo vale a livello
-  di kernel ed i valori saranno applicati a \textsl{tutti} i socket.} (per un
-totale di 11 minuti e 15 secondi) dopo di che, se non si è ricevuta nessuna
-risposta, il socket viene chiuso dopo aver impostato un errore di
-\errcode{ETIMEDOUT}. Se invece si riceve in risposta ad uno di questi messaggi
-un pacchetto ICMP di destinazione irraggiungibile, verrà restituito l'errore
-corrispondente.
+  di kernel ed i suddetti valori saranno applicati a \textsl{tutti} i socket.}
+(per un totale di 11 minuti e 15 secondi) dopo di che, se non si è ricevuta
+nessuna risposta, il socket viene chiuso dopo aver impostato un errore di
+\errcode{ETIMEDOUT}. Qualora la connessione si sia ristabilita e si riceva un
+successivo messaggio di risposta il ciclo riparte come se niente fosse
+avvenuto.  Infine se invece si riceve come risposta un pacchetto ICMP di
+destinazione irraggiungibile (vedi sez.~\ref{sec:icmp_protocol_xxx}), verrà
+restituito l'errore corrispondente.
 
 In generale questa opzione serve per individuare una caduta della
-connessione,\footnote{il crash di un processo di nuovo comporta la chiusura di
-  tutti i file che aveva aperti e la relativa emissione degli opportuni
-  segmenti FIN nel caso dei socket.} e viene usata sui server per evitare di
+connessione\footnote{la terminazione di un processo di nuovo comporta la
+  chiusura di tutti i file che aveva aperti e la relativa emissione degli
+  opportuni segmenti FIN nel caso dei socket.} anche quando non si sta facendo
+traffico su di essa.  In genere viene usata sui server per evitare di
 mantenere impegnate le risorse dedicate a trattare delle connessioni in realtà
-terminate.  Abilitandola le connessioni effettivamente terminate vengono
-chiuse ed una \func{select} potrà rilevare la conclusione delle stesse e
+già terminate (quelle che vengono anche chiamate connessioni
+\textsl{semi-aperte}) in cui il server è in attesa di dati in ingresso che non
+arriveranno mai perché il client sull'altro capo non è più attivo.
+
+Abilitandola le connessioni effettivamente terminate vengono chiuse e ad
+esempio una \func{select} potrà rilevare la conclusione delle stesse e
 ricevere il relativo errore. Si tenga però presente che non si ha la certezza
 assoluta che un errore di \errcode{ETIMEDOUT} corrisponda ad una reale
 conclusione della connessione, il problema potrebbe essere dovuto ad un
 problema di routing che perduri per un tempo maggiore di quello impiegato nei
-vari tentativi di ritrasmissione del \textit{keep-alive}.
+vari tentativi di ritrasmissione del \textit{keep-alive} (anche se questa non
+è una una condizione molto probabile).
+
+\begin{figure}[!htb]
+  \footnotesize \centering
+  \begin{minipage}[c]{15cm}
+    \includecodesample{listati/TCP_echod_fourth.c}
+  \end{minipage}
+  \normalsize
+  \caption{La sezione della nuova versione del server del servizio
+    \textit{echo} che prevede l'attivazione del \textit{keepalive} sui
+    socket.}
+  \label{fig:echod_keepalive_code}
+\end{figure}
+
+Come esempio dell'utilizzo di questa opzione introduciamo all'interno del
+nostro server per il servizio \textit{echo} la nuova opzione \texttt{-k} che
+permette di attivare il \textit{keep-alive} sui socket; tralasciando la parte
+relativa alla gestione di detta opzione (che si limita ad assegnare ad 1 la
+variabile \var{keepalive}) tutte le modifiche al server sono riportate in
+fig.~\ref{fig:echod_keepalive_code}. Al solito il codice completo è contenuto
+nel file \texttt{TCP\_echod\_fourth.c} dei sorgenti allegati alla guida.
+
+Come si può notare la variabile \var{keepalive} è preimpostata (\texttt{\small
+  8}) ad un valore nullo; essa viene utilizzata sia come variabile logica per
+la condizione (\texttt{\small 14}) che controlla l'attivazione del
+\textit{keep-alive} che come valore dell'argomento \param{optval} della
+chiamata a \func{setsockopt} (\texttt{\small 16}).  A seconda del suo valore
+tutte le volta che un processo figlio viene eseguito in risposta ad una
+connessione verrà pertanto eseguita o meno la sezione (\texttt{\small 14--17})
+che esegue l'impostazione di \const{SO\_KEEPALIVE} sul socket connesso.
 \index{\texttt{SO\_KEEPALIVE} (costante)|)}
 
 
 \index{\texttt{SO\_REUSEADDR} (costante)|(}
-La seconda opzione da approfondire è \const{SO\_REUSEADDR}.  Come Stevens
-sottolinea in \cite{UNP1} si distinguono quattro casi per l'utilizzo di questa
-opzione; il primo è quello in cui un server è terminato ma esistono ancora dei
-processi figli che mantengono attiva almeno una connessione remota che
-utilizza l'indirizzo locale. Quando si riavvia il server questo viene bloccato
-sulla chiamata a \func{bind} dato che la porta è ancora utilizzata in una
-connessione esistente.\footnote{questa è una delle domande più frequenti sui
-  newsgroup dedicati allo sviluppo, in quanto è piuttosto comune in questa
-  situazione quando si sta sviluppando un server che si ferma e si riavvia in
-  continuazione.}  Inoltre se si usa il protocollo TCP questo può avvenire
-anche dopo che l'ultimo processo figlio è terminato, dato che la connessione
-può restare attiva anche dopo la chiusura del socket mantenendosi nello stato
-\texttt{TIME\_WAIT}.
+\subsubsection{L'opzione \const{SO\_REUSEADDR}}
+
+La seconda opzione da approfondire è \const{SO\_REUSEADDR}, che consente di
+eseguire \func{bind} su un socket anche quando la porta specificata è già in
+uso da parte di un altro socket. Si ricordi infatti che, come accennato in
+sez.~\ref{sec:TCP_func_bind}, normalmente la funzione \func{bind} fallisce con
+un errore di \errcode{EADDRINUSE} se la porta scelta è già utilizzata da un
+altro socket, proprio per evitare che possano essere lanciati due server sullo
+stesso indirizzo che verrebbero a contendersi i relativi pacchetti.  
+
+Esistono però dei casi speciali in cui non si vuole che questo accada, ed
+allora si può fare ricorso a questa opzione. La questione è comunque
+abbastanza complessa (il che rende questa una delle opzioni piu difficili da
+capire) in quanto, come sottolinea Stevens in \cite{UNP1}, si distinguono ben
+quattro casi diversi in cui è prevista la possibilità di un suo utilizzo.
+
+Il primo ed il più comune caso in cui si fa ricorso a \const{SO\_REUSEADDR} è
+quello in cui un server è terminato ma esistono ancora dei processi figli che
+mantengono attiva almeno una connessione remota che utilizza l'indirizzo
+locale mantenendo occupata la porta. Quando si riesegue il server allora
+questo riceve un errore sulla chiamata a \func{bind} dato che la porta è
+ancora utilizzata in una connessione esistente.\footnote{questa è una delle
+  domande più frequenti sui newsgroup dedicati allo sviluppo, in quanto è
+  piuttosto comune trovarsi in questa situazione quando si sta sviluppando un
+  server che si ferma e si riavvia in continuazione dopo aver fatto
+  modifiche.}  Inoltre se si usa il protocollo TCP questo può avvenire anche
+dopo tutti i processi figlio sono terminati, dato che una connessione può
+restare attiva anche dopo la chiusura del socket, mantenendosi nello stato
+\texttt{TIME\_WAIT} (vedi sez.~\ref{sec:TCP_time_wait}).
 
 Usando \const{SO\_REUSEADDR} fra la chiamata a \func{socket} e quella a
 \func{bind} si consente a quest'ultima di avere comunque successo anche se la
 connessione è attiva (o nello stato \texttt{TIME\_WAIT}). È bene però
-ricordare (si riveda quanto detto in sez.~\ref{sec:TCP_time_wait}) che la
+ricordare (si ricordi quanto detto in sez.~\ref{sec:TCP_time_wait}) che la
 presenza dello stato \texttt{TIME\_WAIT} ha una ragione, ed infatti se si usa
 questa opzione esiste sempre una probabilità, anche se estremamente
 remota,\footnote{perché ciò avvenga infatti non solo devono coincidere gli
@@ -2379,14 +2427,70 @@ remota,\footnote{perch
 eventuali pacchetti rimasti intrappolati in una precedente connessione possano
 finire fra quelli di una nuova.
 
-Il secondo caso in cui viene usata questa opzione è quando si ha una macchina
-cui sono assegnati diversi numeri IP (o come suol dirsi \textit{multi-homed})
-e si vuole porre in ascolto sulla stessa porta un programma diverso (o una
-istanza diversa dello stesso programma) per indirizzi IP diversi. Si ricordi
-infatti che è sempre possibile indicare a \func{bind} di collegarsi solo su di
-un indirizzo specifico; in tal caso se un altro programma cerca di
-riutilizzare la stessa porta (anche specificando un indirizzo diverso) otterrà
-un errore a meno di non aver preventivamente impostato \const{SO\_REUSEADDR}.
+Come esempio di uso di questa connessione abbiamo predisposto una nuova
+versione della funzione \func{sockbind} (vedi fig.~\ref{fig:sockbind_code})
+che consenta l'impostazione di questa opzione. La nuova funzione è
+\func{sockbindopt}, e le principali differenze rispetto alla precedente sono
+illustrate in fig.~\ref{fig:sockbindopt_code} dove si sono riportate le
+sezioni di codice modificate rispetto ad essa. Il codice completo della
+funzione si trova, insieme alle altre funzioni di servizio dei socket,
+all'interno del file \texttt{SockUtils.c} dei sorgenti allegati alla guida.
+
+\begin{figure}[!htb]
+  \footnotesize \centering
+  \begin{minipage}[c]{15cm}
+    \includecodesample{listati/sockbindopt.c}
+  \end{minipage}
+  \normalsize
+  \caption{Le sezioni della funzione \func{sockbindopt} modificate rispetto al
+    codice della precedente \func{sockbind}.} 
+  \label{fig:sockbindopt_code}
+\end{figure}
+
+In realtà tutto quello che si è fatto è stato introdurre (\texttt{\small 1})
+un nuovo argomento intero \param{reuse} nella nuova funzione che conterrà il
+valore logico da usare nella successiva chiamata (\texttt{\small 14}) a
+\func{setsockopt}. Si è poi aggiunta la sezione (\texttt{\small 13-17}) che
+esegue l'impostazione dell'opzione fra la chiamata a \func{socket} e quella a
+\func{bind}. 
+
+
+A questo punto basterà modificare il  server per utilizzare la nuova
+funzione; in fig.~\ref{fig:TCP_echod_fifth} abbiamo riportato le sezioni
+modificate rispetto alla precedente versione di
+fig.~\ref{fig:TCP_echod_third}. Al solito il codice completo è coi sorgenti
+allegati alla guida, nel file \texttt{TCP\_echod\_fifth.c}.
+
+Anche in questo caso si è introdotta (\texttt{\small 8}) una nuova variabile
+\var{reuse} che consente di controllare l'uso dell'opzione e che poi sarà
+usata (\texttt{\small 14}) come ultimo argomento di \func{setsockopt}. Il
+valore di default di questa variabile è nullo, ma usando l'opzione \texttt{-r}
+nell'invocazione del server (al solito la gestione delle opzioni non è
+riportata in fig.~\ref{fig:TCP_echod_fifth}) se ne potrà impostare ad 1 il
+valore, per cui in tal caso la successiva chiamata (\texttt{\small 13-17}) a
+\func{setsockopt} attiverà l'opzione \const{SO\_REUSEADDR}.
+
+\begin{figure}[!htb] 
+  \footnotesize \centering
+  \begin{minipage}[c]{15cm}
+    \includecodesample{listati/TCP_echod_fifth.c}
+  \end{minipage}
+  \normalsize
+  \caption{Il nuovo codice per l'apertura passiva del server \textit{echo} che
+    usa la nuova funzione \func{sockbindopt}.}
+  \label{fig:TCP_echod_fifth}
+\end{figure}
+
+Il secondo caso in cui viene usata \const{SO\_REUSEADDR} è quando si ha una
+macchina cui sono assegnati diversi numeri IP (o come suol dirsi
+\textit{multi-homed}) e si vuole porre in ascolto sulla stessa porta un
+programma diverso (o una istanza diversa dello stesso programma) per indirizzi
+IP diversi. Si ricordi infatti che è sempre possibile indicare a \func{bind}
+di collegarsi solo su di un indirizzo specifico; in tal caso se un altro
+programma cerca di riutilizzare la stessa porta (anche specificando un
+indirizzo diverso) otterrà un errore, a meno di non aver preventivamente
+impostato \const{SO\_REUSEADDR}.
+
 Usando questa opzione diventa anche possibile eseguire \func{bind}
 sull'indirizzo generico, e questo permetterà il collegamento per tutti gli
 indirizzi (di quelli presenti) per i quali la porta non risulti occupata da
@@ -2403,11 +2507,11 @@ il sistema non supporta l'opzione \const{IP\_RECVDSTADDR};\footnote{nel caso
   di Linux questa opzione è stata supportata per in certo periodo nello
   sviluppo del kernel 2.1.x, ma è in seguito stata soppiantata dall'uso di
   \const{IP\_PKTINFO} (vedi sez.~\ref{sec:sock_ipv4_options}).} in tale modo
-si può sapere a quale socket corrisponde un certo indirizzo.  Non ha senso per
-socket TCP dato che su di essi si può sempre invocare \func{getsockname} una
-volta che si è completata la connessione.
+si può sapere a quale socket corrisponde un certo indirizzo.  Non ha senso
+fare questa operazionie per socket TCP dato che su di essi si può sempre
+invocare \func{getsockname} una volta che si è completata la connessione.
 
-Infine il quarto caso è quello in si vuole effettivamente ottenere un
+Infine il quarto caso è quello in cui si vuole effettivamente ottenere un
 \textit{completely duplicate binding}, quando cioè si vuole eseguire
 \func{bind} su un indirizzo ed una porta che sono già \textsl{legati} ad un
 altro socket.  Questo ovviamente non ha senso per il normale traffico di rete,
@@ -2451,13 +2555,16 @@ questa opzione.\footnote{Questa restrizione permette di evitare il cosiddetto
 \index{\texttt{SO\_REUSEADDR} (costante)|)}
 
 
-\index{\texttt{SO\_LINGER} (costante)|(} La terza opzione da approfondire è
-\const{SO\_LINGER}; essa, come il nome suggerisce, consente di
-\textsl{indugiare} nella chiusura di un socket. Il comportamento standard sia
-di \func{close} che \func{shutdown} è quello di terminare immediatamente dopo
-la chiamata, mentre il procedimento di chiusura della connessione e l'invio
-sulla rete di tutti i dati ancora presenti nei buffer viene gestito in
-sottofondo dal kernel.
+\index{\texttt{SO\_LINGER} (costante)|(} 
+\subsubsection{L'opzione \const{SO\_LINGER}}
+
+La terza opzione da approfondire è \const{SO\_LINGER}; essa, come il nome
+suggerisce, consente di ``\textsl{indugiare}'' nella chiusura di un socket. Il
+comportamento standard sia di \func{close} che \func{shutdown} è infatti
+quello di terminare immediatamente dopo la chiamata, mentre il procedimento di
+chiusura della connessione (o di un lato di essa) ed il rispettivo invio sulla
+rete di tutti i dati ancora presenti nei buffer, viene gestito in sottofondo
+dal kernel.
 
 \begin{figure}[!htb]
   \footnotesize \centering
@@ -2470,23 +2577,72 @@ sottofondo dal kernel.
   \label{fig:sock_linger_struct}
 \end{figure}
 
-L'uso di \const{SO\_LINGER} permette di modificare (ed eventualmente
-ripristinare) questo comportamento in base ai valori passati nei campi della
-stuttura \struct{linger}.  Fintanto che il valore del campo \var{l\_onoff} di
-\struct{linger} è nullo la modalità che viene impostata (qualunque sia il
-valore di \var{l\_linger}) è quella standard appena illustrata.
-
-Se però si utilizza un valore di \var{l\_onoff} diverso da zero per
-l'impostazione di \const{SO\_LINGER} il comportamento dipende dal valore di
+L'uso di \const{SO\_LINGER} con \func{setsockopt} permette di modificare (ed
+eventualmente ripristinare) questo comportamento in base ai valori passati nei
+campi della stuttura \struct{linger}, illustrata in
+fig.~\ref{fig:sock_linger_struct}.  Fintanto che il valore del campo
+\var{l\_onoff} di \struct{linger} è nullo la modalità che viene impostata
+(qualunque sia il valore di \var{l\_linger}) è quella standard appena
+illustrata; questa combinazione viene utilizzata per riportarsi al
+comportamento normale qualora esso sia stato cambiato da una precedente
+chiamata.
+
+Se si utilizza un valore di \var{l\_onoff} diverso da zero, il comportamento
+alla chiusura viene a dipendere dal valore specificato per il campo
 \var{l\_linger}; se quest'ultimo è nullo l'uso delle funzioni \func{close} e
 \func{shutdown} provoca la terminazione immediata della connessione: nel caso
 di TCP cioè non viene eseguito il procedimento di chiusura illustrato in
-sez.~\ref{sec:TCP_conn_term}, ma viene inviato un segmento di RST che termina
-immediatamente la connessione. Se invece \var{l\_linger} ha un valore diverso
-da zero sia \func{close} che \func{shutdown} si bloccano e non ritornano
-fintanto che non si sia concluso il procedimento di chiusura della
-connessione, o non siano passati il numero di secondi specificati da
-\var{l\_linger}.
+sez.~\ref{sec:TCP_conn_term}, ma tutti i dati ancora presenti nel buffer
+vengono immediatamente scartati e sulla rete viene inviato un segmento di RST
+che termina immediatamente la connessione.
+
+Un esempio di questo comportamento si può abilitare nel nostro client del
+servizio \textit{echo} utilizzando l'opzione \texttt{-r}; riportiamo in
+fig.~\ref{fig:TCP_echo_sixth} la sezione di codice che permette di introdurre
+questa funzionalità,; al solito il codice completo è disponibile nei sorgenti
+allegati.
+
+\begin{figure}[!htb] 
+  \footnotesize \centering
+  \begin{minipage}[c]{15cm}
+    \includecodesample{listati/TCP_echo_sixth.c}
+  \end{minipage}
+  \normalsize
+  \caption{La sezione del codice del client \textit{echo} che imposta la
+    terminazione immediata della connessione in caso di chiusura.}
+  \label{fig:TCP_echo_sixth}
+\end{figure}
+
+La sezione indicata viene eseguita dopo aver effettuato la connessione e prima
+di chiamare la funzione di gestione, cioè fra le righe (\texttt{\small 12}) e
+(\texttt{\small 13}) del precedente esempio di fig.~\ref{fig:TCP_echo_fifth}.
+Il codice si limita semplicememente a controllare (\texttt{\small 3}) il
+valore della variabile \var{reset} che assegnata nella gestione delle opzioni
+in corrispondenza all'uso di \texttt{-r} nella chiamata del client. Nel caso
+questa sia diversa da zero vengono impostati (\texttt{\small 5--6}) i valori
+della struttura \var{ling} che permettono una terminazione immediata della
+connessine. Questa viene poi usata nella successiva (\texttt{\small 7})
+chiamata a \func{setsockopt}. Al solito si controlla (\texttt{\small 7--10})
+il valore di ritorno e si termina il programma in caso di errore, stampadone
+il valore.
+
+Infine l'ultima possibilità, quella in cui si utilizza effettivamente
+\const{SO\_LINGER} per \textsl{indugiare} nella chiusura, è quella in cui sia
+\var{l\_onoff} che \var{l\_linger} hanno un valore diverso da zero. Se si
+esegue l'impostazione con questi valori sia \func{close} che \func{shutdown}
+si bloccano, nel frattempo viene eseguita la normale procedura di conclusione
+della connessione (quella di sez.~\ref{sec:TCP_conn_term}) ma entrambe le
+funzioni ritornano fintanto che non si sia concluso il procedimento di
+chiusura della connessione, o non sia passato un numero di
+secondi\footnote{questa è l'unità di misura indicata da POSIX ed adottata da
+  Linux, altri kernel possono usare unità di misura diverse, oppure usare il
+  campo \var{l\_linger} come valore logico (ignorandone il valore) per rendere
+  (quando diverso da zero) \func{close} e \func{shutdown} bloccanti fino al
+  completamento della trasmissione dei dati sul buffer.}  pari al valore
+specificato in \var{l\_linger}.
+
+
+
 \index{\texttt{SO\_LINGER} (costante)|)}