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 un'altra funzione, \funcd{gethostbyname2}, il cui prototipo è:
+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}
avuto un errore con \func{gethostbyname}, ma si ricordi che la sicurezza non
è mai troppa.}
-Le funzioni illustrate finora hanno un difetto fondamentale, utilizzando una
-area di memoria interna per allocare il contenuto della struttura
-\struct{hostent} non possono essere rientranti. Per questo motivo ne sono
-state definite delle versioni alternative rientranti, al solito queste sono
+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:
negativo in caso di errore.}
\end{functions}
-Gli argomenti \param{name} (e \param{af} per \func{gethostbyname2}) 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
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 solo dei puntatori,
-dovrà essere allocato anche un buffer in cui le funzioni possano scrivere
-tutti i dati del risultato dell'interrogazione, l'indirizzo e la lunghezza di
-questo buffer devono essere indicati con gli argomenti \param{buf} e
-\param{buflen}.
+\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
Una delle caratteristiche delle interrogazioni al servizio DNS è che queste
sono normalmente eseguite con il protocollo UDP, ci sono casi in cui si
preferisce che vengano usate connessioni permanenti con il protocollo TCP. Per
-ottenere questo sono previste delle funzioni apposite (oltre che delle opzioni
-in \var{\_\_res.options}); la prima è \funcd{sethostent}, il cui prototipo
-è:
+ottenere\footnote{si potrebbero impostare direttamente le opzioni di
+ \var{\_\_res.options}, ma queste funzioni permettono di semplificare la
+ procedura.} questo sono previste delle funzioni apposite; la prima è
+\funcd{sethostent}, il cui prototipo è:
\begin{prototype}{netdb.h}
{void sethostent(int stayopen)}
\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 contentente il valore dell'indirizzo IP (o IPv6) che si
+vuole risolvere. L'uso del tipo \type{char *} per questo argomento ha è
+storico, il dato dovrà essere fornito in una struttura
+\struct{in\_addr}\footnote{si ricordi che, come illustrato in
+ fig.~\ref{fig:sock_sa_ipv4_struct}, questo in realtà corrisponde ad un
+ numero intero, da esprimere comunque in \textit{network order}, non
+ altrettanto avviene però per \var{in6\_addr}, pertanto è sempre opportuno
+ inizializzare questi indirizzi con \func{inet\_pton} (vedi
+ sez.~\ref{sec:sock_conv_func_gen}).} per un indirizzo IPv4 ed una struttura
+\struct{in6\_addr} per un indirizzo IPv6, mentre in \param{len} se ne dovrà
+specificare la dimensione, infine l'argomento \param{type} indica il tipo di
+indirizzo e dovrà essere o \const{AF\_INET} o \const{AF\_INET6}.
+
+
+La funzione restituisce, in caso si successo, un puntatore ad una struttura
+\struct{hostent}, solo che la ricerca è fatta richiedendo al DNS un record di
+tipo \texttt{PTR}. In caso di errore al solito viene usata la variabile
+\var{h\_errno} per restituire un opportuno codice. In questo caso il valore
+dei vari campi \var{h\_addr\_list} viene inizializzato al valore passa
\subsection{Altre funzioni di gestione dei nomi}
una \direct{union} usata per accedere alle diverse classi di indirizzi) che
direttamente come intero. In \file{netinet/in.h} vengono definite anche alcune
costanti che identificano alcuni indirizzi speciali, riportati in
-tab.~\ref{tab:TCP_ipv4_addr}.
+tab.~\ref{tab:TCP_ipv4_addr}, che reincontreremo più avanti.
Infine occorre sottolineare che sia gli indirizzi che i numeri di porta devono
essere specificati in quello che viene chiamato \textit{network order}, cioè
il campo \var{sin6\_flowinfo} è a sua volta diviso in tre parti di cui i 24
bit inferiori indicano l'etichetta di flusso, i successivi 4 bit la priorità e
gli ultimi 4 sono riservati. Questi valori fanno riferimento ad alcuni campi
-specifici dell'header dei pacchetti IPv6 (vedi sez.~\ref{sec:IP_ipv6head}) ed il
-loro uso è sperimentale.
-
-Il campo \var{sin6\_addr} contiene l'indirizzo a 128 bit usato da IPv6, infine
-il campo \var{sin6\_scope\_id} è un campo introdotto in Linux con il kernel
-2.4, per gestire alcune operazioni riguardanti il multicasting.
-
-Si noti che questa struttura ha una dimensione maggiore della struttura
-\struct{sockaddr} generica vista in fig.~\ref{fig:sock_sa_gen_struct}, quindi
-occorre stare attenti a non avere fatto assunzioni riguardo alla possibilità
-di contenere i dati nelle dimensioni di quest'ultima.
+specifici dell'header dei pacchetti IPv6 (vedi sez.~\ref{sec:IP_ipv6head}) ed
+il loro uso è sperimentale.
+
+Il campo \var{sin6\_addr} contiene l'indirizzo a 128 bit usato da IPv6,
+espresso da un vettore di 16 byte. Infine il campo \var{sin6\_scope\_id} è un
+campo introdotto in Linux con il kernel 2.4, per gestire alcune operazioni
+riguardanti il multicasting. Si noti infine che \struct{sockaddr\_in6} ha una
+dimensione maggiore della struttura \struct{sockaddr} generica di
+fig.~\ref{fig:sock_sa_gen_struct}, quindi occorre stare attenti a non avere
+fatto assunzioni riguardo alla possibilità di contenere i dati nelle
+dimensioni di quest'ultima.
\subsection{La struttura degli indirizzi locali}