%% sockctrl.tex
%%
%% Copyright (C) 2004 Simone Piccardi.  Permission is granted to
%% copy, distribute and/or modify this document under the terms of the GNU Free
%% Documentation License, Version 1.1 or any later version published by the
%% Free Software Foundation; with the Invariant Sections being "Prefazione",
%% with no Front-Cover Texts, and with no Back-Cover Texts.  A copy of the
%% license is included in the section entitled "GNU Free Documentation
%% License".
%%
\chapter{La gestione dei socket}
\label{cha:sock_generic_management}

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}.\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=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.\footnote{la sigla LDAP fa riferimento ad
  un protocollo, il \textit{Lightweight Directory Access Protocol}, che
  prevede un meccanismo per la gestione di \textsl{elenchi} di informazioni
  via rete; il contenuto di un elenco può essere assolutamente generico, e
  questo permette il manenimento dei più vari tipi di informazioni su una
  infrastruttura di questo tipo.}

La configurazione del \textit{resolver} attiene più alla amministrazione di
sistema che alla programmazione, ciò non di meno, prima di trattare le varie
funzioni di librerie utilizzate dai programmi, vale la pena fare una
panoramica generale.  Originariamente la configurazione del \textit{resolver}
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}.

Per questo aspetto il file di configurazione principale del sistema è
\file{/etc/resolv.conf} che contiene in sostanza l'elenco dei server DNS da
contattare; a questo 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 quelli del DNS). Tralasciamo i
dettagli relativi alle varie direttive che possono essere usate in questi
file, che si trovano nelle rispettive 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,\footnote{il \textit{Network Information Service} è un servizio, creato da
  Sun, e poi diffuso su tutte le piattaforme unix-like, che permette di
  raggruppare all'interno di una rete (in quelli che appunto vengono chiamati
  \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 \file{/etc/protocols} e \file{/etc/services}.  Molte di queste
informazioni non si trovano su un DNS, e poi in un ambiente distribuito può
essere molto utile centralizzare il mentenimento 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 \file{/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 liberia, prevedendo un ordine di interrogazione predefinito e
  non modificabile (a meno di una ricompilazione delle librerie stesse).}

Per risolvere questa serie di problemi il sistema del \textit{resolver} è
stato incluso all'interno di un meccanismo generico per la risoluzione di
corripondenze 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 disponibili. Il sistema prevede una
serie di possibili classi di corrispondenza, quelle attualmente definite sono
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}

Il sistema  del \textit{Name Service  Switch} è controllato dal  contenuto del
file \file{/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.

Ogni  servizio è  specificato  a sua  volta  da un  nome, come  \texttt{file},
\texttt{dns},  \texttt{db},  ecc.  che  identifica la  libreria  dinamica  che
realizza l'interfaccia  con esso. Per  ciascun servizio se \texttt{NAME}  è il
nome  utilizzato  dentro   \file{/etc/nsswitch.conf},  dovrà  essere  presente
(usualmente  in   \file{/lib})  una  libreria   \texttt{libnss\_NAME}  che  ne
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
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.


\subsection{Le funzioni di interrogazione del \textit{resolver}}
\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 esseguire 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}.

Il sistema del DNS è in sostanza di un database distribuito organizzato in
maniera gerarchica, la manutenzione dei dati è mantenuta in tanti server
distinti ciascuno dei quali si occupa della risoluzione del proprio
\textit{dominio}; i nomi a dominio sono poi organizzati in una struttura ad
albero analoga a quella dell'albero dei file in un sistema unix-like, con
domini di primo livello (come i \texttt{.org}), secondo livello (come
\texttt{.truelite.it}), ecc.  In questo caso le separazioni sono fra i vari
livelli sono definite dal carattere ``\texttt{.}''  ed i nomi devono essere
risolti da destra verso sinistra. Il meccanismo funziona con il criterio della
\textsl{delegazione}, un server responsabile per un dominio di primo livello
può delegare la risoluzione degli indirizzi per un suo dominio di secondo
livello ad un altro server, il quale a sua volta potrà delegare la risoluzione
di un eventuale sottodominio di terzo livello ad un altro server ancora.

In realtà un server DNS contiene comunque una serie di altre informazioni;
ciascuna voce nel database viene chiamata \textit{resource record}, e viene 
vi è associato un certo \textsl{tipo}, identificato da una sigla.




interrogando il quale si possono avere una serie di informazioni,
la principale delle quali è appunto la corrispondenza fra un nome (a dominio)
ed indirizzo IP.


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}






Per questo motivo il \textit{resolver} prevede delle funzioni che permettono
sia di eseguire direttamente delle interrogazione ad un server DNS, che di
controllare le modalità con cui queste vengono eseguite; diventa così
possibile modificare da programma buona parte dei parametri controllati da
\file{/etc/resolv.conf}.



\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}

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. La funzione ritorna sempre una
struttura 

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{Le opzioni dei socket}
\label{sec:TCP_sock_options}

Finora abbiamo trattato i socket nel loro comportamento più comune, è però
possibile attivare alcune modalità diverse di funzionamento degli stessi

Dato che la maggior parte delle opzioni dei socket sono relative ai socket
TCP, ed hanno poi significato analogo quando usate con altri socket, abbiamo
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}





%%% Local Variables: 
%%% mode: latex
%%% TeX-master: "gapil"
%%% End: 
