From 65da2d8d7f73f58e1e3e6f867d91f8bb7cf7bf86 Mon Sep 17 00:00:00 2001 From: Simone Piccardi Date: Fri, 31 Mar 2017 21:22:41 +0000 Subject: [PATCH] Reviosione funzioni per la risoluzione dei nomi. --- sockctrl.tex | 395 +++++++++++++++++++++++++++------------------------ 1 file changed, 211 insertions(+), 184 deletions(-) diff --git a/sockctrl.tex b/sockctrl.tex index a197b90..0364dd7 100644 --- a/sockctrl.tex +++ b/sockctrl.tex @@ -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 -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. @@ -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. +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 @@ -202,7 +205,7 @@ sezioni successive. \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 @@ -265,16 +268,14 @@ di queste funzioni è \funcd{res\_init}, il cui prototipo è: } \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 @@ -615,7 +616,7 @@ tab.~\ref{tab:h_errno_values}. \begin{table}[!htb] \centering \footnotesize - \begin{tabular}[c]{|l|p{11cm}|} + \begin{tabular}[c]{|l|p{9cm}|} \hline \textbf{Costante} & \textbf{Significato} \\ \hline @@ -638,45 +639,34 @@ tab.~\ref{tab:h_errno_values}. \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 è: - -\begin{funcproto}{ +{\centering +\vspace{3pt} +\begin{funcbox}{ \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 è: -\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}). @@ -684,23 +674,30 @@ argomento (che si presume sia dato da \var{h\_errno}). \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 -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 - 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 @@ -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]}. -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 - 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 -(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} @@ -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 -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 @@ -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.} -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: -\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 @@ -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, -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 @@ -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 -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 è: -\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 è -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 -\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 @@ -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 -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. +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 -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: -\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)} - - \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)} +\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 @@ -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 è: -\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 -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 @@ -1257,9 +1287,6 @@ rimandando alle rispettive pagine di manuale. \end{table} - - - \subsection{Le funzioni avanzate per la risoluzione dei nomi} \label{sec:sock_advanced_name_services} -- 2.30.2