Aggiornate le date nelle note di copyright
[gapil.git] / sockctrl.tex
index a6eabcd8cbecd2a044d681b8967645505480269d..4bc3bc4d90e2ef92526840e4501814b8b0dc208e 100644 (file)
@@ -1,6 +1,6 @@
 %% sockctrl.tex
 %%
 %% sockctrl.tex
 %%
-%% Copyright (C) 2004 Simone Piccardi.  Permission is granted to
+%% Copyright (C) 2004-2005 Simone Piccardi.  Permission is granted to
 %% copy, distribute and/or modify this document under the terms of the GNU Free
 %% Documentation License, Version 1.1 or any later version published by the
 %% Free Software Foundation; with the Invariant Sections being "Prefazione",
 %% copy, distribute and/or modify this document under the terms of the GNU Free
 %% Documentation License, Version 1.1 or any later version published by the
 %% Free Software Foundation; with the Invariant Sections being "Prefazione",
@@ -34,6 +34,7 @@ porte o altre propriet
 \subsection{La struttura del \textit{resolver}}
 \label{sec:sock_resolver}
 
 \subsection{La struttura del \textit{resolver}}
 \label{sec:sock_resolver}
 
+\index{\textit{resolver}|(}
 La risoluzione dei nomi è associata tradizionalmente al servizio del
 \textit{Domain Name Service} che permette di identificare le macchine su
 internet invece che per numero IP attraverso il relativo \textsl{nome a
 La risoluzione dei nomi è associata tradizionalmente al servizio del
 \textit{Domain Name Service} che permette di identificare le macchine su
 internet invece che per numero IP attraverso il relativo \textsl{nome a
@@ -428,7 +429,7 @@ tab.~\ref{tab:DNS_address_class}.\footnote{esisteva in realt
     \const{C\_IN}   & indirizzi internet, in pratica i soli utilizzati oggi.\\
     \const{C\_HS}   & indirizzi \textit{Hesiod}, utilizzati solo al MIT, oggi
                       completamente estinti. \\
     \const{C\_IN}   & indirizzi internet, in pratica i soli utilizzati oggi.\\
     \const{C\_HS}   & indirizzi \textit{Hesiod}, utilizzati solo al MIT, oggi
                       completamente estinti. \\
-    \const{C\_CHAOS}& indizzi per la rete \textit{Chaosnet}, un'altra rete
+    \const{C\_CHAOS}& indirizzi per la rete \textit{Chaosnet}, un'altra rete
                       sperimentale nata al MIT. \\
     \const{C\_ANY}  & indica un indirizzo di classe qualunque.\\
     \hline
                       sperimentale nata al MIT. \\
     \const{C\_ANY}  & indica un indirizzo di classe qualunque.\\
     \hline
@@ -607,6 +608,7 @@ Restituisce una stringa corrispondente ad un errore di risoluzione.
 \noindent che, come  l'analoga \func{strerror}, restituisce una stringa con un
 messaggio di errore già formattato, corrispondente al codice passato come
 argomento (che si presume sia dato da \var{h\_errno}).
 \noindent che, come  l'analoga \func{strerror}, restituisce una stringa con un
 messaggio di errore già formattato, corrispondente al codice passato come
 argomento (che si presume sia dato da \var{h\_errno}).
+\index{\textit{resolver}|)}
 
 
 
 
 
 
@@ -614,11 +616,12 @@ argomento (che si presume sia dato da \var{h\_errno}).
 \subsection{La risoluzione dei nomi a dominio}
 \label{sec:sock_name_services}
 
 \subsection{La risoluzione dei nomi a dominio}
 \label{sec:sock_name_services}
 
-La principale funzionalità del \textit{resolver} resta quella di risolvere i
-nomi a dominio in indirizzi IP, per cui non ci dedicheremo oltre alle funzioni
-di richiesta generica ed esamineremo invece le funzioni a questo dedicate. La
-prima funzione è \funcd{gethostbyname} il cui scopo è ottenere l'indirizzo di
-una stazione noto il suo nome a dominio, il suo prototipo è:
+La principale funzionalità del \index{\textit{resolver}}\textit{resolver}
+resta quella di risolvere i nomi a dominio in indirizzi IP, per cui non ci
+dedicheremo oltre alle funzioni di richiesta generica ed esamineremo invece le
+funzioni a questo dedicate. La prima funzione è \funcd{gethostbyname} il cui
+scopo è ottenere l'indirizzo di una stazione noto il suo nome a dominio, il
+suo prototipo è:
 \begin{prototype}{netdb.h}
 {struct hostent *gethostbyname(const char *name)}
 
 \begin{prototype}{netdb.h}
 {struct hostent *gethostbyname(const char *name)}
 
@@ -678,10 +681,10 @@ Con l'uso di \func{gethostbyname} normalmente si ottengono solo gli indirizzi
 IPv4, se si vogliono ottenere degli indirizzi IPv6 occorrerà prima impostare
 l'opzione \const{RES\_USE\_INET6} nel campo \texttt{\_res.options} e poi
 chiamare \func{res\_init} (vedi sez.~\ref{sec:sock_resolver_functions}) per
 IPv4, se si vogliono ottenere degli indirizzi IPv6 occorrerà prima impostare
 l'opzione \const{RES\_USE\_INET6} nel campo \texttt{\_res.options} e poi
 chiamare \func{res\_init} (vedi sez.~\ref{sec:sock_resolver_functions}) per
-modificare le opzioni del resolver; dato che questo non è molto comodo è stata
-definita\footnote{questa è una estensione fornita dalle \acr{glibc},
-  disponibile anche in altri sistemi unix-like.} un'altra funzione,
-\funcd{gethostbyname2}, il cui prototipo è:
+modificare le opzioni del \index{\textit{resolver}}\textit{resolver}; dato che
+questo non è molto comodo è stata definita\footnote{questa è una estensione
+  fornita dalle \acr{glibc}, disponibile anche in altri sistemi unix-like.}
+un'altra funzione, \funcd{gethostbyname2}, il cui prototipo è:
 \begin{functions}
   \headdecl{netdb.h} 
   \headdecl{sys/socket.h}
 \begin{functions}
   \headdecl{netdb.h} 
   \headdecl{sys/socket.h}
@@ -705,20 +708,20 @@ suoi risultati.
 \begin{figure}[!htb]
   \footnotesize \centering
   \begin{minipage}[c]{15cm}
 \begin{figure}[!htb]
   \footnotesize \centering
   \begin{minipage}[c]{15cm}
-    \includecodesample{listati/myhost.c}
+    \includecodesample{listati/mygethost.c}
   \end{minipage}
   \normalsize
   \caption{Esempio di codice per la risoluzione di un indirizzo.}
   \end{minipage}
   \normalsize
   \caption{Esempio di codice per la risoluzione di un indirizzo.}
-  \label{fig:myhost_example}
+  \label{fig:mygethost_example}
 \end{figure}
 
 Vediamo allora un primo esempio dell'uso delle funzioni di risoluzione, in
 \end{figure}
 
 Vediamo allora un primo esempio dell'uso delle funzioni di risoluzione, in
-fig.~\ref{fig:myhost_example} è riportato un estratto del codice di un
-programma che esegue una semplice interrogazione al \textit{resolver} usando
-\func{gethostbyname} e poi ne stampa a video i risultati. Al solito il
-sorgente completo, che comprende il trattamento delle opzioni ed una funzione
-per stampare un messaggio di aiuto, è nel file \texttt{myhost.c} dei sorgenti
-allegati alla guida.
+fig.~\ref{fig:mygethost_example} è riportato un estratto del codice di un
+programma che esegue una semplice interrogazione al
+\index{\textit{resolver}}\textit{resolver} usando \func{gethostbyname} e poi
+ne stampa a video i risultati. Al solito il sorgente completo, che comprende
+il trattamento delle opzioni ed una funzione per stampare un messaggio di
+aiuto, è nel file \texttt{mygethost.c} dei sorgenti allegati alla guida.
 
 Il programma richiede un solo argomento che specifichi il nome da cercare,
 senza il quale (\texttt{\small 12--15}) esce con un errore. Dopo di che
 
 Il programma richiede un solo argomento che specifichi il nome da cercare,
 senza il quale (\texttt{\small 12--15}) esce con un errore. Dopo di che
@@ -1146,7 +1149,7 @@ aperto riporta la posizione di lettura alla prima voce del file, in questo
 modo si può far ricominciare da capo una lettura sequenziale. L'argomento
 \param{stayopen}, se diverso da zero, fa sì che il file resti aperto anche fra
 diverse chiamate a \func{getservbyname} e \func{getservbyaddr}.\footnote{di
 modo si può far ricominciare da capo una lettura sequenziale. L'argomento
 \param{stayopen}, se diverso da zero, fa sì che il file resti aperto anche fra
 diverse chiamate a \func{getservbyname} e \func{getservbyaddr}.\footnote{di
-  default dopo una chiamata a queste funzioni il file viene chiuso, cosicchè
+  default dopo una chiamata a queste funzioni il file viene chiuso, cosicché
   una successiva chiamata a \func{getservent} riparte dall'inizio.}  La terza
 funzione, \funcd{endservent}, provvede semplicemente a chiudere il file.
 
   una successiva chiamata a \func{getservent} riparte dall'inizio.}  La terza
 funzione, \funcd{endservent}, provvede semplicemente a chiudere il file.
 
@@ -1199,16 +1202,18 @@ forniscono una interfaccia sufficientemente generica.
 Inoltre in genere quando si ha a che fare con i socket non esiste soltanto il
 problema della risoluzione del nome che identifica la macchina, ma anche
 quello del servizio a cui ci si vuole rivolgere.  Per questo motivo con lo
 Inoltre in genere quando si ha a che fare con i socket non esiste soltanto il
 problema della risoluzione del nome che identifica la macchina, ma anche
 quello del servizio a cui ci si vuole rivolgere.  Per questo motivo con lo
-standard Posix 1003.1-2001 sono state indicate come deprecate le varie
+standard POSIX 1003.1-2001 sono state indicate come deprecate le varie
 funzioni \func{gethostbyaddr}, \func{gethostbyname}, \var{getipnodebyname} e
 \var{getipnodebyaddr} ed è stata introdotta una interfaccia completamente
 nuova.
 
 funzioni \func{gethostbyaddr}, \func{gethostbyname}, \var{getipnodebyname} e
 \var{getipnodebyaddr} ed è stata introdotta una interfaccia completamente
 nuova.
 
-La prima funzione di questa interfaccia è \funcd{getaddrinfo}, che combina le
+La prima funzione di questa interfaccia è \funcd{getaddrinfo},\footnote{la
+  funzione è definita, insieme a \func{getnameinfo} che vedremo più avanti,
+  nell'\href{http://www.ietf.org/rfc/rfc2553.txt} {RFC~2553}.} che combina le
 funzionalità delle precedenti \func{getipnodebyname}, \func{getipnodebyaddr},
 \func{getservbyname} e \func{getservbyport}, consentendo di ottenere
 contemporaneamente sia la risoluzione di un indirizzo simbolico che del nome
 funzionalità delle precedenti \func{getipnodebyname}, \func{getipnodebyaddr},
 \func{getservbyname} e \func{getservbyport}, consentendo di ottenere
 contemporaneamente sia la risoluzione di un indirizzo simbolico che del nome
-un servizio; il suo prototipo è:
+di un servizio; il suo prototipo è:
 \begin{functions}
   \headdecl{netdb.h} 
   \headdecl{sys/socket.h} 
 \begin{functions}
   \headdecl{netdb.h} 
   \headdecl{sys/socket.h} 
@@ -1230,16 +1235,16 @@ forma \textit{dotted-decimal} per IPv4 o in formato esadecimale per IPv6.  Si
 può anche specificare il nome di una rete invece che di una singola macchina.
 Il secondo argomento, \param{service}, specifica invece il nome del servizio
 che si intende risolvere. Per uno dei due argomenti si può anche usare il
 può anche specificare il nome di una rete invece che di una singola macchina.
 Il secondo argomento, \param{service}, specifica invece il nome del servizio
 che si intende risolvere. Per uno dei due argomenti si può anche usare il
-valore \const{NULL}, nel qual caso la risoluzione verrà effettuata utilizzando
-soltantoo sulla base del valore dell'altro.
+valore \const{NULL}, nel qual caso la risoluzione verrà effettuata soltanto
+sulla base del valore dell'altro.
 
 Il terzo argomento, \param{hints}, deve essere invece un puntatore ad una
 struttura \struct{addrinfo} usata per dare dei \textsl{suggerimenti} al
 procedimento di risoluzione riguardo al protocollo o del tipo di socket che si
 
 Il terzo argomento, \param{hints}, deve essere invece un puntatore ad una
 struttura \struct{addrinfo} usata per dare dei \textsl{suggerimenti} al
 procedimento di risoluzione riguardo al protocollo o del tipo di socket che si
-intenderà utilizzare; la funzione infatti permette di effettuare ricerche
-generiche sugli indirizzi, usando sia IPv4 che IPv6, e richiedere risoluzioni
-sui nomi dei servizi indipendentemente dal protocollo (ad esempio TCP o UDP)
-che questi possono utilizzare.
+intenderà utilizzare; \func{getaddrinfo} infatti permette di effettuare
+ricerche generiche sugli indirizzi, usando sia IPv4 che IPv6, e richiedere
+risoluzioni sui nomi dei servizi indipendentemente dal protocollo (ad esempio
+TCP o UDP) che questi possono utilizzare.
 
 \begin{figure}[!htb]
   \footnotesize \centering
 
 \begin{figure}[!htb]
   \footnotesize \centering
@@ -1257,7 +1262,7 @@ La struttura \struct{addrinfo}, la cui definizione\footnote{la definizione 
   per il campo \var{ai\_addrlen}, qui viene usata quanto previsto dallo
   standard POSIX, in cui viene utilizzato \type{socklen\_t}; i due tipi di
   dati sono comunque equivalenti.} è riportata in
   per il campo \var{ai\_addrlen}, qui viene usata quanto previsto dallo
   standard POSIX, in cui viene utilizzato \type{socklen\_t}; i due tipi di
   dati sono comunque equivalenti.} è riportata in
-fig.~\ref{fig:sock_addrinfo_struct} viene usata sia in ingresso, per passare
+fig.~\ref{fig:sock_addrinfo_struct}, viene usata sia in ingresso, per passare
 dei valori di controllo alla funzione, che in uscita, per ricevere i
 risultati. Il primo campo, \var{ai\_flags}, è una maschera binaria di bit che
 permettono di controllare le varie modalità di risoluzione degli indirizzi,
 dei valori di controllo alla funzione, che in uscita, per ricevere i
 risultati. Il primo campo, \var{ai\_flags}, è una maschera binaria di bit che
 permettono di controllare le varie modalità di risoluzione degli indirizzi,
@@ -1272,10 +1277,10 @@ Tutti i campi seguenti vengono usati soltanto in uscita; il campo
 \var{ai\_addrlen} indica la dimensione della struttura degli indirizzi
 ottenuta come risultato, il cui contenuto sarà memorizzato nella struttura
 \struct{sockaddr} posta all'indirizzo puntato dal campo \var{ai\_addr}. Il
 \var{ai\_addrlen} indica la dimensione della struttura degli indirizzi
 ottenuta come risultato, il cui contenuto sarà memorizzato nella struttura
 \struct{sockaddr} posta all'indirizzo puntato dal campo \var{ai\_addr}. Il
-campo \var{ai\_canonname} è il puntatore alla stringa contenente il nome
+campo \var{ai\_canonname} è un puntatore alla stringa contenente il nome
 canonico della macchina, ed infine, quando la funzione restituisce più di un
 canonico della macchina, ed infine, quando la funzione restituisce più di un
-risultato, \var{ai\_next} è il puntatore alla struttura \struct{addrinfo}
-successiva della lista.
+risultato, \var{ai\_next} è un puntatore alla successiva struttura
+\struct{addrinfo} della lista.
 
 Ovviamente non è necessario dare dei suggerimenti in ingresso, ed usando
 \const{NULL} come valore per l'argomento \param{hints} si possono compiere
 
 Ovviamente non è necessario dare dei suggerimenti in ingresso, ed usando
 \const{NULL} come valore per l'argomento \param{hints} si possono compiere
@@ -1288,10 +1293,10 @@ I due campi \var{ai\_family} e \var{ai\_socktype} prendono gli stessi valori
 degli analoghi argomenti della funzione \func{socket}; in particolare per
 \var{ai\_family} si possono usare i valori di tab.~\ref{tab:net_pf_names} ma
 sono presi in considerazione solo \const{PF\_INET} e \const{PF\_INET6}, mentre
 degli analoghi argomenti della funzione \func{socket}; in particolare per
 \var{ai\_family} si possono usare i valori di tab.~\ref{tab:net_pf_names} ma
 sono presi in considerazione solo \const{PF\_INET} e \const{PF\_INET6}, mentre
-se non si vuole specificare questo nessuna famiglia di indirizzi si può usare
-il valore \const{PF\_UNSPEC}.  Allo stesso modo per \var{ai\_socktype} si
-possono usare i valori illustrati sez.~\ref{sec:sock_type} per indicare per
-quale tipo di socket si vuole risolvere il servizio indicato, anche se i soli
+se non si vuole specificare nessuna famiglia di indirizzi si può usare il
+valore \const{PF\_UNSPEC}.  Allo stesso modo per \var{ai\_socktype} si possono
+usare i valori illustrati in sez.~\ref{sec:sock_type} per indicare per quale
+tipo di socket si vuole risolvere il servizio indicato, anche se i soli
 significativi sono \const{SOCK\_STREAM} e \const{SOCK\_DGRAM}; in questo caso,
 se non si vuole effettuare nessuna risoluzione specifica, si potrà usare un
 valore nullo.
 significativi sono \const{SOCK\_STREAM} e \const{SOCK\_DGRAM}; in questo caso,
 se non si vuole effettuare nessuna risoluzione specifica, si potrà usare un
 valore nullo.
@@ -1328,7 +1333,7 @@ bit della maschera.
                              \const{IN6ADDR\_ANY\_INIT} per IPv6), altrimenti
                              verrà usato l'indirizzo dell'interfaccia di
                              \textit{loopback}. Se invece non è impostato gli
                              \const{IN6ADDR\_ANY\_INIT} per IPv6), altrimenti
                              verrà usato l'indirizzo dell'interfaccia di
                              \textit{loopback}. Se invece non è impostato gli
-                             indirizzi verrano restituiti in formato adatto ad
+                             indirizzi verranno restituiti in formato adatto ad
                              una chiamata a \func{connect} o \func{sendto}.\\
     \const{AI\_CANONNAME}  & richiede la restituzione del nome canonico della
                              macchina, che verrà salvato in una stringa il cui
                              una chiamata a \func{connect} o \func{sendto}.\\
     \const{AI\_CANONNAME}  & richiede la restituzione del nome canonico della
                              macchina, che verrà salvato in una stringa il cui
@@ -1359,12 +1364,12 @@ bit della maschera.
 
 Come ultimo argomento di \func{getaddrinfo} deve essere passato un puntatore
 ad una variabile (di tipo puntatore ad una struttura \struct{addrinfo}) che
 
 Come ultimo argomento di \func{getaddrinfo} deve essere passato un puntatore
 ad una variabile (di tipo puntatore ad una struttura \struct{addrinfo}) che
-verrà utilizzata dalla funzione per restituire (come \textit{value result
+verrà utilizzata dalla funzione per riportare (come \textit{value result
   argument}) i propri risultati. La funzione infatti è rientrante, ed alloca
 autonomamente tutta la memoria necessaria in cui verranno riportati i
   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 restituisce in \param{res} il
-puntatore alla prima di una \textit{linked list} di strutture di tipo
-\struct{addrinfo} contenenti tutte le informazioni ottenute.
+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.
 
 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
 
 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
@@ -1396,7 +1401,8 @@ corrispondente 
                            altri tipi di socket. \\
     \const{EAI\_ADDRFAMILY}& la rete richiesta non ha nessun indirizzo di rete
                            per la famiglia di indirizzi specificata. \\
                            altri tipi di socket. \\
     \const{EAI\_ADDRFAMILY}& la rete richiesta non ha nessun indirizzo di rete
                            per la famiglia di indirizzi specificata. \\
-    \const{EAI\_NODATA}  & la . \\
+    \const{EAI\_NODATA}  & la macchina specificata esiste, ma non ha nessun
+                           indirizzo di rete definito. \\
     \const{EAI\_MEMORY}  & è stato impossibile allocare la memoria necessaria
                            alle operazioni. \\
     \const{EAI\_FAIL}    & il DNS ha restituito un errore di risoluzione  
     \const{EAI\_MEMORY}  & è stato impossibile allocare la memoria necessaria
                            alle operazioni. \\
     \const{EAI\_FAIL}    & il DNS ha restituito un errore di risoluzione  
@@ -1419,14 +1425,36 @@ corrispondente 
   \label{tab:addrinfo_error_code}
 \end{table}
 
   \label{tab:addrinfo_error_code}
 \end{table}
 
+Come per i codici di errore di \func{gethostbyname} anche in questo caso è
+fornita una apposita funzione, analoga di \func{strerror}, che consente di
+utilizzarli direttamente per stampare a video un messaggio esplicativo; la
+funzione è \func{gai\_strerror} ed il suo prototipo è:
+\begin{functions}
+  \headdecl{netdb.h} 
+
+  \funcdecl{const char *gai\_strerror(int errcode)}
+
+  Fornisce il messaggio corrispondente ad un errore di \func{getaddrinfo}.
 
 
-Dato che più di un indirizzo possono corrispondere ad un certo nome a dominio,
-e più di un servizio possono essere associati ad un certo nome (in genere su
-due protocolli diversi) è assolutamente normale ricevere come risposta una
-lista di più strutture \struct{addrinfo}, a meno di non avere usato una
-selezione specifica. Ad esempio se si richiede la risoluzione del servizio
-\textit{echo} si avrà come risposta la lista illustrata in
-fig.~\ref{fig:sock_addrinfo_list}.
+  \bodydesc{La funzione restituisce il puntatore alla stringa contenente il
+    messaggio di errore.}
+\end{functions}
+
+La funzione restituisce un puntatore alla stringa contenente il messaggio
+corrispondente dal codice di errore \param{errcode} ottenuto come valore di
+ritorno di \func{getaddrinfo}.  La stringa è allocata staticamente, ma essendo
+costante, ed accessibile in sola lettura, questo non comporta nessun problema
+di rientranza della funzione.
+
+Dato che ad un certo nome a dominio possono corrispondere più indirizzi IP
+(sia IPv4 che IPv6), e che un certo servizio può essere fornito su protocolli
+e tipi di socket diversi, in generale, a meno di non aver eseguito una
+selezione specifica attraverso l'uso di \param{hints}, si otterrà una diversa
+struttura \struct{addrinfo} per ciascuna possibilità.  Ad esempio se si
+richiede la risoluzione del servizio \textit{echo} per l'indirizzo
+\texttt{www.truelite.it}, e si imposta \const{AI\_CANONNAME} per avere anche
+la risoluzione del nome canonico, si avrà come risposta della funzione la
+lista illustrata in fig.~\ref{fig:sock_addrinfo_list}.
 
 \begin{figure}[!htb]
   \centering
 
 \begin{figure}[!htb]
   \centering
@@ -1436,11 +1464,102 @@ fig.~\ref{fig:sock_addrinfo_list}.
   \label{fig:sock_addrinfo_list}
 \end{figure}
 
   \label{fig:sock_addrinfo_list}
 \end{figure}
 
+Come primo esempio di uso di \func{getaddrinfo} vediamo un programma
+elementare di interrogazione del \index{\textit{resolver}}\textit{resolver}
+basato questa funzione, il cui corpo principale è riportato in
+fig.~\ref{fig:mygetaddr_example}. Il codice completo del programma, compresa
+la gestione delle opzioni in cui è gestita l'eventuale inizializzazione
+dell'argomento \var{hints} per restringere le ricerche su protocolli, tipi di
+socket o famiglie di indirizzi, è disponibile nel file \texttt{mygetaddr.c}
+dei sorgenti allegati alla guida.
+
+\begin{figure}[!htb]
+  \footnotesize \centering
+  \begin{minipage}[c]{15cm}
+    \includecodesample{listati/mygetaddr.c}
+  \end{minipage}
+  \normalsize
+  \caption{Esempio di codice per la risoluzione di un indirizzo.}
+  \label{fig:mygetaddr_example}
+\end{figure}
+
+Il corpo principale inizia controllando (\texttt{\small 1--5}) il numero di
+argomenti passati, che devono essere sempre due, e corrispondere
+rispettivamente all'indirizzo ed al nome del servizio da risolvere. A questo
+segue la chiamata (\texttt{\small 7}) alla funzione \func{getaddrinfo}, ed il
+successivo controllo (\texttt{\small 8--11}) del suo corretto funzionamento,
+senza il quale si esce immediatamente stampando il relativo codice di errore.
+
+Se la funzione ha restituito un valore nullo il programma prosegue
+inizializzando (\texttt{\small 12}) il puntatore \var{ptr} che sarà usato nel
+successivo ciclo (\texttt{\small 14--35}) di scansione della lista delle
+strutture \struct{addrinfo} restituite dalla funzione. Prima di eseguire
+questa scansione (\texttt{\small 12}) viene stampato il valore del nome
+canonico che è presente solo nella prima struttura.
+
+La scansione viene ripetuta (\texttt{\small 14}) fintanto che si ha un
+puntatore valido. La selezione principale è fatta sul campo \var{ai\_family},
+che stabilisce a quale famiglia di indirizzi fa riferimento la struttura in
+esame. Le possibilità sono due, un indirizzo IPv4 o IPv6, se nessuna delle due
+si verifica si provvede (\texttt{\small 27--30}) a stampare un messaggio di
+errore ed uscire.\footnote{questa eventualità non dovrebbe mai verificarsi,
+  almeno fintanto che la funzione \func{getaddrinfo} lavora correttamente.}
+
+Per ciascuno delle due possibili famiglie di indirizzi si estraggono le
+informazioni che poi verranno stampate alla fine del ciclo (\texttt{\small
+  31--34}). Il primo caso esaminato (\texttt{\small 15--21}) è quello degli
+indirizzi IPv4, nel qual caso prima se ne stampa l'indentificazione
+(\texttt{\small 16}) poi si provvede a ricavare la struttura degli indirizzi
+(\texttt{\small 17}) indirizzata dal campo \var{ai\_addr}, eseguendo un
+opportuno casting del puntatore per poter estrarre da questa la porta
+(\texttt{\small 18}) e poi l'indirizzo (\texttt{\small 19}) che verrà
+convertito con una chiamata ad \func{inet\_ntop}.
+
+La stessa operazione (\texttt{\small 21--27}) viene ripetuta per gli indirizzi
+IPv6, usando la rispettiva struttura degli indirizzi. Si noti anche come in
+entrambi i casi per la chiamata a \func{inet\_ntop} si sia dovuto passare il
+puntatore al campo contenente l'indirizzo IP nella struttura puntata dal campo
+\var{ai\_addr}.\footnote{il meccanismo è complesso a causa del fatto che al
+  contrario di IPv4, in cui l'indirizzo IP può essere espresso con un semplice
+  numero intero, in IPv6 questo deve essere necessariamente fornito come
+  struttura, e pertanto anche se nella struttura puntata da \var{ai\_addr}
+  sono presenti direttamente i valori finali, per l'uso con \func{inet\_ntop}
+  occorre comunque passare un puntatore agli stessi (ed il costrutto
+  \code{\&addr6->sin6\_addr} è corretto in quanto l'operatore \texttt{->} ha
+  on questo caso precedenza su \texttt{\&}).}
+
+Una volta estratte dalla struttura \struct{addrinfo} tutte le informazioni
+relative alla risoluzione richiesta e stampati i relativi valori, l'ultimo
+passo (\texttt{\small 34}) è di estrarre da \var{ai\_next} l'indirizzo della
+eventuale successiva struttura presente nella lista e ripetere il ciclo, fin
+tanto che, completata la scansione, questo avrà un valore nullo e si potrà
+terminare (\texttt{\small 36}) il programma.
+
+Si tenga presente che \func{getaddrinfo} non garantisce nessun particolare
+ordinamento della lista delle strutture \struct{addrinfo} restituite, anche se
+usualmente i vari indirizzi IP (se ne è presente più di uno) sono forniti
+nello stesso ordine in cui vengono inviati dal server DNS. In particolare
+nulla garantisce che vengano forniti prima i dati relativi ai servizi di un
+determinato protocollo o tipo di socket, se ne sono presenti di diversi.  Se
+allora utilizziamo il nostro programma potremo verificare il risultato:
+\begin{Verbatim}
+[piccardi@gont sources]$ ./mygetaddr -c  gapil.truelite.it echo
+Canonical name sources2.truelite.it
+IPv4 address:
+        Indirizzo 62.48.34.25
+        Protocollo 6
+        Porta 7
+IPv4 address:
+        Indirizzo 62.48.34.25
+        Protocollo 17
+        Porta 7
+\end{Verbatim}
+%$
 
 Una volta estratti i risultati dalla \textit{linked list} puntata da
 
 Una volta estratti i risultati dalla \textit{linked list} puntata da
-\param{res} si dovrà avere cura di disallocare opportunamente tutta la
-memoria, per questo viene fornita l'apposita funzione \funcd{freeaddrinfo}, il
-cui prototipo è:
+\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} 
 
 \begin{functions}
   \headdecl{netdb.h} 
 
@@ -1457,23 +1576,807 @@ strutture per liberare tutta la memoria allocata. Dato che la funzione non ha
 valori di ritorno deve essere posta molta cura nel passare un valore valido
 per \param{res}.
 
 valori di ritorno deve essere posta molta cura nel passare un valore valido
 per \param{res}.
 
+Si tenga presente infine che se si copiano i risultati da una delle strutture
+\struct{addrinfo} restituite nella lista indicizzata da \param{res}, occorre
+avere cura di eseguire una \index{\textit{deep~copy}}\textit{deep copy} in cui
+si copiano anche tutti i dati presenti agli indirizzi contenuti nella
+struttura \struct{addrinfo}, perché una volta disallocati i dati con
+\func{freeaddrinfo} questi non sarebbero più disponibili. 
+
+Anche la nuova intefaccia definita da POSIX prevede una nuova funzione per
+eseguire la risoluzione inversa e determinare nomi di servizi e di dominio
+dati i rispettivi valori numerici. La funzione che sostituisce le varie
+\func{gethostbyname}, \func{geipnodebyname} e \func{getservname} è
+\funcd{getnameinfo}, ed il suo prototipo è:
+\begin{functions}
+  \headdecl{sys/socket.h}
+  \headdecl{netdb.h}
+
+  \funcdecl{int getnameinfo(const struct sockaddr *sa, socklen\_t salen, char
+    *host, size\_t hostlen, char *serv, size\_t servlen, int flags)}
+
+  Risolve il contenuto di una struttura degli indirizzi in maniera
+  indipendente dal protocollo.
+
+  \bodydesc{La funzione restituisce 0 in caso di successo e un codice di
+    errore diverso da zero altrimenti.}
+\end{functions}
+
+La principale caratteristica di \func{getnameinfo} è che la funzione è in
+grado di eseguire una risoluzione inversa in maniera indipendente dal
+protocollo; il suo primo argomento \param{sa} infatti è il puntatore ad una
+struttura degli indirizzi generica, che può contenere sia indirizzi IPv4 che
+IPv6, la cui dimensione deve comunque essere specificata con l'argomento
+\param{salen}. 
+
+I risultati della funzione saranno restituiti nelle due stringhe puntate da
+\param{host} e \param{serv}, che dovranno essere state precedentemente
+allocate per una lunghezza massima che deve essere specificata con gli altri
+due argomenti \param{hostlen} e \param{servlen}. Si può, quando non si è
+interessati ad uno dei due, passare il valore \const{NULL} come argomento,
+così che la corrispondente informazione non verrà richiesta. Infine l'ultimo
+argomento \param{flags} è una maschera binaria i cui bit consentono di
+impostare le modalità con cui viene eseguita la ricerca, e deve essere
+specificato attraverso l'OR aritmetico dei valori illustrati in
+tab.~\ref{tab:getnameinfo_flags}.
+
+\begin{table}[!htb]
+  \centering
+  \footnotesize
+  \begin{tabular}[c]{|l|p{10cm}|}
+    \hline
+    \textbf{Costante} & \textbf{Significato} \\
+    \hline
+    \hline
+    \const{NI\_NOFQDN}     & richiede che venga restituita solo il nome della
+                             macchina all'interno del dominio al posto del
+                             nome completo (FQDN).\\
+    \const{NI\_NUMERICHOST}& richiede che venga restituita la forma numerica
+                             dell'indirizzo (questo succede sempre se il nome
+                             non può essere ottenuto).\\ 
+    \const{NI\_NAMEREQD}   & richiede la restituzione di un errore se il nome
+                             non può essere risolto.\\
+    \const{NI\_NUMERICSERV}& richiede che il servizio venga restituito in
+                             forma numerica (attraverso il numero di porta).\\
+    \const{NI\_DGRAM}      & richiede che venga restituito il nome del
+                             servizio su UDP invece che quello su TCP per quei
+                             pichi servizi (porte 512-214) che soni diversi
+                             nei due protocolli.\\
+    \hline
+  \end{tabular}
+  \caption{Costanti associate ai bit dell'argomento \param{flags} della  
+    funzione \func{getnameinfo}.} 
+  \label{tab:getnameinfo_flags}
+\end{table}
+
+La funzione ritorna zero in caso di successo, e scrive i propri risultati agli
+indirizzi indicati dagli argomenti \param{host} e \param{serv} come stringhe
+terminate dal carattere NUL, a meno che queste non debbano essere troncate
+qualora la loro dimensione ecceda quelle specificate dagli argomenti
+\param{hostlen} e \param{servlen}. Sono comunque definite le due costanti
+\const{NI\_MAXHOST} e \const{NI\_MAXSERV}\footnote{in Linux le due costanti
+  sono definite in \file{netdb.h} ed hanno rispettivamente il valore 1024 e
+  12.}  che possono essere utilizzate come limiti massimi.  In caso di errore
+viene restituito invece un codice che assume gli stessi valori illustrati in
+tab.~\ref{tab:addrinfo_error_code}.
+
+A questo punto possiamo fornire degli esempi di utilizzo della nuova
+interfaccia, adottandola per le precedenti implementazioni del client e del
+server per il servizio \textit{echo}; dato che l'uso delle funzioni appena
+illustrate (in particolare di \func{getaddrinfo}) è piuttosto complesso,
+essendo necessaria anche una impostazione diretta dei campi dell'argomento
+\param{hints}, provvederemo una interfaccia semplificata per i due casi visti
+finora, quello in cui si specifica nel client un indirizzo remoto per la
+connessione al server, e quello in cui si specifica nel server un indirizzo
+locale su cui porsi in ascolto.
+
+La prima funzione della nostra intefaccia semplificata è \func{sockconn} che
+permette di ottenere un socket, connesso all'indirizzo ed al servizio
+specificati. Il corpo della funzione è riportato in
+fig.~\ref{fig:sockconn_code}, il codice completo è nel file \file{SockUtil.c}
+dei sorgenti allegati alla guida, che contiene varie funzioni di utilità per
+l'uso dei socket.
+
+\begin{figure}[!htb]
+  \footnotesize \centering
+  \begin{minipage}[c]{15cm}
+    \includecodesample{listati/sockconn.c}
+  \end{minipage}
+  \normalsize
+  \caption{Il codice della funzione \func{sockconn}.}
+  \label{fig:sockconn_code}
+\end{figure}
+
+La funzione prende quattro argomenti, i primi due sono le stringhe che
+indicano il nome della macchina a cui collegarsi ed il relativo servizio su
+cui sarà effettuata la risoluzione; seguono il protocollo da usare (da
+specificare con il valore numerico di \file{/etc/protocols}) ed il tipo di
+socket (al solito specificato con i valori illustrati in
+sez.~\ref{sec:sock_type}).  La funzione ritorna il valore del file descriptor
+associato al socket (un numero positivo) in caso di successo, o -1 in caso di
+errore; per risolvere il problema di non poter passare indietro i valori di
+ritorno di \func{getaddrinfo} contenenti i relativi codici di
+errore\footnote{non si può avere nessuna certezza che detti valori siano
+  negativi, è questo è invece nessario per evitare ogni possibile ambiguità
+  nei confronti del valore di ritorno in caso di successo.} si sono stampati i
+messaggi d'errore direttamente nella funzione.
+
+Una volta definite le variabili necessarie (\texttt{\small 3--5}) la funzione
+prima (\texttt{\small 6}) azzera il contenuto della struttura \var{hint} e poi
+provvede (\texttt{\small 7--9}) ad inizializzarne i valori necessari per la
+chiamata (\texttt{\small 10}) a \func{getaddrinfo}. Di quest'ultima si
+controlla (\texttt{\small 12-16}) il codice di ritorno, in modo da stampare un
+avviso di errore, azzerare \var{errno} ed uscire in caso di errore.  Dato che
+ad una macchina possono corrispondere più indirizzi IP, e di tipo diverso (sia
+IPv4 che IPv6), mantre il servizio può essere in ascolto soltanto su uno solo
+di questi, si provvede a tentare la connessione per ciascun indirizzo
+restituito all'interno di un ciclo (\texttt{\small 18-40}) di scansione della
+lista restituita da \func{getaddrinfo}, ma prima (\texttt{\small 17}) si salva
+il valore del puntatore per poterlo riutilizzare alla fine per disallocare la
+lista.
+
+Il ciclo viene ripetuto (\texttt{\small 18}) fintanto che si hanno indirizzi
+validi, ed inizia (\texttt{\small 19}) con l'apertura del socket; se questa
+fallisce si controlla (\texttt{\small 20}) se sono disponibili altri
+indirizzi, nel qual caso si passa al successivo (\texttt{\small 21}) e si
+riprende (\texttt{\small 22}) il ciclo da capo; se non ve ne sono si stampa
+l'errore ritornando immediatamente (\texttt{\small 24-27}). Quando la
+creazione del socket ha avuto successo si procede (\texttt{\small 29})
+direttamente con la connessione, di nuovo in caso di fallimento viene ripetuto
+(\texttt{\small 30--38}) il controllo se vi sono o no altri indirizzi da
+provare nella stessa modalità fatta in precedenza, aggiungendovi però in
+entrambi i casi (\texttt{\small 32} e (\texttt{\small 36}) la chiusura del
+socket precedentemente aperto, che non è più utilizzabile.
+
+Se la connessione ha avuto successo invece si termina (\texttt{\small 39})
+direttamente il ciclo, e prima di ritornare (\texttt{\small 31}) il valore del
+file descriptor del socket si provvede (\texttt{\small 30}) a liberare le
+strutture \struct{addrinfo} allocate da \func{getaddrinfo} utilizzando il
+valore del relativo puntatore precedentemente (\texttt{\small 17}) salvato.
+Si noti come per la funzione sia del tutto irrilevante se la struttura
+ritornata contiene indirizzi IPv6 o IPv4, in quanto si fa uso direttamente dei
+dati relativi alle strutture degli indirizzi di \struct{addrinfo} che sono
+\textsl{opachi} rispetto all'uso della funzione \func{connect}.
+
+\begin{figure}[!htb]
+  \footnotesize \centering
+  \begin{minipage}[c]{15cm}
+    \includecodesample{listati/TCP_echo_fifth.c}
+  \end{minipage}
+  \normalsize
+  \caption{Il nuovo codice per la connessione del client \textit{echo}.}
+  \label{fig:TCP_echo_fifth}
+\end{figure}
+
+Per usare questa funzione possiamo allora modificare ulteriormente il nostro
+programma client per il servizio \textit{echo}; in questo caso rispetto al
+codice usato finora per collegarsi (vedi fig.~\ref{fig:TCP_echo_client_1})
+avremo una semplificazione per cui il corpo principale del nostro client
+diventerà quello illustrato in fig.~\ref{fig:TCP_echo_fifth}, in cui le
+chiamate a \func{socket}, \func{inet\_pton} e \func{connect} sono sostituite
+da una singola chiamata a \func{sockconn}. Inoltre il nuovo client (il cui
+codice completo è nel file \file{TCP\_echo\_fifth.c} dei sorgenti allegati)
+consente di utilizzare come argomento del programma un nome a dominio al posto
+dell'indirizzo numerico, e può utilizzare sia indirizzi IPv4 che IPv6.
+
+\begin{figure}[!htb]
+  \footnotesize \centering
+  \begin{minipage}[c]{15cm}
+    \includecodesample{listati/sockbind.c}
+  \end{minipage}
+  \normalsize
+  \caption{Il codice della funzione \func{sockbind}.}
+  \label{fig:sockbind_code}
+\end{figure}
+
+La seconda funzione di ausilio è \func{sockbind}, il cui corpo principale è
+riportato in fig.~\ref{fig:sockbind_code} (al solito il sorgente completo è
+nel file \file{sockbind.c} dei sorgenti allegati alla guida). Come si può
+notare la funzione è del tutto analoga alla precedente \func{sockconn}, e
+prende gli stessi argomenti, però invece di eseguire una connessione con
+\func{connect} si limita a chiamare \func{bind} per collegare il socket ad una
+porta.
+
+Dato che la funzione è pensata per essere utilizzata da un server ci si può
+chiedere a quale scopo mantenere l'argomento \param{host} quando l'indirizzo
+di questo è usualmente noto. Si ricordi però quanto detto in
+sez.~\ref{sec:TCP_func_bind}, relativamente al significato della scelta di un
+indirizzo specifico come argomento di \func{bind}, che consente di porre il
+server in ascolto su uno solo dei possibili diversi indirizzi presenti su di
+una macchina.  Se non si vuole che la funzione esegua \func{bind} su un
+indirizzo specifico, ma utilizzi l'indirizzo generico, occorrerà avere cura di
+passare un valore \const{NULL} come valore per l'argomento \var{host}; l'uso
+del valore \const{AI\_PASSIVE} serve ad ottenere il valore generico nella
+rispettiva struttura degli indirizzi.
+
+Come già detto la funzione è analoga a \func{sockconn} ed inizia azzerando ed
+inizializzando (\texttt{\small 6-11}) opportunamente la struttura \var{hint}
+con i valori ricevuti come argomenti, soltanto che in questo caso si è usata
+(\texttt{\small 8}) una impostazione specifica dei flag di \var{hint} usando
+\const{AI\_PASSIVE} per indicare che il socket sarà usato per una apertura
+passiva. Per il resto la chiamata (\texttt{\small 12-18}) a \func{getaddrinfo}
+e ed il ciclo principale (\texttt{\small 20--42}) sono identici, solo che si è
+sostituita (\texttt{\small 31}) la chiamata a \func{connect} con una chiamata
+a \func{bind}. Anche la conclusione (\texttt{\small 43--44}) della funzione è
+identica. 
+
+Si noti come anche in questo caso si siano inserite le stampe degli errori
+sullo standard error, nonostante la funzione possa essere invocata da un
+demone. Nel nostro caso questo non è un problema in quanto se la funzione non
+ha successo il programma deve uscire immediatamente prima di essere posto in
+background, e può quindi scrivere gli errori direttamente sullo standard
+error.
+
+\begin{figure}[!htb]
+  \footnotesize \centering
+  \begin{minipage}[c]{15cm}
+    \includecodesample{listati/TCP_echod_third.c}
+  \end{minipage}
+  \normalsize
+  \caption{Nuovo codice per l'apertura passiva del server \textit{echo}.}
+  \label{fig:TCP_echod_third}
+\end{figure}
+
+Con l'uso di questa funzione si può modificare anche il codice del nostro
+server \textit{echo}, che rispetto a quanto illustrato nella versione iniziale
+di fig.~\ref{fig:TCP_echo_server_first_code} viene modificato nella forma
+riportata in fig.~\ref{fig:TCP_echod_third}. In questo caso il socket su cui
+porsi in ascolto viene ottenuto (\texttt{\small 15--18}) da \func{sockbind}
+che si cura anche della eventuale risoluzione di un indirizzo specifico sul
+quale si voglia far ascoltare il server.
 
 
 
 \section{Le opzioni dei socket}
 
 
 
 \section{Le opzioni dei socket}
-\label{sec:TCP_sock_options}
+\label{sec:sock_options}
+
+Benché dal punto di vista del loro uso come canali di trasmissione di dati i
+socket siano trattati allo stesso modo dei file, ed acceduti tramite i file
+descriptor, la normale interfaccia usata per la gestione dei file non è
+sufficiente a poterne controllare tutte le caratteristiche, che variano tra
+l'altro a seconda del loro tipo (e della relativa forma di comunicazione
+sottostante). In questa sezione vedremo allora quali sono le funzioni dedicate
+alla gestione delle caratteristiche specifiche dei vari tipi di socket, le
+cosiddette \textit{socket options}.
+
+
+\subsection{Le funzioni \func{setsockopt} e \func{getsockopt}}
+\label{sec:sock_setsockopt}
+
+Le varie caratteristiche dei socket possono essere gestite attraverso l'uso di
+due funzioni generiche che permettono rispettivamente di impostarle e di
+recuperarne il valore corrente. La prima di queste due funzioni, quella usata
+per impostare le \textit{socket options}, è \funcd{setsockopt}, ed il suo
+prototipo è:
+\begin{functions}
+  \headdecl{sys/socket.h}
+  \headdecl{sys/types.h}
+
+  \funcdecl{int setsockopt(int sock, int level, int optname, const void
+    *optval, socklen\_t optlen)}
+  Imposta le opzioni di un socket.
+
+  \bodydesc{La funzione restituisce 0 in caso di successo e -1 in caso di
+    errore, nel qual caso \var{errno} assumerà i valori:
+  \begin{errlist}
+  \item[\errcode{EBADF}]  il file descriptor \param{sock} non è valido.
+  \item[\errcode{EFAULT}] l'indirizzo \param{optval} non è valido.
+  \item[\errcode{EINVAL}] il valore di \param{optlen} non è valido.
+  \item[\errcode{ENOPROTOOPT}] l'opzione scelta non esiste per il livello
+    indicato. 
+  \item[\errcode{ENOTSOCK}] il file descriptor \param{sock} non corrisponde ad
+    un socket.
+  \end{errlist}
+}
+\end{functions}
+
+
+Il primo argomento della funzione, \param{sock}, indica il socket su cui si
+intende operare; per indicare l'opzione da impostare si devono usare i due
+argomenti successivi, \param{level} e \param{optname}.  Come abbiamo visto in
+sez.~\ref{sec:net_protocols} i protocolli di rete sono strutturati su vari
+livelli, ed l'interfaccia dei socket può usarne più di uno. Si avranno allora
+funzionalità e caratteristiche diverse per ciascun protocollo usato da un
+socket, e quindi saranno anche diverse le opzioni che si potranno impostare
+per ciascun socket, a seconda del \textsl{livello} (trasporto, rete, ecc.) su
+cui si vuole andare ad operare.
+
+Il valore di \param{level} seleziona allora il protocollo su cui vuole
+intervenire, mentre \param{optname} permette di scegliere su quale delle
+opzioni che sono definite per quel protocollo si vuole operare. In sostanza la
+selezione di una specifica opzione viene fatta attraverso una coppia di valori
+\param{level} e \param{optname} e chiaramente la funzione avrà successo
+soltanto se il protocollo in questione prevede quella opzione ed è utilizzato
+dal socket.  Infine \param{level} prevede anche il valore speciale
+\const{SOL\_SOCKET} usato per le opzioni generiche che sono disponibili per
+qualunque tipo di socket.
+
+I valori usati per \param{level}, corrispondenti ad un dato protocollo usato
+da un socket, sono quelli corrispondenti al valore numerico che identifica il
+suddetto protocollo in \file{/etc/protocols}; dato che la leggibilità di un
+programma non trarrebbe certo beneficio dall'uso diretto dei valori numerici,
+più comunemente si indica il protocollo tramite le apposite costanti
+\texttt{SOL\_*} riportate in tab.~\ref{tab:sock_option_levels}, dove si sono
+riassunti i valori che possono essere usati per l'argomento
+\param{level}.\footnote{la notazione in questo caso è, purtroppo, abbastanza
+  confusa: infatti in Linux il valore si può impostare sia usando le costanti
+  \texttt{SOL\_*}, che le analoghe \texttt{IPPROTO\_*} (citate anche da
+  Stevens in \cite{UNP1}); entrambe hanno gli stessi valori che sono
+  equivalenti ai numeri di protocollo di \file{/etc/protocols}, con una
+  eccesione specifica, che è quella del protocollo ICMP, per la quale non
+  esista una costante, il che è comprensibile dato che il suo valore, 1, è
+  quello che viene assegnato a \const{SOL\_SOCKET}.}
+
+\begin{table}[!htb]
+  \centering
+  \footnotesize
+  \begin{tabular}[c]{|l|l|}
+    \hline
+    \textbf{Livello} & \textbf{Significato} \\
+    \hline
+    \hline
+    \const{SOL\_SOCKET}& opzioni generiche dei socket.\\
+    \const{SOL\_IP}    & opzioni specifiche per i socket che usano IPv4.\\
+    \const{SOL\_TCP}   & opzioni per i socket che usano TCP.\\
+    \const{SOL\_IPV6}  & opzioni specifiche per i socket che usano IPv6.\\
+    \const{SOL\_ICMPV6}& opzioni specifiche per i socket che usano ICMPv6.\\
+    \hline
+  \end{tabular}
+  \caption{Possibili valori dell'argomento \param{level} delle 
+    funzioni \func{setsockopt} e \func{getsockopt}.} 
+  \label{tab:sock_option_levels}
+\end{table}
+
+Il quarto argomento, \param{optval} è un puntatore ad una zona di memoria che
+contiene i dati che specificano il valore dell'opzione che si vuole passare al
+socket, mentre l'ultimo argomento \param{optlen},\footnote{questo argomento è
+  in realtà sempre di tipo \ctyp{int}, come era nelle \acr{libc4} e
+  \acr{libc5}; l'uso di \ctyp{socklen\_t} è stato introdotto da POSIX (valgono
+  le stesse considerazioni per l'uso di questo tipo di dato fatte in
+  sez.~\ref{sec:TCP_func_accept}) ed adottato dalle \acr{glibc}.} è la
+dimensione in byte dei dati presenti all'indirizzo indicato da \param{optval}.
+Dato che il tipo di dati varia a seconda dell'opzione scelta, occorrerà
+individuare qual'è quello che deve essere usato, ed utilizzare le opportune
+variabili.
+
+La gran parte delle opzioni utilizzano per \param{optval} un valore intero, se
+poi l'opzione esprime una condizione logica, il valore è sempre un intero, am
+si dovrà usare un valore non nullo per abilitarla ed un valore nullo per
+disabilitarla.  Se invece l'opzione non prevede di dover ricevere nessun tipo
+di valore si deve impostare \param{optval} a \const{NULL}. Un piccolo numero
+di opzioni però usano dei tipi di dati peculiari, è questo il motivo per cui
+\param{optval} è stato definito come puntatore generico.
+
+La seconda funzione usata per controllare le proprietà dei socket è
+\funcd{getsockopt}, che serve a leggere i valori delle opzioni dei socket ed a
+farsi restituire i dati relativi al loro funzionamento; il suo prototipo è:
+\begin{functions}
+  \headdecl{sys/socket.h}
+  \headdecl{sys/types.h}
+
+  \funcdecl{int getsockopt(int s, int level, int optname, void *optval,
+    socklen\_t *optlen)} Legge le opzioni di un socket.
+
+  \bodydesc{La funzione restituisce 0 in caso di successo e -1 in caso di
+    errore, nel qual caso \var{errno} assumerà i valori:
+  \begin{errlist}
+  \item[\errcode{EBADF}] il file descriptor \param{sock} non è valido.
+  \item[\errcode{EFAULT}] l'indirizzo \param{optval} o quello di
+    \param{optlen} non è valido.
+  \item[\errcode{ENOPROTOOPT}] l'opzione scelta non esiste per il livello
+    indicato. 
+  \item[\errcode{ENOTSOCK}] il file descriptor \param{sock} non corrisponde ad
+    un socket.
+  \end{errlist}
+}
+\end{functions}
+
+I primi tre argomenti sono identici ed hanno lo stesso significato di quelli
+di \func{setsockopt}, anche se non è detto che tutte le opzioni siano definite
+per entrambe le funzioni. In questo caso \param{optval} viene usato per
+ricevere le informazioni ed indica l'indirizzo a cui andranno scritti i dati
+letti dal socket, infine \param{optlen} diventa un puntatore ad una variabile
+che viene usata come \textit{value result argument} per indicare, prima della
+chiamata della funzione, la lunghezza del buffer allocato per \param{optval} e
+per ricevere indietro, dopo la chiamata della funzione, la dimensione
+effettiva dei dati scritti su di esso. Se la dimenzione del buffer allocato
+per \param{optval} non è sufficiente si avrà un errore.
+
+
+
+\subsection{Le opzioni generiche}
+\label{sec:sock_generic_options}
+
+Come accennato esiste un insieme generico di opzioni dei socket che possono
+applicarsi a qualunque tipo di socket,\footnote{una descrizione di queste
+  opzioni è generalmente disponibile nella settima sezione delle pagine di
+  manuale, nel caso specifico la si può consultare con \texttt{man 7 socket}.}
+indipendentemente da quale protocollo venga poi utilizzato. Se si vuole
+operare su queste opzioni generiche il livello da utilizzare è
+\const{SOL\_SOCKET}; si è riportato un elenco di queste opzioni in
+tab.~\ref{tab:sock_opt_socklevel}.
+
+
+\begin{table}[!htb]
+  \centering
+  \footnotesize
+  \begin{tabular}[c]{|l|c|c|c|l|l|}
+    \hline
+    \textbf{Opzione}&\texttt{get}&\texttt{set}&\textbf{flag}&\textbf{Tipo}&
+                    \textbf{Descrizione}\\
+    \hline
+    \hline
+    \const{SO\_KEEPALIVE}&$\bullet$&$\bullet$&$\bullet$&\texttt{int}& 
+                          controlla l'attività della connessione.\\
+    \const{SO\_OOBINLINE}&$\bullet$&$\bullet$&$\bullet$&\texttt{int}& 
+                          lascia in linea i dati \textit{out-of-band}.\\
+    \const{SO\_RCVLOWAT} &$\bullet$&$\bullet$&$\bullet$&\texttt{int}& 
+                          basso livello sul buffer di ricezione.\\
+    \const{SO\_SNDLOWAT} &$\bullet$&$\bullet$&         &\texttt{int}&
+                          basso livello sul buffer di trasmissione.\\
+    \const{SO\_RCVTIMEO} &$\bullet$&$\bullet$&         &\texttt{timeval}& 
+                          timeout in ricezione.\\
+    \const{SO\_SNDTIMEO} &$\bullet$&$\bullet$&         &\texttt{timeval}& 
+                          timeout in trasmissione.\\
+    \const{SO\_BSDCOMPAT}&$\bullet$&$\bullet$&$\bullet$&\texttt{int}& 
+                          abilita la compatibilità con BSD.\\
+    \const{SO\_PASSCRED} &$\bullet$&$\bullet$&$\bullet$&\texttt{int}& 
+                          abilita la ricezione di credenziali.\\
+    \const{SO\_PEERCRED} &$\bullet$&         &         &\texttt{ucred}& 
+                          restituisce le credenziali del processo remoto.\\
+    \const{SO\_BINDTODEVICE}&$\bullet$&$\bullet$&         &\texttt{char *}& 
+                          lega il socket ad un dispositivo.\\
+    \const{SO\_DEBUG}    &$\bullet$&$\bullet$&$\bullet$&\texttt{int}& 
+                          abilita il debugging sul socket.\\
+    \const{SO\_REUSEADDR}&$\bullet$&$\bullet$&$\bullet$&\texttt{int}& 
+                          consente il riutilizzo di un indirizzo locale.\\
+    \const{SO\_TYPE}     &$\bullet$&         &         &\texttt{int}& 
+                          restituisce il tipo di socket.\\
+    \const{SO\_ACCEPTCONN}&$\bullet$&        &         &\texttt{int}& 
+                          indica se il socket è in ascolto.\\
+    \const{SO\_DONTROUTE}&$\bullet$&$\bullet$&$\bullet$&\texttt{int}& 
+                          non invia attraverso un gateway.\\
+    \const{SO\_BROADCAST}&$\bullet$&$\bullet$&$\bullet$&\texttt{int}& 
+                          attiva o disattiva il \textit{broadcast}.\\
+    \const{SO\_SNDBUF}   &$\bullet$&$\bullet$&         &\texttt{int}& 
+                          imposta dimensione del buffer di trasmissione.\\
+    \const{SO\_RCVBUF}   &$\bullet$&$\bullet$&         &\texttt{int}& 
+                          imposta dimensione del buffer di ricezione.\\
+    \const{SO\_LINGER}   &$\bullet$&$\bullet$&         &\texttt{linger}&
+                          indugia nella chiusura con dati da spedire.\\
+    \const{SO\_PRIORITY} &$\bullet$&$\bullet$&         &\texttt{int}& 
+                          imposta la priorità del socket.\\
+    \const{SO\_ERROR}    &$\bullet$&         &         &\texttt{int}& 
+                          riceve e cancella gli errori pendenti.\\
+   \hline
+  \end{tabular}
+  \caption{Le opzioni disponibili al livello \const{SOL\_SOCKET}.} 
+  \label{tab:sock_opt_socklevel}
+\end{table}
+
+La tabella elenca le costanti che identificano le singole opzioni da usare
+come valore per \param{optname}; le due colonne seguenti indicano per quali
+delle due funzioni (\func{getsockopt} o \func{setsockopt}) l'opzione è
+disponibile, mentre la colonna successiva indica, quando di ha a che fare con
+un valore di \param{optval} intero, se l'opzione è da considerare un numero o
+un valore logico. Si è inoltre riportato sulla quinta colonna il tipo di dato
+usato per \param{optval} ed una breve descrizione del significato delle
+singole opzioni sulla sesta.
+
+
+Dato che le descrizioni di tab.~\ref{tab:sock_opt_socklevel} sono estremamente
+sommarie, vale la pena entrare in dettagli maggiori; questo ci consentirà
+anche di trattare i vari casi particolari, dato che nonostante queste opzioni
+siano indicate al livello generico, alcune di esse han senso solo per alcuni
+tipi di socket. L'elenco dettagliato del significato di ciascuna di esse è
+allora il seguente:
+\begin{basedescript}{\desclabelwidth{3cm}\desclabelstyle{\nextlinelabel}}
+\item[\const{SO\_KEEPALIVE}] una connessione può restare attiva se non viene
+  effettuato alcun traffico su di essa; 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. 
+
+  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}.
+
+  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
+    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}. 
+
+
+\item[\const{SO\_OOBINLINE}] se questa opzione viene abilitata i dati
+  \textit{out-of-band} vengono inviati direttamente nel flusso di dati del
+  socket (e sono quindi letti con una normale \func{read}) invece che restare
+  disponibili solo per l'accesso con l'uso del flag \const{MSG\_OOB} di
+  \func{recvmsg}. L'argomento è trattato in dettaglio in
+  sez.~\ref{sec:TCP_urgent_data}. L'opzione funziona soltanto con socket che
+  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
+  segnalando ad una \func{select} (vedi sez.~\ref{sec:TCP_sock_select}) che ci
+  sono dati in ingresso. L'opzione utilizza per \param{optval} un intero che
+  specifica il numero di byte, ma con Linux questo valore è sempre 1 e non può
+  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
+  \func{write} di ritornare o segnalando ad una \func{select} (vedi
+  sez.~\ref{sec:TCP_sock_select}) che è possibile eseguire una scrittura.
+  L'opzione utilizza per \param{optval} un intero che specifica il numero di
+  byte, come per la precedente \const{SO\_RCVLOWAT} con Linux questo valore è
+  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})
+  identica a quella usata con \func{select}. Con \func{getsockopt} si può
+  leggere il valore attuale, mentre con \func{setsockopt} si imposta il tempo
+  voluto, usando un valore nullo per \struct{timeval} il timeout viene
+  rimosso. 
+
+  Se l'opzione viene attivata tutte le volte che una delle funzioni di lettura
+  (\func{read}, \func{readv}, \func{recv}, \func{recvfrom} e \func{recvmsg})
+  si blocca in attesa di dati per un tempo maggiore di quello impostato, essa
+  ritornerà un valore -1 e la variabile \var{errno} sarà impostata con un
+  errore di \errcode{EAGAIN} e \errcode{EWOULDBLOCK}, così come sarebbe
+  avvenuto se si fosse aperto il socket in modalità non bloccante.\footnote{in
+    teoria, se il numero di byte presenti nel buffer di ricezione fosse
+    inferiore a quello specificato da \const{SO\_RCVLOWAT}, l'effetto potrebbe
+    essere semplicemente quello di provocare l'uscita delle funzioni di
+    lettura restituendo il numero di byte fino ad allora ricevuti; dato che
+    con Linux questo valore è sempre 1 questo caso non esiste.}
+
+  In genere questa opzione non è molto utilizzata se si ha a che fare con la
+  lettura dei dati, in quanto è sempre possibile usare una \func{select} che
+  consente di specificare un \textit{timeout}; l'uso di \func{select} non
+  consente però di impostare il timout per l'uso di \func{connect}, per avere
+  il quale si può ricorrere a questa opzione. 
+
+% verificare con un programma di test
+
+\item[\const{SO\_SNDTIMEO}] l'opzione permette di impostare un tempo massimo
+  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}
+  qualora queste restino bloccate per un tempo maggiore di quello specificato. 
+
+\item[\const{SO\_BSDCOMPAT}] questa opzione abilita la compatibilità con il
+  comportamento di BSD (in particolare ne riproduce i bug).  Attualmente è una
+  opzione usata solo per il protocollo UDP e ne è prevista la rimozione in
+  futuro.  L'opzione utilizza per \param{optval} un intero usato come valore
+  logico. 
+
+  Quando viene abilitata gli errori riportati da messaggi ICMP per un socket
+  UDP non vengono passati al programma in user space. Con le versioni 2.0.x
+  del kernel erano anche abilitate altre opzioni per i socket raw, che sono
+  state rimosse con il passaggio al 2.2; è consigliato correggere i programmi
+  piuttosto che usare questa funzione. 
+
+\item[\const{SO\_PASSCRED}] questa opzione abilita sui socket unix-domain la
+  ricezione dei messaggi di controllo di tipo \const{SCM\_CREDENTIALS}. Prende
+  come \param{optval} un intero usato come valore logico. 
+
+\item[\const{SO\_PEERCRED}] questa opzione restituisce le credenziali del
+  processo remoto connesso al socket; l'opzione è disponibile solo per socket
+  unix-domain e può essere usata solo con \func{getsockopt}.  Utilizza per
+  \param{optval} una apposita struttura \struct{ucred} (vedi
+  sez.~\ref{sec:unix_socket_xxx}). 
+
+\item[\const{SO\_BINDTODEVICE}] questa opzione permette di \textsl{legare} il
+  socket ad una particolare interfaccia interfaccia, in modo che esso possa
+  ricevere ed inviare pacchetti solo su quella. L'opzione richiede per
+  \param{optval} il puntatore ad una stringa contenente il nome
+  dell'interfaccia (ad esempio \texttt{eth0}); se si utilizza una stringa
+  nulla o un valore nullo per \param{optlen} si rimuove un precedente
+  collegamento. 
+
+  Il nome della interfaccia deve essere specificato con una stringa terminata
+  da uno zero e di lunghezza massima pari a \const{IFNAMSIZ}; l'opzione è
+  effettiva solo per alcuni tipi di socket, ed in particolare per quelli della
+  famiglia \const{AF\_INET}; non è invece supportata per i \textit{packet
+    socket} (vedi sez.~\ref{cha:advanced_socket_xxx}). 
+
+
+\item[\const{SO\_DEBUG}] questa opzione abilita il debugging delle operazioni
+  dei socket; l'opzione utilizza per \param{optval} un intero usato come
+  valore logico, e può essere utilizzata solo da un processo con i privilegi
+  di amministratore (in particolare con la \textit{capability}
+  \const{CAP\_NET\_ADMIN}).  L'opzione necessita inoltre dell'opportuno
+  supporto nel kernel;\footnote{deve cioè essere definita la macro di
+    preprocessore \texttt{SOCK\_DEBUGGING} nel file \file{include/net/sock.h}
+    dei sorgenti del kernel, questo è sempre vero nei kernel delle serie
+    superiori alla 2.3, per i kernel delle serie precedenti invece è
+    necessario aggiungere a mano detta definizione; è inoltre possibile
+    abilitare anche il tracciamento degli stati del TCP definendo la macro
+    \texttt{STATE\_TRACE} in \file{include/net/tcp.h}.}  quando viene
+  abilitata una serie di messaggi con le informazioni di debug vengono inviati
+  direttamente al sistema del kernel log.\footnote{si tenga presente che il
+    comportamento è diverso da quanto avviene con BSD, dove l'opzione opera
+    solo sui socket TCP, causando la scrittura di tutti i pacchetti inviati
+    sulla rete su un buffer circolare che viene letto da un apposito
+    programma, \cmd{trpt}.} 
+
+\item[\const{SO\_REUSEADDR}] questa opzione permette di eseguire la funzione
+  \func{bind} su indirizzi locali che siano già in uso; l'opzione utilizza per
+  \param{optval} un intero usato come valore logico.  Questa opzione modifica
+  il comportamento normale dell'interfaccia dei socket che fa fallire
+  l'esecuzione della funzione \func{bind} con un errore di
+  \errcode{EADDRINUSE} quando l'indirizzo locale\footnote{più propriamente il
+    controllo viene eseguito sulla porta.} è già in uso da parte di un altro
+  socket. 
+
+  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}. 
+
+  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
+  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
+    indirizzi IP e le porte degli estremi della nuova connessione, ma anche i
+    numeri di sequenza dei pacchetti, e questo è estremamente improbabile.}
+  che 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}. 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 risulti libera. Infine si tenga presente che con il protocollo TCP non
+  è mai possibile far partire server che eseguano \func{bind} sullo stesso
+  indirizzo e la stessa porta, cioè ottenere quello che viene chiamato un
+  \textit{completely duplicate binding}.
+
+  Il terzo impiego è simile al precedente e prevede l'uso di \func{bind}
+  all'interno dello stesso programma per associare indirizzi diversi a socket
+  diversi. Vale in questo caso quanto detto in precedenza, l'unica differenza
+  è che in questo caso le diverse chiamate a  \func{bind} sono eseguite
+  all'interno dello stesso programma.
+
+
+\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
+  identifica (ad esempio \const{SOCK\_STREAM}). 
+
+\item[\const{SO\_ACCEPTCONN}] questa opzione permette di rilevare se il socket
+  su cui opera è stato posto in modalità di ricezione di eventuali connessioni
+  con una chiamata a \func{listen}. L'opzione può essere usata soltanto con
+  \func{getsockopt} e utilizza per \param{optval} un intero in cui viene
+  restituito 1 se il socket è in ascolto e 0 altrimenti. 
+
+\item[\const{SO\_DONTROUTE}] questa opzione forza l'invio diretto dei
+  pacchetti del socket, saltando ogni processo relativo all'uso della tabella
+  di routing del kernel. Prende come \param{optval} un intero usato come
+  valore logico. 
+
+\item[\const{SO\_BROADCAST}]
+
+
+\item[\const{SO\_SNDBUF}]
+
+
+\item[\const{SO\_RCVBUF}]  
+
+
+\item[\const{SO\_LINGER}]  
+\item[\const{SO\_PRIORITY}]
+
+\item[\const{SO\_ERROR}] 
+
+\end{basedescript}
+
 
 
-Finora abbiamo trattato i socket nel loro comportamento più comune, è però
-possibile attivare alcune modalità diverse di funzionamento degli stessi
 
 
-Dato che la maggior parte delle opzioni dei socket sono relative ai socket
-TCP, ed hanno poi significato analogo quando usate con altri socket, abbiamo
-preferito trattare l'argomento in generale in questa sezione piuttosto che nel
-capitolo dedicato alla trattazione generica dei socket.
 
 \section{Altre funzioni di controllo}
 
 \section{Altre funzioni di controllo}
-\label{sec:TCP_sock_ctrl}
+\label{sec:sock_ctrl_func}
+
+Benché la maggior parte delle caratteristiche dei socket sia gestita
+attraverso le due funzioni \func{setsockopt} e \func{getsockopt}, alcune
+funzionalità possono essere impostate attraverso quelle che sono le funzioni
+classiche per il controllo delle proprietà dei file, cioè \func{fcntl} e
+\func{ioctl}. 
+
+
+\subsection{L'uso di \func{fcntl} per i socket}
+\label{sec:sock_fcntl}
+
+Abbiamo già trattato l'uso di \func{fcntl} in sez.~\ref{sec:file_fcntl}, dove
+però ne abbiamo descritto le funzionalità nell'ambito della sua applicazione a
+file descriptor associati a file normali; tratteremo qui invece il suo uso
+specifico quando la si impiega su file descriptor associati a dei socket. 
+
+
+\subsection{L'uso di \func{ioctl} per i socket}
+\label{sec:sock_ioctl}
+
+Come per \func{fcntl} abbiamo trattato l'uso di \func{ioctl} in
+sez.~\ref{sec:file_ioctl}, dove ne abbiamo descritto le funzionalità
+nell'ambito dell'applicazione su file normali; tratteremo qui il suo uso
+specifico quando la si impiega su file descriptor associati a dei socket. 
+
+
+\subsection{L'uso di \func{sysctl} per le proprietà della rete}
+\label{sec:sock_sysctl}
 
 
+Come ultimo argomento di questa sezione tratteremo l'uso della funzione
+\func{sysctl} (che è stata introdotta nelle sue funzionalità generiche in
+sez.~\ref{sec:sys_sysctl}) per quanto riguarda le sue capacità di effettuare
+impostazioni relative a proprietà generali dei socket (di tutti quelli di un
+certo tipo o di tutti quelli che usano un certo protocollo) rispetto alle
+funzioni viste finora che consentono di controllare quelle di un singolo
+socket.