Reviosione funzioni per la risoluzione dei nomi.
authorSimone Piccardi <piccardi@gnulinux.it>
Fri, 31 Mar 2017 21:22:41 +0000 (21:22 +0000)
committerSimone Piccardi <piccardi@gnulinux.it>
Fri, 31 Mar 2017 21:22:41 +0000 (21:22 +0000)
sockctrl.tex

index a197b90fe8eec86d753363ee8d6b10021e5a2db1..0364dd7732436b19f853386691c46c8433b16efe 100644 (file)
@@ -87,9 +87,9 @@ dominio, e prevedeva solo l'utilizzo del DNS e del file statico
 
 Per questo aspetto il file di configurazione principale del sistema è
 \conffile{/etc/resolv.conf} che contiene in sostanza l'elenco degli indirizzi
 
 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 affianca il file
-\conffile{/etc/host.conf} il cui scopo principale è indicare l'ordine in cui
-eseguire la risoluzione dei nomi (se usare prima i valori di
+IP dei server DNS da contattare; a questo si affiancava (fino alle \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.
 \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.
@@ -182,6 +182,9 @@ 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.
 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
 
 Ogni servizio è specificato a sua volta da un nome, come \texttt{file},
 \texttt{dns}, \texttt{db}, ecc.  che identifica la libreria dinamica che
@@ -202,7 +205,7 @@ sezioni successive.
 \itindend{Name~Service~Switch~(NSS)}
 
 
 \itindend{Name~Service~Switch~(NSS)}
 
 
-\subsection{Le funzioni di interrogazione del \textit{resolver}}
+\subsection{Le funzioni di interrogazione del DNS}
 \label{sec:sock_resolver_functions}
 
 Prima di trattare le funzioni usate normalmente nella risoluzione dei nomi a
 \label{sec:sock_resolver_functions}
 
 Prima di trattare le funzioni usate normalmente nella risoluzione dei nomi a
@@ -265,16 +268,14 @@ di queste funzioni è \funcd{res\_init}, il cui prototipo è:
 }
 \end{funcproto}
 
 }
 \end{funcproto}
 
-
-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 \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.
+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
 
 Le impostazioni e lo stato del \textit{resolver} inizializzati da
 \func{res\_init} vengono mantenuti in una serie di variabili raggruppate nei
@@ -615,7 +616,7 @@ tab.~\ref{tab:h_errno_values}.
 \begin{table}[!htb]
   \centering
   \footnotesize
 \begin{table}[!htb]
   \centering
   \footnotesize
-  \begin{tabular}[c]{|l|p{11cm}|}
+  \begin{tabular}[c]{|l|p{9cm}|}
     \hline
     \textbf{Costante} & \textbf{Significato} \\
     \hline
     \hline
     \textbf{Costante} & \textbf{Significato} \\
     \hline
@@ -638,45 +639,34 @@ tab.~\ref{tab:h_errno_values}.
   \label{tab:h_errno_values}
 \end{table}
 
   \label{tab:h_errno_values}
 \end{table}
 
-Insieme alla nuova variabile vengono definite anche due nuove funzioni per
+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 è:
 
 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{funcproto}{
+{\centering
+\vspace{3pt}
+\begin{funcbox}{
 \fhead{netdb.h}
 \fdecl{void herror(const char *string)}
 \fdesc{Stampa un errore di risoluzione.} 
 }
 \fhead{netdb.h}
 \fdecl{void herror(const char *string)}
 \fdesc{Stampa un errore di risoluzione.} 
 }
-
-{La funzione ritorna $0$ in caso di successo e $-1$ per un errore, nel qual
-  caso \var{errno} assumerà uno dei valori: 
-  \begin{errlist}
-  \end{errlist}
-  ed inoltre 
- nel loro significato generico.}
-\end{funcproto}
-
-
-
-\begin{functions}
-\headdecl{
-\funcdecl{
-
-.
-\end{functions}
+\end{funcbox}}
 
 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 è:
 
 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}
+{\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}).
 \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}).
@@ -684,23 +674,30 @@ argomento (che si presume sia dato da \var{h\_errno}).
 \itindend{resolver}
 
 
 \itindend{resolver}
 
 
-\subsection{La risoluzione dei nomi a dominio}
+\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
 \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)}
+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.
 
 
-Determina l'indirizzo associato al nome a dominio \param{name}.
+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 è:
 
 
-\bodydesc{La funzione restituisce in caso di successo il puntatore ad una
+\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
   struttura di tipo \struct{hostent} contenente i dati associati al nome a
-  dominio, o un puntatore nullo in caso di errore.}
-\end{prototype}
+  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
 
 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
@@ -747,35 +744,36 @@ 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]}.
 
 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 \textit{resolver}; dato che questo non è molto
-comodo è stata definita\footnote{questa è una estensione fornita dalle
-  \acr{glibc}, disponibile anche in altri sistemi unix-like.}  un'altra
-funzione, \funcd{gethostbyname2}, il cui prototipo è:
-\begin{functions}
-  \headdecl{netdb.h} 
-  \headdecl{sys/socket.h}
-  \funcdecl{struct hostent *gethostbyname2(const char *name, int af)}
+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 dalle \acr{glibc}, disponibile anche in
+altri sistemi unix-like) un'altra funzione, \funcd{gethostbyname2}, il cui
+prototipo è:
 
 
-Determina l'indirizzo di tipo \param{af} associato al nome a dominio
-\param{name}.
+\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.} 
+}
 
 
-\bodydesc{La funzione restituisce in caso di successo il puntatore ad una
+{La funzione ritorna il puntatore ad una
   struttura di tipo \struct{hostent} contenente i dati associati al nome a
   struttura di tipo \struct{hostent} contenente i dati associati al nome a
-  dominio, o un puntatore nullo in caso di errore.}
-\end{functions}
+  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
 
 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 \headfile{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.
+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}[!htbp]
+\begin{figure}[!htb]
   \footnotesize \centering
   \begin{minipage}[c]{\codesamplewidth}
     \includecodesample{listati/mygethost.c}
   \footnotesize \centering
   \begin{minipage}[c]{\codesamplewidth}
     \includecodesample{listati/mygethost.c}
@@ -805,11 +803,10 @@ 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
 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\footnote{si ricordi che la lista viene
-  terminata da un puntatore nullo.} per le stringhe dei nomi; 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.
+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
 
 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
@@ -838,42 +835,47 @@ ci sono precauzioni particolari da prendere.\footnote{volendo essere pignoli
   avuto un errore con \func{gethostbyname}, ma si ricordi che la sicurezza non
   è mai troppa.}
 
   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 \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.}
+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 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:
 
 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}
+
+\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
 
 Gli argomenti \param{name} (e \param{af} per \func{gethostbyname2\_r}) hanno
 lo stesso significato visto in precedenza. Tutti gli altri argomenti hanno lo
@@ -893,7 +895,7 @@ 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,
 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
+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
 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
@@ -906,64 +908,59 @@ 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
 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.
+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 è:
 
 
-\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.
+\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.} 
+}
 
 
-\bodydesc{La funzione non restituisce nulla.}
-\end{prototype}
-\noindent e come si può vedere la funzione è estremamente semplice, non
-richiedendo nessun argomento.
+{Le funzioni non restituiscono nulla, e non danno errori.}
+\end{funcproto}
 
 
-% TODO manca gethostent (e gethostent_r) e altro ? (vedi man page)
+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 è:
 
 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 \val{NULL} in caso di errore.}
-\end{functions}
+\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 è
 
 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}\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 \struct{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à
+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 che, come illustrato in fig.~\ref{fig:sock_sa_ipv4_struct}, che
+mentre \struct{in\_addr} in realtà corrisponde ad un numero intero, 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
 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}.
+\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
 
 La funzione restituisce, in caso di successo, un puntatore ad una struttura
 \struct{hostent}, solo che in questo caso la ricerca viene eseguita
@@ -971,36 +968,68 @@ 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
 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
+dominio, la funzione comunque inizializza anche il primo campo della lista
 \var{h\_addr\_list} col valore dell'indirizzo passato come argomento.
 
 \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 dalle \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
+\funcm{gethostent}, che dovrebbe ritornare la voce successiva nel database dei
+nomi a dominio, ma questo ha senso solo per la 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 di quest'ultimo,
+come avviene in altri sistemi, ed ignora le voci relative ad indirizzi
+IPv6. Dato che i risultati si possono ottenere in modo generico con le
+funzioni già illustrate, non la tratteremo esplicitamente, come non tratteremo
+la sua variante rientrante \funcm{gethostent\_r}.
+
 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
 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
+con \func{gethostbyname}), seguendo
+l'\href{http://www.ietf.org/rfc/rfc2553.txt}{RFC~2553} 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:
   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
+\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)} 
     flags, int *error\_num)} 
-
-  \funcdecl{struct hostent *getipnodebyaddr(const void *addr, size\_t len,
+\fdesc{Richiede la risoluzione di un nome a dominio.} 
+\fdecl{struct hostent *getipnodebyaddr(const void *addr, size\_t len,
     int af, int *error\_num)}
     int af, int *error\_num)}
+\fdesc{Richiede la risoluzione inversa di un indirizzo IP.} 
+}
 
 
-  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 \val{NULL} in caso di errore.}
-\end{functions}
+{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
 
 Entrambe le funzioni supportano esplicitamente la scelta di una famiglia di
 indirizzi con l'argomento \param{af} (che può assumere i valori
@@ -1056,22 +1085,23 @@ 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 è:
 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{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}
+\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
 
 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. 
+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
 
 Infine per concludere la nostra panoramica sulle funzioni di risoluzione dei
 nomi dobbiamo citare le funzioni che permettono di interrogare gli altri
@@ -1257,9 +1287,6 @@ rimandando alle rispettive pagine di manuale.
 \end{table}
 
 
 \end{table}
 
 
-
-
-
 \subsection{Le funzioni avanzate per la risoluzione dei nomi}
 \label{sec:sock_advanced_name_services}
 
 \subsection{Le funzioni avanzate per la risoluzione dei nomi}
 \label{sec:sock_advanced_name_services}