Altro materiale sulla risoluzione dei nomi, e inizio della trattazione di
[gapil.git] / sockctrl.tex
index 66015acec48883333b651c75b5ce3103aafd4bb4..5103df1b9e57d9554c4a0ad2c57614d72630849e 100644 (file)
@@ -17,25 +17,202 @@ indirizzi, le impostazioni delle varie propriet
 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
-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}
 
+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.