X-Git-Url: https://gapil.gnulinux.it/gitweb/?p=gapil.git;a=blobdiff_plain;f=sockctrl.tex;h=6ce42016041f73a4752eb096d2627fc4f5f5aae6;hp=44bb3a1f04b4feee4d6165be4eb7682ebf03a681;hb=fbaf3a4f4f6fe16f6f2233f7165bbfa77557e32e;hpb=de137402ded9a730854f908315767d73c5308d9d diff --git a/sockctrl.tex b/sockctrl.tex index 44bb3a1..6ce4201 100644 --- a/sockctrl.tex +++ b/sockctrl.tex @@ -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