Modifiche non registrate ieri sera
[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à degli stessi, e le funzioni
17 di controllo che vanno ad operare su di essi.
18
19
20 \section{La risoluzione dei nomi}
21 \label{sec:sock_name_resolution}
22
23 Negli esempi precedenti abbiamo sempre identificato le singole macchine
24 attraverso indirizzi numerici, sfruttando al più le funzioni di conversione
25 elementari illustrate in sez.~\ref{sec:sock_addr_func} che permettono di
26 passare da un indirizzo espresso in forma dotted decimal ad un numero. Vedremo
27 in questa sezione le funzioni utilizzate per poter utilizzare dei nomi
28 simbolici al posto dei valori numerici, e viceversa quelle che permettono di
29 ottenere i nomi simbolici associati ad indirizzi, porte o altre proprietà del
30 sistema.
31
32
33 \subsection{La struttura del \textit{resolver}}
34 \label{sec:sock_resolver}
35
36 La risoluzione dei nomi è associata tradizionalmente al servizio del
37 \textit{Domain Name Service} che permette di identificare le macchine su
38 internet invece che per numero IP attraverso il relativo \textsl{nome a
39   dominio}. In realtà per DNS si intendono spesso i server che forniscono su
40 internet questo servizio, mentre nel nostro caso affronteremo la problematica
41 dal lato client, di un qualunque programma che necessita di compiere questa
42 operazione.
43
44 \begin{figure}[htb]
45   \centering
46   \includegraphics[width=10cm]{img/resolver}
47   \caption{Schema di funzionamento delle routine del \textit{resolver}.}
48   \label{fig:sock_resolver_schema}
49 \end{figure}
50
51 Inoltre quella fra nomi a dominio e indirizzi IP non è l'unica corrispondenza
52 possibile fra nomi simbolici e valori numerici, come abbiamo visto anche in
53 sez.~\ref{sec:sys_user_group} per le corrispondenze fra nomi di utenti e
54 gruppi e relativi identificatori numerici; per quanto riguarda però tutti i
55 nomi associati a identificativi o servizi relativi alla rete il servizio di
56 risoluzione è gestito in maniera unificata da un insieme di routine fornite
57 con le librerie del C, detto appunto \textit{resolver}.
58
59 Lo schema di funzionamento del \textit{resolver} è illustrato in
60 fig.~\ref{fig:sock_resolver_schema}; in sostanza i programmi hanno a
61 disposizione un insieme di funzioni di libreria con cui chiamano il
62 \textit{resolver}, indicate con le freccie nere. Ricevuta la richiesta è
63 quest'ultimo che, sulla base della sua configurazione, esegue le operazioni
64 necessarie a fornire la risposta, che possono essere la lettura delle
65 informazioni mantenute nei relativi dei file statici presenti sulla macchina,
66 una interrogazione ad un DNS (che a sua volta, per il funzionamento del
67 protocollo può interrogarene altri) o la richiesta ad altri server per i quali
68 sia fornito il supporto, come LDAP.
69
70 La configurazione del resolver attiene più alla amministrazione di sistema che
71 alla programmazione, ciò non di meno, prima di trattare le varie funzioni che
72 vale la pena farne una panoramica. Originariamente la configurazione
73 riguardava esclusivamente le questioni relative alla gestione dei nomi a
74 dominio, e prevedeva solo l'utilizzo del DNS e del file statico
75 \file{/etc/hosts}, il file di configurazione principale è
76 \file{/etc/resolv.conf} e contiene in sostanza l'elenco dei server DNS da
77 contattare, a cui si affianca \file{/etc/host.conf} per indicare l'ordine in
78 cui eseguire la risoluzione dei nomi (se usare prima i valori di
79 \file{/etc/hosts} o il DNS); tralasciamo i dettagli che si trovano nelle
80 relative pagine di manuale.
81
82 Con il tempo però è divenuto possibile fornire diversi sostituti per
83 l'utilizzo dei file statici, ed ai nomi a dominio si sono aggiunti altri nomi,
84 come quelli associati alle reti ed ai gruppi di macchine definiti dal servizio
85 NIS, o quelli dei protocolli e dei servizi mantenuti nei file statici
86 \file{/etc/protocols} e \file{/etc/services}, tutte informazioni che
87 normalmente non si trovano su un DNS, ma possono essere accedute in maniera
88 centralizzata su opportuni server (ad esempio su LDAP) in grado di mantenerle.
89
90 Questo ha portato alla creazione di un sistema di risoluzione più ampio, il
91 \textit{Name Service Switch} di cui il \textit{resolver} viene a costituire un
92 sottoinsieme. Questo sistema, che si applica anche alla risoluzioni fra nomi
93 di utenti e gruppi e relativi identificatori, permette di definire in maniera
94 generica (attraverso una serie di librerie dinamiche) sia i supporti su cui
95 mantenere i dati di corrispondenza fra nomi e valori numerici, sia l'ordine in
96 cui effettuare le ricerche sui vari supporti disponibili, ed è controllato dal
97 file \file{/etc/nsswitch.conf}. Anche per questo si può fare riferimento alle
98 pagine di manuale ed al relativo capitolo nel manuale \cite{glibc} delle
99 \textsl{glibc}.
100
101 In ogni caso, qualunque sia la modalità con cui ricevono i dati o il supporto
102 su cui vengono mantenuti, dal punto di vista di un programma che deve
103 effettuare la risoluzione di un nome, tutto quello che conta sono le funzioni
104 che il \textit{resolver} mette a disposizione, e sono queste quelle che
105 tratteremo nelle sezioni successive.
106
107
108
109 \subsection{La risoluzione dei nomi a dominio}
110 \label{sec:sock_gethostbyname}
111
112 Dato che la principale funzionalità del \textit{resolver} resta quella di
113 risolvere i nomi a dominio in indirizzi IP, vedremo per prime le funzioni a
114 questo dedicate. La prima funzione è \funcd{gethostbyname} il cui scopo è
115 ottenere l'indirizzo di una stazione noto il suo nome a dominio, il suo
116 prototipo è:
117 \begin{prototype}{netdb.h}
118 {struct hostent *gethostbyname(const char *name)}
119
120 Determina l'indirizzo associato al nome a dominio \param{name}.
121
122 \bodydesc{La funzione restituisce in caso di successo il puntatore ad una
123   struttura di tipo \struct{hostent} contente i dati associati al nome a
124   dominio o un puntatore nullo in caso di errore.}
125 \end{prototype}
126
127 La funzione prende come argomento una stringa \param{name} contenente il nome
128 a dominio che si vuole risolvere, in caso di successo i dati ad esso relativi
129 vengono memorizzati in una opportuna struttura \struct{hostent} la cui
130 definizione è riportata in fig.~\ref{fig:sock_hostent_struct}. In caso di
131 insuccesso l'errore viene segnalato da un valore nullo del puntatore, ma in
132 questo caso, a differenza delle funzioni viste finora, non viene utilizzata la
133 variabile \var{errno} per riportare un codice di errore, in quanto questo è
134 dipende solo dalle sottostanti chiamate al sistema e non avere nessun
135 significato nell'indicare quale parte del procedimento di risoluzione è
136 fallita.
137
138 \begin{figure}[!htb]
139   \footnotesize \centering
140   \begin{minipage}[c]{15cm}
141     \includestruct{listati/hostent.h}
142   \end{minipage}
143   \caption{La struttura \structd{hostent} .}
144   \label{fig:sock_hostent_struct}
145 \end{figure}
146
147 Per questo motivo all'interno del resolver è stata definita una apposita
148 variabile di errore, \var{h\_errno} che viene utilizzata dalle funzioni di
149 libreria per indicare quale problema ha causato il fallimento della
150 risoluzione. Ad essa si può accedere una volta che la si dichiara con:
151 \includecodesnip{listati/herrno.c}
152 ed i valori che può assumere sono i seguenti:
153 \begin{basedescript}{\desclabelwidth{3cm}\desclabelstyle{\nextlinelabel}}
154 \item[\const{HOST\_NOT\_FOUND}] l'indirizzo richiesto non è valido e la
155   macchina indicata è sconosciuta.
156 \item[\const{NO\_ADDRESS}] il nome a dominio richiesto è valido, ma non ha un
157   indirizzo associato ad esso.
158 \item[\const{NO\_RECOVERY}] si è avuto un errore non recuperabile
159   nell'interrogazione di un server DNS.
160 \item[\const{TRY\_AGAIN}] si è avuto un errore temporaneo nell'interrogazione
161   di un server DNS, si può ritentare l'interrogazione in un secondo tempo. 
162 \end{basedescript}
163
164
165 Per capire meglio il contenuto della struttura \struct{hostent} conviene
166 spendere alcune parole sul funzionamento del DNS. Questo in sostanza è un
167 enorme database distribuito interrogando il quale si possono avere una serie
168 di informazioni la principale delle quali è la corrispondenza fra un nome (a
169 dominio) ed indirizzo IP.  Un server DNS contiene comunque una serie di altre
170 informazioni; ciascuna voce nel database viene chiamata \textit{resource
171   record} e vi è associato un certo \textsl{tipo}, identificato da una sigla.
172 Per quanto ci interessa i \textit{resource record} che vengono utilizzati dal
173 \textit{resolver} sono sostanzialmente i seguenti:
174 \begin{basedescript}{\desclabelwidth{1.2cm}\desclabelstyle{\nextlinelabel}}
175 \item[\texttt{A}] indica la corripondenza fra un nome a dominio ed un
176   indirizzo IPv4, ad esempio la corrispondenza fra \texttt{dodds.truelite.it}
177   e l'indirizzo IP \texttt{62.48.34.25}.
178 \item[\texttt{AAAA}] chiamato in questo modo dato che la dimensione è quattro
179   volte quella di un indirizzo IPv4, questo record contiene la corrispondenza
180   fra un nome a dominio ed un indirizzo IPv6.
181 \item[\texttt{PTR}] per provvedere la mappatura inversa fra un indirizzo IP ed
182   un nome a dominio si utilizza invece questo tipo di record (il cui nome sta
183   per \textit{pointer}).
184 \item[\texttt{CNAME}] qualora si abbiamo più nomi con i quali si voglia
185   indicare lo stesso indirizzo (ad esempio \texttt{www.truelite.it}, o
186   \texttt{sources.truelite.it}, che comunque fanno sempre riferimento alla
187   macchina \texttt{dodds.truelite.it}) si può usare questo tipo di record per
188   creare degli \textit{alias} in modo da associare un qualunque altro nome al
189   \textsl{nome canonico} della macchina (quello associato al record
190   \texttt{A}).
191 \end{basedescript}
192
193 Quando un programma chiama \func{gethostbyname} e questa usa il DNS per
194 effettuare la risoluzione del nome, è con i valori di questi record che
195 vengono riempite le varie parti della struttura \struct{hostent}. Il primo
196 campo della struttura, \var{h\_name} contiene sempre il \textsl{nome
197   canonico}, che nel caso del DNS è appunto il nome associato ad un record
198 \texttt{A}. Il secondo campo della struttura invece è un puntatore ad vettore
199 di puntatori, terminato da un puntatore nullo, alle strighe che contengono
200 tutti i possibili altri nomi (quelli che nel DNS sarebbero record
201 \texttt{CNAME}).
202
203 Il terzo campo, \var{h\_addrtype}, indica il tipo di indirizzo che è stato
204 restituito, e può essere solo \const{AF\_INET} o \const{AF\_INET6}, mentre il
205 quarto campo, e \var{h\_length} indica la lunghezza dell'indirizzo stesso in
206 byte. Infine il campo \var{h\_addr\_list} è il puntatore ad un vettore di
207 puntatori ai singoli indirizzi; il vettore è terminato da un puntatore nullo.
208 Inoltre, come illustrato in fig.~\ref{fig:sock_hostent_struct}, viene definito
209 per compatibilità il campo \var{h\_addr} corrispondente al puntatore al primo
210 indirizzo della lista.
211
212 In sostanza 
213
214
215
216
217
218
219
220 \section{Le opzioni dei socket}
221 \label{sec:TCP_sock_options}
222
223 Finora abbiamo trattato i socket nel loro comportamento più comune, è però
224 possibile attivare alcune modalità diverse di funzionamento degli stessi
225
226 Dato che la maggior parte delle opzioni dei socket sono relative ai socket
227 TCP, ed hanno poi significato analogo quando usate con altri socket, abbiamo
228 preferito trattare l'argomento in generale in questa sezione piuttosto che nel
229 capitolo dedicato alla trattazione generica dei socket.
230
231 \section{Altre funzioni di controllo}
232 \label{sec:TCP_sock_ctrl}
233
234
235
236
237
238 %%% Local Variables: 
239 %%% mode: latex
240 %%% TeX-master: "gapil"
241 %%% End: