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
11 \chapter{La gestione dei socket}
12 \label{cha:sock_generic_management}
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
21 \section{La risoluzione dei nomi}
22 \label{sec:sock_name_resolution}
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.
34 \subsection{La struttura del \textit{resolver}}
35 \label{sec:sock_resolver}
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}.\footnote{non staremo ad entrare nei dettagli della definizione di
41 cosa è un nome a dominio, dandolo per noto, una introduzione alla
42 problematica si trova in \cite{AGL} (cap. 9) mentre per una trattazione
43 approfondita di tutte le problematiche relative al DNS si può fare
44 riferimento a \cite{DNSbind}.} In realtà per DNS si intendono spesso i
45 server che forniscono su internet questo servizio, mentre nel nostro caso
46 affronteremo la problematica dal lato client, di un qualunque programma che
47 necessita di compiere questa operazione.
51 \includegraphics[width=10cm]{img/resolver}
52 \caption{Schema di funzionamento delle routine del \textit{resolver}.}
53 \label{fig:sock_resolver_schema}
56 Inoltre quella fra nomi a dominio e indirizzi IP non è l'unica corrispondenza
57 possibile fra nomi simbolici e valori numerici, come abbiamo visto anche in
58 sez.~\ref{sec:sys_user_group} per le corrispondenze fra nomi di utenti e
59 gruppi e relativi identificatori numerici; per quanto riguarda però tutti i
60 nomi associati a identificativi o servizi relativi alla rete il servizio di
61 risoluzione è gestito in maniera unificata da un insieme di routine fornite
62 con le librerie del C, detto appunto \textit{resolver}.
64 Lo schema di funzionamento del \textit{resolver} è illustrato in
65 fig.~\ref{fig:sock_resolver_schema}; in sostanza i programmi hanno a
66 disposizione un insieme di funzioni di libreria con cui chiamano il
67 \textit{resolver}, indicate con le freccie nere. Ricevuta la richiesta è
68 quest'ultimo che, sulla base della sua configurazione, esegue le operazioni
69 necessarie a fornire la risposta, che possono essere la lettura delle
70 informazioni mantenute nei relativi dei file statici presenti sulla macchina,
71 una interrogazione ad un DNS (che a sua volta, per il funzionamento del
72 protocollo può interrogarene altri) o la richiesta ad altri server per i quali
73 sia fornito il supporto, come LDAP.\footnote{la sigla LDAP fa riferimento ad
74 un protocollo, il \textit{Lightweight Directory Access Protocol}, che
75 prevede un meccanismo per la gestione di \textsl{elenchi} di informazioni
76 via rete; il contenuto di un elenco può essere assolutamente generico, e
77 questo permette il manenimento dei più vari tipi di informazioni su una
78 infrastruttura di questo tipo.}
80 La configurazione del \textit{resolver} attiene più alla amministrazione di
81 sistema che alla programmazione, ciò non di meno, prima di trattare le varie
82 funzioni di librerie utilizzate dai programmi, vale la pena fare una
83 panoramica generale. Originariamente la configurazione del \textit{resolver}
84 riguardava esclusivamente le questioni relative alla gestione dei nomi a
85 dominio, e prevedeva solo l'utilizzo del DNS e del file statico
88 Per questo aspetto il file di configurazione principale del sistema è
89 \file{/etc/resolv.conf} che contiene in sostanza l'elenco dei server DNS da
90 contattare; a questo si affianca il file \file{/etc/host.conf} il cui scopo
91 principale è indicare l'ordine in cui eseguire la risoluzione dei nomi (se
92 usare prima i valori di \file{/etc/hosts} o quelli del DNS). Tralasciamo i
93 dettagli relativi alle varie direttive che possono essere usate in questi
94 file, che si trovano nelle rispettive pagine di manuale.
96 Con il tempo però è divenuto possibile fornire diversi sostituti per
97 l'utilizzo delle associazione statiche in \file{/etc/hosts}, inoltre oltre
98 alla risoluzione dei nomi a dominio ci sono anche altri nomi da risolvere,
99 come quelli che possono essere associati ad una rete (invece che ad una
100 singola macchina) o ai gruppi di macchine definiti dal servizio
101 NIS,\footnote{il \textit{Network Information Service} è un servizio, creato da
102 Sun, e poi diffuso su tutte le piattaforme unix-like, che permette di
103 raggruppare all'interno di una rete (in quelli che appunto vengono chiamati
104 \textit{netgroup}) varie macchine, centralizzando i servizi di definizione
105 di utenti e gruppi e di autenticazione, oggi è sempre più spesso sostituito
106 da LDAP.} o come quelli dei protocolli e dei servizi che sono mantenuti nei
107 file statici \file{/etc/protocols} e \file{/etc/services}. Molte di queste
108 informazioni non si trovano su un DNS, e poi in un ambiente distribuito può
109 essere molto utile centralizzare il mentenimento di alcune di esse su
110 opportuni server. Inoltre l'uso di diversi supporti possibili per le stesse
111 informazioni (ad esempio il nome delle macchine può essere mantenuto sia
112 tramite \file{/etc/hosts}, che con il DNS, che con NIS) comporta il problema
113 dell'ordine in cui questi vengono interrogati.\footnote{con le implementazioni
114 classiche i vari supporti erano introdotti modificando direttamente le
115 funzioni di liberia, prevedendo un ordine di interrogazione predefinito e
116 non modificabile (a meno di una ricompilazione delle librerie stesse).}
118 Per risolvere questa serie di problemi il sistema del \textit{resolver} è
119 stato incluso all'interno di un meccanismo generico per la risoluzione di
120 corripondenze fra nomi ed informazioni ad essi associate chiamato \textit{Name
121 Service Switch}\footnote{il sistema è stato introdotto la prima volta nelle
122 librerie standard di Solaris, le \acr{glibc} hanno ripreso lo stesso schema,
123 si tenga presente che questo sistema non esiste per altre librerie standard
124 come le \acr{libc5} o le \acr{uclib}.} cui abbiamo accennato anche in
125 sez.~\ref{sec:sys_user_group} per quanto riguarda la gestione dei dati
126 associati a utenti e gruppi. Il \textit{Name Service Switch} (cui spesso si
127 fa riferimento con l'acronimo NSS) è un sistema di librerie dinamiche che
128 permette di definire in maniera generica sia i supporti su cui mantenere i
129 dati di corrispondenza fra nomi e valori numerici, sia l'ordine in cui
130 effettuare le ricerche sui vari supporti disponibili. Il sistema prevede una
131 serie di possibili classi di corrispondenza, quelle attualmente definite sono
132 riportate in tab.~\ref{tab:sys_NSS_classes}.
137 \begin{tabular}[c]{|l|p{8cm}|}
139 \textbf{Classe} & \textbf{Tipo di corrispondenza}\\
142 \texttt{shadow} & corrispondenze fra username e proprietà dell'utente
144 \texttt{group} & corrispondenze fra nome del gruppo e proprietà dello
146 \texttt{aliases} & alias per la posta elettronica\\
147 \texttt{ethers} & corrispondenze fra numero IP e MAC address della
149 \texttt{hosts} & corrispondenze fra nome a dominio e numero IP.\\
150 \texttt{netgroup} & corrispondenze gruppo di rete e macchine che lo
152 \texttt{networks} & corrispondenze fra nome di una rete e suo indirizzo
154 \texttt{protocols}& corrispondenze fra nome di un protocollo e relativo
155 numero identificativo.\\
156 \texttt{rpc} & corrispondenze fra nome di un servizio RPC e relativo
157 numero identificativo.\\
158 \texttt{services} & corrispondenze fra nome di un servizio e numero di
162 \caption{Le diverse classi di corrispondenze definite
163 all'interno del \textit{Name Service Switch}.}
164 \label{tab:sys_NSS_classes}
167 Il sistema del \textit{Name Service Switch} è controllato dal contenuto del
168 file \file{/etc/nsswitch.conf}; questo contiene una riga\footnote{seguendo una
169 convezione comune per i file di configurazione le righe vuote vengono
170 ignorate e tutto quello che segue un carattere ``\texttt{\#}'' viene
171 considerato un commento.} di configurazione per ciascuna di queste classi,
172 che viene inizia col nome di tab.~\ref{tab:sys_NSS_classes} seguito da un
173 carattere ``\texttt{:}'' e prosegue con la lista dei \textsl{servizi} su cui
174 le relative informazioni sono raggiungibili, scritti nell'ordine in cui si
175 vuole siano interrogati.
177 Ogni servizio è specificato a sua volta da un nome, come \texttt{file},
178 \texttt{dns}, \texttt{db}, ecc. che identifica la libreria dinamica che
179 realizza l'interfaccia con esso. Per ciascun servizio se \texttt{NAME} è il
180 nome utilizzato dentro \file{/etc/nsswitch.conf}, dovrà essere presente
181 (usualmente in \file{/lib}) una libreria \texttt{libnss\_NAME} che ne
182 implementa le funzioni.
184 In ogni caso, qualunque sia la modalità con cui ricevono i dati o il supporto
185 su cui vengono mantenuti, e che si usino o meno funzionalità aggiuntive
186 fornire dal sistema del \textit{Name Service Switch}, dal punto di vista di un
187 programma che deve effettuare la risoluzione di un nome a dominio, tutto
188 quello che conta sono le funzioni classiche che il \textit{resolver} mette a
189 disposizione,\footnote{è cura della implementazione fattane nelle \acr{glibc}
190 tenere conto della presenza del \textit{Name Service Switch}.} e sono queste
191 quelle che tratteremo nelle sezioni successive.
194 \subsection{Le funzioni di interrogazione del \textit{resolver}}
195 \label{sec:sock_resolver_functions}
197 Prima di trattare le funzioni usate normalmente nella risoluzione dei nomi a
198 dominio conviene trattare in maniera più dettagliata il meccanismo principale
199 da esse utilizzato e cioè quello del servizio DNS. Come accennato questo,
200 benché in teoria sia solo uno dei possibili supporti su cui mantenere le
201 informazioni, in pratica costituisce il meccanismo principale con cui vengono
202 risolti i nomi a dominio. Per questo motivo esistono una serie di funzioni di
203 libreria che servono specificamente ad esseguire delle interrogazioni verso un
204 server DNS, funzioni che poi vengono utilizzate per realizzare le funzioni
205 generiche di libreria usate anche dal sistema del \textit{resolver}.
207 Il sistema del DNS è in sostanza di un database distribuito organizzato in
208 maniera gerarchica, la manutenzione dei dati è mantenuta in tanti server
209 distinti ciascuno dei quali si occupa della risoluzione del proprio
210 \textit{dominio}; i nomi a dominio sono poi organizzati in una struttura ad
211 albero analoga a quella dell'albero dei file in un sistema unix-like, con
212 domini di primo livello (come i \texttt{.org}), secondo livello (come
213 \texttt{.truelite.it}), ecc. In questo caso le separazioni sono fra i vari
214 livelli sono definite dal carattere ``\texttt{.}'' ed i nomi devono essere
215 risolti da destra verso sinistra. Il meccanismo funziona con il criterio della
216 \textsl{delegazione}, un server responsabile per un dominio di primo livello
217 può delegare la risoluzione degli indirizzi per un suo dominio di secondo
218 livello ad un altro server, il quale a sua volta potrà delegare la risoluzione
219 di un eventuale sottodominio di terzo livello ad un altro server ancora.
221 In realtà un server DNS contiene comunque una serie di altre informazioni;
222 ciascuna voce nel database viene chiamata \textit{resource record}, e viene
223 vi è associato un certo \textsl{tipo}, identificato da una sigla.
228 interrogando il quale si possono avere una serie di informazioni,
229 la principale delle quali è appunto la corrispondenza fra un nome (a dominio)
233 Per quanto ci interessa i tipi di \textit{resource record} che vengono
234 utilizzati dal \textit{resolver} sono sostanzialmente i seguenti:
235 \begin{basedescript}{\desclabelwidth{1.2cm}\desclabelstyle{\nextlinelabel}}
236 \item[\texttt{A}] indica la corripondenza fra un nome a dominio ed un
237 indirizzo IPv4, ad esempio la corrispondenza fra \texttt{dodds.truelite.it}
238 e l'indirizzo IP \texttt{62.48.34.25}.
239 \item[\texttt{AAAA}] chiamato in questo modo dato che la dimensione è quattro
240 volte quella di un indirizzo IPv4, questo record contiene la corrispondenza
241 fra un nome a dominio ed un indirizzo IPv6.
242 \item[\texttt{PTR}] per provvedere la mappatura inversa fra un indirizzo IP ed
243 un nome a dominio si utilizza invece questo tipo di record (il cui nome sta
244 per \textit{pointer}).
245 \item[\texttt{CNAME}] qualora si abbiamo più nomi con i quali si voglia
246 indicare lo stesso indirizzo (ad esempio \texttt{www.truelite.it}, o
247 \texttt{sources.truelite.it}, che comunque fanno sempre riferimento alla
248 macchina \texttt{dodds.truelite.it}) si può usare questo tipo di record per
249 creare degli \textit{alias} in modo da associare un qualunque altro nome al
250 \textsl{nome canonico} della macchina (quello associato al record
259 Per questo motivo il \textit{resolver} prevede delle funzioni che permettono
260 sia di eseguire direttamente delle interrogazione ad un server DNS, che di
261 controllare le modalità con cui queste vengono eseguite; diventa così
262 possibile modificare da programma buona parte dei parametri controllati da
263 \file{/etc/resolv.conf}.
267 \subsection{La risoluzione dei nomi a dominio}
268 \label{sec:sock_gethostbyname}
270 Dato che la principale funzionalità del \textit{resolver} resta quella di
271 risolvere i nomi a dominio in indirizzi IP, vedremo per prime le funzioni a
272 questo dedicate. La prima funzione è \funcd{gethostbyname} il cui scopo è
273 ottenere l'indirizzo di una stazione noto il suo nome a dominio, il suo
275 \begin{prototype}{netdb.h}
276 {struct hostent *gethostbyname(const char *name)}
278 Determina l'indirizzo associato al nome a dominio \param{name}.
280 \bodydesc{La funzione restituisce in caso di successo il puntatore ad una
281 struttura di tipo \struct{hostent} contente i dati associati al nome a
282 dominio o un puntatore nullo in caso di errore.}
285 La funzione prende come argomento una stringa \param{name} contenente il nome
286 a dominio che si vuole risolvere, in caso di successo i dati ad esso relativi
287 vengono memorizzati in una opportuna struttura \struct{hostent} la cui
288 definizione è riportata in fig.~\ref{fig:sock_hostent_struct}. In caso di
289 insuccesso l'errore viene segnalato da un valore nullo del puntatore, ma in
290 questo caso, a differenza delle funzioni viste finora, non viene utilizzata la
291 variabile \var{errno} per riportare un codice di errore, in quanto questo
292 dipende solo dalle sottostanti chiamate al sistema e può non avere nessun
293 significato nell'indicare quale parte del procedimento di risoluzione è
297 \footnotesize \centering
298 \begin{minipage}[c]{15cm}
299 \includestruct{listati/hostent.h}
301 \caption{La struttura \structd{hostent}.}
302 \label{fig:sock_hostent_struct}
305 Per questo motivo all'interno del resolver è stata definita una apposita
306 variabile di errore, \var{h\_errno} che viene utilizzata dalle funzioni di
307 libreria per indicare quale problema ha causato il fallimento della
308 risoluzione del nome. Ad essa si può accedere una volta che la si dichiara
310 \includecodesnip{listati/herrno.c}
311 ed i valori che può assumere sono i seguenti:
312 \begin{basedescript}{\desclabelwidth{3cm}\desclabelstyle{\nextlinelabel}}
313 \item[\const{HOST\_NOT\_FOUND}] l'indirizzo richiesto non è valido e la
314 macchina indicata è sconosciuta.
315 \item[\const{NO\_ADDRESS}] il nome a dominio richiesto è valido, ma non ha un
316 indirizzo associato ad esso (alternativamente può essere indicato come
318 \item[\const{NO\_RECOVERY}] si è avuto un errore non recuperabile
319 nell'interrogazione di un server DNS.
320 \item[\const{TRY\_AGAIN}] si è avuto un errore temporaneo nell'interrogazione
321 di un server DNS, si può ritentare l'interrogazione in un secondo tempo.
324 Quando un programma chiama \func{gethostbyname} e questa usa il DNS per
325 effettuare la risoluzione del nome, è con i valori di questi record che
326 vengono riempite le varie parti della struttura \struct{hostent}. Il primo
327 campo della struttura, \var{h\_name} contiene sempre il \textsl{nome
328 canonico}, che nel caso del DNS è appunto il nome associato ad un record
329 \texttt{A}. Il secondo campo della struttura, \var{h\_aliases}, invece è un
330 puntatore ad vettore di puntatori, terminato da un puntatore nullo. Ciascun
331 puntatore del vettore punta ad una stringa contenente uno degli altri
332 possibili nomi associati allo stesso \textsl{nome canonico} (quelli che nel
333 DNS vengono inseriti come record di tipo \texttt{CNAME}).
335 Il terzo campo della struttura, \var{h\_addrtype}, indica il tipo di indirizzo
336 che è stato restituito, e può assumere soltanto i valori \const{AF\_INET} o
337 \const{AF\_INET6}, mentre il quarto campo, \var{h\_length}, indica la
338 lunghezza dell'indirizzo stesso in byte. La funzione ritorna sempre una
341 Infine il campo \var{h\_addr\_list} è il puntatore ad un vettore di puntatori
342 ai singoli indirizzi; il vettore è terminato da un puntatore nullo. Inoltre,
343 come illustrato in fig.~\ref{fig:sock_hostent_struct}, viene definito il campo
344 \var{h\_addr} come sinonimo di \code{h\_addr\_list[0]}, cioè un riferimento
345 diretto al primo indirizzo della lista.
347 Oltre ai normali nomi a dominio la funzione accetta come argomento
348 \param{name} anche indirizzi numerici, in formato dotted decimal per IPv4 o
349 con la notazione illustrata in sez.~\ref{sec:IP_ipv6_notation}. In tal caso
350 \func{gethostbyname} non eseguirà nessuna interrogazione remota, ma si
351 limiterà a copiare la stringa nel campo \var{h\_name} ed a creare la
352 corrispondente struttura \var{in\_addr} da indirizzara con
353 \code{h\_addr\_list[0]}.
361 \section{Le opzioni dei socket}
362 \label{sec:TCP_sock_options}
364 Finora abbiamo trattato i socket nel loro comportamento più comune, è però
365 possibile attivare alcune modalità diverse di funzionamento degli stessi
367 Dato che la maggior parte delle opzioni dei socket sono relative ai socket
368 TCP, ed hanno poi significato analogo quando usate con altri socket, abbiamo
369 preferito trattare l'argomento in generale in questa sezione piuttosto che nel
370 capitolo dedicato alla trattazione generica dei socket.
372 \section{Altre funzioni di controllo}
373 \label{sec:TCP_sock_ctrl}
381 %%% TeX-master: "gapil"