Risistemati i font di tutte le figure, piu qualche aggiunta al resolver
[gapil.git] / sockctrl.tex
1 %% sockctrl.tex
2 %%
3 %% Copyright (C) 2004 Simone Piccardi.  Permission is granted to
4 %% copy, distribute and/or modify this document under the terms of the GNU Free
5 %% Documentation License, Version 1.1 or any later version published by the
6 %% Free Software Foundation; with the Invariant Sections being "Prefazione",
7 %% with no Front-Cover Texts, and with no Back-Cover Texts.  A copy of the
8 %% license is included in the section entitled "GNU Free Documentation
9 %% License".
10 %%
11 \chapter{La gestione dei socket}
12 \label{cha:sock_generic_management}
13
14 Esamineremo in questo capitolo una serie di funzionalità aggiuntive relative
15 alla gestione dei socket, come la gestione della risoluzione di nomi e
16 indirizzi, le impostazioni delle varie proprietà ed opzioni relative ai
17 socket, e le funzioni di controllo che permettono di modificarne il
18 comportamento.
19
20
21 \section{La risoluzione dei nomi}
22 \label{sec:sock_name_resolution}
23
24 Negli esempi dei capitoli precedenti abbiamo sempre identificato le singole
25 macchine attraverso indirizzi numerici, sfruttando al più le funzioni di
26 conversione elementare illustrate in sez.~\ref{sec:sock_addr_func} che
27 permettono di passare da un indirizzo espresso in forma dotted decimal ad un
28 numero. Vedremo in questa sezione le funzioni utilizzate per poter utilizzare
29 dei nomi simbolici al posto dei valori numerici, e viceversa quelle che
30 permettono di ottenere i nomi simbolici associati ad indirizzi, porte o altre
31 proprietà del sistema.
32
33
34 \subsection{La struttura del \textit{resolver}}
35 \label{sec:sock_resolver}
36
37 La risoluzione dei nomi è associata tradizionalmente al servizio del
38 \textit{Domain Name Service} che permette di identificare le macchine su
39 internet invece che per numero IP attraverso il relativo \textsl{nome a
40   dominio}. In realtà per DNS si intendono spesso i server che forniscono su
41 internet questo servizio, mentre nel nostro caso affronteremo la problematica
42 dal lato client, di un qualunque programma che necessita di compiere questa
43 operazione.
44
45 \begin{figure}[htb]
46   \centering
47   \includegraphics[width=10cm]{img/resolver}
48   \caption{Schema di funzionamento delle routine del \textit{resolver}.}
49   \label{fig:sock_resolver_schema}
50 \end{figure}
51
52 Inoltre quella fra nomi a dominio e indirizzi IP non è l'unica corrispondenza
53 possibile fra nomi simbolici e valori numerici, come abbiamo visto anche in
54 sez.~\ref{sec:sys_user_group} per le corrispondenze fra nomi di utenti e
55 gruppi e relativi identificatori numerici; per quanto riguarda però tutti i
56 nomi associati a identificativi o servizi relativi alla rete il servizio di
57 risoluzione è gestito in maniera unificata da un insieme di routine fornite
58 con le librerie del C, detto appunto \textit{resolver}.
59
60 Lo schema di funzionamento del \textit{resolver} è illustrato in
61 fig.~\ref{fig:sock_resolver_schema}; in sostanza i programmi hanno a
62 disposizione un insieme di funzioni di libreria con cui chiamano il
63 \textit{resolver}, indicate con le freccie nere. Ricevuta la richiesta è
64 quest'ultimo che, sulla base della sua configurazione, esegue le operazioni
65 necessarie a fornire la risposta, che possono essere la lettura delle
66 informazioni mantenute nei relativi dei file statici presenti sulla macchina,
67 una interrogazione ad un DNS (che a sua volta, per il funzionamento del
68 protocollo può interrogarene altri) o la richiesta ad altri server per i quali
69 sia fornito il supporto, come LDAP.\footnote{la sigla LDAP fa riferimento ad
70   un protocollo, il \textit{Lightweight Directory Access Protocol}, che
71   prevede un meccanismo per la gestione di \textsl{elenchi} di informazioni
72   via rete; il contenuto di un elenco può essere assolutamente generico, e
73   questo permette il manenimento dei più vari tipi di informazioni su una
74   infrastruttura di questo tipo.}
75
76 La configurazione del \textit{resolver} attiene più alla amministrazione di
77 sistema che alla programmazione, ciò non di meno, prima di trattare le varie
78 funzioni di librerie utilizzate dai programmi, vale la pena fare una
79 panoramica generale.  Originariamente la configurazione del \textit{resolver}
80 riguardava esclusivamente le questioni relative alla gestione dei nomi a
81 dominio, e prevedeva solo l'utilizzo del DNS e del file statico
82 \file{/etc/hosts}.
83
84 Per questo aspetto il file di configurazione principale del sistema è
85 \file{/etc/resolv.conf} che contiene in sostanza l'elenco dei server DNS da
86 contattare; a questo si affianca il file \file{/etc/host.conf} il cui scopo
87 principale è indicare l'ordine in cui eseguire la risoluzione dei nomi (se
88 usare prima i valori di \file{/etc/hosts} o quelli del DNS). Tralasciamo i
89 dettagli relativi alle varie direttive che possono essere usate in questi
90 file, che si trovano nelle rispettive pagine di manuale.
91
92 Con il tempo però è divenuto possibile fornire diversi sostituti per
93 l'utilizzo delle associazione statiche in \file{/etc/hosts}, inoltre oltre
94 alla risoluzione dei nomi a dominio ci sono anche altri nomi da risolvere,
95 come quelli che possono essere associati ad una rete (invece che ad una
96 singola macchina) o ai gruppi di macchine definiti dal servizio
97 NIS,\footnote{il \textit{Network Information Service} è un servizio, creato da
98   Sun, e poi diffuso su tutte le piattaforme unix-like, che permette di
99   raggruppare all'interno di una rete (in quelli che appunto vengono chiamati
100   \textit{netgroup}) varie macchine, centralizzando i servizi di definizione
101   di utenti e gruppi e di autenticazione, oggi è sempre più spesso sostituito
102   da LDAP.} o come quelli dei protocolli e dei servizi che sono mantenuti nei
103 file statici \file{/etc/protocols} e \file{/etc/services}.  Molte di queste
104 informazioni non si trovano su un DNS, e poi in un ambiente distribuito può
105 essere molto utile centralizzare il mentenimento di alcune di esse su
106 opportuni server. Inoltre l'uso di diversi supporti possibili per le stesse
107 informazioni (ad esempio il nome delle macchine può essere mantenuto sia
108 tramite \file{/etc/hosts}, che con il DNS, che con NIS) comporta il problema
109 dell'ordine in cui questi vengono interrogati.\footnote{con le implementazioni
110   classiche i vari supporti erano introdotti modificando direttamente le
111   funzioni di liberia, prevedendo un ordine di interrogazione predefinito e
112   non modificabile (a meno di una ricompilazione delle librerie stesse).}
113
114 Per risolvere questa serie di problemi il sistema del \textit{resolver} è
115 stato incluso all'interno di un meccanismo generico per la risoluzione di
116 corripondenze fra nomi ed informazioni ad essi associate chiamato \textit{Name
117   Service Switch}\footnote{il sistema è stato introdotto la prima volta nelle
118   librerie standard di Solaris, le \acr{glibc} hanno ripreso lo stesso schema,
119   si tenga presente che questo sistema non esiste per altre librerie standard
120   come le \acr{libc5} o le \acr{uclib}.} cui abbiamo accennato anche in
121 sez.~\ref{sec:sys_user_group} per quanto riguarda la gestione dei dati
122 associati a utenti e gruppi.  Il \textit{Name Service Switch} (cui spesso si
123 fa riferimento con l'acronimo NSS) è un sistema di librerie dinamiche che
124 permette di definire in maniera generica sia i supporti su cui mantenere i
125 dati di corrispondenza fra nomi e valori numerici, sia l'ordine in cui
126 effettuare le ricerche sui vari supporti disponibili. Il sistema prevede una
127 serie di possibili classi di corrispondenza, quelle attualmente definite sono
128 riportate in tab.~\ref{tab:sys_NSS_classes}.
129
130 \begin{table}[htb]
131   \footnotesize
132   \centering
133   \begin{tabular}[c]{|l|p{8cm}|}
134     \hline
135     \textbf{Classe} & \textbf{Tipo di corrispondenza}\\
136     \hline
137     \hline
138     \texttt{shadow}   & corrispondenze fra username e proprietà dell'utente
139                        (\acr{uid}, ecc.).\\  
140     \texttt{group}    & corrispondenze fra nome del gruppo e proprietà dello 
141                         stesso.\\  
142     \texttt{aliases}  & alias per la posta elettronica\\ 
143     \texttt{ethers}   & corrispondenze fra numero IP e MAC address della
144                         scheda di rete.\\ 
145     \texttt{hosts}    & corrispondenze fra nome a dominio e numero IP.\\ 
146     \texttt{netgroup} & corrispondenze gruppo di rete e macchine che lo
147                         compongono.\\  
148     \texttt{networks} & corrispondenze fra nome di una rete e suo indirizzo
149                         IP.\\  
150     \texttt{protocols}& corrispondenze fra nome di un protocollo e relativo
151                         numero identificativo.\\ 
152     \texttt{rpc}      & corrispondenze fra nome di un servizio RPC e relativo 
153                         numero identificativo.\\ 
154     \texttt{services} & corrispondenze fra nome di un servizio e numero di
155                         porta. \\ 
156     \hline
157   \end{tabular}
158   \caption{Le diverse classi di corrispondenze definite
159     all'interno del \textit{Name Service Switch}.} 
160   \label{tab:sys_NSS_classes}
161 \end{table}
162
163 Il sistema  del \textit{Name Service  Switch} è controllato dal  contenuto del
164 file \file{/etc/nsswitch.conf}; questo contiene una riga\footnote{seguendo una
165   convezione  comune per  i  file  di configurazione  le  righe vuote  vengono
166   ignorate  e  tutto  quello  che  segue un  carattere  ``\texttt{\#}''  viene
167   considerato un  commento.} di configurazione per ciascuna  di queste classi,
168 che  viene inizia  col nome  di tab.~\ref{tab:sys_NSS_classes}  seguito  da un
169 carattere ``\texttt{:}'' e  prosegue con la lista dei  \textsl{servizi} su cui
170 le  relative informazioni sono  raggiungibili, scritti  nell'ordine in  cui si
171 vuole siano interrogati.
172
173 Ogni servizio è specificato a sua volta da un nome, come \texttt{file},
174 \texttt{dns}, \texttt{db}, ecc. che identifica la libreria dinamica che
175 realizza l'interfaccia con esso. Per ciascun servizio se \texttt{NAME} è il
176 nome utilizzato dentro \file{/etc/nsswitch.conf}, dovrà essere presente
177 (usualmente in \file{/lib}) una libreria \texttt{libnss\_NAME} che ne
178 implementa le funzioni. 
179
180 In ogni caso, qualunque sia la modalità con cui ricevono i dati o il supporto
181 su cui vengono mantenuti, e che si usino o meno funzionalità aggiuntive
182 fornire dal sistema del \textit{Name Service Switch}, dal punto di vista di un
183 programma che deve effettuare la risoluzione di un nome a dominio, tutto
184 quello che conta sono le funzioni classiche che il \textit{resolver} mette a
185 disposizione,\footnote{è cura della implementazione fattane nelle \acr{glibc}
186   tenere conto della presenza del \textit{Name Service Switch}.} e sono queste
187 quelle che tratteremo nelle sezioni successive.
188
189
190 \subsection{Le funzioni di interrogazione del \textit{resolver}}
191 \label{sec:sock_resolver_functions}
192
193 Prima di trattare le funzioni usate normalmente nella risoluzione dei nomi a
194 dominio conviene trattare in maniera più dettagliata il meccanismo principale
195 da esse utilizzato e cioè quello del servizio DNS. Come accennato questo,
196 benché in teoria sia solo uno dei possibili supporti su cui mantenere le
197 relative informazioni, in pratica costituisce il meccanismo principale
198
199
200 Per questo motivo il \textit{resolver} prevede delle funzioni che permettono
201 sia di eseguire direttamente delle interrogazione ad un server DNS, che di
202 controllare le modalità con cui queste vengono eseguite; diventa così
203 possibile modificare da programma buona parte dei parametri controllati da
204 \file{/etc/resolv.conf}.
205
206
207
208 Per capire meglio il contenuto della struttura \struct{hostent} conviene
209 spendere alcune parole sul funzionamento del DNS. Questo in sostanza è un
210 database distribuito organizzato in maniera gerarchica, interrogando il quale
211 si possono avere una serie di informazioni, la principale delle quali è la
212 corrispondenza fra un nome (a dominio) ed indirizzo IP.  Un server DNS
213 contiene comunque una serie di altre informazioni; ciascuna voce nel database
214 viene chiamata \textit{resource record} e vi è associato un certo
215 \textsl{tipo}, identificato da una sigla.  Per quanto ci interessa i tipi di
216 \textit{resource record} che vengono utilizzati dal \textit{resolver} sono
217 sostanzialmente i seguenti:
218 \begin{basedescript}{\desclabelwidth{1.2cm}\desclabelstyle{\nextlinelabel}}
219 \item[\texttt{A}] indica la corripondenza fra un nome a dominio ed un
220   indirizzo IPv4, ad esempio la corrispondenza fra \texttt{dodds.truelite.it}
221   e l'indirizzo IP \texttt{62.48.34.25}.
222 \item[\texttt{AAAA}] chiamato in questo modo dato che la dimensione è quattro
223   volte quella di un indirizzo IPv4, questo record contiene la corrispondenza
224   fra un nome a dominio ed un indirizzo IPv6.
225 \item[\texttt{PTR}] per provvedere la mappatura inversa fra un indirizzo IP ed
226   un nome a dominio si utilizza invece questo tipo di record (il cui nome sta
227   per \textit{pointer}).
228 \item[\texttt{CNAME}] qualora si abbiamo più nomi con i quali si voglia
229   indicare lo stesso indirizzo (ad esempio \texttt{www.truelite.it}, o
230   \texttt{sources.truelite.it}, che comunque fanno sempre riferimento alla
231   macchina \texttt{dodds.truelite.it}) si può usare questo tipo di record per
232   creare degli \textit{alias} in modo da associare un qualunque altro nome al
233   \textsl{nome canonico} della macchina (quello associato al record
234   \texttt{A}).
235 \end{basedescript}
236
237
238
239 \subsection{La risoluzione dei nomi a dominio}
240 \label{sec:sock_gethostbyname}
241
242 Dato che la principale funzionalità del \textit{resolver} resta quella di
243 risolvere i nomi a dominio in indirizzi IP, vedremo per prime le funzioni a
244 questo dedicate. La prima funzione è \funcd{gethostbyname} il cui scopo è
245 ottenere l'indirizzo di una stazione noto il suo nome a dominio, il suo
246 prototipo è:
247 \begin{prototype}{netdb.h}
248 {struct hostent *gethostbyname(const char *name)}
249
250 Determina l'indirizzo associato al nome a dominio \param{name}.
251
252 \bodydesc{La funzione restituisce in caso di successo il puntatore ad una
253   struttura di tipo \struct{hostent} contente i dati associati al nome a
254   dominio o un puntatore nullo in caso di errore.}
255 \end{prototype}
256
257 La funzione prende come argomento una stringa \param{name} contenente il nome
258 a dominio che si vuole risolvere, in caso di successo i dati ad esso relativi
259 vengono memorizzati in una opportuna struttura \struct{hostent} la cui
260 definizione è riportata in fig.~\ref{fig:sock_hostent_struct}. In caso di
261 insuccesso l'errore viene segnalato da un valore nullo del puntatore, ma in
262 questo caso, a differenza delle funzioni viste finora, non viene utilizzata la
263 variabile \var{errno} per riportare un codice di errore, in quanto questo
264 dipende solo dalle sottostanti chiamate al sistema e può non avere nessun
265 significato nell'indicare quale parte del procedimento di risoluzione è
266 fallita.
267
268 \begin{figure}[!htb]
269   \footnotesize \centering
270   \begin{minipage}[c]{15cm}
271     \includestruct{listati/hostent.h}
272   \end{minipage}
273   \caption{La struttura \structd{hostent}.}
274   \label{fig:sock_hostent_struct}
275 \end{figure}
276
277 Per questo motivo all'interno del resolver è stata definita una apposita
278 variabile di errore, \var{h\_errno} che viene utilizzata dalle funzioni di
279 libreria per indicare quale problema ha causato il fallimento della
280 risoluzione del nome. Ad essa si può accedere una volta che la si dichiara
281 con: 
282 \includecodesnip{listati/herrno.c} 
283 ed i valori che può assumere sono i seguenti:
284 \begin{basedescript}{\desclabelwidth{3cm}\desclabelstyle{\nextlinelabel}}
285 \item[\const{HOST\_NOT\_FOUND}] l'indirizzo richiesto non è valido e la
286   macchina indicata è sconosciuta.
287 \item[\const{NO\_ADDRESS}] il nome a dominio richiesto è valido, ma non ha un
288   indirizzo associato ad esso (alternativamente può essere indicato come
289   \const{NO\_DATA}).
290 \item[\const{NO\_RECOVERY}] si è avuto un errore non recuperabile
291   nell'interrogazione di un server DNS.
292 \item[\const{TRY\_AGAIN}] si è avuto un errore temporaneo nell'interrogazione
293   di un server DNS, si può ritentare l'interrogazione in un secondo tempo. 
294 \end{basedescript}
295
296 Quando un programma chiama \func{gethostbyname} e questa usa il DNS per
297 effettuare la risoluzione del nome, è con i valori di questi record che
298 vengono riempite le varie parti della struttura \struct{hostent}. Il primo
299 campo della struttura, \var{h\_name} contiene sempre il \textsl{nome
300   canonico}, che nel caso del DNS è appunto il nome associato ad un record
301 \texttt{A}. Il secondo campo della struttura, \var{h\_aliases}, invece è un
302 puntatore ad vettore di puntatori, terminato da un puntatore nullo. Ciascun
303 puntatore del vettore punta ad una stringa contenente uno degli altri
304 possibili nomi associati allo stesso \textsl{nome canonico} (quelli che nel
305 DNS vengono inseriti come record di tipo \texttt{CNAME}).
306
307 Il terzo campo della struttura, \var{h\_addrtype}, indica il tipo di indirizzo
308 che è stato restituito, e può assumere soltanto i valori \const{AF\_INET} o
309 \const{AF\_INET6}, mentre il quarto campo, \var{h\_length}, indica la
310 lunghezza dell'indirizzo stesso in byte. La funzione ritorna sempre una
311 struttura 
312
313 Infine il campo \var{h\_addr\_list} è il puntatore ad un vettore di puntatori
314 ai singoli indirizzi; il vettore è terminato da un puntatore nullo.  Inoltre,
315 come illustrato in fig.~\ref{fig:sock_hostent_struct}, viene definito il campo
316 \var{h\_addr} come sinonimo di \code{h\_addr\_list[0]}, cioè un riferimento
317 diretto al primo indirizzo della lista.
318
319 Oltre ai normali nomi a dominio la funzione accetta come argomento
320 \param{name} anche indirizzi numerici, in formato dotted decimal per IPv4 o
321 con la notazione illustrata in sez.~\ref{sec:IP_ipv6_notation}. In tal caso
322 \func{gethostbyname} non eseguirà nessuna interrogazione remota, ma si
323 limiterà a copiare la stringa nel campo \var{h\_name} ed a creare la
324 corrispondente struttura \var{in\_addr} da indirizzara con
325 \code{h\_addr\_list[0]}.
326
327
328
329
330
331
332
333 \section{Le opzioni dei socket}
334 \label{sec:TCP_sock_options}
335
336 Finora abbiamo trattato i socket nel loro comportamento più comune, è però
337 possibile attivare alcune modalità diverse di funzionamento degli stessi
338
339 Dato che la maggior parte delle opzioni dei socket sono relative ai socket
340 TCP, ed hanno poi significato analogo quando usate con altri socket, abbiamo
341 preferito trattare l'argomento in generale in questa sezione piuttosto che nel
342 capitolo dedicato alla trattazione generica dei socket.
343
344 \section{Altre funzioni di controllo}
345 \label{sec:TCP_sock_ctrl}
346
347
348
349
350
351 %%% Local Variables: 
352 %%% mode: latex
353 %%% TeX-master: "gapil"
354 %%% End: