Aggiornate le date nelle note di copyright
[gapil.git] / sockctrl.tex
index 3adaa2b80042e71265b8be02150e4d9f95c782a1..4bc3bc4d90e2ef92526840e4501814b8b0dc208e 100644 (file)
@@ -1,6 +1,6 @@
 %% 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",
@@ -24,16 +24,17 @@ comportamento.
 Negli esempi dei capitoli precedenti abbiamo sempre identificato le singole
 macchine attraverso indirizzi numerici, sfruttando al più le funzioni di
 conversione elementare illustrate in sez.~\ref{sec:sock_addr_func} che
-permettono di passare da un indirizzo espresso in forma dotted decimal ad un
-numero. Vedremo in questa sezione le funzioni utilizzate per poter utilizzare
-dei nomi simbolici al posto dei valori numerici, e viceversa quelle che
-permettono di ottenere i nomi simbolici associati ad indirizzi, porte o altre
-proprietà del sistema.
+permettono di passare da un indirizzo espresso in forma \textit{dotted
+  decimal} ad un numero. Vedremo in questa sezione le funzioni utilizzate per
+poter utilizzare dei nomi simbolici al posto dei valori numerici, e viceversa
+quelle che permettono di ottenere i nomi simbolici associati ad indirizzi,
+porte o altre proprietà del sistema.
 
 
 \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
@@ -64,17 +65,17 @@ con le librerie del C, detto appunto \textit{resolver}.
 Lo schema di funzionamento del \textit{resolver} è illustrato in
 fig.~\ref{fig:sock_resolver_schema}; in sostanza i programmi hanno a
 disposizione un insieme di funzioni di libreria con cui chiamano il
-\textit{resolver}, indicate con le freccie nere. Ricevuta la richiesta è
+\textit{resolver}, indicate con le frecce nere. Ricevuta la richiesta è
 quest'ultimo che, sulla base della sua configurazione, esegue le operazioni
 necessarie a fornire la risposta, che possono essere la lettura delle
 informazioni mantenute nei relativi dei file statici presenti sulla macchina,
 una interrogazione ad un DNS (che a sua volta, per il funzionamento del
-protocollo può interrogarene altri) o la richiesta ad altri server per i quali
+protocollo, può interrogarne altri) o la richiesta ad altri server per i quali
 sia fornito il supporto, come LDAP.\footnote{la sigla LDAP fa riferimento ad
   un protocollo, il \textit{Lightweight Directory Access Protocol}, che
   prevede un meccanismo per la gestione di \textsl{elenchi} di informazioni
   via rete; il contenuto di un elenco può essere assolutamente generico, e
-  questo permette il manenimento dei più vari tipi di informazioni su una
+  questo permette il mantenimento dei più vari tipi di informazioni su una
   infrastruttura di questo tipo.}
 
 La configurazione del \textit{resolver} attiene più alla amministrazione di
@@ -107,18 +108,18 @@ NIS,\footnote{il \textit{Network Information Service} 
   da LDAP.} o come quelli dei protocolli e dei servizi che sono mantenuti nei
 file statici \file{/etc/protocols} e \file{/etc/services}.  Molte di queste
 informazioni non si trovano su un DNS, ma in una rete locale può essere molto
-utile centralizzare il mentenimento di alcune di esse su opportuni server.
+utile centralizzare il mantenimento di alcune di esse su opportuni server.
 Inoltre l'uso di diversi supporti possibili per le stesse informazioni (ad
 esempio il nome delle macchine può essere mantenuto sia tramite
 \file{/etc/hosts}, che con il DNS, che con NIS) comporta il problema
 dell'ordine in cui questi vengono interrogati.\footnote{con le implementazioni
   classiche i vari supporti erano introdotti modificando direttamente le
-  funzioni di liberia, prevedendo un ordine di interrogazione predefinito e
+  funzioni di libreria, prevedendo un ordine di interrogazione predefinito e
   non modificabile (a meno di una ricompilazione delle librerie stesse).}
 
 Per risolvere questa serie di problemi la risoluzione dei nomi a dominio
-eseguira dal \textit{resolver} è stata inclusa all'interno di un meccanismo
-generico per la risoluzione di corripondenze fra nomi ed informazioni ad essi
+eseguirà dal \textit{resolver} è stata inclusa all'interno di un meccanismo
+generico per la risoluzione di corrispondenze fra nomi ed informazioni ad essi
 associate chiamato \textit{Name Service Switch}\footnote{il sistema è stato
   introdotto la prima volta nelle librerie standard di Solaris, le \acr{glibc}
   hanno ripreso lo stesso schema, si tenga presente che questo sistema non
@@ -202,7 +203,7 @@ da esse utilizzato e cio
 benché in teoria sia solo uno dei possibili supporti su cui mantenere le
 informazioni, in pratica costituisce il meccanismo principale con cui vengono
 risolti i nomi a dominio.  Per questo motivo esistono una serie di funzioni di
-libreria che servono specificamente ad esseguire delle interrogazioni verso un
+libreria che servono specificamente ad eseguire delle interrogazioni verso un
 server DNS, funzioni che poi vengono utilizzate per realizzare le funzioni
 generiche di libreria usate anche dal sistema del \textit{resolver}.
 
@@ -238,7 +239,7 @@ viene utilizzata soltanto una classe di indirizzi; invece le corrispondenze
 fra un nome a dominio ed un indirizzo IP sono solo uno fra i vari tipi di
 informazione che un server DNS fornisce normalmente.
 
-L'esistenza di vari tipi di informazioni è un'altro dei motivi per cui il
+L'esistenza di vari tipi di informazioni è un altro dei motivi per cui il
 \textit{resolver} prevede, rispetto a quelle relative alla semplice
 risoluzione dei nomi, un insieme di funzioni specifiche dedicate
 all'interrogazione di un server DNS; la prima di queste funzioni è
@@ -302,7 +303,7 @@ comportamento del \textit{resolver}.
                               del dominio di default ai nomi singoli (che non
                               contengono cioè un ``\texttt{.}'').\\
     \const{RES\_STAYOPEN}   & usato con \const{RES\_USEVC} per mantenere
-                              aperte le connesioni TCP fra interrogazioni
+                              aperte le connessioni TCP fra interrogazioni
                               diverse. \\
     \const{RES\_DNSRCH}     & se attivo \func{res\_search} esegue le ricerche
                               di nomi di macchine nel dominio corrente o nei
@@ -334,7 +335,7 @@ prenderanno le nuove impostazioni. Le costanti che definiscono i vari bit di
 questo campo, ed il relativo significato sono illustrate in
 tab.~\ref{tab:resolver_option}; trattandosi di una maschera binaria un valore
 deve essere espresso con un opportuno OR aritmetico di dette costanti; ad
-esempio il valore di default delle opzioni, epsresso dalla costante
+esempio il valore di default delle opzioni, espresso dalla costante
 \const{RES\_DEFAULT}, è definito come:
 \includecodesnip{listati/resolv_option_def.c}
 
@@ -350,7 +351,7 @@ significa bloccare l'uso del DNS. Infine con \texttt{RES\_TIMEOUT} si
 soprassiede il valore del campo \var{retrans},\footnote{preimpostato al valore
   della omonima costante \const{RES\_TIMEOUT} di \file{resolv.h}.} che è il
 valore preso come base (in numero di secondi) per definire la scadenza di una
-richiesta, ciascun tentativo di richiesta fallito viene ripetuto raddoppianto
+richiesta, ciascun tentativo di richiesta fallito viene ripetuto raddoppiando
 il tempo di scadenza per il numero massimo di volte stabilito da
 \texttt{RES\_RETRY}.
 
@@ -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\_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
@@ -439,7 +440,7 @@ tab.~\ref{tab:DNS_address_class}.\footnote{esisteva in realt
 \end{table}
 
 Come accennato le tipologie di dati che sono mantenibili su un server DNS sono
-diverse, ed a ciascuna di essa corriponde un diverso tipo di \textit{resource
+diverse, ed a ciascuna di essa corrisponde un diverso tipo di \textit{resource
   record}. L'elenco delle costanti\footnote{ripreso dai file di dichiarazione
   \file{arpa/nameser.h} e \file{arpa/nameser\_compat.h}.} che definiscono i
 valori che si possono usare per l'argomento \param{type} per specificare il
@@ -448,7 +449,7 @@ tab.~\ref{tab:DNS_record_type}; le costanti (tolto il \texttt{T\_} iniziale)
 hanno gli stessi nomi usati per identificare i record nei file di zona di
 BIND,\footnote{BIND, acronimo di \textit{Berkley Internet Name Domain}, è una
   implementazione di un server DNS, ed, essendo utilizzata nella stragrande
-  maggioranza dei casi, fa da rifererimento; i dati relativi ad un certo
+  maggioranza dei casi, fa da riferimento; i dati relativi ad un certo
   dominio (cioè i suoi \textit{resource record} vengono mantenuti in quelli
   che sono usualmente chiamati \textsl{file di zona}, e in essi ciascun tipo
   di dominio è identificato da un nome che è appunto identico a quello delle
@@ -468,7 +469,7 @@ e che normalmente sono anche usati come nomi per indicare i record.
     \const{T\_MD}    & destinazione per la posta elettronica.\\
     \const{T\_MF}    & redistributore per la posta elettronica.\\
     \const{T\_CNAME} & nome canonico.\\
-    \const{T\_SOA}   & inzio di una zona di autorità.\\
+    \const{T\_SOA}   & inizio di una zona di autorità.\\
     \const{T\_MB}    & nome a dominio di una casella di posta.\\
     \const{T\_MG}    & nome di un membro di un gruppo di posta.\\
     \const{T\_MR}    & nome di un cambiamento di nome per la posta.\\
@@ -489,7 +490,7 @@ e che normalmente sono anche usati come nomi per indicare i record.
     \const{T\_SIG}   & firma digitale di sicurezza.\\
     \const{T\_KEY}   & chiave per firma.\\
     \const{T\_PX}    & corrispondenza per la posta X.400.\\
-    \const{T\_GPOS}  & posizione grografica.\\
+    \const{T\_GPOS}  & posizione geografica.\\
     \const{T\_AAAA}  & indirizzo IPv6.\\
     \const{T\_LOC}   & informazione di collocazione.\\
     \const{T\_NXT}   & dominio successivo.\\
@@ -522,13 +523,13 @@ significato di tutti i \textit{resource record}, ma solo di quelli usati dalle
 funzioni del \textit{resolver}. Questi sono sostanzialmente i seguenti (per
 indicarli si è usata la notazione dei file di zona di BIND):
 \begin{basedescript}{\desclabelwidth{1.2cm}\desclabelstyle{\nextlinelabel}}
-\item[\texttt{A}] viene usato per indicare la corripondenza fra un nome a
+\item[\texttt{A}] viene usato per indicare la corrispondenza fra un nome a
   dominio ed un indirizzo IPv4; ad esempio la corrispondenza fra
   \texttt{dodds.truelite.it} e l'indirizzo IP \texttt{62.48.34.25}.
 \item[\texttt{AAAA}] viene usato per indicare la corrispondenza fra un nome a
   dominio ed un indirizzo IPv6; è chiamato in questo modo dato che la
   dimensione di un indirizzo IPv6 è quattro volte quella di un indirizzo IPv4.
-\item[\texttt{PTR}] per fornire la corripondenza inversa fra un indirizzo IP
+\item[\texttt{PTR}] per fornire la corrispondenza inversa fra un indirizzo IP
   ed un nome a dominio ad esso associato si utilizza questo tipo di record (il
   cui nome sta per \textit{pointer}).
 \item[\texttt{CNAME}] qualora si abbiamo più nomi che corrispondono allo
@@ -602,23 +603,25 @@ funzione 
 \headdecl{netdb.h}
 \funcdecl{const char *hstrerror(int err)}
 
-Restituisce una stringa corripondente ad un errore di risoluzione.
+Restituisce una stringa corrispondente ad un errore di risoluzione.
 \end{functions}
-\noindent che, come  l'analoga \func{strerror}, restituise una stringa con un
+\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}|)}
 
 
 
 
 \subsection{La risoluzione dei nomi a dominio}
-\label{sec:sock_gethostbyname}
+\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)}
 
@@ -639,7 +642,8 @@ definizione 
   \begin{minipage}[c]{15cm}
     \includestruct{listati/hostent.h}
   \end{minipage}
-  \caption{La struttura \structd{hostent}.}
+  \caption{La struttura \structd{hostent} per la risoluzione dei nomi a
+    dominio e degli indirizzi IP.}
   \label{fig:sock_hostent_struct}
 \end{figure}
 
@@ -677,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
-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}
@@ -704,24 +708,24 @@ suoi risultati.
 \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.}
-  \label{fig:myhost_example}
+  \label{fig:mygethost_example}
 \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, he 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
-(\texttt{\small 16}) si limita a chiamare \func{gethostbyname}, ricendo il
+(\texttt{\small 16}) si limita a chiamare \func{gethostbyname}, ricevendo il
 risultato nel puntatore \var{data}. Questo (\texttt{\small 17--20}) viene
 controllato per rilevare eventuali errori, nel qual caso il programma esce
 dopo aver stampato un messaggio con \func{herror}. 
@@ -816,7 +820,7 @@ Gli ultimi due argomenti vengono utilizzati per avere indietro i risultati
 come \index{\textit{value~result~argument}}\textit{value result argument}, si
 deve specificare l'indirizzo della variabile su cui la funzione dovrà salvare
 il codice di errore con \param{h\_errnop} e quello su cui dovrà salvare il
-puntatatore che si userà per accedere i dati con \param{result}.
+puntatore che si userà per accedere i dati con \param{result}.
 
 In caso di successo entrambe le funzioni restituiscono un valore nullo,
 altrimenti restituiscono un codice di errore negativo e all'indirizzo puntato
@@ -832,9 +836,9 @@ con un buffer di dimensione maggiore.
 Una delle caratteristiche delle interrogazioni al servizio DNS è che queste
 sono normalmente eseguite con il protocollo UDP, ci sono casi in cui si
 preferisce che vengano usate connessioni permanenti con il protocollo TCP. Per
-ottenere\footnote{si potrebbero impostare direttamente le opzioni di
+ottenere questo\footnote{si potrebbero impostare direttamente le opzioni di
   \var{\_\_res.options}, ma queste funzioni permettono di semplificare la
-  procedura.} questo sono previste delle funzioni apposite; la prima è
+  procedura.} sono previste delle funzioni apposite; la prima è
 \funcd{sethostent}, il cui prototipo è:
 \begin{prototype}{netdb.h}
 {void sethostent(int stayopen)}
@@ -867,8 +871,7 @@ usare la funzione \funcd{gethostbyaddr}, il cui prototipo 
 \begin{functions}
   \headdecl{netdb.h} 
   \headdecl{sys/socket.h} 
-  \funcdecl{struct hostent *gethostbyaddr(const char *addr, int len, int
-    type)}
+  \funcdecl{struct hostent *gethostbyaddr(const char *addr, int len, int type)}
 
   Richiede la risoluzione inversa di un indirizzo IP.
        
@@ -877,50 +880,1503 @@ usare la funzione \funcd{gethostbyaddr}, il cui prototipo 
 \end{functions}
 
 In questo caso l'argomento \param{addr} dovrà essere il puntatore ad una
-appropriata struttura contentente il valore dell'indirizzo IP (o IPv6) che si
-vuole risolvere. L'uso del tipo \type{char *} per questo argomento ha è
-storico, il dato dovrà essere fornito in una struttura
-\struct{in\_addr}\footnote{si ricordi che, come illustrato in
-  fig.~\ref{fig:sock_sa_ipv4_struct}, questo in realtà corrisponde ad un
-  numero intero, da esprimere comunque in \textit{network order}, non
-  altrettanto avviene però per \var{in6\_addr}, pertanto è sempre opportuno
-  inizializzare questi indirizzi con \func{inet\_pton} (vedi
-  sez.~\ref{sec:sock_conv_func_gen}).}  per un indirizzo IPv4 ed una struttura
-\struct{in6\_addr} per un indirizzo IPv6, mentre in \param{len} se ne dovrà
-specificare la dimensione, infine l'argomento \param{type} indica il tipo di
-indirizzo e dovrà essere o \const{AF\_INET} o \const{AF\_INET6}.
-
-
-La funzione restituisce, in caso si successo, un puntatore ad una struttura
-\struct{hostent}, solo che la ricerca è fatta richiedendo al DNS un record di
-tipo \texttt{PTR}. In caso di errore al solito viene usata la variabile
-\var{h\_errno} per restituire un opportuno codice. In questo caso il valore
-dei vari campi \var{h\_addr\_list} viene inizializzato al valore passa
-
-
-\subsection{Altre funzioni di gestione dei nomi}
-\label{sec:sock_name_services}
+appropriata struttura contenente il valore dell'indirizzo IP (o IPv6) che si
+vuole risolvere. L'uso del tipo \type{char *} per questo argomento è storico,
+il dato dovrà essere fornito in una struttura \struct{in\_addr}\footnote{si
+  ricordi che, come illustrato in fig.~\ref{fig:sock_sa_ipv4_struct}, questo
+  in realtà corrisponde ad un numero intero, da esprimere comunque in
+  \textit{network order}, non altrettanto avviene però per \var{in6\_addr},
+  pertanto è sempre opportuno inizializzare questi indirizzi con
+  \func{inet\_pton} (vedi sez.~\ref{sec:sock_conv_func_gen}).}  per un
+indirizzo IPv4 ed una struttura \struct{in6\_addr} per un indirizzo IPv6,
+mentre in \param{len} se ne dovrà specificare la dimensione (rispettivamente 4
+o 16), infine l'argomento \param{type} indica il tipo di indirizzo e dovrà
+essere o \const{AF\_INET} o \const{AF\_INET6}.
+
+La funzione restituisce, in caso di successo, un puntatore ad una struttura
+\struct{hostent}, solo che in questo caso la ricerca viene eseguita
+richiedendo al DNS un record di tipo \texttt{PTR} corrispondente all'indirizzo
+specificato. In caso di errore al solito viene usata la variabile
+\var{h\_errno} per restituire un opportuno codice. In questo caso l'unico
+campo del risultato che interessa è \var{h\_name} che conterrà il nome a
+dominio, la funziona comunque inizializza anche il primo campo della lista
+\var{h\_addr\_list} col valore dell'indirizzo passato come argomento.
+
+Per risolvere il problema dell'uso da parte delle due funzioni
+\func{gethostbyname} e \func{gethostbyaddr} di memoria statica che può essere
+sovrascritta fra due chiamate successive, e per avere sempre la possibilità di
+indicare esplicitamente il tipo di indirizzi voluto (cosa che non è possibile
+con \func{gethostbyname}), vennero introdotte due nuove funzioni di
+risoluzione,\footnote{le funzioni sono presenti nelle \acr{glibc} versione
+  2.1.96, ma essendo considerate deprecate (vedi
+  sez.~\ref{sec:sock_advanced_name_services}) sono state rimosse nelle
+  versioni successive.} \funcd{getipnodebyname} e \funcd{getipnodebyaddr}, i
+cui prototipi sono:
+\begin{functions}
+  \headdecl{netdb.h} 
+  \headdecl{sys/types.h} 
+  \headdecl{sys/socket.h} 
+
+  \funcdecl{struct hostent *getipnodebyname(const char *name, int af, int
+    flags, int *error\_num)} 
+
+  \funcdecl{struct hostent *getipnodebyaddr(const void *addr, size\_t len,
+    int af, int *error\_num)}
+
+  Richiedono rispettivamente la risoluzione e la risoluzione inversa di un
+  indirizzo IP.
+       
+  \bodydesc{Entrambe le funzioni restituiscono l'indirizzo ad una struttura
+    \struct{hostent} in caso di successo ed \const{NULL} in caso di errore.}
+\end{functions}
+
+Entrambe le funzioni supportano esplicitamente la scelta di una famiglia di
+indirizzi con l'argomento \param{af} (che può assumere i valori
+\const{AF\_INET} o \const{AF\_INET6}), e restituiscono un codice di errore
+(con valori identici a quelli precedentemente illustrati in
+tab.~\ref{tab:h_errno_values}) nella variabile puntata da \param{error\_num}.
+La funzione \func{getipnodebyaddr} richiede poi che si specifichi l'indirizzo
+come per \func{gethostbyaddr} passando anche la lunghezza dello stesso
+nell'argomento \param{len}.
+
+La funzione \func{getipnodebyname} prende come primo argomento il nome da
+risolvere, inoltre prevede un apposito argomento \param{flags}, da usare come
+maschera binaria, che permette di specificarne il comportamento nella
+risoluzione dei diversi tipi di indirizzi (IPv4 e IPv6); ciascun bit
+dell'argomento esprime una diversa opzione, e queste possono essere specificate
+con un OR aritmetico delle costanti riportate in
+tab.~\ref{tab:sock_getipnodebyname_flags}.
+
+\begin{table}[!htb]
+  \centering
+  \footnotesize
+  \begin{tabular}[c]{|l|p{10cm}|}
+    \hline
+    \textbf{Costante} & \textbf{Significato} \\
+    \hline
+    \hline
+    \const{AI\_V4MAPPED}  & usato con \const{AF\_INET6} per richiedere una
+                            ricerca su un indirizzo IPv4 invece che IPv6; gli
+                            eventuali risultati saranno rimappati su indirizzi 
+                            IPv6.\\
+    \const{AI\_ALL}       & usato con \const{AI\_V4MAPPED}; richiede sia
+                            indirizzi IPv4 che IPv6, e gli indirizzi IPv4
+                            saranno rimappati in IPv6.\\
+    \const{AI\_ADDRCONFIG}& richiede che una richiesta IPv4 o IPv6 venga
+                            eseguita solo se almeno una interfaccia del
+                            sistema è associata ad un indirizzo di tale tipo.\\
+    \const{AI\_DEFAULT}   & il valore di default, è equivalente alla
+                            combinazione di \const{AI\_ADDRCONFIG} e di
+                            \const{AI\_V4MAPPED)}.\\  
+    \hline
+  \end{tabular}
+  \caption{Valori possibili per i bit dell'argomento \param{flags} della
+    funzione \func{getipnodebyname}.}
+  \label{tab:sock_getipnodebyname_flags}
+\end{table}
+
+Entrambe le funzioni restituiscono un puntatore ad una struttura \var{hostent}
+che contiene i risultati della ricerca, che viene allocata dinamicamente
+insieme a tutto lo spazio necessario a contenere i dati in essa referenziati;
+per questo motivo queste funzioni non soffrono dei problemi dovuti all'uso di
+una sezione statica di memoria presenti con le precedenti \func{gethostbyname}
+e \func{gethostbyaddr}.  L'uso di una allocazione dinamica però comporta anche
+la necessità di deallocare esplicitamente la memoria occupata dai risultati
+una volta che questi non siano più necessari; a tale scopo viene fornita la
+funzione \funcd{freehostent}, il cui prototipo è:
+\begin{functions}
+  \headdecl{netdb.h} 
+  \headdecl{sys/types.h} 
+  \headdecl{sys/socket.h} 
+
+  \funcdecl{void freehostent(struct hostent *ip)} 
+
+  Disalloca una struttura \var{hostent}.
+       
+  \bodydesc{La funzione non ritorna nulla.}
+\end{functions}
+
+La funzione permette di disallocare una struttura \var{hostent}
+precedentemente allocata in una chiamata di \func{getipnodebyname} o
+\func{getipnodebyaddr}, e prende come argomento l'indirizzo restituito da una
+di queste funzioni.
+
+Infine per concludere la nostra panoramica sulle funzioni di risoluzione dei
+nomi dobbiamo citare le funzioni che permettono di interrogare gli altri
+servizi di risoluzione dei nomi illustrati in sez.~\ref{sec:sock_resolver}; in
+generale infatti ci sono una serie di funzioni nella forma
+\texttt{getXXXbyname} e \texttt{getXXXbyaddr} per ciascuna delle informazioni
+di rete mantenute dal \textit{Name Service Switch} che permettono
+rispettivamente di trovare una corrispondenza cercando per nome o per numero.
+
+L'elenco di queste funzioni è riportato nelle colonne finali di
+tab.~\ref{tab:name_resolution_functions}, dove le si sono suddivise rispetto
+al tipo di informazione che forniscono (riportato in prima colonna). Nella
+tabella si è anche riportato il file su cui vengono ordinariamente mantenute
+queste informazioni, che però può essere sostituito da un qualunque supporto
+interno al \textit{Name Service Switch} (anche se usualmente questo avviene
+solo per la risoluzione degli indirizzi). Ciascuna funzione fa riferimento ad
+una sua apposita struttura che contiene i relativi dati, riportata in terza
+colonna.
+
+\begin{table}[!htb]
+  \centering
+  \footnotesize
+  \begin{tabular}[c]{|l|l|l|l|l|}
+    \hline
+    \textbf{Informazione}&\textbf{File}&\textbf{Struttura}&
+    \multicolumn{2}{|c|}{\textbf{Funzioni}}\\
+    \hline
+    \hline
+    indirizzo&\file{/etc/hosts}&\struct{hostent}&\func{gethostbyname}&
+             \func{gethostbyaddr}\\ 
+    servizio &\file{/etc/services}&\struct{servent}&\func{getservbyname}&
+             \func{getservbyaddr}\\ 
+    rete     &\file{/etc/networks}&\struct{netent}&\func{getnetbyname}&
+             \func{getnetbyaddr}\\ 
+    protocollo&\file{/etc/protocols}&\struct{protoent}&\func{getprotobyname}&
+              \func{getprotobyaddr}\\ 
+    \hline
+  \end{tabular}
+  \caption{Funzioni di risoluzione dei nomi per i vari servizi del
+    \textit{Name Service Switch}.}
+  \label{tab:name_resolution_functions}
+\end{table}
+
+Delle funzioni di tab.~\ref{tab:name_resolution_functions} abbiamo trattato
+finora soltanto quelle relative alla risoluzione dei nomi, dato che sono le
+più usate, e prevedono praticamente da sempre la necessità di rivolgersi ad
+una entità esterna; per le altre invece, estensioni fornite dal NSS a parte,
+si fa sempre riferimento ai dati mantenuti nei rispettivi file. 
+
+Dopo la risoluzione dei nomi a dominio una delle ricerche più comuni è quella
+sui nomi dei servizi noti (cioè \texttt{http}, \texttt{smtp}, ecc.) da
+associare alle rispettive porte, le due funzioni da utilizzare per questo sono
+\funcd{getservbyname} e \funcd{getservbyaddr}, che permettono rispettivamente
+di ottenere il numero di porta associato ad un servizio dato il nome e
+viceversa; i loro prototipi sono:
+\begin{functions}
+  \headdecl{netdb.h} 
+  \funcdecl{struct servent *getservbyname(const char *name, const char *proto)}
+  \funcdecl{struct servent *getservbyport(int port, const char *proto)} 
+
+  Risolvono il nome di un servizio nel rispettivo numero di porta e viceversa.
+       
+  \bodydesc{Ritornano il puntatore ad una struttura \struct{servent} con i
+    risultati in caso di successo, o \const{NULL} in caso di errore.}
+\end{functions}
+
+Entrambe le funzioni prendono come ultimo argomento una stringa \param{proto}
+che indica il protocollo per il quale si intende effettuare la
+ricerca,\footnote{le informazioni mantenute in \file{/etc/services} infatti
+  sono relative sia alle porte usate su UDP che su TCP, occorre quindi
+  specificare a quale dei due protocolli si fa riferimento.} che nel caso si
+IP può avere come valori possibili solo \texttt{udp} o
+\texttt{tcp};\footnote{in teoria si potrebbe avere un qualunque protocollo fra
+  quelli citati in \file{/etc/protocols}, posto che lo stesso supporti il
+  concetto di \textsl{porta}, in pratica questi due sono gli unici presenti.}
+se si specifica un puntatore nullo la ricerca sarà eseguita su un protocollo
+qualsiasi.
+
+Il primo argomento è il nome del servizio per \func{getservbyname},
+specificato tramite la stringa \param{name}, mentre \func{getservbyport}
+richiede il numero di porta in \param{port}. Entrambe le funzioni eseguono una
+ricerca sul file \file{/etc/services}\footnote{il \textit{Name Service Switch}
+  astrae il concetto a qualunque supporto su cui si possano mantenere i
+  suddetti dati. } ed estraggono i dati dalla prima riga che corrisponde agli
+argomenti specificati; se la risoluzione ha successo viene restituito un
+puntatore ad una apposita struttura \struct{servent} contenente tutti i
+risultati), altrimenti viene restituito un puntatore nullo.  Si tenga presente
+che anche in questo caso i dati vengono mantenuti in una area di memoria
+statica e che quindi la funzione non è rientrante.
+
+\begin{figure}[!htb]
+  \footnotesize \centering
+  \begin{minipage}[c]{15cm}
+    \includestruct{listati/servent.h}
+  \end{minipage}
+  \caption{La struttura \structd{servent} per la risoluzione dei nomi dei
+    servizi e dei numeri di porta.}
+  \label{fig:sock_servent_struct}
+\end{figure}
+
+La definizione della struttura \struct{servent} è riportata in
+fig.~\ref{fig:sock_servent_struct}, il primo campo, \var{s\_name} contiene
+sempre il nome canonico del servizio, mentre \var{s\_aliases} è un puntatore
+ad un vettore di stringhe contenenti gli eventuali nomi alternativi
+utilizzabili per identificare lo stesso servizio. Infine \var{s\_port}
+contiene il numero di porta e \var{s\_proto} il nome del protocollo.
+
+Come riportato in tab.~\ref{tab:name_resolution_functions} ci sono analoghe
+funzioni per la risoluzione del nome dei protocolli e delle reti; non staremo
+a descriverle nei dettagli, in quanto il loro uso è molto limitato, esse
+comunque hanno una struttura del tutto analoga alle precedenti, e tutti i
+dettagli relativi al loro funzionamento possono essere trovati nelle
+rispettive pagine di manuale.
+
+Oltre alle funzioni di ricerca esistono delle ulteriori funzioni che prevedono
+una lettura sequenziale delle informazioni mantenute nel \textit{Name Service
+  Switch} (in sostanza permettono di leggere i file contenenti le informazioni
+riga per riga), che sono analoghe a quelle elencate in
+tab.~\ref{tab:sys_passwd_func} per le informazioni relative ai dati degli
+utenti e dei gruppi.  Nel caso specifico dei servizi avremo allora le tre
+funzioni \funcd{setservent}, \funcd{getservent} e \funcd{endservent} i cui
+prototipi sono:
+\begin{functions}
+  \headdecl{netdb.h} 
+  \funcdecl{void setservent(int stayopen)} 
+  Apre il file \file{/etc/services} e si posiziona al suo inizio.
+
+  \funcdecl{struct servent *getservent(void)}
+  Legge la voce successiva nel file \file{/etc/services}.      
+
+  \funcdecl{void endservent(void)} 
+  Chiude il file \file{/etc/services}.
+
+  \bodydesc{Le due funzioni \func{setservent} e \func{endservent} non
+    restituiscono nulla, \func{getservent} restituisce il puntatore ad una
+    struttura \struct{servent} in caso di successo e \const{NULL} in caso di
+    errore o fine del file.}
+\end{functions}
+
+La prima funzione, \func{getservent}, legge una singola voce a partire dalla
+posizione corrente in \file{/etc/services}, pertanto si può eseguire una
+lettura sequenziale dello stesso invocandola più volte. Se il file non è
+aperto provvede automaticamente ad aprirlo, nel qual caso leggerà la prima
+voce. La seconda funzione, \func{setservent}, permette di aprire il file
+\file{/etc/services} per una successiva lettura, ma se il file è già stato
+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
+  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.
+
+Queste tre funzioni per la lettura sequenziale di nuovo sono presenti per
+ciascuno dei vari tipi di informazione relative alle reti di
+tab.~\ref{tab:name_resolution_functions}; questo significa che esistono
+altrettante funzioni nella forma \texttt{setXXXent}, \texttt{getXXXent} e
+\texttt{endXXXent}, analoghe alle precedenti per la risoluzione dei servizi,
+che abbiamo riportato in tab.~\ref{tab:name_sequential_read}.  Essendo, a
+parte il tipo di informazione che viene trattato, sostanzialmente identiche
+nel funzionamento e di scarso utilizzo, non staremo a trattarle una per una,
+rimandando alle rispettive pagine di manuale.
+
+\begin{table}[!htb]
+  \centering
+  \footnotesize
+  \begin{tabular}[c]{|l|l|l|l|}
+    \hline
+    \textbf{Informazione}&\multicolumn{3}{|c|}{\textbf{Funzioni}}\\
+    \hline
+    \hline
+    indirizzo&\func{sethostent}&\func{gethostent}&\func{endhostent} \\
+    servizio &cd te\func{setservent}&\func{getservent}&\func{endservent}\\ 
+    rete     &\func{setnetent}&\func{getnetent}&\func{endnetent}\\ 
+    protocollo&\func{setprotoent}&\func{getprotoent}&\func{endprotoent}\\ 
+    \hline
+  \end{tabular}
+  \caption{Funzioni lettura sequenziale dei dati del \textit{Name Service
+      Switch}.} 
+  \label{tab:name_sequential_read}
+\end{table}
+
+
+
+
+
+\subsection{Le funzioni avanzate per la risoluzione dei nomi}
+\label{sec:sock_advanced_name_services}
 
 Quelle illustrate nella sezione precedente sono le funzioni classiche per la
-risoluzione di nomi ed indirizzi IP, ma abbiamo già visto in 
+risoluzione di nomi ed indirizzi IP, ma abbiamo già visto come esse soffrano
+di vari inconvenienti come il fatto che usano informazioni statiche, e non
+prevedono la possibilità di avere diverse classi di indirizzi. Anche se sono
+state create delle estensioni o metodi diversi che permettono di risolvere
+alcuni di questi inconvenienti,\footnote{rimane ad esempio il problema
+  generico che si deve sapere in anticipo quale tipo di indirizzi IP (IPv4 o
+  IPv6) corrispondono ad un certo nome a dominio.}  comunque esse non
+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
+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.
+
+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
+di un servizio; il suo prototipo è:
+\begin{functions}
+  \headdecl{netdb.h} 
+  \headdecl{sys/socket.h} 
+  \headdecl{netdb.h} 
+
+  \funcdecl{int getaddrinfo(const char *node, const char *service, const
+    struct addrinfo *hints, struct addrinfo **res)}
+
+  Esegue una risoluzione di un nome a dominio e di un nome di servizio.
+
+  \bodydesc{La funzione restituisce 0 in caso di successo o un codice di
+    errore diverso da zero in caso di fallimento.}
+\end{functions}
+
+La funzione prende come primo argomento il nome della macchina che si vuole
+risolvere, specificato tramite la stringa \param{node}. Questo argomento,
+oltre ad un comune nome a dominio, può indicare anche un indirizzo numerico in
+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
+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
+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{minipage}[c]{15cm}
+    \includestruct{listati/addrinfo.h}
+  \end{minipage}
+  \caption{La struttura \structd{addrinfo} usata nella nuova interfaccia POSIX
+    per la risoluzione di nomi a dominio e servizi.}
+  \label{fig:sock_addrinfo_struct}
+\end{figure}
+
+La struttura \struct{addrinfo}, la cui definizione\footnote{la definizione è
+  ripresa direttamente dal file \texttt{netdb.h} in questa struttura viene
+  dichiarata, la pagina di manuale riporta \type{size\_t} come tipo di dato
+  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
+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,
+che viene usato soltanto in ingresso. I tre campi successivi \var{ai\_family},
+\var{ai\_socktype}, e \var{ai\_protocol} contengono rispettivamente la
+famiglia di indirizzi, il tipo di socket e il protocollo, in ingresso vengono
+usati per impostare una selezione (impostandone il valore nella struttura
+puntata da \param{hints}), mentre in uscita indicano il tipo di risultato
+contenuto nella struttura. 
+
+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
+campo \var{ai\_canonname} è un puntatore alla stringa contenente il nome
+canonico della macchina, ed infine, quando la funzione restituisce più di un
+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
+ricerche generiche.  Se però si specifica un valore non nullo questo deve
+puntare ad una struttura \struct{addrinfo} precedentemente allocata nella
+quale siano stati opportunamente impostati i valori dei campi
+\var{ai\_family}, \var{ai\_socktype}, \var{ai\_protocol} ed \var{ai\_flags}.
+
+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
+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.
+
+Il campo \var{ai\_protocol} permette invece di effettuare la selezione dei
+risultati per il nome del servizio usando il numero identificativo del
+rispettivo protocollo di trasporto (i cui valori possibili sono riportati in
+\file{/etc/protocols}); di nuovo i due soli valori utilizzabili sono quelli
+relativi a UDP e TCP, o il valore nullo che indica di ignorare questo campo
+nella selezione.
+
+Infine l'ultimo campo è \var{ai\_flags}; che deve essere impostato come una
+maschera binaria; i bit di questa variabile infatti vengono usati per dare
+delle indicazioni sul tipo di risoluzione voluta, ed hanno valori analoghi a
+quelli visti in sez.~\ref{sec:sock_name_services} per \func{getipnodebyname};
+il valore di \var{ai\_flags} può essere impostata con un OR aritmetico delle
+costanti di tab.~\ref{tab:ai_flags_values}, ciascuna delle quali identifica un
+bit della maschera.
+
+\begin{table}[!htb]
+  \centering
+  \footnotesize
+  \begin{tabular}[c]{|l|p{10cm}|}
+    \hline
+    \textbf{Costante} & \textbf{Significato} \\
+    \hline
+    \hline
+    \const{AI\_PASSIVE}    & viene utilizzato per ottenere un indirizzo in
+                             formato adatto per una successiva chiamata a
+                             \func{bind}. Se specificato quando si è usato 
+                             \const{NULL} come valore per \param{node} gli
+                             indirizzi restituiti saranno inizializzati al
+                             valore generico (\const{INADDR\_ANY} per IPv4 e
+                             \const{IN6ADDR\_ANY\_INIT} per IPv6), altrimenti
+                             verrà usato l'indirizzo dell'interfaccia di
+                             \textit{loopback}. Se invece non è impostato gli
+                             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
+                             indirizzo sarà restituito nel campo
+                             \var{ai\_canonname} della prima struttura
+                             \struct{addrinfo} dei risultati. Se il nome
+                             canonico non è disponibile al suo posto
+                             viene restituita una copia di \param{node}. \\ 
+    \const{AI\_NUMERICHOST}& se impostato il nome della macchina specificato
+                             con \param{node} deve essere espresso in forma
+                             numerica, altrimenti sarà restituito un errore
+                             \const{EAI\_NONAME} (vedi
+                             tab.~\ref{tab:addrinfo_error_code}), in questo
+                             modo si evita ogni chiamata alle funzioni di
+                             risoluzione.\\ 
+    \const{AI\_V4MAPPED}   & stesso significato dell'analoga di
+                             tab.~\ref{tab:sock_getipnodebyname_flags}.\\  
+    \const{AI\_ALL}        & stesso significato dell'analoga di
+                             tab.~\ref{tab:sock_getipnodebyname_flags}.\\ 
+    \const{AI\_ADDRCONFIG} & stesso significato dell'analoga di
+                             tab.~\ref{tab:sock_getipnodebyname_flags}.\\ 
+    \hline
+  \end{tabular}
+  \caption{Costanti associate ai bit del campo \var{ai\_flags} della struttura 
+    \struct{addrinfo}.} 
+  \label{tab:ai_flags_values}
+\end{table}
+
+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 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
+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
+tab.~\ref{tab:addrinfo_error_code}; dato che la funzione utilizza altre
+funzioni e chiamate al sistema per ottenere il suo risultato in generale il
+valore di \var{errno} non è significativo, eccetto il caso in cui si sia
+ricevuto un errore di \const{EAI\_SYSTEM}, nel qual caso l'errore
+corrispondente è riportato tramite \var{errno}.
+
+\begin{table}[!htb]
+  \centering
+  \footnotesize
+  \begin{tabular}[c]{|l|p{10cm}|}
+    \hline
+    \textbf{Costante} & \textbf{Significato} \\
+    \hline
+    \hline
+    \const{EAI\_FAMILY}  & la famiglia di indirizzi richiesta non è
+                           supportata. \\ 
+    \const{EAI\_SOCKTYPE}& il tipo di socket richiesto non è supportato. \\
+    \const{EAI\_BADFLAGS}& il campo \var{ai\_flags} contiene dei valori non
+                           validi. \\
+    \const{EAI\_NONAME}  & il nome a dominio o il servizio non sono noti,
+                           viene usato questo errore anche quando si specifica
+                           il valore \const{NULL} per entrambi gli argomenti
+                           \param{node} e \param{service}. \\
+    \const{EAI\_SERVICE} & il servizio richiesto non è disponibile per il tipo
+                           di socket richiesto, anche se può esistere per
+                           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 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  
+                           permanente. \\
+    \const{EAI\_AGAIN}   & il DNS ha restituito un errore di risoluzione  
+                           temporaneo, si può ritentare in seguito. \\
+    \const{EAI\_SYSTEM}  & c'è stato un errore di sistema, si può controllare
+                           \var{errno} per i dettagli. \\
+%    \hline
+% estensioni GNU, trovarne la documentazione
+%    \const{EAI\_INPROGRESS}& richiesta in corso. \\
+%    \const{EAI\_CANCELED}& la richiesta è stata cancellata.\\
+%    \const{EAI\_NOTCANCELED}& la richiesta non è stata cancellata. \\
+%    \const{EAI\_ALLDONE} & tutte le richieste sono complete. \\
+%    \const{EAI\_INTR}    & richiesta interrotta. \\
+    \hline
+  \end{tabular}
+  \caption{Costanti associate ai valori dei codici di errore della funzione
+    \func{getaddrinfo}.} 
+  \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}.
+
+  \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
+  \includegraphics[width=10cm]{img/addrinfo_list}
+  \caption{La \textit{linked list} delle strutture \struct{addrinfo}
+    restituite da \func{getaddrinfo}.}
+  \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
+\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} 
+
+  \funcdecl{void freeaddrinfo(struct addrinfo *res)}
+
+  Libera la memoria allocata da una precedente chiamata a \func{getaddrinfo}.
+
+  \bodydesc{La funzione non restituisce nessun codice di errore.}
+\end{functions}
+
+La funzione prende come unico argomento il puntatore \param{res}, ottenuto da
+una precedente chiamata a \func{getaddrinfo}, e scandisce la lista delle
+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}.
+
+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}
-\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}
-\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.