Correzioni rimaste indietro ed espansione funzioni del resolver.
[gapil.git] / sockctrl.tex
index 44bb3a1f04b4feee4d6165be4eb7682ebf03a681..6ce42016041f73a4752eb096d2627fc4f5f5aae6 100644 (file)
@@ -35,18 +35,17 @@ porte o altre proprietà del sistema.
 \subsection{La struttura del \textit{resolver}}
 \label{sec:sock_resolver}
 
-\itindbeg{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.
+\itindbeg{resolver} La risoluzione dei nomi è associata tradizionalmente al
+servizio del \itindex{Domain~Name~Service} \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=11cm]{img/resolver}
@@ -106,32 +105,34 @@ NIS,\footnote{il \textit{Network Information Service} è un servizio, creato da
   \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 \conffile{/etc/protocols} e \conffile{/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
+file statici \conffile{/etc/protocols} e \conffile{/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 \conffile{/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).}
+problema dell'ordine in cui questi vengono interrogati. 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).
+
+\itindbeg{Name~Service~Switch~(NSS)} 
 
-\itindbeg{Name~Service~Switch~(NSS)}
 Per risolvere questa serie di problemi la risoluzione dei nomi a dominio
-eseguirà dal \textit{resolver} è stata inclusa all'interno di un meccanismo
+eseguità 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
+associate chiamato \textit{Name Service Switch} cui abbiamo accennato anche in
+sez.~\ref{sec:sys_user_group} per quanto riguarda la gestione dei dati
+associati a utenti e gruppi. Il sistema è stato introdotto la prima volta
+nelle librerie standard di Solaris e 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}.
+
+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}.
@@ -176,14 +177,11 @@ tab.~\ref{tab:sys_NSS_classes}.
 % TODO rivedere meglio la tabella
 
 Il sistema del \textit{Name Service Switch} è controllato dal contenuto del
-file \conffile{/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.
+file \conffile{/etc/nsswitch.conf}; questo contiene una riga 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
@@ -194,12 +192,13 @@ 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
+fornite 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.
+disposizione (è cura delle \acr{glibc} tenere conto della presenza del
+\textit{Name Service Switch}) e sono queste quelle che tratteremo nelle
+sezioni successive.  
+
 \itindend{Name~Service~Switch~(NSS)}
 
 
@@ -207,14 +206,15 @@ quelle che tratteremo nelle sezioni successive.
 \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}.
+dominio conviene trattare in maniera più dettagliata il servizio DNS. Come
+accennato questo, benché esso 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. Inolte esso può fornire anche
+ulteriori informazioni oltre relative alla risoluzione dei 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 anche per realizzare le funzioni generiche di
+libreria usate 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
@@ -235,33 +235,36 @@ per un suo dominio di secondo livello ad un altro server, il quale a sua volta
 potrà delegare la risoluzione di un eventuale sotto-dominio 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
+Come accennato un server DNS è in grado di fare molto 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 (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}.
+\textit{resolver} prevede, oltre a quelle relative alla semplice risoluzione
+dei nomi, un insieme di funzioni specifiche dedicate all'interrogazione di un
+server DNS, tutte nella forma \texttt{res\_}\textsl{\texttt{nome}}.
+Tradizionalmente la prima di queste funzioni è \funcd{res\_init}, il cui
+prototipo è:
 
-\bodydesc{La funzione restituisce 0 in caso di successo e -1 in caso di
-  errore.}
-\end{functions}
+\begin{funcproto}{
+\fhead{netinet/in.h} 
+\fhead{arpa/nameser.h} 
+\fhead{resolv.h}
+\fdecl{int res\_init(void)}
+\fdesc{Inizializza il sistema del \textit{resolver}.} 
+}
+{La funzione ritorna $0$ in caso di successo e $-1$ per un errore.
+}
+\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,
@@ -273,20 +276,48 @@ ambiente \envvar{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 \headfiled{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:
+Le impostazioni e lo stato del \textit{resolver} inizializzati da
+\func{res\_init} 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 \headfiled{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
+Dato che l'uso di una variabile globale rende tutte le funzioni classiche non
+rientranti, con l'uscita di BIND 8.2 è stata introdotta una nuova interfaccia
+in cui tutte le nuove funzioni (il cui nome è ottenuto apponendo una
+``\texttt{n}'' al nome di quella tradizionale nella forma
+\texttt{res\_n\textsl{nome}}). Tutte le nuove funzioni prendono un primo
+argomento aggiuntivo, \param{statep}, che punti ad una struttura dello stesso
+tipo, che verrà usato per mantenere lo stato del \textit{resolver} e potrà
+essere usata senza problemi anche con programmi \textit{multithread}.  Anche
+in questo caso per poterlo utilizzare occorrerà una opportuna dichiarazione
+del tipo di dato con:
+\includecodesnip{listati/resolv_newoption.c}
+e la nuova funzione che utilizzata per inizializzare il \textit{resolver} (che
+come la precedente viene chiamata automaticamente dalle altre funzioni) è
+\funcd{res\_ninit} il cui prototipo è:
+
+\begin{funcproto}{
+\fhead{netinet/in.h} 
+\fhead{arpa/nameser.h} 
+\fhead{resolv.h}
+\fdecl{int res\_ninit(res\_state statep)}
+\fdesc{Inizializza il sistema del \textit{resolver}.} 
+}
+{La funzione ritorna $0$ in caso di successo e $-1$ per un errore.
+}
+\end{funcproto}
+
+Indipendentemente da quale versione delle funzioni si usino, tutti i campi
+della struttura sono ad uso interno, e vengono usualmente inizializzate da
+\func{res\_init} o \func{res\_ninit} 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}. 
+comportamento del \textit{resolver}.
 
 \begin{table}[htb]
   \centering
@@ -359,34 +390,37 @@ di ambiente come abbiamo visto per \envvar{LOCALDOMAIN}. In particolare con
 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 \envvar{RES\_TIMEOUT} si
-soprassiede il valore del campo \var{retrans},\footnote{preimpostato al valore
-  della omonima costante \const{RES\_TIMEOUT} di \headfile{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
+soprassiede il valore del campo \var{retrans} (preimpostato al valore della
+omonima costante \const{RES\_TIMEOUT} di \headfile{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
-\itindex{Fully~Qualified~Domain~Name~(FQDN)} 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,
+La funzione di interrogazione principale è \funcd{res\_query}
+(\funcd{res\_nquery} per la nuova interfaccia), che serve ad eseguire una
+richiesta ad un server DNS per un nome a dominio \textsl{completamente
+  specificato} (quello che si chiama
+\itindex{Fully~Qualified~Domain~Name~(FQDN)} FQDN, \textit{Fully Qualified 
+  Domain Name}); il loro prototipo è:
+
+\begin{funcproto}{
+\fhead{netinet/in.h} 
+\fhead{arpa/nameser.h} 
+\fhead{resolv.h}
+\fdecl{int res\_query(const char *dname, int class, int type,
               unsigned char *answer, int anslen)}
+\fdecl{int res\_nquery(res\_state statep, const char *dname, int class, int
+  type, \\
+  \phantom{int res\_nquery(}unsigned char *answer, int anslen)}
+\fdesc{Esegue una interrogazione al DNS.} 
+}
+{Le funzioni ritornano un valore positivo pari alla lunghezza dei dati scritti
+  nel buffer \param{answer} in caso di successo e $-1$ per un errore.
+}
+\end{funcproto}
 
-  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
+Le funzioni eseguono 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
@@ -394,34 +428,38 @@ 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à
+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}
+\const{RES\_DNSRCH}, è \funcd{res\_search} (\funcd{res\_nsearch} per la nuova
+interfaccia), il cui prototipo è:
+
+\begin{funcproto}{
+\fhead{netinet/in.h} 
+\fhead{arpa/nameser.h} 
+\fhead{resolv.h}
+\fdecl{int res\_search(const char *dname, int class, int type,
+  unsigned char *answer, \\
+  \phantom{int res\_search}int anslen)}
+\fdecl{int res\_nsearch(res\_state statep, const char *dname, int class, 
+  int type, \\
+  \phantom{int res\_nsearch(}unsigned char *answer, int anslen)}
+\fdesc{Esegue una interrogazione al DNS.} 
+}
+{Le funzioni ritornano un valore positivo pari alla lunghezza dei dati scritti
+  nel buffer \param{answer} in caso di successo e $-1$ per un errore.
+}
+\end{funcproto}
 
 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}.
+(\func{res\_nquery}) 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