Altro materiale sulla risoluzione dei nomi, e inizio della trattazione di
authorSimone Piccardi <piccardi@gnulinux.it>
Sun, 2 May 2004 22:38:52 +0000 (22:38 +0000)
committerSimone Piccardi <piccardi@gnulinux.it>
Sun, 2 May 2004 22:38:52 +0000 (22:38 +0000)
gethostbyname.

img/resolver.dia [new file with mode: 0644]
listati/hostent.h [new file with mode: 0644]
sockctrl.tex

diff --git a/img/resolver.dia b/img/resolver.dia
new file mode 100644 (file)
index 0000000..d935609
Binary files /dev/null and b/img/resolver.dia differ
diff --git a/listati/hostent.h b/listati/hostent.h
new file mode 100644 (file)
index 0000000..2c34947
--- /dev/null
@@ -0,0 +1,8 @@
+struct hostent {
+        char    *h_name;        /* official name of host */
+        char    **h_aliases;    /* alias list */
+        int     h_addrtype;     /* host address type */
+        int     h_length;       /* length of address */
+        char    **h_addr_list;  /* list of addresses */
+}
+#define h_addr  h_addr_list[0]  /* for backward compatibility */
index 66015acec48883333b651c75b5ce3103aafd4bb4..5103df1b9e57d9554c4a0ad2c57614d72630849e 100644 (file)
@@ -17,25 +17,202 @@ indirizzi, le impostazioni delle varie propriet
 di controllo che vanno ad operare su di essi.
 
 
 di controllo che vanno ad operare su di essi.
 
 
-
-\section{La gestione degli indirizzi}
-\label{sec:sock_addresses}
+\section{La risoluzione dei nomi}
+\label{sec:sock_name_resolution}
 
 Negli esempi precedenti abbiamo sempre identificato le singole macchine
 attraverso indirizzi numerici, sfruttando al più le funzioni di conversione
 elementari illustrate in sez.~\ref{sec:sock_addr_func} che permettono di
 passare da un indirizzo espresso in forma dotted decimal ad un numero. Vedremo
 
 Negli esempi precedenti abbiamo sempre identificato le singole macchine
 attraverso indirizzi numerici, sfruttando al più le funzioni di conversione
 elementari illustrate in sez.~\ref{sec:sock_addr_func} che permettono di
 passare da un indirizzo espresso in forma dotted decimal ad un numero. Vedremo
-in questa sezione le funzioni utilizzate per poter identificare le varie
-proprietà di un indirizzo (numero IP e porta) attraverso dei nomi simbolici
-che vengano automaticamente tradotti nei rispettivi valori numerici.
+in questa sezione le funzioni utilizzate per poter utilizzare dei nomi
+simbolici al posto dei valori numerici, e viceversa quelle che permettono di
+ottenere i nomi simbolici associati ad indirizzi, porte o altre proprietà del
+sistema.
 
 
 
 
-\subsection{Il sistema del \textit{resolver}}
+\subsection{La struttura del \textit{resolver}}
 \label{sec:sock_resolver}
 
 \label{sec:sock_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}. 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=10cm]{img/resolver}
+  \caption{Schema di funzionamento delle routine del \textit{resolver}.}
+  \label{fig:sock_resolver_schema}
+\end{figure}
+
+Inoltre quella fra nomi a dominio e indirizzi IP non è l'unica corrispondenza
+possibile fra nomi simbolici e valori numerici, come abbiamo visto anche in
+sez.~\ref{sec:sys_user_group} per le corrispondenze fra nomi di utenti e
+gruppi e relativi identificatori numerici; per quanto riguarda però tutti i
+nomi associati a identificativi o servizi relativi alla rete il servizio di
+risoluzione è gestito in maniera unificata da un insieme di routine fornite
+con le librerie del C, detto appunto \textit{resolver}.
+
+Lo schema di funzionamento del \textit{resolver} è illustrato in
+fig.~\ref{fig:sock_resolver_schema}; in sostanza i programmi hanno a
+disposizione un insieme di funzioni di libreria con cui chiamano il
+\textit{resolver}, indicate con le freccie nere. Ricevuta la richiesta è
+quest'ultimo che, sulla base della sua configurazione, esegue le operazioni
+necessarie a fornire la risposta, che possono essere la lettura delle
+informazioni mantenute nei relativi dei file statici presenti sulla macchina,
+una interrogazione ad un DNS (che a sua volta, per il funzionamento del
+protocollo può interrogarene altri) o la richiesta ad altri server per i quali
+sia fornito il supporto, come LDAP.
+
+La configurazione del resolver attiene più alla amministrazione di sistema che
+alla programmazione, ciò non di meno, prima di trattare le varie funzioni che
+vale la pena farne una panoramica. Originariamente la configurazione
+riguardava esclusivamente le questioni relative alla gestione dei nomi a
+dominio, e prevedeva solo l'utilizzo del DNS e del file statico
+\file{/etc/hosts}, il file di configurazione principale è
+\file{/etc/resolv.conf} e contiene in sostanza l'elenco dei server DNS da
+contattare, a cui si affianca \file{/etc/host.conf} per indicare l'ordine in
+cui eseguire la risoluzione dei nomi (se usare prima i valori di
+\file{/etc/hosts} o il DNS); tralasciamo i dettagli che si trovano nelle
+relative pagine di manuale.
+
+Con il tempo però è divenuto possibile fornire diversi sostituti per
+l'utilizzo dei file statici, ed ai nomi a dominio si sono aggiunti altri nomi,
+come quelli associati alle reti ed ai gruppi di macchine definiti dal servizio
+NIS, o quelli dei protocolli e dei servizi mantenuti nei file statici
+\file{/etc/protocols} e \file{/etc/services}, tutte informazioni che
+normalmente non si trovano su un DNS, ma possono essere accedute in maniera
+centralizzata su opportuni server (ad esempio su LDAP) in grado di mantenerle.
+
+Questo ha portato alla creazione di un sistema di risoluzione più ampio, il
+\textit{Name Service Switch} di cui il \textit{resolver} viene a costituire un
+sottoinsieme. Questo sistema, che si applica anche alla risoluzioni fra nomi
+di utenti e gruppi e relativi identificatori, permette di definire in maniera
+generica (attraverso una serie di librerie dinamiche) 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, ed è controllato dal
+file \file{/etc/nsswitch.conf}. Anche per questo si può fare riferimento alle
+pagine di manuale ed al relativo capitolo nel manuale \cite{glibc} delle
+\textsl{glibc}.
+
+In ogni caso, qualunque sia la modalità con cui ricevono i dati o il supporto
+su cui vengono mantenuti, dal punto di vista di un programma che deve
+effettuare la risoluzione di un nome, tutto quello che conta sono le funzioni
+che il \textit{resolver} mette a disposizione, e sono queste quelle che
+tratteremo nelle sezioni successive.
+
+
+
+\subsection{La risoluzione dei nomi a dominio}
+\label{sec:sock_gethostbyname}
+
+Dato che la principale funzionalità del \textit{resolver} resta quella di
+risolvere i nomi a dominio in indirizzi IP, vedremo per prime 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)}
+
+Determina l'indirizzo associato al nome a dominio \param{name}.
+
+\bodydesc{La funzione restituisce in caso di successo il puntatore ad una
+  struttura di tipo \struct{hostent} contente i dati associati al nome a
+  dominio o un puntatore nullo in caso di errore.}
+\end{prototype}
+
+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
+vengono memorizzati in una opportuna struttura \struct{hostent} la cui
+definizione è riportata in fig.~\ref{fig:sock_hostent_struct}. In caso di
+insuccesso l'errore viene segnalato da un valore nullo del puntatore, ma in
+questo caso, a differenza delle funzioni viste finora, non viene utilizzata la
+variabile \var{errno} per riportare un codice di errore, in quanto questo è
+dipende solo dalle sottostanti chiamate al sistema e non avere nessun
+significato nell'indicare quale parte del procedimento di risoluzione è
+fallita.
+
+\begin{figure}[!htb]
+  \footnotesize \centering
+  \begin{minipage}[c]{15cm}
+    \includestruct{listati/hostent.h}
+  \end{minipage}
+  \caption{La struttura \structd{hostent} .}
+  \label{fig:sock_hostent_struct}
+\end{figure}
+
+Per questo motivo all'interno del resolver è stata definita una apposita
+variabile di errore, \var{h\_errno} che viene utilizzata dalle funzioni di
+libreria per indicare quale problema ha causato il fallimento della
+risoluzione. Ad essa si può accedere una volta che la si dichiara con:
+\includecodesnip{listati/herrno.c}
+ed i valori che può assumere sono i seguenti:
+\begin{basedescript}{\desclabelwidth{3cm}\desclabelstyle{\nextlinelabel}}
+\item[\const{HOST\_NOT\_FOUND}] l'indirizzo richiesto non è valido e la
+  macchina indicata è sconosciuta.
+\item[\const{NO\_ADDRESS}] il nome a dominio richiesto è valido, ma non ha un
+  indirizzo associato ad esso.
+\item[\const{NO\_RECOVERY}] si è avuto un errore non recuperabile
+  nell'interrogazione di un server DNS.
+\item[\const{TRY\_AGAIN}] si è avuto un errore temporaneo nell'interrogazione
+  di un server DNS, si può ritentare l'interrogazione in un secondo tempo. 
+\end{basedescript}
+
+
+Per capire meglio il contenuto della struttura \struct{hostent} conviene
+spendere alcune parole sul funzionamento del DNS. Questo in sostanza è un
+enorme database distribuito interrogando il quale si possono avere una serie
+di informazioni la principale delle quali è la corrispondenza fra un nome (a
+dominio) ed indirizzo IP.  Un server DNS contiene comunque una serie di altre
+informazioni; ciascuna voce nel database viene chiamata \textit{resource
+  record} e vi è associato un certo \textsl{tipo}, identificato da una sigla.
+Per quanto ci interessa i \textit{resource record} che vengono utilizzati dal
+\textit{resolver} sono sostanzialmente i seguenti:
+\begin{basedescript}{\desclabelwidth{1.2cm}\desclabelstyle{\nextlinelabel}}
+\item[\texttt{A}] indica la corripondenza fra un nome a dominio ed un
+  indirizzo IPv4, ad esempio la corrispondenza fra \texttt{dodds.truelite.it}
+  e l'indirizzo IP \texttt{62.48.34.25}.
+\item[\texttt{AAAA}] chiamato in questo modo dato che la dimensione è quattro
+  volte quella di un indirizzo IPv4, questo record contiene la corrispondenza
+  fra un nome a dominio ed un indirizzo IPv6.
+\item[\texttt{PTR}] per provvedere la mappatura inversa fra un indirizzo IP ed
+  un nome a dominio si utilizza invece questo tipo di record (il cui nome sta
+  per \textit{pointer}).
+\item[\texttt{CNAME}] qualora si abbiamo più nomi con i quali si voglia
+  indicare lo stesso indirizzo (ad esempio \texttt{www.truelite.it}, o
+  \texttt{sources.truelite.it}, che comunque fanno sempre riferimento alla
+  macchina \texttt{dodds.truelite.it}) si può usare questo tipo di record per
+  creare degli \textit{alias} in modo da associare un qualunque altro nome al
+  \textsl{nome canonico} della macchina (quello associato al record
+  \texttt{A}).
+\end{basedescript}
+
+Quando un programma chiama \func{gethostbyname} e questa usa il DNS per
+effettuare la risoluzione del nome, è con i valori di questi record che
+vengono riempite le varie parti della struttura \struct{hostent}. Il primo
+campo della struttura, \var{h\_name} contiene sempre il \textsl{nome
+  canonico}, che nel caso del DNS è appunto il nome associato ad un record
+\texttt{A}. Il secondo campo della struttura invece è un puntatore ad vettore
+di puntatori, terminato da un puntatore nullo, alle strighe che contengono
+tutti i possibili altri nomi (quelli che nel DNS sarebbero record
+\texttt{CNAME}).
+
+Il terzo campo, \var{h\_addrtype}, indica il tipo di indirizzo che è stato
+restituito, e può essere solo \const{AF\_INET} o \const{AF\_INET6}, mentre il
+quarto campo, e \var{h\_length} indica la lunghezza dell'indirizzo stesso in
+byte. Infine il campo \var{h\_addr\_list} è il puntatore ad un vettore di
+puntatori ai singoli indirizzi; il vettore è terminato da un puntatore nullo.
+Inoltre, come illustrato in fig.~\ref{fig:sock_hostent_struct}, viene definito
+per compatibilità il campo \var{h\_addr} corrispondente al puntatore al primo
+indirizzo della lista.
+
+In sostanza 
+
+
 
 
-Effettueremo in questa sezione una trattazione completa delle funzioni
-utilizzate per la gestione degli indirizzi dei socket.