+Esamineremo in questo capitolo una serie di funzionalità aggiuntive relative
+alla gestione dei socket, come la gestione della risoluzione di nomi e
+indirizzi, le impostazioni delle varie proprietà ed opzioni relative ai
+socket, e le funzioni di controllo che permettono di modificarne il
+comportamento.
+
+
+\section{La risoluzione dei nomi}
+\label{sec:sock_name_resolution}
+
+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 \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}
+
+\itindbeg{resolver} La risoluzione dei nomi è associata tradizionalmente al
+servizio del \itindex{Domain~Name~Service~(DNS)} \textit{Domain Name Service}
+che permette di identificare le macchine su internet invece che per numero IP
+attraverso il relativo \textsl{nome a dominio}.\footnote{non staremo ad
+ entrare nei dettagli della definizione di cosa è un nome a dominio, dandolo
+ per noto, una introduzione alla problematica si trova in \cite{AGL} (cap.~9)
+ mentre per una trattazione approfondita di tutte le problematiche relative
+ al DNS si può fare riferimento a \cite{DNSbind}.} In realtà per DNS si
+intendono spesso i server che forniscono su internet questo servizio, mentre
+nel nostro caso affronteremo la problematica dal lato client, di un qualunque
+programma che necessita di compiere questa operazione.
+
+\begin{figure}[!htb]
+ \centering \includegraphics[width=11cm]{img/resolver}
+ \caption{Schema di funzionamento delle funzioni del \textit{resolver}.}
+ \label{fig:sock_resolver_schema}
+\end{figure}
+
+Inoltre quella fra nomi a dominio e indirizzi IP non è l'unica corrispondenza
+possibile fra nomi simbolici e valori numerici, come abbiamo visto anche in
+sez.~\ref{sec:sys_user_group} per le corrispondenze fra nomi di utenti e
+gruppi e relativi identificatori numerici; per quanto riguarda però tutti i
+nomi associati a identificativi o servizi relativi alla rete il servizio di
+risoluzione è gestito in maniera unificata da un insieme di funzioni fornite
+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 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ò 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 mantenimento dei più vari tipi di informazioni su una
+ infrastruttura di questo tipo.}
+
+La configurazione del \textit{resolver} attiene più alla amministrazione di
+sistema che alla programmazione, ciò non di meno, prima di trattare le varie
+funzioni di librerie utilizzate dai programmi, vale la pena fare una
+panoramica generale. Originariamente la configurazione del \textit{resolver}
+riguardava esclusivamente le questioni relative alla gestione dei nomi a
+dominio, e prevedeva solo l'utilizzo del DNS e del file statico
+\conffile{/etc/hosts}.
+
+Per questo aspetto il file di configurazione principale del sistema è
+\conffile{/etc/resolv.conf} che contiene in sostanza l'elenco degli indirizzi
+IP dei server DNS da contattare; a questo si affiancava (fino alla \acr{glibc}
+2.4) il file \conffile{/etc/host.conf} il cui scopo principale era indicare
+l'ordine in cui eseguire la risoluzione dei nomi (se usare prima i valori di
+\conffile{/etc/hosts} o quelli del DNS). Tralasciamo i dettagli relativi alle
+varie direttive che possono essere usate in questi file, che si trovano nelle
+rispettive pagine di manuale.
+
+Con il tempo però è divenuto possibile fornire diversi sostituti per
+l'utilizzo delle associazione statiche in \conffile{/etc/hosts}, inoltre oltre
+alla risoluzione dei nomi a dominio ci sono anche altri nomi da risolvere,
+come quelli che possono essere associati ad una rete (invece che ad una
+singola macchina) o ai gruppi di macchine definiti dal servizio
+NIS,\footnote{il \textit{Network Information Service} è un servizio, creato da
+ Sun, e poi diffuso su tutte le piattaforme unix-like, che permette di
+ raggruppare all'interno di una rete (in quelli che appunto vengono chiamati
+ \textit{netgroup}) varie macchine, centralizzando i servizi di definizione
+ di utenti e gruppi e di autenticazione, oggi è sempre più spesso sostituito
+ da LDAP.} o come quelli dei protocolli e dei servizi che sono mantenuti nei
+file statici \conffile{/etc/protocols} e \conffile{/etc/services}.
+
+Molte di queste informazioni non si trovano su un DNS, ma in una rete locale
+può essere molto 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 \conffile{/etc/hosts}, che con il DNS, che con NIS) comporta il
+problema dell'ordine in cui questi vengono interrogati. Con le implementazioni
+classiche i vari supporti erano introdotti modificando direttamente le
+funzioni di libreria, prevedendo un ordine di interrogazione predefinito e non
+modificabile (a meno di una ricompilazione delle librerie stesse).
+
+\itindbeg{Name~Service~Switch~(NSS)}
+
+Per risolvere questa serie di problemi la risoluzione dei nomi a dominio
+eseguità 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}, cui abbiamo accennato anche in
+sez.~\ref{sec:sys_user_group} per quanto riguarda la gestione dei dati
+associati a utenti e gruppi. Il sistema è stato introdotto la prima volta
+nella libreria standard di Solaris e la \acr{glibc} ha ripreso lo stesso
+schema; si tenga presente che questo sistema non esiste per altre librerie
+standard come la \acr{libc5} o la \acr{uClib}.
+
+Il \textit{Name Service Switch} (cui spesso si fa riferimento con l'acronimo
+NSS) è un sistema di librerie dinamiche che permette di definire in maniera
+generica sia i supporti su cui mantenere i dati di corrispondenza fra nomi e
+valori numerici, sia l'ordine in cui effettuare le ricerche sui vari supporti
+disponibili. Il sistema prevede una serie di possibili classi di
+corrispondenza, quelle attualmente definite sono riportate in
+tab.~\ref{tab:sys_NSS_classes}.
+
+\begin{table}[htb]
+ \footnotesize
+ \centering
+ \begin{tabular}[c]{|l|p{8cm}|}
+ \hline
+ \textbf{Classe} & \textbf{Tipo di corrispondenza}\\
+ \hline
+ \hline
+ \texttt{passwd} & Corrispondenze fra nome dell'utente e relative
+ proprietà (\ids{UID}, gruppo principale, ecc.).\\
+ \texttt{shadow} & Corrispondenze fra username e password dell'utente
+ (e altre informazioni relative alle password).\\
+ \texttt{group} & Corrispondenze fra nome del gruppo e proprietà dello
+ stesso.\\
+ \texttt{aliases} & Alias per la posta elettronica.\\
+ \texttt{ethers} & Corrispondenze fra numero IP e MAC address della
+ scheda di rete.\\
+ \texttt{hosts} & Corrispondenze fra nome a dominio e numero IP.\\
+ \texttt{netgroup} & Corrispondenze fra gruppo di rete e macchine che lo
+ compongono.\\
+ \texttt{networks} & Corrispondenze fra nome di una rete e suo indirizzo
+ IP.\\
+ \texttt{protocols}& Corrispondenze fra nome di un protocollo e relativo
+ numero identificativo.\\
+ \texttt{rpc} & Corrispondenze fra nome di un servizio RPC e relativo
+ numero identificativo.\\
+ \texttt{publickey}& Chiavi pubbliche e private usate per gli RFC sicuri,
+ utilizzate da NFS e NIS+. \\
+ \texttt{services} & Corrispondenze fra nome di un servizio e numero di
+ porta. \\
+ \hline
+ \end{tabular}
+ \caption{Le diverse classi di corrispondenze definite
+ all'interno del \textit{Name Service Switch}.}
+ \label{tab:sys_NSS_classes}
+\end{table}
+
+% TODO rivedere meglio la tabella
+
+Il sistema del \textit{Name Service Switch} è controllato dal contenuto del
+file \conffile{/etc/nsswitch.conf}; questo contiene una riga di configurazione
+per ciascuna di queste classi, che viene inizia col nome di
+tab.~\ref{tab:sys_NSS_classes} seguito da un carattere ``\texttt{:}'' e
+prosegue con la lista dei \textsl{servizi} su cui le relative informazioni
+sono raggiungibili, scritti nell'ordine in cui si vuole siano interrogati.
+Pertanto nelle versioni recenti delle librerie è questo file e non
+\conffile{/etc/host.conf} a indicare l'ordine con cui si esegue la
+risoluzione dei nomi.
+
+Ogni servizio è specificato a sua volta da un nome, come \texttt{file},
+\texttt{dns}, \texttt{db}, ecc. che identifica la libreria dinamica che
+realizza l'interfaccia con esso. Per ciascun servizio se \texttt{NAME} è il
+nome utilizzato dentro \conffile{/etc/nsswitch.conf}, dovrà essere presente
+(usualmente in \file{/lib}) una libreria \texttt{libnss\_NAME} che ne
+implementa le funzioni.
+
+In ogni caso, qualunque sia la modalità con cui ricevono i dati o il supporto
+su cui vengono mantenuti, e che si usino o meno funzionalità aggiuntive
+fornite dal sistema del \textit{Name Service Switch}, dal punto di vista di un
+programma che deve effettuare la risoluzione di un nome a dominio, tutto
+quello che conta sono le funzioni classiche che il \textit{resolver} mette a
+disposizione (è cura della \acr{glibc} tenere conto della presenza del
+\textit{Name Service Switch}) e sono queste quelle che tratteremo nelle
+sezioni successive.
+
+\itindend{Name~Service~Switch~(NSS)}
+
+
+\subsection{Le funzioni di interrogazione del DNS}
+\label{sec:sock_resolver_functions}
+
+Prima di trattare le funzioni usate normalmente nella risoluzione dei nomi a
+dominio conviene trattare in maniera più dettagliata il servizio DNS. Come
+accennato questo, benché esso 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. Inolte esso può fornire anche
+ulteriori informazioni oltre relative alla risoluzione dei nomi a dominio.
+Per questo motivo esistono una serie di funzioni di libreria che servono
+specificamente ad eseguire delle interrogazioni verso un server DNS, funzioni
+che poi vengono utilizzate anche per realizzare le funzioni generiche di
+libreria usate dal sistema del \textit{resolver}.
+
+Il sistema del DNS è in sostanza di un database distribuito organizzato in
+maniera gerarchica, i dati vengono mantenuti in tanti server distinti ciascuno
+dei quali si occupa della risoluzione del proprio \textsl{dominio}; i nomi a
+dominio sono organizzati in una struttura ad albero analoga a quella
+dell'albero dei file, con domini di primo livello (come i \texttt{.org}),
+secondo livello (come \texttt{.truelite.it}), ecc. In questo caso le
+separazioni sono fra i vari livelli sono definite dal carattere ``\texttt{.}''
+ed i nomi devono essere risolti da destra verso sinistra.\footnote{per chi si
+ stia chiedendo quale sia la radice di questo albero, cioè l'equivalente di
+ ``\texttt{/}'', la risposta è il dominio speciale ``\texttt{.}'', che in
+ genere non viene mai scritto esplicitamente, ma che, come chiunque abbia
+ configurato un server DNS sa bene, esiste ed è gestito dai cosiddetti
+ \textit{root DNS} che risolvono i domini di primo livello.} Il meccanismo
+funziona con il criterio della \textsl{delegazione}, un server responsabile
+per un dominio di primo livello può delegare la risoluzione degli indirizzi
+per un suo dominio di secondo livello ad un altro server, il quale a sua volta
+potrà delegare la risoluzione di un eventuale sotto-dominio di terzo livello ad
+un altro server ancora.
+
+Come accennato un server DNS è in grado di fare molto altro rispetto alla
+risoluzione di un nome a dominio in un indirizzo IP: ciascuna voce nel
+database viene chiamata \textit{resource record}, e può contenere diverse
+informazioni. In genere i \textit{resource record} vengono classificati per la
+\textsl{classe di indirizzi} cui i dati contenuti fanno riferimento, e per il
+\textsl{tipo} di questi ultimi (ritroveremo classi di indirizzi e tipi di
+record più avanti in tab.~\ref{tab:DNS_address_class} e
+tab.~\ref{tab:DNS_record_type}). Oggigiorno i dati mantenuti nei server DNS
+sono quasi esclusivamente relativi ad indirizzi internet, per cui in pratica
+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
+\textit{resolver} prevede, oltre a quelle relative alla semplice risoluzione
+dei nomi, un insieme di funzioni specifiche dedicate all'interrogazione di un
+server DNS, tutte nella forma \texttt{res\_}\textsl{\texttt{nome}}. La prima
+di queste funzioni è \funcd{res\_init}, il cui prototipo è:
+
+\begin{funcproto}{
+\fhead{netinet/in.h}
+\fhead{arpa/nameser.h}
+\fhead{resolv.h}
+\fdecl{int res\_init(void)}
+\fdesc{Inizializza il sistema del \textit{resolver}.}
+}
+{La funzione ritorna $0$ in caso di successo e $-1$ per un errore.
+}
+\end{funcproto}
+
+La funzione legge il contenuto dei file di configurazione per impostare il
+dominio di default, gli indirizzi dei server DNS da contattare e l'ordine
+delle ricerche; se non sono specificati server verrà utilizzato l'indirizzo
+locale, e se non è definito un dominio di default sarà usato quello associato
+con l'indirizzo locale (ma questo può essere sovrascritto con l'uso della
+variabile di ambiente \envvar{LOCALDOMAIN}). In genere non è necessario
+eseguire questa funzione esplicitamente, in quanto viene automaticamente
+chiamata la prima volta che si esegue una qualunque delle altre.
+
+Le impostazioni e lo stato del \textit{resolver} inizializzati da
+\func{res\_init} vengono mantenuti in una serie di variabili raggruppate nei
+campi di una apposita struttura. Questa struttura viene definita in
+\headfiled{resolv.h} e mantenuta nella variabile globale \var{\_res}, che
+viene utilizzata internamente da tutte le funzioni dell'interfaccia. Questo
+consente anche di accedere direttamente al contenuto della variabile
+all'interno di un qualunque programma, una volta che la sia opportunamente
+dichiarata con:
+\includecodesnip{listati/resolv_option.c}
+
+Dato che l'uso di una variabile globale rende tutte le funzioni
+dell'interfaccia classica non rientranti, queste sono state deprecate in
+favore di una nuova interfaccia in cui esse sono state sostituite da
+altrettante nuove funzioni, il cui nome è ottenuto apponendo una
+``\texttt{n}'' al nome di quella tradizionale (cioè nella forma
+\texttt{res\_n\textsl{nome}}). Tutte le nuove funzioni sono identiche alle
+precedenti, ma hanno un primo argomento aggiuntivo, \param{statep}, puntatore
+ad una struttura dello stesso tipo di \var{\_res}. Questo consente di usare
+una variabile locale per mantenere lo stato del \textit{resolver}, rendendo le
+nuove funzioni rientranti. In questo caso per poter utilizzare il nuovo
+argomento occorrerà una opportuna dichiarazione del relativo tipo di dato con:
+\includecodesnip{listati/resolv_newoption.c}
+
+Così la nuova funzione utilizzata per inizializzare il \textit{resolver} (che
+come la precedente viene chiamata automaticamente da tutte altre funzioni) è
+\funcd{res\_ninit}, ed il suo prototipo è:
+
+\begin{funcproto}{
+\fhead{netinet/in.h}
+\fhead{arpa/nameser.h}
+\fhead{resolv.h}
+\fdecl{int res\_ninit(res\_state statep)}
+\fdesc{Inizializza il sistema del \textit{resolver}.}
+}
+{La funzione ritorna $0$ in caso di successo e $-1$ per un errore.
+}
+\end{funcproto}
+
+Indipendentemente da quale versione delle funzioni si usino, tutti i campi
+della struttura (\var{\_res} o la variabile puntata da \param{statep}) sono ad
+uso interno, e vengono usualmente inizializzate da \func{res\_init} o
+\func{res\_ninit} in base al contenuto dei file di configurazione e ad una
+serie di valori di default. L'unico campo che può essere utile modificare è
+\var{\_res.options} (o l'equivalente della variabile puntata
+da\param{statep}), una maschera binaria che contiene una serie di bit che
+esprimono le opzioni che permettono di controllare il comportamento del
+\textit{resolver}.
+
+\begin{table}[htb]
+ \centering
+ \footnotesize
+ \begin{tabular}[c]{|l|p{8cm}|}
+ \hline
+ \textbf{Costante} & \textbf{Significato} \\
+ \hline
+ \hline
+ \constd{RES\_INIT} & Viene attivato se è stata chiamata
+ \func{res\_init}. \\
+ \constd{RES\_DEBUG} & Stampa dei messaggi di debug.\\
+ \constd{RES\_AAONLY} & Accetta solo risposte autoritative.\\
+ \constd{RES\_USEVC} & Usa connessioni TCP per contattare i server
+ invece che l'usuale UDP.\\
+ \constd{RES\_PRIMARY} & Interroga soltanto server DNS primari.\\
+ \constd{RES\_IGNTC} & Ignora gli errori di troncamento, non ritenta la
+ richiesta con una connessione TCP.\\
+ \constd{RES\_RECURSE} & Imposta il bit che indica che si desidera
+ eseguire una interrogazione ricorsiva.\\
+ \constd{RES\_DEFNAMES} & Se attivo \func{res\_search} aggiunge il nome
+ del dominio di default ai nomi singoli (che non
+ contengono cioè un ``\texttt{.}'').\\
+ \constd{RES\_STAYOPEN} & Usato con \const{RES\_USEVC} per mantenere
+ aperte le connessioni TCP fra interrogazioni
+ diverse.\\
+ \constd{RES\_DNSRCH} & Se attivo \func{res\_search} esegue le ricerche
+ di nomi di macchine nel dominio corrente o nei
+ domini ad esso sovrastanti.\\
+ \constd{RES\_INSECURE1} & Blocca i controlli di sicurezza di tipo 1.\\
+ \constd{RES\_INSECURE2} & Blocca i controlli di sicurezza di tipo 2.\\
+ \constd{RES\_NOALIASES} & Blocca l'uso della variabile di ambiente
+ \envvar{HOSTALIASES}.\\
+ \constd{RES\_USE\_INET6} & Restituisce indirizzi IPv6 con
+ \func{gethostbyname}. \\
+ \constd{RES\_ROTATE} & Ruota la lista dei server DNS dopo ogni
+ interrogazione.\\
+ \constd{RES\_NOCHECKNAME}& Non controlla i nomi per verificarne la
+ correttezza sintattica. \\
+ \constd{RES\_KEEPTSIG} & Non elimina i record di tipo \texttt{TSIG}.\\
+ \constd{RES\_BLAST} & Effettua un ``\textit{blast}'' inviando
+ simultaneamente le richieste a tutti i server;
+ non ancora implementata. \\
+ \constd{RES\_DEFAULT} & Combinazione di \const{RES\_RECURSE},
+ \const{RES\_DEFNAMES} e \const{RES\_DNSRCH}.\\
+ \hline
+ \end{tabular}
+ \caption{Costanti utilizzabili come valori per \var{\_res.options}.}
+ \label{tab:resolver_option}
+\end{table}
+
+Per utilizzare questa funzionalità per modificare le impostazioni direttamente
+da programma occorrerà impostare un opportuno valore per questo campo ed
+invocare esplicitamente \func{res\_init} o \func{res\_ninit}, dopo di che le
+altre funzioni 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, espresso dalla costante
+\const{RES\_DEFAULT}, è definito come:
+\includecodesnip{listati/resolv_option_def.c}
+
+Non tratteremo il significato degli altri campi non essendovi necessità di
+modificarli direttamente; gran parte di essi sono infatti impostati dal
+contenuto dei file di configurazione, mentre le funzionalità controllate da
+alcuni di esse possono essere modificate con l'uso delle opportune variabili
+di ambiente come abbiamo visto per \envvar{LOCALDOMAIN}. In particolare con
+\envvar{RES\_RETRY} si soprassiede il valore del campo \var{retry} che
+controlla quante volte viene ripetuto il tentativo di connettersi ad un server
+DNS prima di dichiarare fallimento; il valore di default è 4, un valore nullo
+significa bloccare l'uso del DNS. Infine con \envvar{RES\_TIMEOUT} si
+soprassiede il valore del campo \var{retrans} (preimpostato al valore della
+omonima costante \const{RES\_TIMEOUT} di \headfile{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 raddoppiando
+il tempo di scadenza per il numero massimo di volte stabilito da
+\texttt{RES\_RETRY}.
+
+La funzione di interrogazione principale è \funcd{res\_query}
+(\funcd{res\_nquery} per la nuova interfaccia), che serve ad eseguire una
+richiesta ad un server DNS per un nome a dominio \textsl{completamente
+ specificato} (quello che si chiama
+\itindex{Fully~Qualified~Domain~Name~(FQDN)} FQDN, \textit{Fully Qualified
+ Domain Name}); il loro prototipo è:
+
+\begin{funcproto}{
+\fhead{netinet/in.h}
+\fhead{arpa/nameser.h}
+\fhead{resolv.h}
+\fdecl{int res\_query(const char *dname, int class, int type,
+ unsigned char *answer, int anslen)}
+\fdecl{int res\_nquery(res\_state statep, const char *dname, int class, int
+ type, \\
+ \phantom{int res\_nquery(}unsigned char *answer, int anslen)}
+\fdesc{Esegue una interrogazione al DNS.}
+}
+{Le funzioni ritornano un valore positivo pari alla lunghezza dei dati scritti
+ nel buffer \param{answer} in caso di successo e $-1$ per un errore.
+}
+\end{funcproto}
+
+Le funzioni eseguono una interrogazione ad un server DNS relativa al nome da
+risolvere passato nella stringa indirizzata da \param{dname}, inoltre deve
+essere specificata la classe di indirizzi in cui eseguire la ricerca con
+\param{class}, ed il tipo di \textit{resource record} che si vuole ottenere
+con \param{type}. Il risultato della ricerca verrà scritto nel buffer di
+lunghezza \param{anslen} puntato da \param{answer} che si sarà opportunamente
+allocato in precedenza.
+
+Una seconda funzione di ricerca analoga a \func{res\_query}, che prende gli
+stessi argomenti ma che esegue l'interrogazione con le funzionalità
+addizionali previste dalle due opzioni \const{RES\_DEFNAMES} e
+\const{RES\_DNSRCH}, è \funcd{res\_search} (\funcd{res\_nsearch} per la nuova
+interfaccia), il cui prototipo è:
+
+\begin{funcproto}{
+\fhead{netinet/in.h}
+\fhead{arpa/nameser.h}
+\fhead{resolv.h}
+\fdecl{int res\_search(const char *dname, int class, int type,
+ unsigned char *answer, \\
+ \phantom{int res\_search}int anslen)}
+\fdecl{int res\_nsearch(res\_state statep, const char *dname, int class,
+ int type, \\
+ \phantom{int res\_nsearch(}unsigned char *answer, int anslen)}
+\fdesc{Esegue una interrogazione al DNS.}
+}
+{Le funzioni ritornano un valore positivo pari alla lunghezza dei dati scritti
+ nel buffer \param{answer} in caso di successo e $-1$ per un errore.
+}
+\end{funcproto}
+
+In sostanza la funzione ripete una serie di chiamate a \func{res\_query}
+(\func{res\_nquery}) aggiungendo al nome contenuto nella stringa \param{dname}
+il dominio di default da cercare, fermandosi non appena trova un risultato.
+Il risultato di entrambe le funzioni viene scritto nel formato opportuno (che
+sarà diverso a seconda del tipo di record richiesto) nel buffer di ritorno;
+sarà compito del programma (o di altre funzioni) estrarre i relativi dati,
+esistono una serie di funzioni interne usate per la scansione di questi dati,
+per chi fosse interessato una trattazione dettagliata è riportata nel
+quattordicesimo capitolo di \cite{DNSbind}.
+
+Le classi di indirizzi supportate da un server DNS sono tre, ma di queste in
+pratica oggi viene utilizzata soltanto quella degli indirizzi internet; le
+costanti che identificano dette classi, da usare come valore per l'argomento
+\param{class} delle precedenti funzioni, sono riportate in
+tab.~\ref{tab:DNS_address_class} (esisteva in realtà anche una classe
+\constd{C\_CSNET} per la omonima rete, ma è stata dichiarata obsoleta).
+
+\begin{table}[htb]
+ \centering
+ \footnotesize
+ \begin{tabular}[c]{|l|p{8cm}|}
+ \hline
+ \textbf{Costante} & \textbf{Significato} \\
+ \hline
+ \hline
+ \constd{C\_IN} & Indirizzi internet, in pratica i soli utilizzati oggi.\\
+ \constd{C\_HS} & Indirizzi \textit{Hesiod}, utilizzati solo al MIT, oggi
+ completamente estinti. \\
+ \constd{C\_CHAOS}& Indirizzi per la rete \textit{Chaosnet}, un'altra rete
+ sperimentale nata al MIT. \\
+ \constd{C\_ANY} & Indica un indirizzo di classe qualunque.\\
+ \hline
+ \end{tabular}
+ \caption{Costanti identificative delle classi di indirizzi per l'argomento
+ \param{class} di \func{res\_query}.}
+ \label{tab:DNS_address_class}
+\end{table}
+
+Come accennato le tipologie di dati che sono mantenibili su un server DNS sono
+diverse, ed a ciascuna di essa corrisponde un diverso tipo di \textit{resource
+ record}. L'elenco delle costanti, ripreso dai file di dichiarazione
+\headfiled{arpa/nameser.h} e \headfiled{arpa/nameser\_compat.h}, che
+definiscono i valori che si possono usare per l'argomento \param{type} per
+specificare il tipo di \textit{resource record} da richiedere è riportato in
+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 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 costanti di
+ tab.~\ref{tab:DNS_record_type} senza il \texttt{T\_} iniziale.} e che
+normalmente sono anche usati come nomi per indicare i record.
+
+\begin{table}[!htb]
+ \centering
+ \footnotesize
+ \begin{tabular}[c]{|l|l|}
+ \hline
+ \textbf{Costante} & \textbf{Significato} \\
+ \hline
+ \hline
+ \constd{T\_A} & Indirizzo di una stazione.\\
+ \constd{T\_NS} & Server DNS autoritativo per il dominio richiesto.\\
+ \constd{T\_MD} & Destinazione per la posta elettronica.\\
+ \constd{T\_MF} & Redistributore per la posta elettronica.\\
+ \constd{T\_CNAME} & Nome canonico.\\
+ \constd{T\_SOA} & Inizio di una zona di autorità.\\
+ \constd{T\_MB} & Nome a dominio di una casella di posta.\\
+ \constd{T\_MG} & Nome di un membro di un gruppo di posta.\\
+ \constd{T\_MR} & Nome di un cambiamento di nome per la posta.\\
+ \constd{T\_NULL} & Record nullo.\\
+ \constd{T\_WKS} & Servizio noto.\\
+ \constd{T\_PTR} & Risoluzione inversa di un indirizzo numerico.\\
+ \constd{T\_HINFO} & Informazione sulla stazione.\\
+ \constd{T\_MINFO} & Informazione sulla casella di posta.\\
+ \constd{T\_MX} & Server cui instradare la posta per il dominio.\\
+ \constd{T\_TXT} & Stringhe di testo (libere).\\
+ \constd{T\_RP} & Nome di un responsabile (\textit{responsible person}).\\
+ \constd{T\_AFSDB} & Database per una cella AFS.\\
+ \constd{T\_X25} & Indirizzo di chiamata per X.25.\\
+ \constd{T\_ISDN} & Indirizzo di chiamata per ISDN.\\
+ \constd{T\_RT} & Router.\\
+ \constd{T\_NSAP} & Indirizzo NSAP.\\
+ \constd{T\_NSAP\_PTR}& Risoluzione inversa per NSAP (deprecato).\\
+ \constd{T\_SIG} & Firma digitale di sicurezza.\\
+ \constd{T\_KEY} & Chiave per firma.\\
+ \constd{T\_PX} & Corrispondenza per la posta X.400.\\
+ \constd{T\_GPOS} & Posizione geografica.\\
+ \constd{T\_AAAA} & Indirizzo IPv6.\\
+ \constd{T\_LOC} & Informazione di collocazione.\\
+ \constd{T\_NXT} & Dominio successivo.\\
+ \constd{T\_EID} & Identificatore di punto conclusivo.\\
+ \constd{T\_NIMLOC}& Posizionatore \textit{nimrod}.\\
+ \constd{T\_SRV} & Servizio.\\
+ \constd{T\_ATMA} & Indirizzo ATM.\\
+ \constd{T\_NAPTR} & Puntatore ad una \textit{naming authority}.\\
+ \constd{T\_TSIG} & Firma di transazione.\\
+ \constd{T\_IXFR} & Trasferimento di zona incrementale.\\
+ \constd{T\_AXFR} & Trasferimento di zona di autorità.\\
+ \constd{T\_MAILB} & Trasferimento di record di caselle di posta.\\
+ \constd{T\_MAILA} & Trasferimento di record di server di posta.\\
+ \constd{T\_ANY} & Valore generico.\\
+ \hline
+ \end{tabular}
+ \caption{Costanti identificative del tipo di record per l'argomento
+ \param{type} di \func{res\_query}.}
+ \label{tab:DNS_record_type}
+\end{table}
+
+
+L'elenco di tab.~\ref{tab:DNS_record_type} è quello di \textsl{tutti} i
+\textit{resource record} definiti, con una breve descrizione del relativo
+significato. Di tutti questi però viene impiegato correntemente solo un
+piccolo sottoinsieme, alcuni sono obsoleti ed altri fanno riferimento a dati
+applicativi che non ci interessano non avendo nulla a che fare con la
+risoluzione degli indirizzi IP, pertanto non entreremo nei dettagli del
+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 corrispondenza fra un nome a
+ dominio ed un indirizzo IPv4; ad esempio la corrispondenza fra
+ \texttt{jojo.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 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
+ stesso indirizzo (come ad esempio \texttt{www.truelite.it} e
+ \texttt{sources.truelite.it}, che fanno entrambi riferimento alla stessa
+ macchina (nel caso \texttt{dodds.truelite.it}) si può usare questo tipo di
+ record per creare degli \textit{alias} in modo da associare un qualunque
+ altro nome al \textsl{nome canonico} della macchina (si chiama così quello
+ associato al record \texttt{A}).
+\end{basedescript}
+
+Come accennato in caso di successo le due funzioni di richiesta restituiscono
+il risultato della interrogazione al server, in caso di insuccesso l'errore
+invece viene segnalato da un valore di ritorno pari a $-1$, ma in questo caso,
+non può essere utilizzata la variabile \var{errno} per riportare un codice di
+errore, in quanto questo viene impostato per ciascuna delle chiamate al
+sistema utilizzate dalle funzioni del \textit{resolver}, non avrà alcun
+significato nell'indicare quale parte del procedimento di risoluzione è
+fallita.
+
+Per questo motivo è stata definita una variabile di errore separata,
+\var{h\_errno}, che viene utilizzata dalle funzioni del \textit{resolver} per
+indicare quale problema ha causato il fallimento della risoluzione del nome.
+Ad essa si può accedere una volta che la si dichiara con:
+\includecodesnip{listati/herrno.c}
+ed i valori che può assumere, con il relativo significato, sono riportati in
+tab.~\ref{tab:h_errno_values}.
+
+\begin{table}[!htb]
+ \centering
+ \footnotesize
+ \begin{tabular}[c]{|l|p{9cm}|}
+ \hline
+ \textbf{Costante} & \textbf{Significato} \\
+ \hline
+ \hline
+ \constd{HOST\_NOT\_FOUND}& L'indirizzo richiesto non è valido e la
+ macchina indicata è sconosciuta.\\
+ \constd{NO\_ADDRESS} & Il nome a dominio richiesto è valido, ma non ha
+ un indirizzo associato ad esso
+ (alternativamente può essere indicato come
+ \constd{NO\_DATA}).\\
+ \constd{NO\_RECOVERY} & Si è avuto un errore non recuperabile
+ nell'interrogazione di un server DNS.\\
+ \constd{TRY\_AGAIN} & Si è avuto un errore temporaneo
+ nell'interrogazione di un server DNS, si può
+ ritentare l'interrogazione in un secondo
+ tempo.\\
+ \hline
+ \end{tabular}
+ \caption{Valori possibili della variabile \var{h\_errno}.}
+ \label{tab:h_errno_values}
+\end{table}
+
+Insieme alla nuova variabile vengono definite anche delle nuove funzioni per
+stampare l'errore a video, analoghe a quelle di sez.~\ref{sec:sys_strerror}
+per \var{errno}, ma che usano il valore di \var{h\_errno}; la prima è
+\funcd{herror} ed il suo prototipo è:
+
+{\centering
+\vspace{3pt}
+\begin{funcbox}{
+\fhead{netdb.h}
+\fdecl{void herror(const char *string)}
+\fdesc{Stampa un errore di risoluzione.}
+}
+\end{funcbox}}
+
+La funzione è l'analoga di \func{perror} e stampa sullo \textit{standard error} un
+messaggio di errore corrispondente al valore corrente di \var{h\_errno}, a cui
+viene anteposta la stringa \param{string} passata come argomento. La seconda
+funzione è \funcd{hstrerror} ed il suo prototipo è:
+
+{\centering
+\vspace{3pt}
+\begin{funcbox}{
+\fhead{netdb.h}
+\fdecl{const char *hstrerror(int err)}
+\fdesc{Restituisce una stringa corrispondente ad un errore di risoluzione.}
+}
+\end{funcbox}}
+
+\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}).
+
+\itindend{resolver}
+
+
+\subsection{La vecchia interfaccia per la risoluzione dei nomi a dominio}
+\label{sec:sock_name_services}
+
+La principale funzionalità del \textit{resolver} resta quella di risolvere i
+nomi a dominio in indirizzi IP, per cui non ci dedicheremo oltre alle funzioni
+per effetture delle richieste generiche al DNS ed esamineremo invece le
+funzioni del \textit{resolver} dedicate specificamente a questo. Tratteremo in
+questa sezione l'interfaccia tradizionale, che ormai è deprecata, mentre
+vedremo nella sezione seguente la nuova interfaccia.
+
+La prima funzione dell'interfaccia tradizionale è \funcd{gethostbyname} il cui
+scopo è ottenere l'indirizzo di una stazione noto il suo nome a dominio, il
+suo prototipo è:
+
+\begin{funcproto}{
+\fhead{netdb.h}
+\fdecl{struct hostent *gethostbyname(const char *name)}
+\fdesc{Determina l'indirizzo associato ad un nome a dominio.}
+}
+
+{La funzione ritorna il puntatore ad una
+ struttura di tipo \struct{hostent} contenente i dati associati al nome a
+ dominio in caso di successo o un puntatore nullo per un errore.}
+\end{funcproto}
+
+La funzione prende come argomento una stringa \param{name} contenente il nome
+a dominio che si vuole risolvere, in caso di successo i dati ad esso relativi
+vengono memorizzati in una opportuna struttura \struct{hostent} la cui
+definizione è riportata in fig.~\ref{fig:sock_hostent_struct}.
+
+\begin{figure}[!htb]
+ \footnotesize \centering
+ \begin{minipage}[c]{0.80\textwidth}
+ \includestruct{listati/hostent.h}
+ \end{minipage}
+ \caption{La struttura \structd{hostent} per la risoluzione dei nomi a
+ dominio e degli indirizzi IP.}
+ \label{fig:sock_hostent_struct}
+\end{figure}
+
+Quando un programma chiama \func{gethostbyname} e questa usa il DNS per
+effettuare la risoluzione del nome, è con i valori contenuti nei relativi
+record che vengono riempite le varie parti della struttura \struct{hostent}.
+Il primo campo della struttura, \var{h\_name} contiene sempre il \textsl{nome
+ canonico}, che nel caso del DNS è appunto il nome associato ad un record
+\texttt{A}. Il secondo campo della struttura, \var{h\_aliases}, invece è un
+puntatore ad vettore di puntatori, terminato da un puntatore nullo. Ciascun
+puntatore del vettore punta ad una stringa contenente uno degli altri
+possibili nomi associati allo stesso \textsl{nome canonico} (quelli che nel
+DNS vengono inseriti come record di tipo \texttt{CNAME}).
+
+Il terzo campo della struttura, \var{h\_addrtype}, indica il tipo di indirizzo
+che è stato restituito, e può assumere soltanto i valori \const{AF\_INET} o
+\const{AF\_INET6}, mentre il quarto campo, \var{h\_length}, indica la
+lunghezza dell'indirizzo stesso in byte.
+
+Infine il campo \var{h\_addr\_list} è il puntatore ad un vettore di puntatori
+ai singoli indirizzi; il vettore è terminato da un puntatore nullo. Inoltre,
+come illustrato in fig.~\ref{fig:sock_hostent_struct}, viene definito il campo
+\var{h\_addr} come sinonimo di \code{h\_addr\_list[0]}, cioè un riferimento
+diretto al primo indirizzo della lista.
+
+Oltre ai normali nomi a dominio la funzione accetta come argomento
+\param{name} anche indirizzi numerici, in formato dotted decimal per IPv4 o
+con la notazione illustrata in sez.~\ref{sec:IP_ipv6_notation} per IPv6. In
+tal caso \func{gethostbyname} non eseguirà nessuna interrogazione remota, ma
+si limiterà a copiare la stringa nel campo \var{h\_name} ed a creare la
+corrispondente struttura \var{in\_addr} da indirizzare con
+\code{h\_addr\_list[0]}.
+
+Con l'uso di \func{gethostbyname} 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 \textit{resolver}; dato che questo non è molto comodo è stata
+definita (è una estensione fornita dalla \acr{glibc}, disponibile anche in
+altri sistemi unix-like) un'altra funzione, \funcd{gethostbyname2}, il cui
+prototipo è:
+
+\begin{funcproto}{
+\fhead{netdb.h}
+\fhead{sys/socket.h}
+\fdecl{struct hostent *gethostbyname2(const char *name, int af)}
+\fdesc{Determina l'indirizzo del tipo scelto associato ad un nome a dominio.}
+}
+
+{La funzione ritorna il puntatore ad una
+ struttura di tipo \struct{hostent} contenente i dati associati al nome a
+ dominio in caso di successo e un puntatore nullo per un errore.}
+\end{funcproto}
+
+In questo caso la funzione prende un secondo argomento \param{af} che indica
+quale famiglia di indirizzi è quella che dovrà essere utilizzata per
+selezionare i risultati restituiti dalla funzione; i soli valori consentiti
+sono \const{AF\_INET} o \const{AF\_INET6} per indicare rispettivamente IPv4 e
+IPv6 (per questo è necessario l'uso di \headfile{sys/socket.h}). Per tutto il
+resto la funzione è identica a \func{gethostbyname}, ed identici sono i suoi
+risultati.
+
+\begin{figure}[!htb]
+ \footnotesize \centering
+ \begin{minipage}[c]{\codesamplewidth}
+ \includecodesample{listati/mygethost.c}
+ \end{minipage}
+ \normalsize
+ \caption{Esempio di codice per la risoluzione di un indirizzo.}
+ \label{fig:mygethost_example}
+\end{figure}
+
+Vediamo allora un primo esempio dell'uso delle funzioni di risoluzione, in
+fig.~\ref{fig:mygethost_example} è riportato un estratto del codice di un
+programma che esegue una semplice interrogazione al \textit{resolver} usando
+\func{gethostbyname} e poi ne stampa a video i risultati. Al solito il
+sorgente completo, che comprende il trattamento delle opzioni ed una funzione
+per stampare un messaggio di aiuto, è nel file \texttt{mygethost.c} dei
+sorgenti allegati alla guida.
+
+Il programma richiede un solo argomento che specifichi il nome da cercare,
+senza il quale (\texttt{\small 15--18}) esce con un errore. Dopo di che
+(\texttt{\small 20}) si limita a chiamare \func{gethostbyname}, ricevendo il
+risultato nel puntatore \var{data}. Questo (\texttt{\small 21--24}) viene
+controllato per rilevare eventuali errori, nel qual caso il programma esce
+dopo aver stampato un messaggio con \func{herror}.
+
+Se invece la risoluzione è andata a buon fine si inizia (\texttt{\small 25})
+con lo stampare il nome canonico, dopo di che (\texttt{\small 26--30}) si
+stampano eventuali altri nomi. Per questo prima (\texttt{\small 26}) si prende
+il puntatore alla cima della lista che contiene i nomi e poi (\texttt{\small
+ 27--30}) si esegue un ciclo che sarà ripetuto fin tanto che nella lista si
+troveranno dei puntatori validi per le stringhe dei nomi (si ricordi che la
+lista viene terminata da un puntatore nullo); prima (\texttt{\small 28}) si
+stamperà la stringa e poi (\texttt{\small 29}) si provvederà ad incrementare
+il puntatore per passare al successivo elemento della lista.
+
+Una volta stampati i nomi si passerà a stampare gli indirizzi, il primo passo
+(\texttt{\small 31--38}) è allora quello di riconoscere il tipo di indirizzo
+sulla base del valore del campo \var{h\_addrtype}, stampandolo a video. Si è
+anche previsto di stampare un errore nel caso (che non dovrebbe mai accadere)
+di un indirizzo non valido.
+
+Infine (\texttt{\small 39--44}) si stamperanno i valori degli indirizzi, di
+nuovo (\texttt{\small 39}) si inizializzerà un puntatore alla cima della lista
+e si eseguirà un ciclo fintanto che questo punterà ad indirizzi validi in
+maniera analoga a quanto fatto in precedenza per i nomi a dominio. Si noti
+come, essendo il campo \var{h\_addr\_list} un puntatore ad strutture di
+indirizzi generiche, questo sia ancora di tipo \texttt{char **} e si possa
+riutilizzare lo stesso puntatore usato per i nomi.
+
+Per ciascun indirizzo valido si provvederà (\texttt{\small 41}) a una
+conversione con la funzione \func{inet\_ntop} (vedi
+sez.~\ref{sec:sock_addr_func}) passandole gli opportuni argomenti, questa
+restituirà la stringa da stampare (\texttt{\small 42}) con il valore
+dell'indirizzo in \var{buffer}, che si è avuto la cura di dichiarare
+inizialmente (\texttt{\small 10}) con dimensioni adeguate; dato che la
+funzione è in grado di tenere conto automaticamente del tipo di indirizzo non
+ci sono precauzioni particolari da prendere.\footnote{volendo essere pignoli
+ si dovrebbe controllarne lo stato di uscita, lo si è tralasciato per non
+ appesantire il codice, dato che in caso di indirizzi non validi si sarebbe
+ avuto un errore con \func{gethostbyname}, ma si ricordi che la sicurezza non
+ è mai troppa.}
+
+Le funzioni illustrate finora hanno un difetto: utilizzano tutte una area di
+memoria interna per allocare i contenuti della struttura \struct{hostent} e
+per questo non possono essere rientranti. L'uso della memoria interna inoltre
+comporta anche che in due successive chiamate i dati potranno essere
+sovrascritti.
+
+Si tenga presente poi che copiare il contenuto della sola struttura non è
+sufficiente per salvare tutti i dati, in quanto questa contiene puntatori ad
+altri dati, che pure possono essere sovrascritti; per questo motivo, se si
+vuole salvare il risultato di una chiamata, occorrerà eseguire quella che si
+chiama una \itindex{deep~copy} \textit{deep copy}.\footnote{si chiama così
+ quella tecnica per cui, quando si deve copiare il contenuto di una struttura
+ complessa (con puntatori che puntano ad altri dati, che a loro volta possono
+ essere puntatori ad altri dati) si deve copiare non solo il contenuto della
+ struttura, ma eseguire una scansione per risolvere anche tutti i puntatori
+ contenuti in essa (e così via se vi sono altre sotto-strutture con altri
+ puntatori) e copiare anche i dati da questi referenziati.}
+
+Per ovviare a questi problemi nella \acr{glibc} sono definite anche delle
+versioni rientranti delle precedenti funzioni, al solito queste sono
+caratterizzate dall'avere un suffisso \texttt{\_r}, pertanto avremo le due
+funzioni \funcd{gethostbyname\_r} e \funcd{gethostbyname2\_r} i cui prototipi
+sono:
+
+\begin{funcproto}{
+\fhead{netdb.h}
+\fhead{sys/socket.h}
+\fdecl{int gethostbyname\_r(const char *name, struct hostent *ret,
+ char *buf, size\_t buflen,\\
+\phantom{int gethostbyname\_r(}struct hostent **result, int *h\_errnop)}
+\fdecl{int gethostbyname2\_r(const char *name, int af,
+ struct hostent *ret, char *buf,\\
+\phantom{int gethostbyname2\_r(}size\_t buflen, struct hostent **result, int *h\_errnop)}
+
+\fdesc{Versioni rientranti delle funzioni \func{gethostbyname} e
+ \func{gethostbyname2}.}
+}
+
+{Le funzioni ritornano $0$ in caso di successo ed un valore diverso da zero per
+ un errore.}
+\end{funcproto}
+
+Gli argomenti \param{name} (e \param{af} per \func{gethostbyname2\_r}) hanno
+lo stesso significato visto in precedenza. Tutti gli altri argomenti hanno lo
+stesso significato per entrambe le funzioni. Per evitare l'uso di variabili
+globali si dovrà allocare preventivamente una struttura \struct{hostent} in
+cui ricevere il risultato, passandone l'indirizzo alla funzione nell'argomento
+\param{ret}. Inoltre, dato che \struct{hostent} contiene dei puntatori, dovrà
+essere allocato anche un buffer in cui le funzioni possano scrivere tutti i
+dati del risultato dell'interrogazione da questi puntati; l'indirizzo e la
+lunghezza di questo buffer devono essere indicati con gli argomenti
+\param{buf} e \param{buflen}.
+
+Gli ultimi due argomenti vengono utilizzati per avere indietro i risultati
+come \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 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 valore non nulla e all'indirizzo puntato
+da \param{result} sarà salvato un puntatore nullo, mentre a quello puntato da
+\param{h\_errnop} sarà salvato il valore del codice di errore, dato che per
+essere rientrante la funzione non può la variabile globale \var{h\_errno}. In
+questo caso il codice di errore, oltre ai valori di
+tab.~\ref{tab:h_errno_values}, può avere anche quello di \errcode{ERANGE}
+qualora il buffer allocato su \param{buf} non sia sufficiente a contenere i
+dati, in tal caso si dovrà semplicemente ripetere l'esecuzione della funzione
+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 questo sono previste delle funzioni apposite (si potrebbero impostare
+direttamente le opzioni di \var{\_\_res.options}, ma queste funzioni
+permettono di semplificare la procedura); la prime sono \funcd{sethostent} e
+\func{endhostent}, il cui prototipo è:
+
+\begin{funcproto}{
+\fhead{netdb.h}
+\fdecl{void sethostent(int stayopen)}
+\fdesc{Richiede l'uso di connessioni TCP per le interrogazioni ad un server DNS.}
+\fdecl{void endhostent(void)}
+\fdesc{Disattiva l'uso di connessioni TCP per le interrogazioni ad un server DNS.}
+}
+
+{Le funzioni non restituiscono nulla, e non danno errori.}
+\end{funcproto}
+
+La funzione \func{sethostent} permette di richiedere l'uso di connessioni TCP
+per la richiesta dei dati, e che queste restino aperte per successive
+richieste; il valore dell'argomento \param{stayopen} indica se attivare questa
+funzionalità, un valore diverso da zero, che indica una condizione vera in C,
+attiva la funzionalità. Per disattivare l'uso delle connessioni TCP si può
+invece usare \func{endhostent}, e come si vede la funzione è estremamente
+semplice, non richiedendo nessun argomento.
+
+Infine si può richiedere la risoluzione inversa di un indirizzo IP od IPv6,
+per ottenerne il nome a dominio ad esso associato, per fare questo si può
+usare la funzione \funcd{gethostbyaddr}, il cui prototipo è:
+
+\begin{funcproto}{
+\fhead{netdb.h}
+\fhead{sys/socket.h}
+\fdecl{struct hostent *gethostbyaddr(const char *addr, int len, int type)}
+\fdesc{Richiede la risoluzione inversa di un indirizzo IP.}
+}
+
+{La funzione ritorna l'indirizzo ad una struttura \struct{hostent} in caso di
+ successo e \val{NULL} per un errore.}
+\end{funcproto}
+
+In questo caso l'argomento \param{addr} dovrà essere il puntatore ad una
+appropriata struttura contenente il valore dell'indirizzo IP (o IPv6) che si
+vuole risolvere. L'uso del tipo \texttt{char *} per questo argomento è
+storico, il dato dovrà essere fornito in una struttura \struct{in\_addr} per
+un indirizzo IPv4 ed una struttura \struct{in6\_addr} per un indirizzo IPv6.
+
+Si ricordi inoltre, come illustrato in fig.~\ref{fig:sock_sa_ipv4_struct}, che
+mentre \struct{in\_addr} corrisponde in realtà ad un oridinario numero intero
+a 32 bit (da esprimere comunque in \textit{network order}) non altrettanto
+avviene per \struct{in6\_addr}, pertanto è sempre opportuno inizializzare
+questi indirizzi con \func{inet\_pton} (vedi
+sez.~\ref{sec:sock_conv_func_gen}).
+
+Nell'argomento \param{len} se ne dovrà poi specificare la dimensione
+(rispettivamente 4 o 16), infine l'argomento
+\param{type} deve indicare 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 funzione comunque inizializza anche il primo campo della lista
+\var{h\_addr\_list} col valore dell'indirizzo passato come argomento.
+
+Dato che \func{gethostbyaddr} usa un buffer statico, anche di questa funzione
+esiste una versione rientrante \funcd{gethostbyaddr\_r} fornita come
+estensione dalla \acr{glibc}, il cui prototipo è:
+
+\begin{funcproto}{
+\fhead{netdb.h}
+\fhead{sys/socket.h}
+\fdecl{struct hostent *gethostbyaddr\_r(const void *addr, socklen\_t len, int type,\\
+\phantom{struct hostent *gethostbyaddr\_r(}struct hostent *ret, char *buf, size\_t buflen,\\
+\phantom{struct hostent *gethostbyaddr\_r(}struct hostent **result, int *h\_errnop);}
+\fdesc{Richiede la risoluzione inversa di un indirizzo IP.}
+}
+
+{La funzione ritorna $0$ in caso di successo e un valore non nullo per un errore.}
+\end{funcproto}
+
+La funzione prende per gli argomenti \param{addr}, \param{len} e \param{type}
+gli stessi valori di \func{gethostbyaddr} con lo stesso significato, gli
+argomenti successivi vengono utilizzati per restituire i dati, sono identici a
+quelli già illustrati in per \func{gethostbyname\_r} e
+\func{gethostbyname2\_r} e devono essere usati allo stesso modo.
+
+Infine lo standard POSIX prevede la presenza della funzione
+\funcd{gethostent}, il cui prototipo è:
+
+\begin{funcproto}{
+\fhead{netdb.h}
+\fdecl{struct hostent *gethostent(void)}
+\fdesc{Ottiene la voce successiva nel database dei nomi a dominio.}
+}
+
+{La funzione ritorna l'indirizzo ad una struttura \struct{hostent} in caso di
+ successo e \val{NULL} per un errore.}
+\end{funcproto}
+
+La funzione dovrebbe ritornare (come puntatore alla solita struttura
+\struct{hostent} allocata internamente) la voce successiva nel database dei
+nomi a dominio, ma questo ha un significato soltato quando è relativo alla
+lettura dei dati da un file come \conffile{/etc/hosts} e non per i risultati
+del DNS. Nel caso della \acr{glibc} questa viene usata allora solo per la
+lettura delle voci presenti in quest'ultimo, come avviene anche in altri
+sistemi unix-like, ed inoltre ignora le voci relative ad indirizzi IPv6.
+
+Della stessa funzione la \acr{glibc} fornisce anche una versione rientrante
+\funcd{gethostent\_r}, il cui prototipo è:
+
+\begin{funcproto}{
+\fhead{netdb.h}
+\fdecl{struct hostent *gethostent\_r(struct hostent *ret, char *buf, size\_t buflen,\\
+\phantom{struct hostent *gethostent\_r(}struct hostent **result, int *h\_errnop);}
+\fdesc{Ottiene la voce successiva nel database dei nomi a dominio.}
+}
+
+{La funzione ritorna $0$ in caso di successo e un valore non nullo per un errore.}
+\end{funcproto}
+
+La funzione ha lo stesso effetto di \func{gethostent}; gli argomenti servono a
+restituire i risultati in maniera rientrante e vanno usati secondo le modalità
+già illustrate per \func{gethostbyname\_r} e \func{gethostbyname2\_r}.
+
+Dati i limiti delle funzioni \func{gethostbyname} e \func{gethostbyaddr} con
+l'uso 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}),
+è stata successivamente proposta,
+nell'\href{http://www.ietf.org/rfc/rfc2553.txt}{RFC~2553} un diversa
+interfaccia con l'introduzione due nuove funzioni di
+risoluzione,\footnote{dette funzioni sono presenti nella \acr{glibc} 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{funcproto}{
+\fhead{netdb.h}
+\fhead{sys/types.h}
+\fhead{sys/socket.h}
+\fdecl{struct hostent *getipnodebyname(const char *name, int af, int
+ flags, int *error\_num)}
+\fdesc{Richiede la risoluzione di un nome a dominio.}
+\fdecl{struct hostent *getipnodebyaddr(const void *addr, size\_t len,
+ int af, int *error\_num)}
+\fdesc{Richiede la risoluzione inversa di un indirizzo IP.}
+}
+
+{Le funzioni ritornano l'indirizzo ad una struttura \struct{hostent} in caso
+ di successo e \val{NULL} per un errore.}
+\end{funcproto}
+
+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{8cm}|}
+ \hline
+ \textbf{Costante} & \textbf{Significato} \\
+ \hline
+ \hline
+ \constd{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.\\
+ \constd{AI\_ALL} & Usato con \const{AI\_V4MAPPED}; richiede sia
+ indirizzi IPv4 che IPv6, e gli indirizzi IPv4
+ saranno rimappati in IPv6.\\
+ \constd{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.\\
+ \constd{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 disallocare 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{funcproto}{
+\fhead{netdb.h}
+\fhead{sys/types.h}
+\fhead{sys/socket.h}
+\fdecl{void freehostent(struct hostent *ip)}
+\fdesc{Disalloca una struttura \var{hostent}.}
+}
+
+{La funzione non ritorna nulla, e non da errori.}
+\end{funcproto}
+
+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{get\textsl{XXX}byname} e \texttt{get\textsl{XXX}byaddr} (dove
+\texttt{\textsl{XXX}} indica il servizio) 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 &\conffile{/etc/hosts}&\struct{hostent}&\func{gethostbyname}&
+ \func{gethostbyaddr}\\
+ servizio &\conffile{/etc/services}&\struct{servent}&\func{getservbyname}&
+ \func{getservbyport}\\
+ rete &\conffile{/etc/networks}&\struct{netent}&\funcm{getnetbyname}&
+ \funcm{getnetbyaddr}\\
+ protocollo&\conffile{/etc/protocols}&\struct{protoent}&
+ \funcm{getprotobyname}&\funcm{getprotobyaddr}\\
+ \hline
+ \end{tabular}
+ \caption{Funzioni di risoluzione dei nomi per i vari servizi del
+ \textit{Name Service Switch} riguardanti la rete.}
+ \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 \textit{Name
+ Service Switch} 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 di rete più comuni (cioè \texttt{http}, \texttt{smtp},
+ecc.) da associare alle rispettive porte. Le due funzioni da utilizzare per
+questo sono \funcd{getservbyname} e \funcd{getservbyport}, che permettono
+rispettivamente di ottenere il numero di porta associato ad un servizio dato
+il nome e viceversa; i loro prototipi sono:
+
+
+
+\begin{funcproto}{
+\fhead{netdb.h}
+\fdecl{struct servent *getservbyname(const char *name, const char *proto)}
+\fdecl{struct servent *getservbyport(int port, const char *proto)}
+\fdesc{Risolvono il nome di un servizio nel rispettivo numero di porta e viceversa.}
+}
+
+{Le funzioni ritornano il puntatore ad una struttura \struct{servent} con i
+ risultati in caso di successo e \val{NULL} per un errore.}
+\end{funcproto}
+
+Entrambe le funzioni prendono come ultimo argomento una stringa \param{proto}
+che indica il protocollo per il quale si intende effettuare la ricerca (le
+informazioni mantenute in \conffile{/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 di 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
+ \conffile{/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 \conffile{/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]{0.80\textwidth}
+ \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 utilizzano una loro struttura dedicata del tutto analoga alle
+precedenti: 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{funcproto}{
+\fhead{netdb.h}
+\fdecl{struct servent *getservent(void)}
+\fdesc{Legge la voce successiva nel file \conffile{/etc/services}.}
+\fdecl{void setservent(int stayopen)}
+\fdesc{Apre il file \conffile{/etc/services} e si posiziona al suo inizio.}
+\fdecl{void endservent(void)}
+\fdesc{Chiude il file \conffile{/etc/services}.}
+}
+
+{Le due funzioni \func{setservent} e \func{endservent} non ritornano nulla,
+ \func{getservent} restituisce il puntatore ad una struttura \struct{servent}
+ in caso di successo e \val{NULL} per un errore o fine del file.}
+\end{funcproto}
+
+La prima funzione, \func{getservent}, legge una singola voce a partire dalla
+posizione corrente in \conffile{/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
+\conffile{/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.
+
+\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 &\func{setservent} &\func{getservent} &\func{endservent}\\
+ rete &\funcm{setnetent} &\funcm{getnetent} &\funcm{endnetent}\\
+ protocollo&\funcm{setprotoent}&\funcm{getprotoent}&\funcm{endprotoent}\\
+ \hline
+ \end{tabular}
+ \caption{Funzioni lettura sequenziale dei dati del
+ \textit{Name Service Switch}.}
+ \label{tab:name_sequential_read}
+\end{table}
+
+L'argomento \param{stayopen} di \func{setservent}, se diverso da zero, fa sì
+che il file resti aperto anche fra diverse chiamate a \func{getservbyname} e
+\func{getservbyport}; 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, \func{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.
+
+
+\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 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, comunque esse non forniscono una interfaccia
+sufficientemente generica.\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.}
+
+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}, 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; la funzione è stata introdotta, insieme a \func{getnameinfo}
+che vedremo più avanti,
+nell'\href{http://www.ietf.org/rfc/rfc2553.txt}{RFC~2553} ed il suo prototipo è:
+
+
+\begin{funcproto}{
+\fhead{netdb.h}
+\fhead{sys/socket.h}
+\fdecl{int getaddrinfo(const char *node, const char *service, const
+ struct addrinfo *hints, \\
+\phantom{int getaddrinfo(}struct addrinfo **res)}
+\fdesc{Esegue una risoluzione di un nome a dominio e di un nome di servizio.}
+}
+
+{La funzione ritorna $0$ in caso di successo e un codice di errore diverso da
+ zero per un errore.}
+\end{funcproto}
+
+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 \val{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.
+
+Come ultimo argomento in \param{res} 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à all'indirizzo puntato da \param{res} il
+puntatore iniziale ad una \textit{linked list} di strutture di tipo
+\struct{addrinfo} contenenti tutte le informazioni ottenute.
+
+\begin{figure}[!htb]
+ \footnotesize \centering
+ \begin{minipage}[c]{0.90\textwidth}
+ \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}
+
+Come illustrato la struttura \struct{addrinfo}, la cui definizione è 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. La definizione è ripresa direttamente dal file \headfiled{netdb.h}
+in cui 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.
+
+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 e devono essere nulli
+o \val{NULL} in ingresso; 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
+\val{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{AF\_INET} e \const{AF\_INET6}, mentre
+se non si vuole specificare nessuna famiglia di indirizzi si può usare il
+valore \const{AF\_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
+\conffile{/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.
+
+\begin{table}[!htb]
+ \centering
+ \footnotesize
+ \begin{tabular}[c]{|l|p{8cm}|}
+ \hline
+ \textbf{Costante} & \textbf{Significato} \\
+ \hline
+ \hline
+ \const{AI\_ADDRCONFIG} & 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}.\\
+ \constd{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}. \\
+ \constd{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.\\
+ \constd{AI\_NUMERICSERVICE}& Analogo di \const{AI\_NUMERICHOST} per la
+ risoluzione di un servizio, con
+ \param{service} che deve essere espresso in forma
+ numerica.\\
+ \constd{AI\_PASSIVE} & Viene utilizzato per ottenere un indirizzo in
+ formato adatto per una successiva chiamata a
+ \func{bind}. Se specificato quando si è usato
+ \val{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\_V4MAPPED} & Stesso significato dell'analoga di
+ tab.~\ref{tab:sock_getipnodebyname_flags}.\\
+ \hline
+ \const{AI\_CANONIDN} & Se il nome canonico richiesto con
+ \const{AI\_CANONNAME} è codificato con questo
+ flag la codifica viene convertita in forma
+ leggibile nella localizzazione corrente.\\
+ \const{AI\_IDN} & Se specificato il nome viene convertito, se
+ necessario, nella codifica IDN, usando la
+ localizzazione corrente.\\
+ \const{AI\_IDN\_ALLOW\_UNASSIGNED} & attiva il controllo
+ \texttt{IDNA\_ALLOW\_UNASSIGNED}.\\
+ \const{AI\_AI\_IDN\_USE\_STD3\_ASCII\_RULES} & attiva il controllo
+ \texttt{IDNA\_USE\_STD3\_ASCII\_RULES}\\
+ \hline
+ \end{tabular}
+ \caption{Costanti associate ai bit del campo \var{ai\_flags} della struttura
+ \struct{addrinfo}.}
+ \label{tab:ai_flags_values}
+\end{table}
+
+% TODO mettere riferimento a IDNA_ALLOW_UNASSIGNED e IDNA_USE_STD3_ASCII_RULES
+
+Infine gli ultimi dettagli si controllano con il 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.
+
+Nella seconda parte della tabella si sono riportati i valori delle costanti
+aggiunte a partire dalla \acr{glibc} 2.3.4 per gestire la
+internazionalizazione dei nomi a dominio (IDN o \textit{Internationalized
+ Domain Names}) secondo quanto specificato
+nell'\href{http://www.ietf.org/rfc/rfc3490.txt}{RFC~3490} (potendo cioè usare
+codifiche di caratteri che consentono l'espressione di nomi a dominio in
+qualunque lingua).
+
+Come accennato passando un valore \val{NULL} per l'argomento \param{hints} si
+effettua una risuluzione generica, equivalente ad aver impostato un valore
+nullo per \var{ai\_family} e \var{ai\_socktype}, un valore \const{AF\_UNSPEC}
+per \var{ai\_family} e il valore \code{(AI\_V4MAPPED|AI\_ADDRCONFIG)} per
+\var{ai\_flags}.
+
+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
+ \constd{EAI\_ADDRFAMILY}& La richiesta non ha nessun indirizzo di rete
+ per la famiglia di indirizzi specificata. \\
+ \constd{EAI\_AGAIN} & Il DNS ha restituito un errore di risoluzione
+ temporaneo, si può ritentare in seguito. \\
+ \constd{EAI\_BADFLAGS}& Il campo \var{ai\_flags} contiene dei valori non
+ validi per i flag o si è richiesto
+ \const{AI\_CANONNAME} con \param{name} nullo. \\
+ \constd{EAI\_FAIL} & Il DNS ha restituito un errore di risoluzione
+ permanente. \\
+ \constd{EAI\_FAMILY} & La famiglia di indirizzi richiesta non è
+ supportata. \\
+ \constd{EAI\_MEMORY} & È stato impossibile allocare la memoria necessaria
+ alle operazioni. \\
+ \constd{EAI\_NODATA} & La macchina specificata esiste, ma non ha nessun
+ indirizzo di rete definito. \\
+ \constd{EAI\_NONAME} & Il nome a dominio o il servizio non sono noti,
+ viene usato questo errore anche quando si specifica
+ il valore \val{NULL} per entrambi gli argomenti
+ \param{node} e \param{service}. \\
+ \constd{EAI\_SERVICE} & Il servizio richiesto non è disponibile per il tipo
+ di socket richiesto, anche se può esistere per
+ altri tipi di socket. \\
+ \constd{EAI\_SOCKTYPE}& Il tipo di socket richiesto non è supportato. \\
+ \constd{EAI\_SYSTEM} & C'è stato un errore di sistema, si può controllare
+ \var{errno} per i dettagli. \\
+% \hline
+% TODO estensioni GNU, trovarne la documentazione
+% \constd{EAI\_INPROGRESS}& Richiesta in corso. \\
+% \constd{EAI\_CANCELED}& La richiesta è stata cancellata.\\
+% \constd{EAI\_NOTCANCELED}& La richiesta non è stata cancellata. \\
+% \constd{EAI\_ALLDONE} & Tutte le richieste sono complete. \\
+% \constd{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, simile a \func{strerror}, che consente di
+utilizzare direttamente il codice restituito dalla funzione per stampare a
+video un messaggio esplicativo; la funzione è \funcd{gai\_strerror} ed il suo
+prototipo è:
+
+\begin{funcproto}{
+\fhead{netdb.h}
+\fdecl{const char *gai\_strerror(int errcode)}
+\fdesc{Fornisce il messaggio corrispondente ad un errore di \func{getaddrinfo}.}
+}
+
+{La funzione ritorna il puntatore alla stringa contenente il messaggio di
+ errore.}
+\end{funcproto}
+
+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, la funzione è rientrante.
+
+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 \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]{\codesamplewidth}
+ \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 (questa eventualità non dovrebbe comunque 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'identificazione
+(\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
+ in 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{Console}
+[piccardi@gont sources]$ \textbf{./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{Console}
+%$
+
+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{funcproto}{
+\fhead{netdb.h}
+\fdecl{void freeaddrinfo(struct addrinfo *res)}
+\fdesc{Libera la memoria allocata da una precedente chiamata a \func{getaddrinfo}.}
+}
+
+{La funzione non restituisce nessun codice di errore.}
+\end{funcproto}
+
+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} ed usare un indirizzo non valido o già liberato può avere
+conseguenze non prevedibili.
+
+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 \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 interfaccia 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{getipnodebyname} e \func{getservbyname} è
+\funcd{getnameinfo}, ed il suo prototipo è:
+
+\begin{funcproto}{
+\fhead{netdb.h}
+\fhead{sys/socket.h}
+\fdecl{int getnameinfo(const struct sockaddr *sa, socklen\_t salen, \\
+\phantom{int getnameinfo(}char *host, size\_t hostlen, char *serv, size\_t
+servlen, int flags)}
+\fdesc{Effettua una risoluzione di un indirizzo di rete in maniera
+ indipendente dal protocollo.}
+}
+
+{La funzione ritorna $0$ in caso di successo e un codice di errore diverso da
+ zero per un errore.}
+\end{funcproto}
+
+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}. Quando non si è
+interessati ad uno dei due, si può passare il valore \val{NULL} come argomento,
+così che la corrispondente informazione non venga 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}, nella seconda parte della tabella si sono
+aggiunti i valori introdotto con la \acr{glibc} 2.3.4 per gestire la
+internazionalizzione dei nomi a dominio.
+
+\begin{table}[!htb]
+ \centering
+ \footnotesize
+ \begin{tabular}[c]{|l|p{8cm}|}
+ \hline
+ \textbf{Costante} & \textbf{Significato} \\
+ \hline
+ \hline
+ \constd{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.\\
+ \constd{NI\_NOFQDN} & Richiede che venga restituita solo il nome della
+ macchina all'interno del dominio al posto del
+ nome completo (FQDN).\\
+ \constd{NI\_NAMEREQD} & Richiede la restituzione di un errore se il nome
+ non può essere risolto.\\
+ \constd{NI\_NUMERICHOST}& Richiede che venga restituita la forma numerica
+ dell'indirizzo (questo succede sempre se il nome
+ non può essere ottenuto).\\
+ \constd{NI\_NUMERICSERV}& Richiede che il servizio venga restituito in
+ forma numerica (attraverso il numero di
+ porta).\\
+ \hline
+ \const{NI\_IDN} & Se specificato il nome restituito viene convertito usando la
+ localizzazione corrente, se necessario, nella
+ codifica IDN.\\
+ \const{NI\_IDN\_ALLOW\_UNASSIGNED} & attiva il controllo
+ \texttt{IDNA\_ALLOW\_UNASSIGNED}.\\
+ \const{NI\_AI\_IDN\_USE\_STD3\_ASCII\_RULES} & attiva il controllo
+ \texttt{IDNA\_USE\_STD3\_ASCII\_RULES}\\
+ \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
+\constd{NI\_MAXHOST} e \constd{NI\_MAXSERV}\footnote{in Linux le due costanti
+ sono definite in \headfile{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 interfaccia semplificata è \texttt{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]{\codesamplewidth}
+ \includecodesample{listati/sockconn.c}
+ \end{minipage}
+ \normalsize
+ \caption{Il codice della funzione \texttt{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 \conffile{/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 si sono stampati i
+messaggi d'errore direttamente nella funzione; infatti non si può avere
+nessuna certezza che detti valori siano negativi e per cui stampare subito
+l'errore diventa necessario per evitare ogni possibile ambiguità nei confronti
+del valore di ritorno in caso di successo.
+
+Una volta definite le variabili occorrenti (\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), mentre 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
+opachi rispetto all'uso della funzione \func{connect}.
+
+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 \texttt{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]{\codesamplewidth}
+ \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}
+
+La seconda funzione di ausilio che abbiamo creato è \texttt{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
+\texttt{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.
+
+\begin{figure}[!htb]
+ \footnotesize \centering
+ \begin{minipage}[c]{\codesamplewidth}
+ \includecodesample{listati/sockbind.c}
+ \end{minipage}
+ \normalsize
+ \caption{Il codice della funzione \texttt{sockbind}.}
+ \label{fig:sockbind_code}
+\end{figure}
+
+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 \val{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 \texttt{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 \textit{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
+\textit{standard error}.
+
+\begin{figure}[!htbp]
+ \footnotesize \centering
+ \begin{minipage}[c]{\codesamplewidth}
+ \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 \texttt{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:sock_options}
+
+Benché dal punto di vista del loro uso come canali di trasmissione di dati i
+socket vengano trattati allo stesso modo dei file, acceduti tramite i file
+descriptor, e gestiti con le ordinarie funzioni di lettura e scrittura dei
+file, l'interfaccia standard usata per la gestione dei file generici non è
+comunque sufficiente a controllare la moltitudine di caratteristiche
+specifiche che li contraddistinguono, considerato tra l'altro che queste
+possono essere completamente diverse fra loro a seconda del tipo di socket 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, che vengono
+raggruppate sotto il nome generico di ``\textit{socket options}'', ma
+soprattutto analizzaremo quali sono queste opzioni e quali caretteristiche e
+comportamenti dei socket permettono di controllare.
+
+
+\subsection{Le funzioni di gestione delle opzioni dei socket}
+\label{sec:sock_setsockopt}
+
+La modalità principale con cui si possono gestire le caratteristiche dei
+socket (ne vedremo delle ulteriori nelle prossime sezioni) è quella che passa
+attraverso l'uso di due funzioni di sistema 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{funcproto}{
+\fhead{sys/socket.h}
+\fhead{sys/types.h}
+\fdecl{int setsockopt(int sock, int level, int optname, const void
+ *optval, socklen\_t optlen)}
+\fdesc{Imposta le opzioni di un socket.}
+}
+
+{La funzione ritorna $0$ in caso di successo e $-1$ per un errore, nel qual
+ caso \var{errno} assumerà uno dei 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{funcproto}
+
+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.
+
+\begin{table}[!htb]
+ \centering
+ \footnotesize
+ \begin{tabular}[c]{|l|l|}
+ \hline
+ \textbf{Livello} & \textbf{Significato} \\
+ \hline
+ \hline
+ \constd{SOL\_SOCKET}& Opzioni generiche dei socket.\\
+ \constd{SOL\_IP} & Opzioni specifiche per i socket che usano IPv4.\\
+ \constd{SOL\_TCP} & Opzioni per i socket che usano TCP.\\
+ \constd{SOL\_IPV6} & Opzioni specifiche per i socket che usano IPv6.\\
+ \constd{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}
+
+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 \conffile{/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}.
+
+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 \conffile{/etc/protocols}, con una eccezione specifica, che è quella del
+protocollo ICMP, per la quale non esiste una costante, il che è comprensibile
+dato che il suo valore, 1, è quello che viene assegnato a \const{SOL\_SOCKET}.
+
+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 \type{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 dalla \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, ma
+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 \val{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{funcproto}{
+\fhead{sys/socket.h}
+\fhead{sys/types.h}
+\fdecl{int getsockopt(int s, int level, int optname, void *optval,
+ socklen\_t *optlen)}
+\fdesc{Legge le opzioni di un socket.}
+}
+
+{La funzione ritorna $0$ in caso di successo e $-1$ per un errore, nel qual
+ caso \var{errno} assumerà uno dei 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{funcproto}
+
+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 dimensione 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, indipendentemente da quale protocollo
+venga poi utilizzato. 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}. 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\_ACCEPTCONN}&$\bullet$& & &\texttt{int}&
+ Indica se il socket è in ascolto.\\
+ \const{SO\_ATTACH\_FILTER}& &$\bullet$& &\texttt{sock\_fprog}&
+ Aggancia un filtro BPF al socket.\\
+ \const{SO\_BINDTODEVICE}&$\bullet$&$\bullet$& &\texttt{char *}&
+ Lega il socket ad un dispositivo.\\
+ \const{SO\_BROADCAST}&$\bullet$&$\bullet$&$\bullet$&\texttt{int}&
+ Attiva o disattiva il \textit{broadcast}.\\
+ \const{SO\_BSDCOMPAT}&$\bullet$&$\bullet$&$\bullet$&\texttt{int}&
+ Abilita la compatibilità con BSD.\\
+ \const{SO\_BUSY\_POLL}&$\bullet$&$\bullet$&$\bullet$&\texttt{int}&
+ Attiva il ``\textit{busy poll}'' sul socket.\\
+ \const{SO\_DEBUG} &$\bullet$&$\bullet$&$\bullet$&\texttt{int}&
+ Abilita il debugging sul socket.\\
+ \const{SO\_DETACH\_FILTER}& &$\bullet$&$\bullet$&\texttt{int}&
+ Rimuove il filtro BPF agganciato al socket.\\
+ \const{SO\_DOMAIN} &$\bullet$& & &\texttt{int}&
+ Legge il tipo di socket.\\
+ \const{SO\_DONTROUTE}&$\bullet$&$\bullet$&$\bullet$&\texttt{int}&
+ Non invia attraverso un gateway.\\
+ \const{SO\_ERROR} &$\bullet$& & &\texttt{int}&
+ Riceve e cancella gli errori pendenti.\\
+ \const{SO\_KEEPALIVE}&$\bullet$&$\bullet$&$\bullet$&\texttt{int}&
+ Controlla l'attività della connessione.\\
+ \const{SO\_LINGER} &$\bullet$&$\bullet$& &\texttt{linger}&
+ Indugia nella chiusura con dati da spedire.\\
+ \const{SO\_LOCK\_FILTER}& &$\bullet$&$\bullet$&\texttt{int}&
+ Blocca il filtro BPF agganciato al socket.\\
+ \const{SO\_MARK} &$\bullet$&$\bullet$& &\texttt{int}&
+ Imposta un ``\textit{firewall mark}'' sul socket.\\
+ \const{SO\_OOBINLINE}&$\bullet$&$\bullet$&$\bullet$&\texttt{int}&
+ Lascia in linea i dati \textit{out-of-band}.\\
+ \const{SO\_PASSCRED} &$\bullet$&$\bullet$&$\bullet$&\texttt{int}&
+ Abilita la ricezione di credenziali.\\
+ \const{SO\_PEEK\_OFF} &$\bullet$&$\bullet$&$\bullet$&\texttt{int}&
+ Imposta il valore del ``\textit{peek offset}''.\\
+ \const{SO\_PEERCRED} &$\bullet$& & &\texttt{ucred}&
+ Restituisce le credenziali del processo remoto.\\
+ \const{SO\_PRIORITY} &$\bullet$&$\bullet$& &\texttt{int}&
+ Imposta la priorità del socket.\\
+ \const{SO\_PROTOCOL} &$\bullet$& & &\texttt{int}&
+ Ottiene il protocollo usato dal socket.\\
+ \const{SO\_RCVBUF} &$\bullet$&$\bullet$& &\texttt{int}&
+ Imposta dimensione del buffer di ricezione.\\
+ \const{SO\_RCVBUFFORCE}&$\bullet$&$\bullet$& &\texttt{int}&
+ Forza dimensione del buffer di ricezione.\\
+ \const{SO\_RCVLOWAT} &$\bullet$&$\bullet$&$\bullet$&\texttt{int}&
+ Basso livello sul buffer di ricezione.\\
+ \const{SO\_RCVTIMEO} &$\bullet$&$\bullet$& &\texttt{timeval}&
+ Timeout in ricezione.\\
+ \const{SO\_REUSEADDR}&$\bullet$&$\bullet$&$\bullet$&\texttt{int}&
+ Consente il riutilizzo di un indirizzo locale.\\
+ \const{SO\_REUSEPORT}&$\bullet$&$\bullet$&$\bullet$&\texttt{int}&
+ Consente il riutilizzo di una porta.\\
+ \const{SO\_RXQ\_OVFL} &$\bullet$&$\bullet$&$\bullet$&\texttt{int}&
+ Richiede messaggio ancillare con pacchetti persi.\\
+ \const{SO\_SNDBUF} &$\bullet$&$\bullet$& &\texttt{int}&
+ Imposta dimensione del buffer di trasmissione.\\
+ \const{SO\_SNDBUFFORCE}&$\bullet$&$\bullet$& &\texttt{int}&
+ Forza dimensione del buffer di trasmissione.\\
+ \const{SO\_SNDLOWAT} &$\bullet$&$\bullet$& &\texttt{int}&
+ Basso livello sul buffer di trasmissione.\\
+ \const{SO\_SNDTIMEO} &$\bullet$&$\bullet$& &\texttt{timeval}&
+ Timeout in trasmissione.\\
+ \const{SO\_TIMESTAMP}&$\bullet$&$\bullet$&$\bullet$&\texttt{int}&
+ Abilita/disabilita la ricezione dei \textit{timestamp}.\\
+ \const{SO\_TYPE} &$\bullet$& & &\texttt{int}&
+ Restituisce il tipo di socket.\\
+ \hline
+ \end{tabular}
+ \caption{Le opzioni disponibili al livello \const{SOL\_SOCKET}.}
+ \label{tab:sock_opt_socklevel}
+\end{table}
+
+% TODO aggiungere e documentare SO_ATTACH_BPF, introdotta con il kernel 3.19,
+% vedi http://lwn.net/Articles/625224/
+% TODO aggiungere e documentare SO_INCOMING_CPU, introdotta con il kernel 3.19,
+% TODO documentare SO_PEERGROUPS introdotta con il kernel 4.13, citata
+% in https://lwn.net/Articles/727385/
+% TODO documentare SO_ZEROCOPY, vedi https://lwn.net/Articles/726917/ (e il
+% resto pure) introdotta con il kernel 4.14
+
+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 si 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.
+
+Le descrizioni delle opzioni presenti in tab.~\ref{tab:sock_opt_socklevel}
+sono estremamente sommarie, è perciò necessario fornire un po' più di
+informazioni. Alcune opzioni inoltre hanno una notevole rilevanza nella
+gestione dei socket, e pertanto il loro utilizzo sarà approfondito
+separatamente in sez.~\ref{sec:sock_options_main}. Quello che segue è quindi
+soltanto un elenco più dettagliato della breve descrizione di
+tab.~\ref{tab:sock_opt_socklevel} sul significato delle varie opzioni:
+
+\begin{basedescript}{\desclabelwidth{2.2cm}\desclabelstyle{\nextlinelabel}}
+\item[\constd{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} ed utilizza per \param{optval} un intero in cui viene
+ restituito 1 se il socket è in ascolto e 0 altrimenti.
+
+\item[\constd{SO\_ATTACH\_FILTER}] questa opzione permette di agganciare ad un
+ socket un filtro di selezione dei pacchetti con la stessa sintassi del BPF
+ (\textit{Berkley Packet Filter}) di BSD, che consente di selezionare, fra
+ tutti quelli ricevuti, verranno letti. Può essere usata solo con
+ \func{setsockopt} ed utilizza per \param{optval} un puntatore ad una
+ struttura \struct{sock\_fprog} (definita in
+ \headfile{linux/filter.h}). Questa opzione viene usata principalmente con i
+ socket di tipo \const{AF\_PACKET} (torneremo su questo in
+ sez.~\ref{sec:packet_socket}) dalla libreria \texttt{libpcap} per
+ implementare programmi di cattura dei pacchetti, e per questo tipo di
+ applicazione è opportuno usare sempre quest'ultima.\footnote{la trattazione
+ del BPF va al di là dell'argomento di questa sezione per la documentazione
+ si consulti il file \texttt{networking/filter.txt} nella documentazione
+ del kernel.}
+
+\item[\constd{SO\_BINDTODEVICE}] questa opzione permette di \textsl{legare} il
+ socket ad una particolare 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}); utilizzando una stringa nulla o un valore nullo per
+ \param{optlen} si può rimuovere un precedente collegamento.
+
+ Il nome della interfaccia deve essere specificato con una stringa terminata
+ da uno zero e di lunghezza massima pari a \constd{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{sec:socket_raw}).
+
+\item[\constd{SO\_BROADCAST}] questa opzione abilita il \textit{broadcast}:
+ quando abilitata i socket di tipo \const{SOCK\_DGRAM} riceveranno i
+ pacchetti inviati all'indirizzo di \textit{broadcast} e potranno scrivere
+ pacchetti su tale indirizzo. Prende per \param{optval} un intero usato come
+ valore logico. L'opzione non ha effetti su un socket di tipo
+ \const{SOCK\_STREAM}.
+
+\item[\constd{SO\_BSDCOMPAT}] questa opzione abilita la compatibilità con il
+ comportamento di BSD (in particolare ne riproduce alcuni bug). Attualmente
+ è una opzione usata solo per il protocollo UDP e ne è prevista la rimozione.
+ 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 \textit{user space}. Con le versioni
+ 2.0.x del kernel erano anche abilitate altre opzioni di compatibilità per i
+ socket raw (modifiche casuali agli header, perdita del flag di
+ \textit{broadcast}) che sono state rimosse con il passaggio al 2.2; è
+ consigliato correggere i programmi piuttosto che usare questa funzione. Dal
+ kernel 2.4 viene ignorata, e dal 2.6 genera un messaggio di log del kernel.
+
+\item[\constd{SO\_BUSY\_POLL}] questa opzione, presente dal kernel 3.11,
+ imposta un tempo approssimato in microsecondi, per cui in caso di ricezione
+ bloccante verrà eseguito un \itindex{busy~poll} ``\textit{busy
+ poll}'',\footnote{con \textit{busy poll} si fa riferimento al
+ \textit{polling} su una risorsa occupata; si continuerà cioè a tentare di
+ leggere anche quando non ci sono dati senza portare il processo stato di
+ \textit{sleep}, in alcuni casi, quando ci si aspetta che i dati arrivino a
+ breve, questa tecnica può dare un miglioramento delle prestazioni.} da
+ indicare in \param{optval} con un valore intero. Si tratta di una opzione
+ utilizzabile solo con socket che ricevono dati da un dispositivo di rete che
+ la supporti, e che consente di ridurre la latenza per alcune applicazioni,
+ ma che comporta un maggiore utilizzo della CPU (e quindi di energia); per
+ questo il valore può essere aumentato solo da processi con i privilegi di
+ amministratore (in particolare con la \textit{capability}
+ \const{CAP\_NET\_ADMIN}). Il valore di default viene controllato dal file
+ \sysctlrelfile{net/core}{busy\_read} per le funzioni di lettura mentre il
+ file \sysctlrelfile{net/core}{busy\_poll} controlla il ``\textit{busy
+ poll}'' per \func{select} e \func{poll}.
+
+\item[\constd{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 \macrod{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
+ \macrod{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[\constd{SO\_DETACH\_FILTER}] consente di distaccare un filtro
+ precedentemente aggiunto ad un socket con l'opzione
+ \const{SO\_ATTACH\_FILTER}, in genere non viene usata direttamente in quanto
+ i filtri BPF vengono automaticamente rimossi alla chiusura del socket, il
+ suo utilizzo è pertanto limitato ai rari casi in cui si vuole rimuovere un
+ precedente filtro per inserirne uno diverso. Come \const{SO\_ATTACH\_FILTER}
+ può essere usato solo \func{setsockopt} e prende per \param{optval} un
+ intero usato come valore logico.
+
+\item[\constd{SO\_DOMAIN}] questa opzione, presente dal kernel 2.6.32, legge
+ il ``\textsl{dominio}'' (la famiglia di indirizzi) del socket.
+. Funziona solo con \func{getsockopt}, ed
+ utilizza per \param{optval} un intero in cui verrà restituito il valore
+ numerico che lo identifica (ad esempio \texttt{AF\_INET}).
+
+\item[\constd{SO\_DONTROUTE}] questa opzione richiede che l'invio dei
+ pacchetti del socket sia eseguito soltanto verso una destinazione
+ direttamente connessa, impedendo l'uso di un \textit{gateway} e saltando
+ ogni processo relativo all'uso della tabella di routing del kernel. Prende
+ per \param{optval} un intero usato come valore logico. È equivalente all'uso
+ del flag \const{MSG\_DONTROUTE} su una \func{send} (vedi
+ sez.~\ref{sec:net_send_recv}).
+
+\item[\constd{SO\_ERROR}] questa opzione riceve un errore presente sul socket;
+ può essere utilizzata soltanto con \func{getsockopt} e prende per
+ \param{optval} un valore intero, nel quale viene restituito il codice di
+ errore, e la condizione di errore sul socket viene cancellata. Viene
+ usualmente utilizzata per ricevere il codice di errore, come accennato in
+ sez.~\ref{sec:TCP_sock_select}, quando si sta osservando il socket con una
+ \func{select} che ritorna a causa dello stesso.
+
+\item[\const{SO\_KEEPALIVE}] questa opzione abilita un meccanismo di verifica
+ della persistenza di una connessione associata al socket; è pertanto
+ effettiva solo sui socket che supportano le connessioni, ed è usata
+ principalmente con il TCP. L'opzione utilizza per \param{optval} un intero
+ usato come valore logico. Maggiori dettagli sul suo funzionamento sono
+ forniti in sez.~\ref{sec:sock_options_main}.
+
+\item[\const{SO\_LINGER}] questa opzione controlla le modalità con cui viene
+ chiuso un socket quando si utilizza un protocollo che supporta le
+ connessioni (è pertanto usata con i socket TCP ed ignorata per UDP) e
+ modifica il comportamento delle funzioni \func{close} e \func{shutdown}.
+ L'opzione richiede che l'argomento \param{optval} sia una struttura di tipo
+ \struct{linger}, definita in \headfile{sys/socket.h} ed illustrata in
+ fig.~\ref{fig:sock_linger_struct}. Maggiori dettagli sul suo funzionamento
+ sono forniti in sez.~\ref{sec:sock_options_main}.
+
+\item[\constd{SO\_LOCK\_FILTER}] consente di bloccare un filtro
+ precedentemente aggiunto ad un socket con l'opzione
+ \const{SO\_ATTACH\_FILTER}, in modo che non possa essere né rimosso né
+ modificato, questo consente di impostare un filtro su un socket, bloccarlo e
+ poi cedere i privilegi con la sicurezza che il filtro permarrà fino alla
+ chiusura del socket. Come \const{SO\_ATTACH\_FILTER} può essere usato solo
+ \func{setsockopt} e prende per \param{optval} un intero usato come valore
+ logico.
+
+\item[\constd{SO\_MARK}] questa opzione, presente dal kernel 2.6.25, imposta
+ un valore di marcatura sui pacchetti del socket. Questa è una funzionalità
+ specifica di Linux, ottenibile anche con l'uso del target \texttt{MARK}
+ del comando \texttt{iptables} (l'argomento è trattato in sez.~3.3.5 di
+ \cite{SGL}). Il valore di marcatura viene mantenuto all'interno dello stack
+ di rete del kernel e può essere usato sia dal \itindex{netfilter}
+ \textit{netfilter}\footnote{il \textit{netfilter} è l'infrastruttura usata
+ per il filtraggio dei pacchetti del kernel, per maggiori dettagli si
+ consulti il cap.~2 di \cite{FwGL}.} di Linux che per impostare politiche
+ di routing avanzato. Il valore deve essere specificato in \param{optval}
+ come un intero. L'opzione richiede i privilegi di amministratore con la
+ \textit{capability} \const{CAP\_NET\_ADMIN}.
+
+\item[\constd{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[\constd{SO\_PASSCRED}] questa opzione abilita sui socket unix-domain
+ (vedi sez.~\ref{sec:unix_socket}) la ricezione dei messaggi di controllo di
+ tipo \const{SCM\_CREDENTIALS}. Prende come \param{optval} un intero usato
+ come valore logico.
+
+\item[\constd{SO\_PEEK\_OFF}] questa opzione, disponibile a partire dal kernel
+ 3.4, imposta un ``\textit{peek offset}'' sul socket (attualmente disponibile
+ solo per i socket unix-domain (vedi sez.~\ref{sec:unix_socket}). La funzione
+ serve come ausilio per l'uso del flag \const{MSG\_PEEK} di \func{recv} che
+ consente di ``\textsl{sbirciare}'' nei dati di un socket, cioè di leggerli
+ senza rimuoverli dalla coda in cui sono mantenuti, così che vengano
+ restituiti anche da una successiva lettura ordinaria.
+
+ Un valore negativo (il default è $-1$) riporta alla situazione ordinaria in
+ cui si ``\textsl{sbircia}'' a partire dalla testa della coda, un valore
+ positivo consente di leggere a partire dalla posizione indicata nella coda e
+ tutte le volte che si sbirciano dei dati il valore dell'offset viene
+ automaticamente aumentato della quantità di dati sbirciati, in modo che si
+ possa proseguire da dove si era arrivati. Il valore deve essere specificato
+ in \param{optval} come intero.
+
+\item[\constd{SO\_PEERCRED}] questa opzione restituisce le credenziali del
+ processo remoto connesso al socket; l'opzione è disponibile solo per socket
+ unix-domain di tipo \textit{stream} e anche per quelli di tipo
+ \textit{datagram} quando se ne crea una coppia con \func{socketpair}, e può
+ essere usata solo con \func{getsockopt}. Utilizza per
+ \param{optval} una apposita struttura \struct{ucred} (vedi
+ sez.~\ref{sec:unix_socket}).
+
+\item[\constd{SO\_PRIORITY}] questa opzione permette di impostare le priorità
+ per tutti i pacchetti che sono inviati sul socket, prende per \param{optval}
+ un valore intero. Con questa opzione il kernel usa il valore per ordinare le
+ priorità sulle code di rete,\footnote{questo richiede che sia abilitato il
+ sistema di \textit{Quality of Service} disponibile con le opzioni di
+ routing avanzato.} i pacchetti con priorità più alta vengono processati
+ per primi, in modalità che dipendono dalla disciplina di gestione della
+ coda. Nel caso di protocollo IP questa opzione permette anche di impostare i
+ valori del campo \textit{type of service} (noto come TOS, vedi
+ sez.~\ref{sec:IP_header}) per i pacchetti uscenti. Per impostare una
+ priorità al di fuori dell'intervallo di valori fra 0 e 6 sono richiesti i
+ privilegi di amministratore con la \textit{capability}
+ \const{CAP\_NET\_ADMIN}.
+
+\item[\constd{SO\_PROTOCOL}] questa opzione, presente dal kernel 2.6.32, legge
+ il protocollo usato dal socket. Funziona solo con \func{getsockopt}, ed
+ utilizza per \param{optval} un intero in cui verrà restituito il valore
+ numerico che lo identifica (ad esempio \texttt{IPPROTO\_TCP}).
+
+\item[\constd{SO\_RCVBUF}] questa opzione imposta la dimensione del buffer di
+ ricezione del socket. Prende per \param{optval} un intero indicante il
+ numero di byte. Il valore di default ed il valore massimo che si può
+ specificare come argomento per questa opzione sono impostabili tramiti gli
+ opportuni valori di \func{sysctl} (vedi sez.~\ref{sec:sock_sysctl}).
+
+ Si tenga presente che nel caso di socket TCP il kernel alloca effettivamente
+ una quantità di memoria doppia rispetto a quanto richiesto con
+ \func{setsockopt} per entrambe le opzioni \const{SO\_RCVBUF} e
+ \const{SO\_SNDBUF}. Questo comporta che una successiva lettura con
+ \func{getsockopt} riporterà un valore diverso da quello impostato con
+ \func{setsockopt}. Questo avviene perché TCP necessita dello spazio in più
+ per mantenere dati amministrativi e strutture interne, e solo una parte
+ viene usata come buffer per i dati, mentre il valore letto da
+ \func{getsockopt} e quello riportato nei vari parametri di
+ \textit{sysctl}\footnote{cioè \sysctlrelfile{net/core}{wmem\_max} e
+ \sysctlrelfile{net/core}{rmem\_max} in \texttt{/proc/sys/net/core} e
+ \sysctlrelfile{net/ipv4}{tcp\_wmem} e \sysctlrelfile{net/ipv4}{tcp\_rmem}
+ in \texttt{/proc/sys/net/ipv4}, vedi sez.~\ref{sec:sock_sysctl}.} indica
+ la memoria effettivamente impiegata. Si tenga presente inoltre che le
+ modifiche alle dimensioni dei buffer di ricezione e trasmissione, per poter
+ essere effettive, devono essere impostate prima della chiamata alle funzioni
+ \func{listen} o \func{connect}.
+
+\item[\constd{SO\_RCVBUFFORCE}] questa opzione, presente dal kernel 2.6.14, è
+ identica a \const{SO\_RCVBUF} ma consente ad un processo con i privilegi di
+ amministratore (per la precisione con la \textit{capability}
+ \const{CAP\_NET\_ADMIN}) di impostare in valore maggiore del limite di
+ \sysctlrelfile{net/core}{rmem\_max}.
+
+\item[\constd{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; con Linux questo valore è sempre 1 e può essere
+ cambiato solo con i kernel a partire dal 2.4. Si tenga presente però che per
+ i kernel prima del 2.6.28 sia \func{poll} che \func{select} non supportano
+ questa funzionalità e ritornano comunque, indicando il socket come
+ leggibile, non appena almeno un byte è presente, con una successiva lettura
+ con \func{read} che si blocca fintanto che non diventa disponibile la
+ quantità di byte indicati. Con \func{getsockopt} si può leggere questo
+ valore mentre \func{setsockopt} darà un errore di \errcode{ENOPROTOOPT}
+ quando il cambiamento non è supportato.
+
+\item[\constd{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.}
+
+ 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 timeout per l'uso di \func{connect}, per avere
+ il quale si può ricorrere a questa opzione (nel qual caso il raggiungimento
+ del \textit{timeout} restituisce l'errore \errcode{EINPROGRESS}).
+
+\item[\const{SO\_REUSEADDR}] questa opzione permette di eseguire la funzione
+ \func{bind} su indirizzi locali che siano già in uso da altri socket;
+ 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 (più propriamente il
+ controllo viene eseguito sulla porta) è già in uso da parte di un altro
+ socket. Maggiori dettagli sul suo funzionamento sono forniti in
+ sez.~\ref{sec:sock_options_main}.
+
+\item[\const{SO\_REUSEPORT}] questa opzione, presente a partire dal kernel
+ 3.9, permette di far usare a più socket di tipo \const{AF\_INET} o
+ \const{AF\_INET6} lo stesso indirizzo locale, e costituisce una estensione
+ della precedente \const{SO\_REUSEADDR}. Maggiori dettagli sul suo
+ funzionamento sono forniti in sez.~\ref{sec:sock_options_main}.
+
+\item[\constd{SO\_RXQ\_OVFL}] questa opzione, presente dal kernel 2.6.33,
+ permette di abilitare o disabilitare sul socket la ricezione di un messaggio
+ ancillare (tratteremo l'argomento in sez.~\ref{sec:net_ancillary_data})
+ contenente un intero senza segno a 32 bit che indica il numero di pacchetti
+ scartati sul socket fra l'ultimo pacchetto ricevuto e questo. L'opzione
+ utilizza per \param{optval} un intero usato come valore logico.
+
+% TODO documentare SO_RXQ_OVFL, vedi https://lwn.net/Articles/626150/ capire
+% che significa 'questo'
+
+\item[\constd{SO\_SNDLOWAT}] questa opzione imposta il valore che indica il
+ numero minimo di byte che devono essere presenti nel buffer di trasmissione
+ 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; 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[\constd{SO\_SNDBUF}] questa opzione imposta la dimensione del buffer di
+ trasmissione del socket. Prende per \param{optval} un intero indicante il
+ numero di byte. Il valore di default ed il valore massimo che si possono
+ specificare come argomento per questa opzione sono impostabili
+ rispettivamente tramite gli opportuni valori di \func{sysctl} (vedi
+ sez.~\ref{sec:sock_sysctl}).
+
+\item[\constd{SO\_SNDBUFFORCE}] questa opzione, presente dal kernel 2.6.14, è
+ identica a \const{SO\_SNDBUF} ma consente ad un processo con i privilegi di
+ amministratore (per la precisione con la \textit{capability}
+ \const{CAP\_NET\_ADMIN}) di impostare in valore maggiore del limite di
+ \sysctlrelfile{net/core}{wmem\_max}.
+
+% TODO verificare il timeout con un programma di test
+
+\item[\constd{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{sendto} e \func{sendmsg}
+ qualora queste restino bloccate per un tempo maggiore di quello specificato.
+
+\item[\constd{SO\_TIMESTAMP}] questa opzione, presente dal kernel 2.6.30,
+ permette di abilitare o disabilitare sul socket la ricezione di un messaggio
+ ancillare di tipo \const{SO\_TIMESTAMP}. Il messaggio viene inviato con
+ livello \const{SOL\_SOCKET} ed nel campo \var{cmsg\_data} (per i dettagli si
+ veda sez.~\ref{sec:net_ancillary_data}) viene impostata una struttura
+ \struct{timeval} che indica il tempo di ricezione dell'ultimo pacchetto
+ passato all'utente. L'opzione utilizza per \param{optval} un intero usato
+ come valore logico.
+
+% TODO capire meglio la tempistica di questi messaggi ancillari
+% TODO documentare SO_TIMESTAMP e le altre opzioni di timestamping dei
+% pacchetti, introdotte nel 2.6.30, vedi nei sorgenti del kernel:
+% Documentation/networking/timestamping.txt
+
+\item[\constd{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à restituito il valore numerico che lo
+ identifica (ad esempio \const{SOCK\_STREAM}).
+
+
+\end{basedescript}
+
+
+\subsection{L'uso delle principali opzioni dei socket}
+\label{sec:sock_options_main}
+
+La descrizione sintetica del significato delle opzioni generiche dei socket,
+riportata nell'elenco in sez.~\ref{sec:sock_generic_options}, è
+necessariamente sintetica, alcune di queste però possono essere utilizzate
+per controllare delle funzionalità che hanno una notevole rilevanza nella
+programmazione dei socket. Per questo motivo faremo in questa sezione un
+approfondimento sul significato delle opzioni generiche più importanti.
+
+
+\constbeg{SO\_KEEPALIVE}
+\subsubsection{L'opzione \const{SO\_KEEPALIVE}}
+
+La prima opzione da approfondire è \const{SO\_KEEPALIVE} che permette di
+tenere sotto controllo lo stato di una connessione. Una connessione infatti
+resta attiva anche quando non viene effettuato alcun traffico su di essa; è
+allora possibile, in caso di una interruzione completa della rete, che la
+caduta della connessione non venga rilevata, dato che sulla stessa non passa
+comunque alcun traffico.
+
+Se si imposta questa opzione, è invece cura del kernel inviare degli appositi
+messaggi sulla rete, detti appunto \textit{keep-alive}, per verificare se la
+connessione è attiva. L'opzione funziona soltanto con i socket che supportano
+le connessioni (non ha senso per socket UDP ad esempio) e si applica
+principalmente ai socket TCP.
+
+Con le impostazioni di default (che sono riprese da BSD) Linux emette un
+messaggio di \textit{keep-alive} (in sostanza un segmento ACK vuoto, cui sarà
+risposto con un altro segmento ACK vuoto) verso l'altro capo della connessione
+se questa è rimasta senza traffico per più di due ore. Se è tutto a posto il
+messaggio viene ricevuto e verrà emesso un segmento ACK di risposta, alla cui
+ricezione ripartirà un altro ciclo di attesa per altre due ore di inattività;
+il tutto avviene all'interno del kernel e le applicazioni non riceveranno
+nessun dato.
+
+Qualora ci siano dei problemi di rete si possono invece verificare i due casi
+di terminazione precoce del server già illustrati in
+sez.~\ref{sec:TCP_conn_crash}. Il primo è quello in cui la macchina remota ha
+avuto un crollo del sistema ed è stata riavviata, per cui dopo il riavvio la
+connessione non esiste più.\footnote{si ricordi che un normale riavvio o il
+ crollo dell'applicazione non ha questo effetto, in quanto in tal caso si
+ passa sempre per la chiusura del processo, e questo, come illustrato in
+ sez.~\ref{sec:file_open_close}, comporta anche la regolare chiusura del
+ socket con l'invio di un segmento FIN all'altro capo della connessione.} In
+questo caso all'invio del messaggio di \textit{keep-alive} si otterrà come
+risposta un segmento RST che indica che l'altro capo non riconosce più
+l'esistenza della connessione ed il socket verrà chiuso riportando un errore
+di \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 per un massimo di 9 volte\footnote{entrambi questi valori possono
+ essere modificati a livello di sistema (cioè per tutti i socket) con gli
+ opportuni parametri illustrati in sez.~\ref{sec:sock_sysctl} ed a livello di
+ singolo socket con le opzioni \texttt{TCP\_KEEP*} di
+ sez.~\ref{sec:sock_tcp_udp_options}.} (per un totale di 11 minuti e 15
+secondi) dopo di che, se non si è ricevuta nessuna risposta, il socket viene
+chiuso dopo aver impostato un errore di \errcode{ETIMEDOUT}. Qualora la
+connessione si sia ristabilita e si riceva un successivo messaggio di risposta
+il ciclo riparte come se niente fosse avvenuto. Infine se si riceve come
+risposta un pacchetto ICMP di destinazione irraggiungibile (vedi
+sez.~\ref{sec:ICMP_protocol}), verrà restituito l'errore corrispondente.
+
+In generale questa opzione serve per individuare una caduta della connessione
+anche quando non si sta facendo traffico su di essa. Viene usata
+principalmente sui server per evitare di mantenere impegnate le risorse che
+verrebbero dedicate a trattare delle connessioni che in realtà sono già
+terminate (quelle che vengono anche chiamate connessioni
+\textsl{semi-aperte}); in tutti quei casi cioè in cui il server si trova in
+attesa di dati in ingresso su una connessione che non arriveranno mai o perché
+il client sull'altro capo non è più attivo o perché non è più in grado di
+comunicare con il server via rete.
+
+\begin{figure}[!htbp]
+ \footnotesize \centering
+ \begin{minipage}[c]{\codesamplewidth}
+ \includecodesample{listati/TCP_echod_fourth.c}
+ \end{minipage}
+ \normalsize
+ \caption{La sezione della nuova versione del server del servizio
+ \textit{echo} che prevede l'attivazione del \textit{keepalive} sui
+ socket.}
+ \label{fig:echod_keepalive_code}
+\end{figure}
+
+Abilitandola dopo un certo tempo le connessioni effettivamente terminate
+verranno comunque chiuse per cui, utilizzando ad esempio una \func{select}, se
+ne potrà rilevare la conclusione e ricevere il relativo errore. Si tenga
+presente però che non può avere la certezza assoluta che un errore di
+\errcode{ETIMEDOUT} ottenuto dopo aver abilitato questa opzione corrisponda
+necessariamente ad una reale conclusione della connessione, il problema
+potrebbe anche essere dovuto ad un problema di routing che perduri per un
+tempo maggiore di quello impiegato nei vari tentativi di ritrasmissione del
+\textit{keep-alive} (anche se questa non è una condizione molto probabile).
+
+Come esempio dell'utilizzo di questa opzione introduciamo all'interno del
+nostro server per il servizio \textit{echo} la nuova opzione \texttt{-k} che
+permette di attivare il \textit{keep-alive} sui socket; tralasciando la parte
+relativa alla gestione di detta opzione (che si limita ad assegnare ad 1 la
+variabile \var{keepalive}) tutte le modifiche al server sono riportate in
+fig.~\ref{fig:echod_keepalive_code}. Al solito il codice completo è contenuto
+nel file \texttt{TCP\_echod\_fourth.c} dei sorgenti allegati alla guida.
+
+Come si può notare la variabile \var{keepalive} è preimpostata (\texttt{\small
+ 8}) ad un valore nullo; essa viene utilizzata sia come variabile logica per
+la condizione (\texttt{\small 14}) che controlla l'attivazione del
+\textit{keep-alive} che come valore dell'argomento \param{optval} della
+chiamata a \func{setsockopt} (\texttt{\small 16}). A seconda del suo valore
+tutte le volte che un processo figlio viene eseguito in risposta ad una
+connessione verrà pertanto eseguita o meno la sezione (\texttt{\small 14--17})
+che esegue l'impostazione di \const{SO\_KEEPALIVE} sul socket connesso,
+attivando il relativo comportamento.
+\constend{SO\_KEEPALIVE}
+
+
+
+\constbeg{SO\_REUSEADDR}
+\subsubsection{Le opzioni \const{SO\_REUSEADDR} e \const{SO\_REUSEPORT}}
+
+La seconda opzione da approfondire è \constd{SO\_REUSEADDR}, che consente di
+eseguire \func{bind} su un socket anche quando la porta specificata è già in
+uso da parte di un altro socket. Si ricordi infatti che, come accennato in
+sez.~\ref{sec:TCP_func_bind}, normalmente la funzione \func{bind} fallisce con
+un errore di \errcode{EADDRINUSE} se la porta scelta è già utilizzata da un
+altro socket, proprio per evitare che possano essere lanciati due server sullo
+stesso indirizzo e la stessa porta, che verrebbero a contendersi i pacchetti
+aventi quella destinazione.
+
+Esistono però situazioni ed esigenze particolari in cui non si vuole che
+questo comportamento di salvaguardia accada, ed allora si può fare ricorso a
+questa opzione. La questione è comunque abbastanza complessa in quanto, come
+sottolinea Stevens in \cite{UNP1}, si distinguono ben quattro casi diversi in
+cui è prevista la possibilità di un utilizzo di questa opzione, il che la
+rende una delle più difficili da capire.
+
+Il primo caso in cui si fa ricorso a \const{SO\_REUSEADDR}, che è anche il più
+comune, è quello in cui un server è terminato ma esistono ancora dei processi
+figli che mantengono attiva almeno una connessione remota che utilizza
+l'indirizzo locale, mantenendo occupata la porta. Quando si riesegue il server
+allora questo riceve un errore sulla chiamata a \func{bind} dato che la porta
+è ancora utilizzata in una connessione esistente.\footnote{questa è una delle
+ domande più frequenti relative allo sviluppo, in quanto è piuttosto comune
+ trovarsi in questa situazione quando si sta sviluppando un server che si
+ ferma e si riavvia in continuazione dopo aver fatto modifiche.} Inoltre se
+si usa il protocollo TCP questo può avvenire anche dopo tutti i processi figli
+sono terminati, dato che una connessione può restare attiva anche dopo la
+chiusura del socket, mantenendosi nello stato \texttt{TIME\_WAIT} (vedi
+sez.~\ref{sec:TCP_time_wait}).
+
+\begin{figure}[!htbp]
+ \footnotesize \centering
+ \begin{minipage}[c]{\codesamplewidth}
+ \includecodesample{listati/sockbindopt.c}
+ \end{minipage}
+ \normalsize
+ \caption{Le sezioni della funzione \texttt{sockbindopt} modificate rispetto al
+ codice della precedente \texttt{sockbind}.}
+ \label{fig:sockbindopt_code}
+\end{figure}
+
+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.
+
+Come esempio di uso di questa connessione abbiamo predisposto una nuova
+versione della funzione \texttt{sockbind} (vedi fig.~\ref{fig:sockbind_code})
+che consenta l'impostazione di questa opzione. La nuova funzione è
+\texttt{sockbindopt}, e le principali differenze rispetto alla precedente sono
+illustrate in fig.~\ref{fig:sockbindopt_code}, dove si sono riportate le
+sezioni di codice modificate rispetto alla versione precedente. Il codice
+completo della funzione si trova, insieme alle altre funzioni di servizio dei
+socket, all'interno del file \texttt{SockUtils.c} dei sorgenti allegati alla
+guida.
+
+In realtà tutto quello che si è fatto è stato introdurre nella nuova funzione
+(\texttt{\small 1}) un nuovo argomento intero, \param{reuse}, che conterrà il
+valore logico da usare nella successiva chiamata (\texttt{\small 14}) a
+\func{setsockopt}. Si è poi aggiunta una sezione (\texttt{\small 13--17}) che
+esegue l'impostazione dell'opzione fra la chiamata a \func{socket} e quella a
+\func{bind}.
+
+\begin{figure}[!htbp]
+ \footnotesize \centering
+ \begin{minipage}[c]{\codesamplewidth}
+ \includecodesample{listati/TCP_echod_fifth.c}
+ \end{minipage}
+ \normalsize
+ \caption{Il nuovo codice per l'apertura passiva del server \textit{echo} che
+ usa la nuova funzione \texttt{sockbindopt}.}
+ \label{fig:TCP_echod_fifth}
+\end{figure}
+
+A questo punto basterà modificare il server per utilizzare la nuova
+funzione; in fig.~\ref{fig:TCP_echod_fifth} abbiamo riportato le sezioni
+modificate rispetto alla precedente versione di
+fig.~\ref{fig:TCP_echod_third}. Al solito il codice completo è coi sorgenti
+allegati alla guida, nel file \texttt{TCP\_echod\_fifth.c}.
+
+Anche in questo caso si è introdotta (\texttt{\small 8}) una nuova variabile
+\var{reuse} che consente di controllare l'uso dell'opzione e che poi sarà
+usata (\texttt{\small 14}) come ultimo argomento di \func{setsockopt}. Il
+valore di default di questa variabile è nullo, ma usando l'opzione \texttt{-r}
+nell'invocazione del server (al solito la gestione delle opzioni non è
+riportata in fig.~\ref{fig:TCP_echod_fifth}) se ne potrà impostare ad 1 il
+valore, per cui in tal caso la successiva chiamata (\texttt{\small 13--17}) a
+\func{setsockopt} attiverà l'opzione \const{SO\_REUSEADDR}.
+
+Il secondo caso in cui viene usata \const{SO\_REUSEADDR} è quando si ha una
+macchina cui sono assegnati diversi indirizzi IP (o come suol dirsi
+\textit{multi-homed}) e si vuole porre in ascolto sulla stessa porta un
+programma diverso (o una istanza diversa dello stesso programma) per indirizzi
+IP diversi. Si ricordi infatti che è sempre possibile indicare a \func{bind}
+di collegarsi solo su di un indirizzo specifico; in tal caso se un altro
+programma cerca di riutilizzare la stessa porta (anche specificando un
+indirizzo diverso) otterrà un errore, a meno di non aver preventivamente
+impostato \const{SO\_REUSEADDR}.
+
+Usando questa opzione diventa anche possibile eseguire \func{bind}
+sull'indirizzo generico, e questo permetterà il collegamento per tutti gli
+indirizzi (di quelli presenti) per i quali la porta non risulti occupata da
+una precedente chiamata più specifica. Si tenga presente infatti che con il
+protocollo TCP non è in genere possibile far partire più server che eseguano
+\func{bind} sullo stesso indirizzo e la stessa porta se su di esso c'è già un
+socket in ascolto, cioè ottenere quello che viene chiamato un
+\itindex{completely~duplicate~binding} \textit{completely duplicate binding}
+(per questo è stata introdotta \const{SO\_REUSEPORT}).
+
+Il terzo impiego è simile al precedente e prevede l'uso di \func{bind}
+all'interno dello stesso programma per associare indirizzi locali diversi a
+socket diversi. In genere questo viene fatto per i socket UDP quando è
+necessario ottenere l'indirizzo a cui sono rivolte le richieste del client ed
+il sistema non supporta l'opzione \constd{IP\_RECVDSTADDR};\footnote{nel caso
+ di Linux questa opzione è stata supportata per in certo periodo nello
+ sviluppo del kernel 2.1.x, ma è in seguito stata soppiantata dall'uso di
+ \const{IP\_PKTINFO} (vedi sez.~\ref{sec:sock_ipv4_options}).} in tale modo
+si può sapere a quale socket corrisponde un certo indirizzo. Non ha senso
+fare questa operazione per un socket TCP dato che su di essi si può sempre
+invocare \func{getsockname} una volta che si è completata la connessione.
+
+Infine il quarto caso è quello in cui si vuole effettivamente ottenere un
+\textit{completely duplicate binding}, quando cioè si vuole eseguire
+\func{bind} su un indirizzo ed una porta che sono già ``\textsl{legati}'' ad
+un altro socket. Come accennato questo con TCP non è possibile, ed ha anche
+poco senso pensare di mettere in ascolto due server sulla stessa porta. Se
+però si prende in considerazione il traffico in \textit{multicast}, diventa
+assolutamente normale che i pacchetti provenienti dal traffico in
+\textit{multicast} possano essere ricevuti da più applicazioni o da diverse
+istanze della stessa applicazione sulla stessa porte di un indirizzo di
+\textit{multicast}.
+
+Un esempio classico è quello di uno streaming di dati (audio, video, ecc.) in
+cui l'uso del \textit{multicast} consente di trasmettere un solo pacchetto da
+recapitare a tutti i possibili destinatari (invece di inviarne un duplicato a
+ciascuno); in questo caso è perfettamente logico aspettarsi che sulla stessa
+macchina più utenti possano lanciare un programma che permetta loro di
+ricevere gli stessi dati, e quindi effettuare un \textit{completely duplicate
+ binding}.
+
+In questo caso utilizzando \const{SO\_REUSEADDR} si può consentire ad una
+applicazione eseguire \func{bind} sulla stessa porta ed indirizzo usata da
+un'altra, così che anche essa possa ricevere gli stessi pacchetti. Come detto
+la cosa non è possibile con i socket TCP (per i quali il \textit{multicast}
+comunque non è applicabile), ma lo è per quelli UDP che è il protocollo
+normalmente in uso da parte di queste applicazioni. La regola è che quando si
+hanno più applicazioni che hanno eseguito \func{bind} sulla stessa porta, di
+tutti pacchetti destinati ad un indirizzo di \textit{broadcast} o di
+\textit{multicast} viene inviata una copia a ciascuna applicazione. Non è
+definito invece cosa accade qualora il pacchetto sia destinato ad un indirizzo
+normale (\textit{unicast}).
+
+% TODO documentare SO_REUSEPORT, vedi https://lwn.net/Articles/542260/
+
+\constbeg{SO\_REUSEPORT}
+
+Esistono però dei casi, in particolare per l'uso di programmi
+\textit{multithreaded}, in cui può servire un \textit{completely duplicate
+ binding} anche per delle ordinarie connessioni TCP. Per supportare queste
+esigenze a partire dal kernel 3.9 è stata introdotta un'altra opzione,
+\const{SO\_REUSEPORT} (già presente in altri sistemi come BSD), che consente
+di eseguire il \textit{completely duplicate binding}, fintanto che essa venga
+specificata per tutti i socket interessati. Come per \const{SO\_REUSEADDR}
+sarà possibile usare l'opzione su un socket legato allo stesso indirizzo e
+porta solo se il programma che ha eseguito il primo \func{bind} ha impostato
+questa opzione.
+
+Nel caso di \const{SO\_REUSEPORT} oltre al fatto che l'opzione deve essere
+attivata sul socket prima di chiamare \func{bind} ed attiva su tutti i socket
+con \textit{completely duplicate binding}, è richiesto pure che tutti i
+processi che si mettono in ascolto sullo stesso indirizzo e porta abbiano lo
+stesso \ids{UID} effettivo, per evitare che un altro utente possa ottenere il
+relativo traffico (eseguendo quello che viene definito \textit{port hijacking}
+o \textit{port stealing}). L'opzione utilizza per \param{optval} un intero
+usato come valore logico.
+
+L'opzione si usa sia per socket TCP che UDP, nel primo caso consente un uso
+distribuito di \func{accept} in una applicazione \textit{multithreaded}
+passando un diverso \textit{listening socket} ad ogni thread, cosa che
+migliora le prestazioni rispetto all'approccio tradizionale di usare un thread
+per usare \func{accept} e distribuire le connessioni agli altri o avere più
+thread che competono per usare \func{accept} sul socket. Nel caso di UDP
+l'opzione consente di distribuire meglio i pacchetti su più processi o thread,
+rispetto all'approccio tradizionale di far competere gli stessi per l'accesso
+in ricezione al socket.
+
+% TODO documentare SO_REUSEPORT introdotta con il kernel 3.9, vedi
+% http://git.kernel.org/linus/c617f398edd4db2b8567a28e899a88f8f574798d TODO:
+% in cosa differisce da REUSEADDR?
+
+\constend{SO\_REUSEPORT}
+\constend{SO\_REUSEADDR}
+
+
+\constbeg{SO\_LINGER}
+\subsubsection{L'opzione \const{SO\_LINGER}}