\chapter{La gestione dei socket}
\label{cha:sock_generic_management}
-Esamineremo in questo capitolo le funzionalità più evolute della gestione dei
-socket TCP, come l'uso del I/O multiplexing (trattato in
-\secref{sec:file_multiplexing}) con i socket, l'uso delle opzioni dei socket e
-la gestione dei dati urgenti e \textit{out-of-band}.
+Esamineremo in questo capitolo una serie di funzionalità aggiuntive relative
+alla gestione dei socket, come la gestione della risoluzione di nomi e
+indirizzi, le impostazioni delle varie proprietà ed opzioni relative ai
+socket, e le funzioni di controllo che permettono di modificarne il
+comportamento.
+\section{La risoluzione dei nomi}
+\label{sec:sock_name_resolution}
+
+Negli esempi dei capitoli precedenti abbiamo sempre identificato le singole
+macchine attraverso indirizzi numerici, sfruttando al più le funzioni di
+conversione elementare 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 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{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}.
+
+In questo caso il file di configurazione principale è \file{/etc/resolv.conf}
+che contiene in sostanza l'elenco dei server DNS da contattare, a cui si
+affianca il file \file{/etc/host.conf} il cui scopo principale è 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 relativi alle varie
+direttive che possono essere usate in questi file, che si trovano nelle
+relative pagine di manuale.
+
+Con il tempo però è divenuto possibile fornire diversi sostituti per
+l'utilizzo delle associazione statiche in \file{/etc/hosts}, inoltre oltre
+alla risoluzione dei nomi a dominio ci sono anche altri nomi da risolvere,
+come quelli che possono essere associati ad una rete (invece che ad una
+singola macchina) o ai gruppi di macchine definiti dal servizio NIS, o come
+quelli dei protocolli e dei servizi che sono mantenuti nei file statici
+\file{/etc/protocols} e \file{/etc/services}. Tutte queste sono informazioni
+che normalmente non si trovano su un DNS, ma che in un ambiente distribuito
+possono essere centralizzate su opportuni server (ad esempio su LDAP) in grado
+di mantenerle.
+
+
+
+Il sistema del \textit{Name Service Switch} (cui faremo riferimento in seguito
+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, riportate in
+tab.~\ref{tab:sys_NSS_classes}.
+
+\begin{table}[htb]
+ \footnotesize
+ \centering
+ \begin{tabular}[c]{|l|p{8cm}|}
+ \hline
+ \textbf{Classe} & \textbf{Tipo di corrispondenza}\\
+ \hline
+ \hline
+ \texttt{shadow} & corrispondenze fra username e proprietà dell'utente
+ (\acr{uid}, ecc.).\\
+ \texttt{group} & corrispondenze fra nome del gruppo e proprietà dello
+ stesso.\\
+ \texttt{aliases} & alias per la posta elettronica\\
+ \texttt{ethers} & corrispondenze fra numero IP e MAC address della
+ scheda di rete.\\
+ \texttt{hosts} & corrispondenze fra nome a dominio e numero IP.\\
+ \texttt{netgroup} & corrispondenze gruppo di rete e macchine che lo
+ compongono.\\
+ \texttt{networks} & corrispondenze fra nome di una rete e suo indirizzo
+ IP.\\
+ \texttt{protocols}& corrispondenze fra nome di un protocollo e relativo
+ numero identificativo.\\
+ \texttt{rpc} & corrispondenze fra nome di un servizio RPC e relativo
+ numero identificativo.\\
+ \texttt{services} & corrispondenze fra nome di un servizio e numero di
+ porta. \\
+ \hline
+ \end{tabular}
+ \caption{Le diverse classi di corrispondenze definite
+ all'interno del \textit{Name Service Switch}.}
+ \label{tab:sys_NSS_classes}
+\end{table}
+
+
+
+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 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. Il sistema è
+controllato dal file \file{/etc/nsswitch.conf}, ed anche per questo si può
+fare riferimento alle pagine di manuale ed al relativo capitolo nel manuale
+\cite{glibc} delle \textsl{glibc}.
+
+Il
+sistema è controllato dal file \file{/etc/nsswitch.conf}, ed anche per questo
+si può fare riferimento alle pagine di manuale ed al relativo capitolo nel
+manuale \cite{glibc} delle \textsl{glibc}.
+
+
+
+Per questo motivo anche il sistema del \textit{resolver} è stato poi incluso
+all'interno del sistema sistema di risoluzione più ampio costituito dal
+\textit{Name Service Switch} che abbiamo visto in
+sez.~\ref{sec:sys_user_group}, dove sono previste le funzionalità di controllo
+per la risoluzione anche di questo tipo di corrispondenze. Questo significa
+allora, per quanto riguarda la risoluzione dei nomi a dominio, che oltre ai
+file che abbiamo appena illustrato, dovremo tenere in considerazione anche il
+contenuto del file \file{/etc/nsswitch.conf}.
+
+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
+programma che deve effettuare la risoluzione di un nome, tutto quello che
+conta sono le funzioni 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.
+
+
+
+\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 può 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 del nome. 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 (alternativamente può essere indicato come
+ \const{NO\_DATA}).
+\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
+database distribuito organizzato in maniera gerarchica, 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 tipi di
+\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, \var{h\_aliases}, invece è un
+puntatore ad vettore di puntatori, terminato da un puntatore nullo. Ciascun
+puntatore del vettore punta ad una stringa contenente uno degli altri
+possibili nomi associati allo stesso \textsl{nome canonico} (quelli che nel
+DNS vengono inseriti come record di tipo \texttt{CNAME}).
+
+Il terzo campo della struttura, \var{h\_addrtype}, indica il tipo di indirizzo
+che è stato restituito, e può assumere soltanto i valori \const{AF\_INET} o
+\const{AF\_INET6}, mentre il quarto campo, \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 il campo \var{h\_addr} come
+sinonimo di \code{h\_addr\_list[0]}, cioè un riferimento diretto al primo
+indirizzo della lista.
+
+
+
+Oltre ai normali nomi a dominio la funzione accetta come argomento
+\param{name} anche indirizzi numerici, in formato dotted decimal per IPv4 o
+con la notazione illustrata in sez.~\ref{sec:IP_ipv6_notation}. In tal caso
+\func{gethostbyname} non eseguirà nessuna interrogazione remota, ma si
+limiterà a copiare la stringa nel campo \var{h\_name} ed a creare la
+corrispondente struttura \var{in\_addr} da indirizzara con
+\code{h\_addr\_list[0]}.
-\section{La gestione degli indirizzi}
-\label{sec:sock_addresses}
-Effettueremo in questa sezione una trattazione completa delle funzioni
-utilizzate per la gestione degli indirizzi dei socket.
preferito trattare l'argomento in generale in questa sezione piuttosto che nel
capitolo dedicato alla trattazione generica dei socket.
+\section{Altre funzioni di controllo}
+\label{sec:TCP_sock_ctrl}