Materiale sulle funzioni di interrogazione dei nomi e del resolver
authorSimone Piccardi <piccardi@gnulinux.it>
Sun, 3 Oct 2004 22:56:37 +0000 (22:56 +0000)
committerSimone Piccardi <piccardi@gnulinux.it>
Sun, 3 Oct 2004 22:56:37 +0000 (22:56 +0000)
sockctrl.tex

index 3adaa2b80042e71265b8be02150e4d9f95c782a1..5ef2c7cc0ab160165a4d742fd3661294aba778c6 100644 (file)
@@ -612,7 +612,7 @@ argomento (che si presume sia dato da \var{h\_errno}).
 
 
 \subsection{La risoluzione dei nomi a dominio}
 
 
 \subsection{La risoluzione dei nomi a dominio}
-\label{sec:sock_gethostbyname}
+\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
 
 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
@@ -832,9 +832,9 @@ 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\footnote{si potrebbero impostare direttamente le opzioni di
+ottenere questo\footnote{si potrebbero impostare direttamente le opzioni di
   \var{\_\_res.options}, ma queste funzioni permettono di semplificare la
   \var{\_\_res.options}, ma queste funzioni permettono di semplificare la
-  procedura.} questo sono previste delle funzioni apposite; la prima è
+  procedura.} sono previste delle funzioni apposite; la prima è
 \funcd{sethostent}, il cui prototipo è:
 \begin{prototype}{netdb.h}
 {void sethostent(int stayopen)}
 \funcd{sethostent}, il cui prototipo è:
 \begin{prototype}{netdb.h}
 {void sethostent(int stayopen)}
@@ -867,8 +867,7 @@ usare la funzione \funcd{gethostbyaddr}, il cui prototipo 
 \begin{functions}
   \headdecl{netdb.h} 
   \headdecl{sys/socket.h} 
 \begin{functions}
   \headdecl{netdb.h} 
   \headdecl{sys/socket.h} 
-  \funcdecl{struct hostent *gethostbyaddr(const char *addr, int len, int
-    type)}
+  \funcdecl{struct hostent *gethostbyaddr(const char *addr, int len, int type)}
 
   Richiede la risoluzione inversa di un indirizzo IP.
        
 
   Richiede la risoluzione inversa di un indirizzo IP.
        
@@ -878,32 +877,222 @@ usare la funzione \funcd{gethostbyaddr}, il cui prototipo 
 
 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
 
 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}
-\label{sec:sock_name_services}
+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
+socrascritta 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
+(identico 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}
+allocata dinamicamente che contiene i risultati della ricerca, e per questo
+non soffrono dei problemi dovuti all'uso di una sezione statica di memoria
+presenti con le precedenti \func{gethostbyname} e \func{gethostbyaddr}.
+Questo però comporta la necessità di deallocare esplicitamente la memoria
+occupata dai risultati una volta che questi non siano più necessari, onde
+evitare perdite di memoria; 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 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. 
+
+Consideriamo allora una ricerca sui nomi dei servizi, le due funzioni in
+questione sono \funcd{getservbyname} e \funcd{getservbyaddr} i cui prototopi
+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)} 
+
+  Disalloca una struttura \var{hostent}.
+       
+  \bodydesc{La funzione non ritorna nulla.}
+\end{functions}
+
+
+
+Oltre alle precedenti funzioni di ricerca sono definite anche delle ulteriori
+funzioni generiche che permettono di accedere direttamente al contenuto dei
+file contenenti le informazioni; come le precedenti esse sono tutte nella
+forma \texttt{setXXXent}, \texttt{getXXXent} ed \texttt{endXXXent}, e sono
+analoghe a quelle viste in sez.~\ref{sec:sys_user_group} per la lettura delle
+informazioni relative ai dati degli utenti e dei gruppi (vedi
+tab.~\ref{tab:sys_passwd_func}) che pure sono mantenute tremite il
+\textit{Name Service Switch}.
+
+
+
+
+
+
+\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
 
 Quelle illustrate nella sezione precedente sono le funzioni classiche per la
-risoluzione di nomi ed indirizzi IP, ma abbiamo già visto in 
+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
+questi inconvenienti, non c'è comunque una interfaccia sufficientemente
+generica 
+
+
+Per questo motivo lo standard Posix 1003.1-2001 indicava come deprecate le
+varie \func{gethostbyaddr}, \func{gethostbyname}, \var{getipnodebyname} e
+\var{getipnodebyaddr} per introdurre una interfaccia 
+
+
 
 
+rimane comunque il problema generico che si deve sapere
+in anticipo quale tipo di indirizzi devo