ALcune correzioni sparse, risistemati i commenti interni delle varie
[gapil.git] / sockctrl.tex
index 100d7cd3565887f610b15b447aad4591b503b383..62fd3d7037692a521a027423fa3d9f40f293cf9a 100644 (file)
 \chapter{La gestione dei socket}
 \label{cha:sock_generic_management}
 
-Esamineremo in questo capitolo le funzionalità più evolute della gestione dei
-socket TCP, come l'uso del I/O multiplexing (trattato in
-\secref{sec:file_multiplexing}) con i socket, l'uso delle opzioni dei socket e
-la gestione dei dati urgenti e \textit{out-of-band}.
+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.
 
-\section{La gestione degli indirizzi}
-\label{sec:sock_addresses}
 
-Effettueremo in questa sezione una trattazione completa delle funzioni
-utilizzate per la gestione degli indirizzi dei socket.
+\subsection{La struttura del \textit{resolver}}
+\label{sec:sock_resolver}
 
+La risoluzione dei nomi è associata tradizionalmente al servizio del
+\textit{Domain Name Service} che permette di identificare le macchine su
+internet invece che per numero IP attraverso il relativo \textsl{nome a
+  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=10cm]{img/resolver}
+  \caption{Schema di funzionamento delle routine 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 routine 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
+\file{/etc/hosts}.
+
+Per questo aspetto il file di configurazione principale del sistema è
+\file{/etc/resolv.conf} che contiene in sostanza l'elenco degli indirizzi IP
+dei server DNS da contattare; a questo si affianca il file
+\file{/etc/host.conf} il cui scopo principale è indicare l'ordine in cui
+eseguire la risoluzione dei nomi (se usare prima i valori di \file{/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 \file{/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 \file{/etc/protocols} e \file{/etc/services}.  Molte di queste
+informazioni non si trovano su un DNS, ma in una rete locale può essere molto
+utile centralizzare il mantenimento di alcune di esse su opportuni server.
+Inoltre l'uso di diversi supporti possibili per le stesse informazioni (ad
+esempio il nome delle macchine può essere mantenuto sia tramite
+\file{/etc/hosts}, che con il DNS, che con NIS) comporta il problema
+dell'ordine in cui questi vengono interrogati.\footnote{con le implementazioni
+  classiche i vari supporti erano introdotti modificando direttamente le
+  funzioni di libreria, prevedendo un ordine di interrogazione predefinito e
+  non modificabile (a meno di una ricompilazione delle librerie stesse).}
+
+Per risolvere questa serie di problemi la risoluzione dei nomi a dominio
+eseguirà dal \textit{resolver} è stata inclusa all'interno di un meccanismo
+generico per la risoluzione di corrispondenze fra nomi ed informazioni ad essi
+associate chiamato \textit{Name Service Switch}\footnote{il sistema è stato
+  introdotto la prima volta nelle librerie standard di Solaris, le \acr{glibc}
+  hanno ripreso lo stesso schema, si tenga presente che questo sistema non
+  esiste per altre librerie standard come le \acr{libc5} o le \acr{uclib}.}
+cui abbiamo accennato anche in sez.~\ref{sec:sys_user_group} per quanto
+riguarda la gestione dei dati associati a utenti e gruppi.  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{shadow}   & corrispondenze fra username e proprietà dell'utente
+                       (\acr{uid}, ecc.).\\  
+    \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 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{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}
+
+Il sistema  del \textit{Name Service  Switch} è controllato dal  contenuto del
+file \file{/etc/nsswitch.conf}; questo contiene una riga\footnote{seguendo una
+  convezione  comune per  i  file  di configurazione  le  righe vuote  vengono
+  ignorate  e  tutto  quello  che  segue un  carattere  ``\texttt{\#}''  viene
+  considerato un  commento.} 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.
+
+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   \file{/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
+fornire 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,\footnote{è cura della implementazione fattane nelle \acr{glibc}
+  tenere conto della presenza del \textit{Name Service Switch}.} e sono queste
+quelle che tratteremo nelle sezioni successive.
+
+
+\subsection{Le funzioni di interrogazione del \textit{resolver}}
+\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 meccanismo principale
+da esse utilizzato e cioè quello del servizio DNS. Come accennato questo,
+benché in teoria sia solo uno dei possibili supporti su cui mantenere le
+informazioni, in pratica costituisce il meccanismo principale con cui vengono
+risolti i nomi a dominio.  Per questo motivo esistono una serie di funzioni di
+libreria che servono specificamente ad eseguire delle interrogazioni verso un
+server DNS, funzioni che poi vengono utilizzate per realizzare le funzioni
+generiche di libreria usate anche dal sistema del \textit{resolver}.
+
+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 sottodominio di terzo livello ad
+un altro server ancora.
+
+In realtà un server DNS è in grado di fare 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.\footnote{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, rispetto a quelle relative alla semplice
+risoluzione dei nomi, un insieme di funzioni specifiche dedicate
+all'interrogazione di un server DNS; la prima di queste funzioni è
+\funcd{res\_init}, il cui prototipo è:
+\begin{functions}
+  \headdecl{netinet/in.h} \headdecl{arpa/nameser.h} \headdecl{resolv.h}
+  \funcdecl{int res\_init(void)}
+
+Inizializza il sistema del \textit{resolver}.
+
+\bodydesc{La funzione restituisce 0 in caso di successo e -1 in caso di
+  errore.}
+\end{functions}
+
+La funzione legge il contenuto dei file di configurazione (i già citati
+\file{resolv.conf} e \file{host.conf}) 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 \texttt{LOCALDOMAIN}). In genere non è necessario eseguire questa
+funzione direttamente in quanto viene automaticamente chiamata la prima volta
+che si esegue una delle altre.
+
+Le impostazioni e lo stato del \textit{resolver} vengono mantenuti in una
+serie di variabili raggruppate nei campi di una apposita struttura \var{\_res}
+usata da tutte queste funzioni. Essa viene definita in \file{resolv.h} ed è
+utilizzata internamente alle funzioni essendo definita come variabile globale;
+questo consente anche di accedervi direttamente all'interno di un qualunque
+programma, una volta che la sia opportunamente dichiarata come:
+\includecodesnip{listati/resolv_option.c}
+
+Tutti i campi della struttura sono ad uso interno, e vengono usualmente
+inizializzati da \func{res\_init} 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}, una maschera binaria che
+contiene una serie di bit di opzione 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
+    \const{RES\_INIT}       & viene attivato se è stata chiamata
+                              \func{res\_init}. \\
+    \const{RES\_DEBUG}      & stampa dei messaggi di debug.\\
+    \const{RES\_AAONLY}     & accetta solo risposte autoritative.\\
+    \const{RES\_USEVC}      & usa connessioni TCP per contattare i server 
+                              invece che l'usuale UDP.\\
+    \const{RES\_PRIMARY}    & interroga soltanto server DNS primari.
+                              \\
+    \const{RES\_IGNTC}      & ignora gli errori di troncamento, non ritenta la
+                              richiesta con una connessione TCP.\\
+    \const{RES\_RECURSE}    & imposta il bit che indica che si desidera
+                              eseguire una interrogazione ricorsiva.\\
+    \const{RES\_DEFNAMES}   & se attivo \func{res\_search} aggiunge il nome
+                              del dominio di default ai nomi singoli (che non
+                              contengono cioè un ``\texttt{.}'').\\
+    \const{RES\_STAYOPEN}   & usato con \const{RES\_USEVC} per mantenere
+                              aperte le connessioni TCP fra interrogazioni
+                              diverse. \\
+    \const{RES\_DNSRCH}     & se attivo \func{res\_search} esegue le ricerche
+                              di nomi di macchine nel dominio corrente o nei
+                              domini ad esso sovrastanti.\\
+    \const{RES\_INSECURE1}  & blocca i controlli di sicurezza di tipo 1.\\
+    \const{RES\_INSECURE2}  & blocca i controlli di sicurezza di tipo 2.\\
+    \const{RES\_NOALIASES}  & blocca l'uso della variabile di ambiente
+                              \texttt{HOSTALIASES}.\\ 
+    \const{RES\_USE\_INET6} & restituisce indirizzi IPv6 con
+                              \func{gethostbyname}. \\
+    \const{RES\_ROTATE}     & ruota la lista dei server DNS dopo ogni
+                              interrogazione.\\
+    \const{RES\_NOCHECKNAME}& non controlla i nomi per verificarne la
+                              correttezza sintattica. \\
+    \const{RES\_KEEPTSIG}   & non elimina i record di tipo \texttt{TSIG}.\\
+    \const{RES\_BLAST}      & \\
+    \const{RES\_DEFAULT}    & è l'insieme 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}, 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 \texttt{LOCALDOMAIN}. In particolare con
+\texttt{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 \texttt{RES\_TIMEOUT} si
+soprassiede il valore del campo \var{retrans},\footnote{preimpostato al valore
+  della omonima costante \const{RES\_TIMEOUT} di \file{resolv.h}.} che è il
+valore preso come base (in numero di secondi) per definire la scadenza di una
+richiesta, ciascun tentativo di richiesta fallito viene ripetuto raddoppiando
+il tempo di scadenza per il numero massimo di volte stabilito da
+\texttt{RES\_RETRY}.
+
+La funzione di interrogazione principale è \funcd{res\_query}, che serve ad
+eseguire una richiesta ad un server DNS per un nome a dominio
+\textsl{completamente specificato} (quello che si chiama FQDN, \textit{Fully
+  Qualified Domain Name}); il suo prototipo è:
+
+\begin{functions}
+\headdecl{netinet/in.h}
+\headdecl{arpa/nameser.h}
+\headdecl{resolv.h}
+\funcdecl{int res\_query(const char *dname, int class, int type,
+              unsigned char *answer, int anslen)}
+
+  Esegue una interrogazione al DNS.
+
+\bodydesc{La funzione restituisce un valore positivo pari alla lunghezza dei
+    dati scritti nel buffer \param{answer} in caso di successo e -1 in caso di
+    errore.}
+\end{functions}
+
+La funzione esegue 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}, il cui prototipo è:
+\begin{functions}
+\headdecl{netinet/in.h}
+\headdecl{arpa/nameser.h}
+\headdecl{resolv.h}
+\funcdecl{int res\_search(const char *dname, int class, int type,
+              unsigned char *answer, int anslen)}
+
+  Esegue una interrogazione al DNS.
+  
+  \bodydesc{La funzione restituisce un valore positivo pari alla lunghezza dei
+    dati scritti nel buffer \param{answer} in caso di successo e -1 in caso di
+    errore.}
+\end{functions}
+
+In sostanza la funzione ripete una serie di chiamate a \func{res\_query}
+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}.\footnote{esisteva in realtà anche una classe
+  \const{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
+    \const{C\_IN}   & indirizzi internet, in pratica i soli utilizzati oggi.\\
+    \const{C\_HS}   & indirizzi \textit{Hesiod}, utilizzati solo al MIT, oggi
+                      completamente estinti. \\
+    \const{C\_CHAOS}& indizzi per la rete \textit{Chaosnet}, un'altra rete
+                      sperimentale nata al MIT. \\
+    \const{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\footnote{ripreso dai file di dichiarazione
+  \file{arpa/nameser.h} e \file{arpa/nameser\_compat.h}.} che definiscono i
+valori che si possono usare per l'argomento \param{type} per specificare il
+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
+    \const{T\_A}     & indirizzo di una stazione.\\
+    \const{T\_NS}    & server DNS autoritativo per il dominio richiesto.\\
+    \const{T\_MD}    & destinazione per la posta elettronica.\\
+    \const{T\_MF}    & redistributore per la posta elettronica.\\
+    \const{T\_CNAME} & nome canonico.\\
+    \const{T\_SOA}   & inizio di una zona di autorità.\\
+    \const{T\_MB}    & nome a dominio di una casella di posta.\\
+    \const{T\_MG}    & nome di un membro di un gruppo di posta.\\
+    \const{T\_MR}    & nome di un cambiamento di nome per la posta.\\
+    \const{T\_NULL}  & record nullo.\\
+    \const{T\_WKS}   & servizio noto.\\
+    \const{T\_PTR}   & risoluzione inversa di un indirizzo numerico.\\
+    \const{T\_HINFO} & informazione sulla stazione.\\
+    \const{T\_MINFO} & informazione sulla casella di posta.\\
+    \const{T\_MX}    & server cui instradare la posta per il dominio.\\
+    \const{T\_TXT}   & stringhe di testo (libere).\\
+    \const{T\_RP}    & nome di un responsabile (\textit{responsible person}).\\
+    \const{T\_AFSDB} & database per una cella AFS.\\
+    \const{T\_X25}   & indirizzo di chiamata per X.25.\\
+    \const{T\_ISDN}  & indirizzo di chiamata per ISDN.\\
+    \const{T\_RT}    & router.\\
+    \const{T\_NSAP}  & indirizzo NSAP.\\
+    \const{T\_NSAP\_PTR}& risoluzione inversa per NSAP (deprecato).\\
+    \const{T\_SIG}   & firma digitale di sicurezza.\\
+    \const{T\_KEY}   & chiave per firma.\\
+    \const{T\_PX}    & corrispondenza per la posta X.400.\\
+    \const{T\_GPOS}  & posizione geografica.\\
+    \const{T\_AAAA}  & indirizzo IPv6.\\
+    \const{T\_LOC}   & informazione di collocazione.\\
+    \const{T\_NXT}   & dominio successivo.\\
+    \const{T\_EID}   & identificatore di punto conclusivo.\\
+    \const{T\_NIMLOC}& posizionatore \textit{nimrod}.\\
+    \const{T\_SRV}   & servizio.\\
+    \const{T\_ATMA}  & indirizzo ATM.\\
+    \const{T\_NAPTR} & puntatore ad una \textit{naming authority} .\\
+    \const{T\_TSIG}  & firma di transazione.\\
+    \const{T\_IXFR}  & trasferimento di zona incrementale.\\
+    \const{T\_AXFR}  & trasferimento di zona di autorità.\\
+    \const{T\_MAILB} & trasferimento di record di caselle di posta.\\
+    \const{T\_MAILA} & trasferimento di record di server di posta.\\
+    \const{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{dodds.truelite.it} e l'indirizzo IP \texttt{62.48.34.25}.
+\item[\texttt{AAAA}] viene usato per indicare la corrispondenza fra un nome a
+  dominio ed un indirizzo IPv6; è chiamato in questo modo dato che la
+  dimensione di un indirizzo IPv6 è quattro volte quella di un indirizzo IPv4.
+\item[\texttt{PTR}] per fornire la 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}, o
+  \texttt{sources.truelite.it}, che fanno sempre riferimento a
+  \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{10cm}|}
+    \hline
+    \textbf{Costante} & \textbf{Significato} \\
+    \hline
+    \hline
+    \const{HOST\_NOT\_FOUND} & l'indirizzo richiesto non è valido e la
+                               macchina indicata è sconosciuta. \\
+    \const{NO\_ADDRESS}      & il nome a dominio richiesto è valido, ma non ha
+                               un indirizzo associato ad esso
+                               (alternativamente può essere indicato come 
+                               \const{NO\_DATA}). \\
+    \const{NO\_RECOVERY}     & si è avuto un errore non recuperabile
+                               nell'interrogazione di un server DNS. \\
+    \const{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 due 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 è:
+\begin{functions}
+\headdecl{netdb.h}
+\funcdecl{void herror(const char *string)}
+
+Stampa un errore di risoluzione.
+\end{functions}
+
+La funzione è l'analoga di \func{perror} e stampa sullo 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 è:
+\begin{functions}
+\headdecl{netdb.h}
+\funcdecl{const char *hstrerror(int err)}
+
+Restituisce una stringa corrispondente ad un errore di risoluzione.
+\end{functions}
+\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}).
+
+
+
+
+\subsection{La risoluzione dei nomi a dominio}
+\label{sec:sock_name_services}
+
+La principale funzionalità del \textit{resolver} resta quella di risolvere i
+nomi a dominio in indirizzi IP, per cui non ci dedicheremo oltre alle funzioni
+di richiesta generica ed esamineremo invece le funzioni a questo dedicate. La
+prima funzione è \funcd{gethostbyname} il cui scopo è ottenere l'indirizzo di
+una stazione noto il suo nome a dominio, il suo prototipo è:
+\begin{prototype}{netdb.h}
+{struct hostent *gethostbyname(const char *name)}
+
+Determina l'indirizzo associato al nome a dominio \param{name}.
+
+\bodydesc{La funzione restituisce in caso di successo il puntatore ad una
+  struttura di tipo \struct{hostent} contenente i dati associati al nome a
+  dominio, o un puntatore nullo in caso di errore.}
+\end{prototype}
+
+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]{15cm}
+    \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} normalmente si ottengono solo gli indirizzi
+IPv4, se si vogliono ottenere degli indirizzi IPv6 occorrerà prima impostare
+l'opzione \const{RES\_USE\_INET6} nel campo \texttt{\_res.options} e poi
+chiamare \func{res\_init} (vedi sez.~\ref{sec:sock_resolver_functions}) per
+modificare le opzioni del resolver; dato che questo non è molto comodo è stata
+definita\footnote{questa è una estensione fornita dalle \acr{glibc},
+  disponibile anche in altri sistemi unix-like.} un'altra funzione,
+\funcd{gethostbyname2}, il cui prototipo è:
+\begin{functions}
+  \headdecl{netdb.h} 
+  \headdecl{sys/socket.h}
+  \funcdecl{struct hostent *gethostbyname2(const char *name, int af)}
+
+Determina l'indirizzo di tipo \param{af} associato al nome a dominio
+\param{name}.
+
+\bodydesc{La funzione restituisce in caso di successo il puntatore ad una
+  struttura di tipo \struct{hostent} contenente i dati associati al nome a
+  dominio, o un puntatore nullo in caso di errore.}
+\end{functions}
+
+In questo caso la funzione prende un secondo argomento \param{af} che indica
+(i soli valori consentiti sono \const{AF\_INET} o \const{AF\_INET6}, per
+questo è necessario l'uso di \texttt{sys/socket.h}) la famiglia di indirizzi
+che dovrà essere utilizzata nei risultati restituiti dalla funzione. Per tutto
+il resto la funzione è identica a \func{gethostbyname}, ed identici sono i
+suoi risultati.
+
+\begin{figure}[!htb]
+  \footnotesize \centering
+  \begin{minipage}[c]{15cm}
+    \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 12--15}) esce con un errore. Dopo di che
+(\texttt{\small 16}) si limita a chiamare \func{gethostbyname}, ricevendo il
+risultato nel puntatore \var{data}. Questo (\texttt{\small 17--20}) viene
+controllato per rilevare eventuali errori, nel qual caso il programma esce
+dopo aver stampato un messaggio con \func{herror}. 
+
+Se invece la risoluzione è andata a buon fine si inizia (\texttt{\small 21})
+con lo stampare il nome canonico, dopo di che (\texttt{\small 22--26}) si
+stampano eventuali altri nomi. Per questo prima (\texttt{\small 22}) si prende
+il puntatore alla cima della lista che contiene i nomi e poi (\texttt{\small
+  23--26}) si esegue un ciclo che sarà ripetuto fin tanto che nella lista si
+troveranno dei puntatori validi\footnote{si ricordi che la lista viene
+  terminata da un puntatore nullo.} per le stringhe dei nomi; prima
+(\texttt{\small 24}) si stamperà la stringa e poi (\texttt{\small 25}) 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 27--34}) è 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 35--40}) si stamperanno i valori degli indirizzi, di
+nuovo (\texttt{\small 35}) 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 37}) ad 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 38}) 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: utilizzando una area di
+memoria interna per allocare i contenuti della struttura \struct{hostent} non
+possono essere rientranti. Questo 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
+\index{\textit{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 sottostrutture con altri
+  puntatori) e copiare anche i dati da questi referenziati.}
+
+Per ovviare a questi problemi nelle \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{functions}
+  \headdecl{netdb.h} 
+  \headdecl{sys/socket.h}
+  \funcdecl{int gethostbyname\_r(const char *name, struct hostent *ret, 
+    char *buf, size\_t buflen, struct hostent **result, int *h\_errnop)}
+  \funcdecl{int gethostbyname2\_r(const char *name, int af,
+         struct hostent *ret, char *buf, size\_t buflen, 
+         struct hostent **result, int *h\_errnop)}
+  
+  Versioni rientranti delle funzioni \func{gethostbyname} e
+  \func{gethostbyname2}. 
+       
+  \bodydesc{Le funzioni restituiscono 0 in caso di successo ed un valore
+    negativo in caso di errore.}
+\end{functions}
+
+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 \index{\textit{value~result~argument}}\textit{value result argument}, si
+deve specificare l'indirizzo della variabile su cui la funzione dovrà salvare
+il codice di errore con \param{h\_errnop} e quello su cui dovrà salvare il
+puntatore che si userà per accedere i dati con \param{result}.
+
+In caso di successo entrambe le funzioni restituiscono un valore nullo,
+altrimenti restituiscono un codice di errore negativo e all'indirizzo puntato
+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\footnote{si potrebbero impostare direttamente le opzioni di
+  \var{\_\_res.options}, ma queste funzioni permettono di semplificare la
+  procedura.} sono previste delle funzioni apposite; la prima è
+\funcd{sethostent}, il cui prototipo è:
+\begin{prototype}{netdb.h}
+{void sethostent(int stayopen)}
+
+Richiede l'uso di connessioni per le interrogazioni ad un server DNS.
+
+\bodydesc{La funzione non restituisce nulla.}
+\end{prototype}
+
+La funzione 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 pari a 1 (o diverso da zero), che indica una condizione vera in C,
+attiva la funzionalità.  Come si attiva l'uso delle connessioni TCP lo si può
+disattivare con la funzione \funcd{endhostent}; il suo prototipo è:
+\begin{prototype}{netdb.h}
+{void endhostent(void)}
+
+Disattiva l'uso di connessioni per le interrogazioni ad un server DNS.
+
+\bodydesc{La funzione non restituisce nulla.}
+\end{prototype}
+\noindent e come si può vedere 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{functions}
+  \headdecl{netdb.h} 
+  \headdecl{sys/socket.h} 
+  \funcdecl{struct hostent *gethostbyaddr(const char *addr, int len, int type)}
+
+  Richiede la risoluzione inversa di un indirizzo IP.
+       
+  \bodydesc{La funzione restituisce l'indirizzo ad una struttura
+    \struct{hostent} in caso di successo ed \const{NULL} in caso di errore.}
+\end{functions}
+
+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 \type{char *} per questo argomento è storico,
+il dato dovrà essere fornito in una struttura \struct{in\_addr}\footnote{si
+  ricordi che, come illustrato in fig.~\ref{fig:sock_sa_ipv4_struct}, questo
+  in realtà corrisponde ad un numero intero, da esprimere comunque in
+  \textit{network order}, non altrettanto avviene però per \var{in6\_addr},
+  pertanto è sempre opportuno inizializzare questi indirizzi con
+  \func{inet\_pton} (vedi sez.~\ref{sec:sock_conv_func_gen}).}  per un
+indirizzo IPv4 ed una struttura \struct{in6\_addr} per un indirizzo IPv6,
+mentre in \param{len} se ne dovrà specificare la dimensione (rispettivamente 4
+o 16), infine l'argomento \param{type} indica il tipo di indirizzo e dovrà
+essere o \const{AF\_INET} o \const{AF\_INET6}.
+
+La funzione restituisce, in caso di successo, un puntatore ad una struttura
+\struct{hostent}, solo che in questo caso la ricerca viene eseguita
+richiedendo al DNS un record di tipo \texttt{PTR} corrispondente all'indirizzo
+specificato. In caso di errore al solito viene usata la variabile
+\var{h\_errno} per restituire un opportuno codice. In questo caso l'unico
+campo del risultato che interessa è \var{h\_name} che conterrà il nome a
+dominio, la funziona comunque inizializza anche il primo campo della lista
+\var{h\_addr\_list} col valore dell'indirizzo passato come argomento.
+
+Per risolvere il problema dell'uso da parte delle due funzioni
+\func{gethostbyname} e \func{gethostbyaddr} di memoria statica che può essere
+sovrascritta fra due chiamate successive, e per avere sempre la possibilità di
+indicare esplicitamente il tipo di indirizzi voluto (cosa che non è possibile
+con \func{gethostbyname}), vennero introdotte due nuove funzioni di
+risoluzione,\footnote{le funzioni sono presenti nelle \acr{glibc} versione
+  2.1.96, ma essendo considerate deprecate (vedi
+  sez.~\ref{sec:sock_advanced_name_services}) sono state rimosse nelle
+  versioni successive.} \funcd{getipnodebyname} e \funcd{getipnodebyaddr}, i
+cui prototipi sono:
+\begin{functions}
+  \headdecl{netdb.h} 
+  \headdecl{sys/types.h} 
+  \headdecl{sys/socket.h} 
+
+  \funcdecl{struct hostent *getipnodebyname(const char *name, int af, int
+    flags, int *error\_num)} 
+
+  \funcdecl{struct hostent *getipnodebyaddr(const void *addr, size\_t len,
+    int af, int *error\_num)}
+
+  Richiedono rispettivamente la risoluzione e la risoluzione inversa di un
+  indirizzo IP.
+       
+  \bodydesc{Entrambe le funzioni restituiscono l'indirizzo ad una struttura
+    \struct{hostent} in caso di successo ed \const{NULL} in caso di errore.}
+\end{functions}
+
+Entrambe le funzioni supportano esplicitamente la scelta di una famiglia di
+indirizzi con l'argomento \param{af} (che può assumere i valori
+\const{AF\_INET} o \const{AF\_INET6}), e restituiscono un codice di errore
+(con valori identici a quelli precedentemente illustrati in
+tab.~\ref{tab:h_errno_values}) nella variabile puntata da \param{error\_num}.
+La funzione \func{getipnodebyaddr} richiede poi che si specifichi l'indirizzo
+come per \func{gethostbyaddr} passando anche la lunghezza dello stesso
+nell'argomento \param{len}.
+
+La funzione \func{getipnodebyname} prende come primo argomento il nome da
+risolvere, inoltre prevede un apposito argomento \param{flags}, da usare come
+maschera binaria, che permette di specificarne il comportamento nella
+risoluzione dei diversi tipi di indirizzi (IPv4 e IPv6); ciascun bit
+dell'argomento esprime una diversa opzione, e queste possono essere specificate
+con un OR aritmetico delle costanti riportate in
+tab.~\ref{tab:sock_getipnodebyname_flags}.
+
+\begin{table}[!htb]
+  \centering
+  \footnotesize
+  \begin{tabular}[c]{|l|p{10cm}|}
+    \hline
+    \textbf{Costante} & \textbf{Significato} \\
+    \hline
+    \hline
+    \const{AI\_V4MAPPED}  & usato con \const{AF\_INET6} per richiedere una
+                            ricerca su un indirizzo IPv4 invece che IPv6; gli
+                            eventuali risultati saranno rimappati su indirizzi 
+                            IPv6.\\
+    \const{AI\_ALL}       & usato con \const{AI\_V4MAPPED}; richiede sia
+                            indirizzi IPv4 che IPv6, e gli indirizzi IPv4
+                            saranno rimappati in IPv6.\\
+    \const{AI\_ADDRCONFIG}& richiede che una richiesta IPv4 o IPv6 venga
+                            eseguita solo se almeno una interfaccia del
+                            sistema è associata ad un indirizzo di tale tipo.\\
+    \const{AI\_DEFAULT}   & il valore di default, è equivalente alla
+                            combinazione di \const{AI\_ADDRCONFIG} e di
+                            \const{AI\_V4MAPPED)}.\\  
+    \hline
+  \end{tabular}
+  \caption{Valori possibili per i bit dell'argomento \param{flags} della
+    funzione \func{getipnodebyname}.}
+  \label{tab:sock_getipnodebyname_flags}
+\end{table}
+
+Entrambe le funzioni restituiscono un puntatore ad una struttura \var{hostent}
+che contiene i risultati della ricerca, che viene allocata dinamicamente
+insieme a tutto lo spazio necessario a contenere i dati in essa referenziati;
+per questo motivo queste funzioni non soffrono dei problemi dovuti all'uso di
+una sezione statica di memoria presenti con le precedenti \func{gethostbyname}
+e \func{gethostbyaddr}.  L'uso di una allocazione dinamica però comporta anche
+la necessità di deallocare esplicitamente la memoria occupata dai risultati
+una volta che questi non siano più necessari; a tale scopo viene fornita la
+funzione \funcd{freehostent}, il cui prototipo è:
+\begin{functions}
+  \headdecl{netdb.h} 
+  \headdecl{sys/types.h} 
+  \headdecl{sys/socket.h} 
+
+  \funcdecl{void freehostent(struct hostent *ip)} 
+
+  Disalloca una struttura \var{hostent}.
+       
+  \bodydesc{La funzione non ritorna nulla.}
+\end{functions}
+
+La funzione permette di disallocare una struttura \var{hostent}
+precedentemente allocata in una chiamata di \func{getipnodebyname} o
+\func{getipnodebyaddr}, e prende come argomento l'indirizzo restituito da una
+di queste funzioni.
+
+Infine per concludere la nostra panoramica sulle funzioni di risoluzione dei
+nomi dobbiamo citare le funzioni che permettono di interrogare gli altri
+servizi di risoluzione dei nomi illustrati in sez.~\ref{sec:sock_resolver}; in
+generale infatti ci sono una serie di funzioni nella forma
+\texttt{getXXXbyname} e \texttt{getXXXbyaddr} per ciascuna delle informazioni
+di rete mantenute dal \textit{Name Service Switch} che permettono
+rispettivamente di trovare una corrispondenza cercando per nome o per numero.
+
+L'elenco di queste funzioni è riportato nelle colonne finali di
+tab.~\ref{tab:name_resolution_functions}, dove le si sono suddivise rispetto
+al tipo di informazione che forniscono (riportato in prima colonna). Nella
+tabella si è anche riportato il file su cui vengono ordinariamente mantenute
+queste informazioni, che però può essere sostituito da un qualunque supporto
+interno al \textit{Name Service Switch} (anche se usualmente questo avviene
+solo per la risoluzione degli indirizzi). Ciascuna funzione fa riferimento ad
+una sua apposita struttura che contiene i relativi dati, riportata in terza
+colonna.
+
+\begin{table}[!htb]
+  \centering
+  \footnotesize
+  \begin{tabular}[c]{|l|l|l|l|l|}
+    \hline
+    \textbf{Informazione}&\textbf{File}&\textbf{Struttura}&
+    \multicolumn{2}{|c|}{\textbf{Funzioni}}\\
+    \hline
+    \hline
+    indirizzo&\file{/etc/hosts}&\struct{hostent}&\func{gethostbyname}&
+             \func{gethostbyaddr}\\ 
+    servizio &\file{/etc/services}&\struct{servent}&\func{getservbyname}&
+             \func{getservbyaddr}\\ 
+    rete     &\file{/etc/networks}&\struct{netent}&\func{getnetbyname}&
+             \func{getnetbyaddr}\\ 
+    protocollo&\file{/etc/protocols}&\struct{protoent}&\func{getprotobyname}&
+              \func{getprotobyaddr}\\ 
+    \hline
+  \end{tabular}
+  \caption{Funzioni di risoluzione dei nomi per i vari servizi del
+    \textit{Name Service Switch}.}
+  \label{tab:name_resolution_functions}
+\end{table}
+
+Delle funzioni di tab.~\ref{tab:name_resolution_functions} abbiamo trattato
+finora soltanto quelle relative alla risoluzione dei nomi, dato che sono le
+più usate, e prevedono praticamente da sempre la necessità di rivolgersi ad
+una entità esterna; per le altre invece, estensioni fornite dal NSS a parte,
+si fa sempre riferimento ai dati mantenuti nei rispettivi file. 
+
+Dopo la risoluzione dei nomi a dominio una delle ricerche più comuni è quella
+sui nomi dei servizi noti (cioè \texttt{http}, \texttt{smtp}, ecc.) da
+associare alle rispettive porte, le due funzioni da utilizzare per questo sono
+\funcd{getservbyname} e \funcd{getservbyaddr}, che permettono rispettivamente
+di ottenere il numero di porta associato ad un servizio dato il nome e
+viceversa; i loro prototipi sono:
+\begin{functions}
+  \headdecl{netdb.h} 
+  \funcdecl{struct servent *getservbyname(const char *name, const char *proto)}
+  \funcdecl{struct servent *getservbyport(int port, const char *proto)} 
+
+  Risolvono il nome di un servizio nel rispettivo numero di porta e viceversa.
+       
+  \bodydesc{Ritornano il puntatore ad una struttura \struct{servent} con i
+    risultati in caso di successo, o \const{NULL} in caso di errore.}
+\end{functions}
+
+Entrambe le funzioni prendono come ultimo argomento una stringa \param{proto}
+che indica il protocollo per il quale si intende effettuare la
+ricerca,\footnote{le informazioni mantenute in \file{/etc/services} infatti
+  sono relative sia alle porte usate su UDP che su TCP, occorre quindi
+  specificare a quale dei due protocolli si fa riferimento.} che nel caso si
+IP può avere come valori possibili solo \texttt{udp} o
+\texttt{tcp};\footnote{in teoria si potrebbe avere un qualunque protocollo fra
+  quelli citati in \file{/etc/protocols}, posto che lo stesso supporti il
+  concetto di \textsl{porta}, in pratica questi due sono gli unici presenti.}
+se si specifica un puntatore nullo la ricerca sarà eseguita su un protocollo
+qualsiasi.
+
+Il primo argomento è il nome del servizio per \func{getservbyname},
+specificato tramite la stringa \param{name}, mentre \func{getservbyport}
+richiede il numero di porta in \param{port}. Entrambe le funzioni eseguono una
+ricerca sul file \file{/etc/services}\footnote{il \textit{Name Service Switch}
+  astrae il concetto a qualunque supporto su cui si possano mantenere i
+  suddetti dati. } ed estraggono i dati dalla prima riga che corrisponde agli
+argomenti specificati; se la risoluzione ha successo viene restituito un
+puntatore ad una apposita struttura \struct{servent} contenente tutti i
+risultati), altrimenti viene restituito un puntatore nullo.  Si tenga presente
+che anche in questo caso i dati vengono mantenuti in una area di memoria
+statica e che quindi la funzione non è rientrante.
+
+\begin{figure}[!htb]
+  \footnotesize \centering
+  \begin{minipage}[c]{15cm}
+    \includestruct{listati/servent.h}
+  \end{minipage}
+  \caption{La struttura \structd{servent} per la risoluzione dei nomi dei
+    servizi e dei numeri di porta.}
+  \label{fig:sock_servent_struct}
+\end{figure}
+
+La definizione della struttura \struct{servent} è riportata in
+fig.~\ref{fig:sock_servent_struct}, il primo campo, \var{s\_name} contiene
+sempre il nome canonico del servizio, mentre \var{s\_aliases} è un puntatore
+ad un vettore di stringhe contenenti gli eventuali nomi alternativi
+utilizzabili per identificare lo stesso servizio. Infine \var{s\_port}
+contiene il numero di porta e \var{s\_proto} il nome del protocollo.
+
+Come riportato in tab.~\ref{tab:name_resolution_functions} ci sono analoghe
+funzioni per la risoluzione del nome dei protocolli e delle reti; non staremo
+a descriverle nei dettagli, in quanto il loro uso è molto limitato, esse
+comunque hanno una struttura del tutto analoga alle precedenti, e tutti i
+dettagli relativi al loro funzionamento possono essere trovati nelle
+rispettive pagine di manuale.
+
+Oltre alle funzioni di ricerca esistono delle ulteriori funzioni che prevedono
+una lettura sequenziale delle informazioni mantenute nel \textit{Name Service
+  Switch} (in sostanza permettono di leggere i file contenenti le informazioni
+riga per riga), che sono analoghe a quelle elencate in
+tab.~\ref{tab:sys_passwd_func} per le informazioni relative ai dati degli
+utenti e dei gruppi.  Nel caso specifico dei servizi avremo allora le tre
+funzioni \funcd{setservent}, \funcd{getservent} e \funcd{endservent} i cui
+prototipi sono:
+\begin{functions}
+  \headdecl{netdb.h} 
+  \funcdecl{void setservent(int stayopen)} 
+  Apre il file \file{/etc/services} e si posiziona al suo inizio.
+
+  \funcdecl{struct servent *getservent(void)}
+  Legge la voce successiva nel file \file{/etc/services}.      
+
+  \funcdecl{void endservent(void)} 
+  Chiude il file \file{/etc/services}.
+
+  \bodydesc{Le due funzioni \func{setservent} e \func{endservent} non
+    restituiscono nulla, \func{getservent} restituisce il puntatore ad una
+    struttura \struct{servent} in caso di successo e \const{NULL} in caso di
+    errore o fine del file.}
+\end{functions}
+
+La prima funzione, \func{getservent}, legge una singola voce a partire dalla
+posizione corrente in \file{/etc/services}, pertanto si può eseguire una
+lettura sequenziale dello stesso invocandola più volte. Se il file non è
+aperto provvede automaticamente ad aprirlo, nel qual caso leggerà la prima
+voce. La seconda funzione, \func{setservent}, permette di aprire il file
+\file{/etc/services} per una successiva lettura, ma se il file è già stato
+aperto riporta la posizione di lettura alla prima voce del file, in questo
+modo si può far ricominciare da capo una lettura sequenziale. L'argomento
+\param{stayopen}, se diverso da zero, fa sì che il file resti aperto anche fra
+diverse chiamate a \func{getservbyname} e \func{getservbyaddr}.\footnote{di
+  default dopo una chiamata a queste funzioni il file viene chiuso, cosicchè
+  una successiva chiamata a \func{getservent} riparte dall'inizio.}  La terza
+funzione, \funcd{endservent}, provvede semplicemente a chiudere il file.
+
+Queste tre funzioni per la lettura sequenziale di nuovo sono presenti per
+ciascuno dei vari tipi di informazione relative alle reti di
+tab.~\ref{tab:name_resolution_functions}; questo significa che esistono
+altrettante funzioni nella forma \texttt{setXXXent}, \texttt{getXXXent} e
+\texttt{endXXXent}, analoghe alle precedenti per la risoluzione dei servizi,
+che abbiamo riportato in tab.~\ref{tab:name_sequential_read}.  Essendo, a
+parte il tipo di informazione che viene trattato, sostanzialmente identiche
+nel funzionamento e di scarso utilizzo, non staremo a trattarle una per una,
+rimandando alle rispettive pagine di manuale.
+
+\begin{table}[!htb]
+  \centering
+  \footnotesize
+  \begin{tabular}[c]{|l|l|l|l|}
+    \hline
+    \textbf{Informazione}&\multicolumn{3}{|c|}{\textbf{Funzioni}}\\
+    \hline
+    \hline
+    indirizzo&\func{sethostent}&\func{gethostent}&\func{endhostent} \\
+    servizio &cd te\func{setservent}&\func{getservent}&\func{endservent}\\ 
+    rete     &\func{setnetent}&\func{getnetent}&\func{endnetent}\\ 
+    protocollo&\func{setprotoent}&\func{getprotoent}&\func{endprotoent}\\ 
+    \hline
+  \end{tabular}
+  \caption{Funzioni lettura sequenziale dei dati del \textit{Name Service
+      Switch}.} 
+  \label{tab:name_sequential_read}
+\end{table}
+
+
+
+
+
+\subsection{Le funzioni avanzate per la risoluzione dei nomi}
+\label{sec:sock_advanced_name_services}
+
+Quelle illustrate nella sezione precedente sono le funzioni classiche per la
+risoluzione di nomi ed indirizzi IP, ma abbiamo già visto come esse soffrano
+di vari inconvenienti come il fatto che usano informazioni statiche, e non
+prevedono la possibilità di avere diverse classi di indirizzi. Anche se sono
+state create delle estensioni o metodi diversi che permettono di risolvere
+alcuni di questi inconvenienti,\footnote{rimane ad esempio il problema
+  generico che si deve sapere in anticipo quale tipo di indirizzi IP (IPv4 o
+  IPv6) corrispondono ad un certo nome a dominio.}  comunque esse non
+forniscono una interfaccia sufficientemente generica.
+
+Inoltre in genere quando si ha a che fare con i socket non esiste soltanto il
+problema della risoluzione del nome che identifica la macchina, ma anche
+quello del servizio a cui ci si vuole rivolgere.  Per questo motivo con lo
+standard POSIX 1003.1-2001 sono state indicate come deprecate le varie
+funzioni \func{gethostbyaddr}, \func{gethostbyname}, \var{getipnodebyname} e
+\var{getipnodebyaddr} ed è stata introdotta una interfaccia completamente
+nuova.
+
+La prima funzione di questa interfaccia è \funcd{getaddrinfo},\footnote{la
+  funzione è definita, insieme a \func{getnameinfo} che vedremo più avanti,
+  nell'\href{http://www.ietf.org/rfc/rfc2553.txt} {RFC~2553}.} che combina le
+funzionalità delle precedenti \func{getipnodebyname}, \func{getipnodebyaddr},
+\func{getservbyname} e \func{getservbyport}, consentendo di ottenere
+contemporaneamente sia la risoluzione di un indirizzo simbolico che del nome
+di un servizio; il suo prototipo è:
+\begin{functions}
+  \headdecl{netdb.h} 
+  \headdecl{sys/socket.h} 
+  \headdecl{netdb.h} 
+
+  \funcdecl{int getaddrinfo(const char *node, const char *service, const
+    struct addrinfo *hints, struct addrinfo **res)}
+
+  Esegue una risoluzione di un nome a dominio e di un nome di servizio.
+
+  \bodydesc{La funzione restituisce 0 in caso di successo o un codice di
+    errore diverso da zero in caso di fallimento.}
+\end{functions}
+
+La funzione prende come primo argomento il nome della macchina che si vuole
+risolvere, specificato tramite la stringa \param{node}. Questo argomento,
+oltre ad un comune nome a dominio, può indicare anche un indirizzo numerico in
+forma \textit{dotted-decimal} per IPv4 o in formato esadecimale per IPv6.  Si
+può anche specificare il nome di una rete invece che di una singola macchina.
+Il secondo argomento, \param{service}, specifica invece il nome del servizio
+che si intende risolvere. Per uno dei due argomenti si può anche usare il
+valore \const{NULL}, nel qual caso la risoluzione verrà effettuata soltanto
+sulla base del valore dell'altro.
+
+Il terzo argomento, \param{hints}, deve essere invece un puntatore ad una
+struttura \struct{addrinfo} usata per dare dei \textsl{suggerimenti} al
+procedimento di risoluzione riguardo al protocollo o del tipo di socket che si
+intenderà utilizzare; \func{getaddrinfo} infatti permette di effettuare
+ricerche generiche sugli indirizzi, usando sia IPv4 che IPv6, e richiedere
+risoluzioni sui nomi dei servizi indipendentemente dal protocollo (ad esempio
+TCP o UDP) che questi possono utilizzare.
+
+\begin{figure}[!htb]
+  \footnotesize \centering
+  \begin{minipage}[c]{15cm}
+    \includestruct{listati/addrinfo.h}
+  \end{minipage}
+  \caption{La struttura \structd{addrinfo} usata nella nuova interfaccia POSIX
+    per la risoluzione di nomi a dominio e servizi.}
+  \label{fig:sock_addrinfo_struct}
+\end{figure}
+
+La struttura \struct{addrinfo}, la cui definizione\footnote{la definizione è
+  ripresa direttamente dal file \texttt{netdb.h} in questa struttura viene
+  dichiarata, la pagina di manuale riporta \type{size\_t} come tipo di dato
+  per il campo \var{ai\_addrlen}, qui viene usata quanto previsto dallo
+  standard POSIX, in cui viene utilizzato \type{socklen\_t}; i due tipi di
+  dati sono comunque equivalenti.} è riportata in
+fig.~\ref{fig:sock_addrinfo_struct}, viene usata sia in ingresso, per passare
+dei valori di controllo alla funzione, che in uscita, per ricevere i
+risultati. Il primo campo, \var{ai\_flags}, è una maschera binaria di bit che
+permettono di controllare le varie modalità di risoluzione degli indirizzi,
+che viene usato soltanto in ingresso. I tre campi successivi \var{ai\_family},
+\var{ai\_socktype}, e \var{ai\_protocol} contengono rispettivamente la
+famiglia di indirizzi, il tipo di socket e il protocollo, in ingresso vengono
+usati per impostare una selezione (impostandone il valore nella struttura
+puntata da \param{hints}), mentre in uscita indicano il tipo di risultato
+contenuto nella struttura. 
+
+Tutti i campi seguenti vengono usati soltanto in uscita; il campo
+\var{ai\_addrlen} indica la dimensione della struttura degli indirizzi
+ottenuta come risultato, il cui contenuto sarà memorizzato nella struttura
+\struct{sockaddr} posta all'indirizzo puntato dal campo \var{ai\_addr}. Il
+campo \var{ai\_canonname} è un puntatore alla stringa contenente il nome
+canonico della macchina, ed infine, quando la funzione restituisce più di un
+risultato, \var{ai\_next} è un puntatore alla successiva struttura
+\struct{addrinfo} della lista.
+
+Ovviamente non è necessario dare dei suggerimenti in ingresso, ed usando
+\const{NULL} come valore per l'argomento \param{hints} si possono compiere
+ricerche generiche.  Se però si specifica un valore non nullo questo deve
+puntare ad una struttura \struct{addrinfo} precedentemente allocata nella
+quale siano stati opportunamente impostati i valori dei campi
+\var{ai\_family}, \var{ai\_socktype}, \var{ai\_protocol} ed \var{ai\_flags}.
+
+I due campi \var{ai\_family} e \var{ai\_socktype} prendono gli stessi valori
+degli analoghi argomenti della funzione \func{socket}; in particolare per
+\var{ai\_family} si possono usare i valori di tab.~\ref{tab:net_pf_names} ma
+sono presi in considerazione solo \const{PF\_INET} e \const{PF\_INET6}, mentre
+se non si vuole specificare nessuna famiglia di indirizzi si può usare il
+valore \const{PF\_UNSPEC}.  Allo stesso modo per \var{ai\_socktype} si possono
+usare i valori illustrati in sez.~\ref{sec:sock_type} per indicare per quale
+tipo di socket si vuole risolvere il servizio indicato, anche se i soli
+significativi sono \const{SOCK\_STREAM} e \const{SOCK\_DGRAM}; in questo caso,
+se non si vuole effettuare nessuna risoluzione specifica, si potrà usare un
+valore nullo.
+
+Il campo \var{ai\_protocol} permette invece di effettuare la selezione dei
+risultati per il nome del servizio usando il numero identificativo del
+rispettivo protocollo di trasporto (i cui valori possibili sono riportati in
+\file{/etc/protocols}); di nuovo i due soli valori utilizzabili sono quelli
+relativi a UDP e TCP, o il valore nullo che indica di ignorare questo campo
+nella selezione.
+
+Infine l'ultimo campo è \var{ai\_flags}; che deve essere impostato come una
+maschera binaria; i bit di questa variabile infatti vengono usati per dare
+delle indicazioni sul tipo di risoluzione voluta, ed hanno valori analoghi a
+quelli visti in sez.~\ref{sec:sock_name_services} per \func{getipnodebyname};
+il valore di \var{ai\_flags} può essere impostata con un OR aritmetico delle
+costanti di tab.~\ref{tab:ai_flags_values}, ciascuna delle quali identifica un
+bit della maschera.
+
+\begin{table}[!htb]
+  \centering
+  \footnotesize
+  \begin{tabular}[c]{|l|p{10cm}|}
+    \hline
+    \textbf{Costante} & \textbf{Significato} \\
+    \hline
+    \hline
+    \const{AI\_PASSIVE}    & viene utilizzato per ottenere un indirizzo in
+                             formato adatto per una successiva chiamata a
+                             \func{bind}. Se specificato quando si è usato 
+                             \const{NULL} come valore per \param{node} gli
+                             indirizzi restituiti saranno inizializzati al
+                             valore generico (\const{INADDR\_ANY} per IPv4 e
+                             \const{IN6ADDR\_ANY\_INIT} per IPv6), altrimenti
+                             verrà usato l'indirizzo dell'interfaccia di
+                             \textit{loopback}. Se invece non è impostato gli
+                             indirizzi verrano restituiti in formato adatto ad
+                             una chiamata a \func{connect} o \func{sendto}.\\
+    \const{AI\_CANONNAME}  & richiede la restituzione del nome canonico della
+                             macchina, che verrà salvato in una stringa il cui
+                             indirizzo sarà restituito nel campo
+                             \var{ai\_canonname} della prima struttura
+                             \struct{addrinfo} dei risultati. Se il nome
+                             canonico non è disponibile al suo posto
+                             viene restituita una copia di \param{node}. \\ 
+    \const{AI\_NUMERICHOST}& se impostato il nome della macchina specificato
+                             con \param{node} deve essere espresso in forma
+                             numerica, altrimenti sarà restituito un errore
+                             \const{EAI\_NONAME} (vedi
+                             tab.~\ref{tab:addrinfo_error_code}), in questo
+                             modo si evita ogni chiamata alle funzioni di
+                             risoluzione.\\ 
+    \const{AI\_V4MAPPED}   & stesso significato dell'analoga di
+                             tab.~\ref{tab:sock_getipnodebyname_flags}.\\  
+    \const{AI\_ALL}        & stesso significato dell'analoga di
+                             tab.~\ref{tab:sock_getipnodebyname_flags}.\\ 
+    \const{AI\_ADDRCONFIG} & stesso significato dell'analoga di
+                             tab.~\ref{tab:sock_getipnodebyname_flags}.\\ 
+    \hline
+  \end{tabular}
+  \caption{Costanti associate ai bit del campo \var{ai\_flags} della struttura 
+    \struct{addrinfo}.} 
+  \label{tab:ai_flags_values}
+\end{table}
+
+Come ultimo argomento di \func{getaddrinfo} deve essere passato un puntatore
+ad una variabile (di tipo puntatore ad una struttura \struct{addrinfo}) che
+verrà utilizzata dalla funzione per riportare (come \textit{value result
+  argument}) i propri risultati. La funzione infatti è rientrante, ed alloca
+autonomamente tutta la memoria necessaria in cui verranno riportati i
+risultati della risoluzione.  La funzione scriverà in \param{res} il puntatore
+iniziale ad una \textit{linked list} di strutture di tipo \struct{addrinfo}
+contenenti tutte le informazioni ottenute.
+
+La funzione restituisce un valore nullo in caso di successo, o un codice in
+caso di errore. I valori usati come codice di errore sono riportati in
+tab.~\ref{tab:addrinfo_error_code}; dato che la funzione utilizza altre
+funzioni e chiamate al sistema per ottenere il suo risultato in generale il
+valore di \var{errno} non è significativo, eccetto il caso in cui si sia
+ricevuto un errore di \const{EAI\_SYSTEM}, nel qual caso l'errore
+corrispondente è riportato tramite \var{errno}.
+
+\begin{table}[!htb]
+  \centering
+  \footnotesize
+  \begin{tabular}[c]{|l|p{10cm}|}
+    \hline
+    \textbf{Costante} & \textbf{Significato} \\
+    \hline
+    \hline
+    \const{EAI\_FAMILY}  & la famiglia di indirizzi richiesta non è
+                           supportata. \\ 
+    \const{EAI\_SOCKTYPE}& il tipo di socket richiesto non è supportato. \\
+    \const{EAI\_BADFLAGS}& il campo \var{ai\_flags} contiene dei valori non
+                           validi. \\
+    \const{EAI\_NONAME}  & il nome a dominio o il servizio non sono noti,
+                           viene usato questo errore anche quando si specifica
+                           il valore \const{NULL} per entrambi gli argomenti
+                           \param{node} e \param{service}. \\
+    \const{EAI\_SERVICE} & il servizio richiesto non è disponibile per il tipo
+                           di socket richiesto, anche se può esistere per
+                           altri tipi di socket. \\
+    \const{EAI\_ADDRFAMILY}& la rete richiesta non ha nessun indirizzo di rete
+                           per la famiglia di indirizzi specificata. \\
+    \const{EAI\_NODATA}  & la macchina specificata esiste, ma non ha nessun
+                           indirizzo di rete definito. \\
+    \const{EAI\_MEMORY}  & è stato impossibile allocare la memoria necessaria
+                           alle operazioni. \\
+    \const{EAI\_FAIL}    & il DNS ha restituito un errore di risoluzione  
+                           permanente. \\
+    \const{EAI\_AGAIN}   & il DNS ha restituito un errore di risoluzione  
+                           temporaneo, si può ritentare in seguito. \\
+    \const{EAI\_SYSTEM}  & c'è stato un errore di sistema, si può controllare
+                           \var{errno} per i dettagli. \\
+%    \hline
+% estensioni GNU, trovarne la documentazione
+%    \const{EAI\_INPROGRESS}& richiesta in corso. \\
+%    \const{EAI\_CANCELED}& la richiesta è stata cancellata.\\
+%    \const{EAI\_NOTCANCELED}& la richiesta non è stata cancellata. \\
+%    \const{EAI\_ALLDONE} & tutte le richieste sono complete. \\
+%    \const{EAI\_INTR}    & richiesta interrotta. \\
+    \hline
+  \end{tabular}
+  \caption{Costanti associate ai valori dei codici di errore della funzione
+    \func{getaddrinfo}.} 
+  \label{tab:addrinfo_error_code}
+\end{table}
+
+Come per i codici di errore di \func{gethostbyname} anche in questo caso è
+fornita una apposita funzione, analoga di \func{strerror}, che consente di
+utilizzarli direttamente per stampare a video un messaggio esplicativo; la
+funzione è \func{gai\_strerror} ed il suo prototipo è:
+\begin{functions}
+  \headdecl{netdb.h} 
+
+  \funcdecl{const char *gai\_strerror(int errcode)}
+
+  Fornisce il messaggio corrispondente ad un errore di \func{getaddrinfo}.
+
+  \bodydesc{La funzione restituisce il puntatore alla stringa contenente il
+    messaggio di errore.}
+\end{functions}
+
+La funzione restituisce un puntatore alla stringa contenente il messaggio
+corrispondente dal codice di errore \param{errcode} ottenuto come valore di
+ritorno di \func{getaddrinfo}.  La stringa è allocata staticamente, ma essendo
+costante, ed accessibile in sola lettura, questo non comporta nessun problema
+di rientranza della funzione.
+
+Dato che ad un certo nome a dominio possono corrispondere più indirizzi IP
+(sia IPv4 che IPv6), e che un certo servizio può essere fornito su protocolli
+e tipi di socket diversi, in generale, a meno di non aver eseguito una
+selezione specifica attraverso l'uso di \param{hints}, si otterrà una diversa
+struttura \struct{addrinfo} per ciascuna possibilità.  Ad esempio se si
+richiede la risoluzione del servizio \textit{echo} per l'indirizzo
+\texttt{www.truelite.it}, e si imposta \const{AI\_CANONNAME} per avere anche
+la risoluzione del nome canonico, si avrà come risposta della funzione la
+lista illustrata in fig.~\ref{fig:sock_addrinfo_list}.
+
+\begin{figure}[!htb]
+  \centering
+  \includegraphics[width=10cm]{img/addrinfo_list}
+  \caption{La \textit{linked list} delle strutture \struct{addrinfo}
+    restituite da \func{getaddrinfo}.}
+  \label{fig:sock_addrinfo_list}
+\end{figure}
+
+Come primo esempio di uso di \func{getaddrinfo} vediamo un programma
+elementare di interrogazione del resolver basato questa funzione, il cui corpo
+principale è riportato in fig.~\ref{fig:mygetaddr_example}. Il codice completo
+del programma, compresa la gestione delle opzioni in cui è gestita l'eventuale
+inizializzazione dell'argomento \var{hints} per restringere le ricerche su
+protocolli, tipi di socket o famiglie di indirizzi, è disponibile nel file
+\texttt{mygetaddr.c} dei sorgenti allegati alla guida.
+
+\begin{figure}[!htb]
+  \footnotesize \centering
+  \begin{minipage}[c]{15cm}
+    \includecodesample{listati/mygetaddr.c}
+  \end{minipage}
+  \normalsize
+  \caption{Esempio di codice per la risoluzione di un indirizzo.}
+  \label{fig:mygetaddr_example}
+\end{figure}
+
+Il corpo principale inizia controllando (\texttt{\small 1--5}) il numero di
+argomenti passati, che devono essere sempre due, e corrispondere
+rispettivamente all'indirizzo ed al nome del servizio da risolvere. A questo
+segue la chiamata (\texttt{\small 7}) alla funzione \func{getaddrinfo}, ed il
+successivo controllo (\texttt{\small 8--11}) del suo corretto funzionamento,
+senza il quale si esce immediatamente stampando il relativo codice di errore.
+
+Se la funzione ha restituito un valore nullo il programma prosegue
+inizializzando (\texttt{\small 12}) il puntatore \var{ptr} che sarà usato nel
+sucessivo ciclo (\texttt{\small 14--35}) di scansione della lista delle
+strutture \struct{addrinfo} restituite dalla funzione. Prima di eseguire
+questa scansione (\texttt{\small 12}) viene stampato il valore del nome
+canonico che è presente solo nella prima struttura.
+
+La scansione viene ripetuta (\texttt{\small 14}) fintanto che si ha un
+puntatore valido. La selezione principale è fatta sul campo \var{ai\_family},
+che stabilisce a quale famiglia di indirizzi fa riferimento la struttura in
+esame. Le possibilità sono due, un indirizzo IPv4 o IPv6, se nessuna delle due
+si verifica si provvede (\texttt{\small 27--30}) a stampare un messaggio di
+errore ed uscire.\footnote{questa eventualità non dovrebbe mai verificarsi,
+  almeno fintanto che la funzione \func{getaddrinfo} lavora correttamente.}
+
+Per ciascuno delle due possibili famiglie di indirizzi si estraggono le
+informazioni che poi verranno stampate alla fine del ciclo (\texttt{\small
+  31--34}). Il primo caso esaminato (\texttt{\small 15--21}) è quello degli
+indirizzi IPv4, nel qual caso prima se ne stampa l'indentificazione
+(\texttt{\small 16}) poi si provvede a ricavare la struttura degli indirizzi
+(\texttt{\small 17}) indirizzata dal campo \var{ai\_addr}, eseguendo un
+opportuno casting del puntatore per poter estrarre da questa la porta
+(\texttt{\small 18}) e poi l'indirizzo (\texttt{\small 19}) che verrà
+convertito con una chiamata ad \func{inet\_ntop}.
+
+La stessa operazione (\texttt{\small 21--27}) viene ripetuta per gli indirizzi
+IPv6, usando la rispettiva struttura degli indirizzi. Si noti anche come in
+entrambi i casi per la chiamata a \func{inet\_ntop} si sia dovuto passare il
+puntatore al campo contenente l'indirizzo IP nella struttura puntata dal campo
+\var{ai\_addr}.\footnote{il meccanismo è complesso a causa del fatto che al
+  contrario di IPv4, in cui l'indirizzo IP può essere espresso con un semplice
+  numero intero, in IPv6 questo deve essere necessariamente fornito come
+  struttura, e pertanto anche se nella struttura puntata da \var{ai\_addr}
+  sono presenti direttamente i valori finali, per l'uso con \func{inet\_ntop}
+  occorre comunque passare un puntatore agli stessi (ed il costrutto
+  \code{\&addr6->sin6\_addr} è corretto in quanto l'operatore \texttt{->} ha
+  on questo caso precedenza su \texttt{\&}).}
+
+Una volta estratte dalla struttura \struct{addrinfo} tutte le informazioni
+relative alla risoluzione richiesta e stampati i relativi valori, l'ultimo
+passo (\texttt{\small 34}) è di estrarre da \var{ai\_next} l'indirizzo della
+eventuale successiva struttura presente nella lista e ripetere il ciclo, fin
+tanto che, completata la scansione, questo avrà un valore nullo e si potrà
+terminare (\texttt{\small 36}) il programma.
+
+Si tenga presente che \func{getaddrinfo} non garantisce nessun particolare
+ordinamento della lista delle strutture \struct{addrinfo} restituite, anche se
+usualmente i vari indirizzi IP (se ne è presente più di uno) sono forniti
+nello stesso ordine in cui vengono inviati dal server DNS. In particolare
+nulla garantisce che vengano forniti prima i dati relativi ai servizi di un
+determinato protocollo o tipo di socket, se ne sono presenti di diversi.  Se
+allora utilizziamo il nostro programma potremo verificare il risultato:
+\begin{verbatim}
+[piccardi@gont sources]$ ./mygetaddr -c  gapil.truelite.it echo
+Canonical name sources2.truelite.it
+IPv4 address:
+        Indirizzo 62.48.34.25
+        Protocollo 6
+        Porta 7
+IPv4 address:
+        Indirizzo 62.48.34.25
+        Protocollo 17
+        Porta 7
+\end{verbatim}
+%$
+
+Una volta estratti i risultati dalla \textit{linked list} puntata da
+\param{res} se questa non viene più utilizzata si dovrà avere cura di
+disallocare opportunamente tutta la memoria, per questo viene fornita
+l'apposita funzione \funcd{freeaddrinfo}, il cui prototipo è:
+\begin{functions}
+  \headdecl{netdb.h} 
+
+  \funcdecl{void freeaddrinfo(struct addrinfo *res)}
+
+  Libera la memoria allocata da una precedente chiamata a \func{getaddrinfo}.
+
+  \bodydesc{La funzione non restituisce nessun codice di errore.}
+\end{functions}
+
+La funzione prende come unico argomento il puntatore \param{res}, ottenuto da
+una precedente chiamata a \func{getaddrinfo}, e scandisce la lista delle
+strutture per liberare tutta la memoria allocata. Dato che la funzione non ha
+valori di ritorno deve essere posta molta cura nel passare un valore valido
+per \param{res}.
+
+Si tenga presente infine che se si copiano i risultati da una delle strutture
+\struct{addrinfo} restituite nella lista indicizzata da \param{res}, occorre
+avere cura di eseguire una \index{\textit{deep~copy}}\textit{deep copy} in cui
+si copiano anche tutti i dati presenti agli indirizzi contenuti nella
+struttura \struct{addrinfo}, perché una volta disallocati i dati con
+\func{freeaddrinfo} questi non sarebbero più disponibili. 
+
+Anche la nuova intefaccia definita da POSIX prevede una nuova funzione per
+eseguire la risoluzione inversa e determinare nomi di servizi e di dominio
+dati i rispettivi valori numerici. La funzione che sostituisce le varie
+\func{gethostbyname}, \func{geipnodebyname} e \func{getservname} è
+\funcd{getnameinfo}, ed il suo prototipo è:
+\begin{functions}
+  \headdecl{sys/socket.h}
+  \headdecl{netdb.h}
+
+  \funcdecl{int getnameinfo(const struct sockaddr *sa, socklen\_t salen, char
+    *host, size\_t hostlen, char *serv, size\_t servlen, int flags)}
+
+  Risolve il contenuto di una struttura degli indirizzi in maniera
+  indipendente dal protocollo.
+
+  \bodydesc{La funzione restituisce 0 in caso di successo e un codice di
+    errore diverso da zero altrimenti.}
+\end{functions}
+
+La principale caratteristica di \func{getnameinfo} è che la funzione è in
+grado di eseguire una risoluzione inversa in maniera indipendente dal
+protocollo; il suo primo argomento \param{sa} infatti è il puntatore ad una
+struttura degli indirizzi generica, che può contenere sia indirizzi IPv4 che
+IPv6, la cui dimensione deve comunque essere specificata con l'argomento
+\param{salen}. 
+
+I risultati della funzione saranno restituiti nelle due stringhe puntate da
+\param{host} e \param{serv}, che dovranno essere state precedentemente
+allocate per una lunghezza massima che deve essere specificata con gli altri
+due argomenti \param{hostlen} e \param{servlen}. Si può, quando non si è
+interessati ad uno dei due, passare il valore \const{NULL} come argomento,
+così che la corrispondente informazione non verrà richiesta. Infine l'ultimo
+argomento \param{flags} è una maschera binaria i cui bit consentono di
+impostare le modalità con cui viene eseguita la ricerca, e deve essere
+specificato attraverso l'OR aritmetico dei valori illustrati in
+tab.~\ref{tab:getnameinfo_flags}.
+
+\begin{table}[!htb]
+  \centering
+  \footnotesize
+  \begin{tabular}[c]{|l|p{10cm}|}
+    \hline
+    \textbf{Costante} & \textbf{Significato} \\
+    \hline
+    \hline
+    \const{NI\_NOFQDN}     & richiede che venga restituita solo il nome della
+                             macchina all'interno del dominio al posto del
+                             nome completo (FQDN).\\
+    \const{NI\_NUMERICHOST}& richiede che venga restituita la forma numerica
+                             dell'indirizzo (questo succede sempre se il nome
+                             non può essere ottenuto).\\ 
+    \const{NI\_NAMEREQD}   & richiede la restituzione di un errore se il nome
+                             non può essere risolto.\\
+    \const{NI\_NUMERICSERV}& richiede che il servizio venga restituito in
+                             forma numerica (attraverso il numero di porta).\\
+    \const{NI\_DGRAM}      & richiede che venga restituito il nome del
+                             servizio su UDP invece che quello su TCP per quei
+                             pichi servizi (porte 512-214) che soni diversi
+                             nei due protocolli.\\
+    \hline
+  \end{tabular}
+  \caption{Costanti associate ai bit dell'argomento \param{flags} della  
+    funzione \func{getnameinfo}.} 
+  \label{tab:getnameinfo_flags}
+\end{table}
+
+La funzione ritorna zero in caso di successo, e scrive i propri risultati agli
+indirizzi indicati dagli argomenti \param{host} e \param{serv} come stringhe
+terminate dal carattere NUL, a meno che queste non debbano essere troncate
+qualora la loro dimensione ecceda quelle specificate dagli argomenti
+\param{hostlen} e \param{servlen}. Sono comunque definite le due costanti
+\const{NI\_MAXHOST} e \const{NI\_MAXSERV}\footnote{le due costanti sono
+  definite in \file{netdb.h} ed hanno rispettivamente il valore 1024 e 12.}
+che possono essere utilizzate come limiti massimi.  In caso di errore viene
+restituito invece un codice che assume gli stessi valori illustrati in
+tab.~\ref{tab:addrinfo_error_code}.
+
+A questo punto possiamo fornire degli esempi di utilizzo diretto della nuova
+interfaccia, adottandola per rendere i nostri client 
 
 
 \section{Le opzioni dei socket}
@@ -35,10 +1667,12 @@ Finora abbiamo trattato i socket nel loro comportamento pi
 possibile attivare alcune modalità diverse di funzionamento degli stessi
 
 Dato che la maggior parte delle opzioni dei socket sono relative ai socket
-TCP, ed hanno poi significato analogo quando usate con altri socket, abbiamo
+ TCP, ed hanno poi significato analogo quando usate con altri socket, abbiamo
 preferito trattare l'argomento in generale in questa sezione piuttosto che nel
 capitolo dedicato alla trattazione generica dei socket.
 
+\section{Altre funzioni di controllo}
+\label{sec:TCP_sock_ctrl}