Un po' di materiale sulle opzioni dei socket Ipv4
[gapil.git] / sockctrl.tex
index 7e8a5b611baff469dd1c6aaf389b0ed783d03603..87dca619d0fa1875bae7456e23ff12a493c834eb 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
@@ -2285,87 +2272,154 @@ tab.~\ref{tab:sock_opt_socklevel} sul significato delle varie opzioni:
 \end{basedescript}
 
 
-\subsection{Luso delle principali opzioni dei socket}
+\subsection{L'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}, è
+necessariamente sintentica, alcune di queste però possono essere utilizzate
+per controllare delle funzionalità che hanno una notevole rilevanza nella
+programmazione dei socket.  Per questo motivo faremo in questa sezione un
+approfondimento sul significato delle opzioni generiche più importanti.
+
+
+\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:
 il primo è quello in cui la macchina remota è caduta ed è stata riavviata, per
 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
-tal caso il socket viene chiuso dopo aver impostato un errore
-\errcode{ECONNRESET}.
+  ricordi che un normale riavvio non ha questo effetto, in quanto in tal caso
+  si passa per la chiusura del processo, e questo, come illustrato in
+  sez.~\ref{sec:file_close}, comporta la chiusura del socket col'invio di un
+  segmento FIN all'altro capo della connessione, che verrà regolarmente
+  chiusa.} 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.
-
-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
-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
-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}.
+  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
+anche quando non si sta facendo traffico su di essa.  Viene usata
+principalmente sui server per evitare di mantenere impegnate le risorse che
+verrbbero dedicate a trattare delle connessioni che in realtà sono già
+terminate (quelle che vengono anche chiamate connessioni
+\textsl{semi-aperte}); in tutti quei casi cioè in cui il server si trova in
+attesa di dati in ingresso su una connessione che non arriveranno mai perché o
+il client sull'altro capo non è più attivo o non è più in grado di comunicare
+con il server via rete.
+
+\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}
+
+Abilitandola dopo un certo tempo le connessioni effettivamente terminate
+verrano comunque chiuse per cui, utilizzando ad esempio una \func{select}, se
+be potrà rilevare la conclusione e ricevere il relativo errore. Si tenga
+presente però che non può avere la certezza assoluta che un errore di
+\errcode{ETIMEDOUT} ottenuto dopo aver abilitato questa opzione corrisponda
+necessariamente ad una reale conclusione della connessione, il problema
+potrebbe anche 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} (anche se questa non è una una condizione molto
+probabile).
+
+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 volte 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,
+attivando il relativo comportamento.
 \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 e la stessa porta, che verrebbero a contendersi i pacchetti
+aventi quella destinazione.
+
+Esistono però situazioni ed esigenze particolari in cui non si vuole che
+questo comportamento di salvaguardia accada, ed allora si può fare ricorso a
+questa opzione.  La questione è comunque abbastanza complessa in quanto, come
+sottolinea Stevens in \cite{UNP1}, si distinguono ben quattro casi diversi in
+cui è prevista la possibilità di un utilizzo di questa opzione, il che la
+rende una delle più difficili da capire.
+
+Il primo caso, che è anche il più comune, 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 figli 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
@@ -2379,14 +2433,71 @@ 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 alla versione precedente. 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 nella nuova funzione
+(\texttt{\small 1}) un nuovo argomento intero, \param{reuse}, che conterrà il
+valore logico da usare nella successiva chiamata (\texttt{\small 14}) a
+\func{setsockopt}. Si è poi aggiunta una 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 +2514,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,
@@ -2441,23 +2552,27 @@ opzione sia specificata per tutti i socket per i quali si vuole eseguire il
 esiste, ma il comportamento di \const{SO\_REUSEADDR} è analogo, sarà cioè
 possibile effettuare un \textit{completely duplicate binding} ed ottenere il
 successo di \func{bind} su un socket legato allo stesso indirizzo e porta solo
-se il primo programma che ha eseguito \func{bind} su di essi ha impostato
+se il programma che ha eseguito per primo \func{bind} su di essi ha impostato
 questa opzione.\footnote{Questa restrizione permette di evitare il cosiddetto
   \textit{port stealing}, in cui un programma, usando \const{SO\_REUSEADDR},
   può collegarsi ad una porta già in uso e ricevere i pacchetti destinati ad
   un altro programma; con questa caratteristica ciò è possibile soltanto se il
   primo programma a consentirlo, avendo usato fin dall'inizio
-  \const{SO\_REUSEADDR}.}
+  \const{SO\_REUSEADDR}.}  
+
 \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 +2585,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 non 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)|)}
 
 
@@ -2560,11 +2724,51 @@ opzioni in tab.~\ref{tab:sock_opt_iplevel}.
   \label{tab:sock_opt_iplevel}
 \end{table}
 
-
 Le descrizioni di tab.~\ref{tab:sock_opt_iplevel} sono estremamente succinte,
 una maggiore quantità di dettagli su queste opzioni è fornito nel seguente
 elenco:
 \begin{basedescript}{\desclabelwidth{2.5cm}\desclabelstyle{\nextlinelabel}}
+
+
+\item[\const{IP\_OPTIONS}] l'opzione permette di impostare o leggere le
+  opzioni del protocollo IP (si veda sez.~\ref{sec:IP_options}). L'opzione
+  prende come valore dell'argomento \param{optval} un puntatore ad un buffer
+  dove sono mantenute le opzioni, mentre \param{optlen} indica la dimensione
+  di quest'ultimo. Quando la si usa con \func{setsockopt} 
+
+\item[\const{IP\_PKTINFO}]
+
+\item[\const{IP\_RECVTOS}]
+
+\item[\const{IP\_RECVTTL}]
+
+\item[\const{IP\_RECVOPTS}]
+
+\item[\const{IP\_RETOPTS}]
+
+
+\item[\const{IP\_TOS}]
+
+
+\item[\const{IP\_TTL}]
+
+
+\item[\const{IP\_HDRINCL}]
+
+
+\item[\const{IP\_RECVERR}]
+
+\item[\const{IP\_MTU\_DISCOVER}]
+
+\item[\const{IP\_MTU}]
+
+\item[\const{IP\_ROUTER\_ALERT}]
+
+\item[\const{IP\_MULTICAST\_TTL}]
+
+
+
+
 \item[\const{IP\_MULTICAST\_LOOP}] L'opzione consente di decidere se i dati
   che si inviano su un socket usato con il multicast vengano ricevuti anche
   sulla stessa macchina da cui li si stanno inviando.  Prende per
@@ -2576,6 +2780,13 @@ elenco:
   disponibili l'uso di questa opzione permette di disabilitare questo tipo di
   traffico. 
 
+\item[\const{IP\_ADD\_MEMBERSHIP}]
+
+\item[\const{IP\_DROP\_MEMBERSHIP}]
+
+\item[\const{IP\_MULTICAST\_IF}]
+
+
 \end{basedescript}