7c7475c616638a57be422a8a8f664ecfb92c4cf4
[gapil.git] / othersock.tex
1 %% othersock.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{Gli altri tipi di socket}
12 \label{cha:other_socket}
13
14 Dopo aver trattato in \capref{cha:TCP_socket} i socket TCP, che costituiscono
15 l'esempio più comune dell'interfaccia dei socket, esamineremo in questo
16 capitolo gli altri tipi di socket, a partire dai socket UDP, e i socket deiit
17 \textit{Unix domain} già incontrati in \secref{sec:ipc_socketpair}.
18
19
20 \section{I socket UDP}
21 \label{sec:UDP_socket}
22
23 Dopo i socket TCP i socket più utilizzati nella programmazione di rete sono i
24 socket UDP: protocolli diffusi come NFS o il DNS usano principalmente questo
25 tipo di socket. Tratteremo in questa sezione le loro caratteristiche
26 principali e le modalità per il loro utilizzo.
27
28
29 \subsection{Le caratteristiche di un socket UDP}
30 \label{sec:UDP_characteristics}
31
32 Come illustrato in \secref{sec:net_udp} UDP è un protocollo molto semplice che
33 non supporta le connessioni e non è affidabile: esso si appoggia direttamente
34 sopra IP (per i dettagli sul protocollo si veda \secref{sec:udp_protocol}).  I
35 dati vengono inviati in forma di pacchetti, e non ne è assicurata né la
36 effettiva ricezione né l'arrivo nell'ordine in cui vengono inviati. Il
37 vantaggio del protocollo è la velocità, non è necessario trasmettere le
38 informazioni di controllo ed il risultato è una trasmissione di dati più
39 veloce ed immediata.
40
41 Questo significa che a differenza dei socket TCP i socket UDP non supportano
42 una comunicazione di tipo \textit{stream} in cui si ha a disposizione un
43 flusso continuo di dati che può essere letto un po' alla volta, ma piuttosto
44 una comunicazione di tipo \textit{datagram}, in cui i dati arrivano in singoli
45 blocchi che devono essere letti integralmente.
46
47 Questo diverso comportamento significa anche che i socket UDP, pur
48 appartenendo alla famiglia \const{PF\_INET}\footnote{o \const{PF\_INET6}
49   qualora si usasse invece il protocollo IPv6, che pure supporta UDP.} devono
50 essere aperti quando si usa la funzione \func{socket} (si riveda quanto
51 illustrato a suo tempo in \tabref{tab:sock_sock_valid_combinations})
52 utilizzando per il tipo di socket il valore \const{SOCK\_DGRAM}.
53
54 Questa differenza comporta ovviamente che anche le modalità con cui si usano i
55 socket UDP sono completamente diverse rispetto ai socket TCP, ed in
56 particolare non esistendo il concetto di connessione non esiste il meccanismo
57 del \textit{three way handshake} nè quello degli stati del protocollo. In
58 realtà tutto quello che avviene nella comunicazione attraverso dei socket UDP
59 è la trasmissione di un pacchetto da un client ad un server o viceversa,
60 secondo lo schema illustrato in \figref{fig:UDP_packet-exchange}.
61
62 \begin{figure}[htb]
63   \centering
64   \includegraphics[width=10cm]{img/udp_connection}  
65   \caption{Lo schema di interscambio dei pacchetti per una comunicazione via
66      UDP.}
67   \label{fig:UDP_packet-exchange}
68 \end{figure}
69
70 Come illustrato in \figref{fig:UDP_packet-exchange} la struttura generica di
71 un server UDP prevede, una volta creato il socket, la chiamata a \func{bind}
72 per mettersi in ascolto dei dati. Questa è l'unica parte comune con un server
73 TCP: non essendovi il concetto di connessione le funzioni \func{listen} ed
74 \func{accept} non sono mai utilizzate nel caso di server UDP. La ricezione dei
75 dati dal client avviene attraverso la funzione \func{recvfrom}, mentre una
76 eventuale risposta sarà inviata con la funzione \func{sendto}. 
77
78 Da parte del client invece, una volta creato il socket non sarà necessario
79 connettersi con \func{connect} (anche se, come vedremo in
80 \secref{sec:UDP_connect}, è possibile usare questa funzione, con un
81 significato comunque diverso) ma si potrà effettuare direttamente una
82 richiesta inviando un pacchetto con la funzione \func{sendto} e si potrà
83 leggere una eventuale risposta con la funzione \func{recvfrom}.
84
85 Anche se UDP è completamente diverso rispetto a TCP resta identica la
86 possibilità di gestire più canali di comunicazione fra due macchine
87 utilizzando le porte. In questo caso il server dovrà usare comunque la
88 funzione \func{bind} per scegliere la porta su cui ricevere i dati, e come nel
89 caso dei socket TCP si potrà usare il comando \cmd{netstat} per
90 verificare quali socket sono in ascolto:
91 \begin{verbatim}
92 [piccardi@gont gapil]# netstat -anu
93 Active Internet connections (servers and established)
94 Proto Recv-Q Send-Q Local Address           Foreign Address         State
95 udp        0      0 0.0.0.0:32768           0.0.0.0:*
96 udp        0      0 192.168.1.2:53          0.0.0.0:*
97 udp        0      0 127.0.0.1:53            0.0.0.0:*
98 udp        0      0 0.0.0.0:67              0.0.0.0:*
99 \end{verbatim}
100 in questo caso abbiamo attivi il DNS (sulla porta 53, e sulla 32768 per la
101 connessione di controllo del server \cmd{named}) ed un server DHCP (sulla
102 porta 67).
103
104 Si noti però come in questo caso la colonna che indica lo stato sia vuota. I
105 socket UDP infatti non hanno uno stato. Inoltre anche in presenza di traffico
106 non si avranno indicazioni delle connessioni attive, proprio perché questo
107 concetto non esiste per i socket UDP, il kernel si limita infatti a ricevere i
108 pacchetti ed inviarli al processo in ascolto sulla porta cui essi sono
109 destinati, oppure a scartarli inviando un messaggio \textit{ICMP port
110   unreachable} qualora non vi sia nessun processo in ascolto.
111
112
113 \subsection{Le funzioni \func{sendto} e \func{recvfrom}}
114 \label{sec:UDP_sendto_recvfrom}
115
116 Come accennato in \secref{sec:UDP_characteristics} le due funzioni principali
117 usate per la trasmissione di dati attraverso i socket UDP sono \func{sendto} e
118 \func{recvfrom}. La necessità di usare queste funzioni è dovuta al fatto che
119 non esistendo con UDP il concetto di connessione, non si ha neanche a
120 disposizione un \textsl{socket connesso} su cui sia possibile usare
121 direttamente \func{read} e \func{write} avendo già stabilito (grazie alla
122 chiamata ad \func{accept} che lo associa ad una connessione) quali sono
123 sorgente e destinazione dei dati.
124
125 Per questo motivo nel caso di UDP diventa essenziale utilizzare queste due
126 funzioni, che sono comunque utilizzabili in generale per la trasmissione di
127 dati attraverso qualunque tipo di socket. Esse hanno la caratteristica di
128 prevedere tre argomenti aggiuntivi attraveso i quali è possibile specificare
129 la destinazione o l'origine dei dati trasmessi. La prima di queste funzioni è
130 \funcd{sendto} ed il suo prototipo\footnote{il prototipo illustrato è quello
131   utilizzato dalle \acr{glibc}, che seguono le \textit{Single Unix
132     Specification}, l'argomento \param{flags} era di tipo \type{int} nei vari
133   BSD4.*, mentre nelle \acr{libc4} e \acr{libc5} veniva usato un
134   \type{unsigned int}; l'argomento \param{len} era \type{int} nei vari BSD4.*
135   e nelle \acr{libc4}, ma \type{size\_t} nelle \acr{libc5}; infine l'argomento
136   \param{tolen} era \type{int} nei vari BSD4.* nelle \acr{libc4} e nelle
137   \acr{libc5}.} è:
138 \begin{functions}
139   \headdecl{sys/types.h}
140   \headdecl{sys/socket.h}
141   
142   \funcdecl{ssize\_t sendto(int sockfd, const void *buf, size\_t len, int
143     flags, const struct sockaddr *to, socklen\_t tolen)}
144   
145   Trasmette un messaggio ad un altro socket.
146   
147   \bodydesc{La funzione restituisce il numero di caratteri inviati in caso di
148     successo e -1 per un errore; nel qual caso \var{errno} viene impostata al
149     rispettivo codice di errore:
150   \begin{errlist}
151   \item[\errcode{EAGAIN}] il socket è in modalità non bloccante, ma
152     l'operazione richede che la funzione si blocchi.
153   \item[\errcode{ECONNRESET}] l'altro capo della comunicazione ha resettato la
154     conessione.
155   \item[\errcode{EDESTADDRREQ}] il socket non è di tipo connesso, e non si è
156     specificato un indirizzo di destinazione.
157   \item[\errcode{EISCONN}] il socket è già connesso, ma si è specificato un
158     destinatario.
159   \item[\errcode{EMSGSIZE}] il tipo di socket richiede l'invio dei dati in un
160     blocco unico, ma la dimensione del messaggio lo rende impossibile.
161   \item[\errcode{ENOBUFS}] la coda di uscita dell'interfaccia è già piena (di
162     norma Linux non usa questo messaggio ma scarta silenziosamente i
163     pacchetti).
164   \item[\errcode{ENOTCONN}] il socket non è connesso e non si è specificata
165     una destinazione.
166   \item[\errcode{EOPNOTSUPP}] il valore di \param{flag} non è appropriato per
167     il tipo di socket usato.
168   \item[\errcode{EPIPE}] il capo locale della connessione è stato chiuso, si
169     riceverà anche un segnale di \const{SIGPIPE}, a meno di non aver impostato
170     \const{MSG\_NOSIGNAL} in \param{flags}.
171   \end{errlist}
172   ed anche \errval{EFAULT}, \errval{EBADF}, \errval{EINVAL}, \errval{EINTR},
173   \errval{ENOMEM}, \errval{ENOTSOCK} più gli eventuali altri errori relativi
174   ai protocolli utilizzati.}
175 \end{functions}
176
177 I primi tre argomenti sono identici a quelli della funzione \func{write} e
178 specificano il socket \param{sockfd} a cui si fa riferimento, il buffer
179 \param{buf} che contiene i dati da inviare e relativa lunghezza \param{len}.
180 Come per \func{write} la funzione ritorna il numero di byte inviati; nel caso
181 di UDP però questo deve sempre corrispondere alla dimensione totale
182 specificata da \param{len} in quanto i dati vengono sempre inviati in forma di
183 pacchetto e non possono essere spezzati in invii successivi. Qualora non ci
184 sia spazio nel buffer di uscita la funzione si blocca (a meno di non avere
185 aperto il socket in modalità non bloccante), se invece non è possibile inviare
186 il messaggio all'interno di un unico pacchetto (ad esempio perché eccede le
187 dimensioni massime del protocollo sottostante utilizzati) essa fallisce con
188 l'errore di \errcode{EMSGSIZE}.
189
190 I due argomenti \param{to} e \param{tolen} servono a specificare la
191 destinazione del messaggio da inviare, e indicano rispettivamente la struttura
192 contentento l'indirizzo di quest'ultima e la relativa lunghezza. Questi
193 argomenti vanno specificati stessa forma in cui lo si userebbero con
194 \func{connect}: \param{to} deve cioè puntare alla struttura contenente
195 l'indirizzo IP e la porta di destinazione verso cui si vogliono inviare i dati
196 mentre \param{tolen} specifica la dimensione di quest'ultima.
197
198 Se il socket è di un tipo che prevede le connessioni (ad esempio qualora si
199 usi la funzione con un socket TCP), questo deve essere già connesso prima di
200 eseguire la funzione, altrimenti si avrà un errore di \errcode{ENOTCONN};
201 inoltre in questo caso gli argomenti \param{to} e \param{tolen} devono essere
202 inizializzati rispettivamente a \const{NULL} e 0 (di solito vengono ignorati,
203 ma si potrebbe anche ricevere un errore di \errcode{EISCONN}).
204
205 Infine l'argomento \param{flags} è un intero usato come maschera binaria che
206 permette di impostare una serie di modalità di funzionamento della
207 comunicazione attraverso il socket (come \const{MSG\_NOSIGNAL} che impedisce
208 l'invio del segnale \const{SIGPIPE} quando si è già chiuso il capo locale
209 della connessione). Torneremo con maggiori dettagli sul significato di questo
210 argomento in \secref{sec:xxx_sendmsg}, per il momento ci si può limitare ad
211 usare sempre un valore nullo.
212
213 La seconda funzione utilizzata nella comunicazione fra socket UDP è
214 \funcd{recvfrom} che serve a ricevere i dati inviati da un altro socket, il
215 suo prototipo\footnote{il prototipo è quello delle \acr{glibc} che seguono le
216   \textit{Single Unix Specification}, i vari BSD4.*, le \acr{libc4} e le
217   \acr{libc5} usano un \type{int} come valore di ritorno; per gli argomenti
218   \param{flags} e \param{len} vale quanto detto a proposito di \func{sendto};
219   infine l'argomento \param{fromlen} è \type{int} per i vari BSD4.*, le
220   \acr{libc4} e le \acr{libc5}.} è:
221 \begin{functions}
222   \headdecl{sys/types.h}
223   \headdecl{sys/socket.h}
224   
225   \funcdecl{ssize\_t recvfrom(int sockfd, const void *buf, size\_t len, int
226     flags, const struct sockaddr *from, socklen\_t *fromlen)}
227   
228   Riceve un messaggio ad un socket.
229   
230   \bodydesc{La funzione restituisce il numero di byte ricevuti in caso di
231     successo e -1 in caso di errore; nel qual caso \var{errno} assumerà il
232     valore:
233   \begin{errlist}
234   \item[\errcode{EAGAIN}] il socket è in modalità non bloccante, ma
235     l'operazione richede che la funzione si blocchi, oppure si è impostato un
236     timeout in ricezione e questo è scaduto.
237   \item[\errcode{ECONNREFUSED}] l'altro capo della comunicazione ha rifiutato
238     la connessione (in genere perché il relativo servizio non è disponibile).
239   \item[\errcode{ENOTCONN}] il socket è di tipo connesso, ma non si è eseguita
240     la connessione.
241   \end{errlist}
242   ed anche \errval{EFAULT}, \errval{EBADF}, \errval{EINVAL}, \errval{EINTR},
243   \errval{ENOMEM}, \errval{ENOTSOCK} più gli eventuali altri errori relativi
244   ai protocolli utilizzati.}
245 \end{functions}
246
247 Come per \func{sendto} i primi tre argomenti sono identici agli analoghi di
248 \func{read}: dal socket vengono letti \param{len} byte che vengono salvati nel
249 buffer \param{buf}. A seconda del tipo di socket (se di tipo \textit{datagram}
250 o \textit{stream}) inoltre i byte in eccesso che non sono stati letti possono
251 rispettivamente andare persi o restare disponibili per una lettura successiva.
252 Se non sono disponibili dati la funzione si blocca, a meno di non aver aperto
253 il socket in modalità non bloccante, nel qual caso si avrà il solito errore di
254 \errcode{EAGAIN}.  Qualora \param{len} ecceda la dimensione del pacchetto la
255 funzione legge comunque i dati disponibili, ed il suo valore di ritorno è
256 comunque il numero di byte letti.
257
258 I due argomenti \param{from} e \param{fromlen} sono utilizzati per ottenere
259 l'indirizzo del mittente del pacchetto che è stato ricevuto, e devono essere
260 opportunamente inizializzati con i puntatori alle variabili dove la struttura
261 contenente quest'ultimo e la relativa lunghezza saranno scritti (si noti che
262 \param{fromlen} è un valore intero ottenuto come \textit{value return
263   argoment}).  Se non si è interessati a questa informazione, entrambi gli
264 argomenti devono essere inizializzati al valore \const{NULL}.
265
266 Un'altra differenza fondamentale di queste funzioni rispetto alle usuali
267 \func{read} e \func{write} che abbiamo usato con i socket TCP è che in questo
268 caso è perfettamente legale inviare con \func{sendto} un pacchetto vuoto (che
269 nel caso conterrà solo le intestazioni di IP e di UDP), scrivendo 0 byte. Allo
270 stesso modo è possibile ricevere con \func{recvfrom} un valore di ritorno di 0
271 byte, senza che questo possa configurarsi come una chiusura della
272 connessione\footnote{dato che la connessione non esiste, non ha senso parlare
273   di chiusura della connessione, questo significa anche che con i socket UDP
274   non è necessario usare \func{close} o \func{shutdown} per terminare la
275   cominicazione.} o come una cessazione delle comunicazioni.
276
277
278
279 \subsection{Un client elementare}
280 \label{sec:UDP_simple_server}
281
282 Vediamo allora come implementare un primo client elementare con dei socket
283 UDP; ricalcando quanto fatto nel caso dei socket TCP prenderemo come primo
284 esempio l'uso del servizio \textit{daytime}, utilizzando questa volta UDP. Il
285 servizio è definito nell'\href{http://www.ietf.org/rfc/rfc0862.txt}{RFC~867},
286 che nel caso di uso di UDP prescrive che il client debba inviare un pacchetto
287 UDP al server (di contenuto non specificato), il quale risponderà a inviando a
288 sua volta un pacchetto UDP contenente la data.
289
290 \begin{figure}[!htb] 
291   \footnotesize \centering
292   \begin{minipage}[c]{15.6cm}
293     \includecodesample{listati/UDP_daytime.c}
294   \end{minipage} 
295   \normalsize
296   \caption{Sezione principale del client per il servizio \textit{daytime} su
297     UDP.}
298   \label{fig:UDP_daytime}
299 \end{figure}
300
301 In \figref{fig:UDP_daytime} è riportato la sezione principale del codice del
302 nostro client, il contenuto completo si trova nel file \file{UDP\_daytime.c}
303 dei sorgenti allegati; al solito si è tralasciata la gestione delle opzioni a
304 riga di comando (nel caso praticamente assenti). 
305
306 Il programma inizia (\texttt{\small 9--12}) con la creazione del socket, al
307 solito uscendo dopo aver stampato un messaggio in caso errore. Si noti come in
308 questo caso, rispetto all'analogo client basato su socket TCP di
309 \figref{fig:TCP_daytime_client_code} si sia usato per il tipo di socket il
310 valore \const{SOCK\_DGRAM}, pur mantenendosi nella stessa famiglia data da
311 \const{AF\_INET}. 
312
313 Il passo successivo (\texttt{\small 13--21}) è l'inizializzazione della
314 struttura degli indirizzi; prima (\texttt{\small 14}) si cancella
315 completamente la stessa con \func{memset}, (\texttt{\small 15}) poi si imposta
316 la famiglia dell'indirizzo ed infine (\texttt{\small 16} la porta. Infine
317 (\texttt{\small 18--21}) si ricava l'indirizzo del server da contattare dal
318 parametro passato a riga di comando, convertendolo con \func{inet\_pton}. Si
319 noti come questa sezione sia identica a quella del client TCP di
320 \figref{fig:TCP_daytime_client_code}, in quanto la determinazione dell'uso di
321 UDP al posto di TCP è stata effettuata quando si è creato il socket.
322
323 Una volta completate le inizializzazioni inizia il corpo principale del
324 programma, il primo passo è inviare, come richiesto dal protocollo, un
325 pacchetto al server. Questo lo si fa (\texttt{\small 16}) inviando un
326 pacchetto vuoto (si ricordi quanto detto in \secref{sec:UDP_sendto_recvfrom})
327 con \func{sendto}, avendo cura di passare un valore nullo per il puntatore al
328 buffer e la lunghezza del messaggio. In realtà il protocollo non richiede che
329 il pacchetto sia vuoto, ma dato che il server comunque ne ignorerà il
330 contenuto, è inutile inviare dei dati.
331
332 Verificato (\texttt{\small 24--27}) che non ci siano stati errori nell'invio
333 si provvede (\texttt{\small 28}) ad invocare \func{recvfrom} per ricevere la
334 risposta del server. Si controlla poi (\texttt{\small 29--32}) che non vi
335 siano stati errori in ricezione (uscendo con un messaggio in caso contrario);
336 se è tutto a posto la variabile \var{nread} conterrà la dimensione del
337 messaggio di risposta inviato dal server memorizzato su \var{buffer}, se
338 (\texttt{\small 34}) pertanto il valore è positivo si provvederà
339 (\texttt{\small 35}) a terminare la stringa contenuta nel buffer di
340 lettura\footnote{si ricordi che, come illustrato in
341   \secref{sec:TCP_daytime_client}, il server invia in risposta una stringa
342   contenente la data, terminata dai due carratteri CR e LF, che pertanto prima
343   di essere stampata deve essere opportunamente terminata con NUL.} e a
344 stamparla (\texttt{\small 36}) sullo standard output, controllando
345 (\texttt{\small 36--38}) anche in questo caso l'esito dell'operazione ed
346 uscendo in caso di errore.
347
348 Se pertanto si è avuto cura di attivare il server del servizio
349 \textit{daytime}\footnote{di norma questo è un servizio standard fornito dal
350   \textsl{superdemone} \cmd{inetd}, per cui basta abilitarlo nel file di
351   configurazione di quest'ultimo, avendo cura di predisporre il servizio su
352   UDP.} potremo verificare il funzionamento del nostro client interrogando
353 quest'ultimo con:
354 \begin{verbatim}
355 [piccardi@gont sources]$ ./daytime 127.0.0.1
356 Sat Mar 20 23:17:13 2004
357 \end{verbatim}%$
358 ed osservando il traffico con uno sniffer potremo effettivamente vedere lo
359 scambio dei due pacchetti, quello vuoto di richiesta, e la risposta del
360 server:
361 \begin{verbatim}
362 [root@gont gapil]# tcpdump -i lo
363 tcpdump: listening on lo
364 23:41:21.645579 localhost.32780 > localhost.daytime: udp 0 (DF)
365 23:41:21.645710 localhost.daytime > localhost.32780: udp 26 (DF)
366 \end{verbatim} 
367
368
369
370 \subsection{L'uso della funzione \func{connect} con i socket UDP}
371 \label{sec:UDP_connect}
372
373 Come illustrato in \secref{sec:UDP_characteristics} essendo i socket UDP privi
374 di connessione non è necessario per i client usare \func{connect} prima di
375 iniziare una comunicazione con un server.
376
377
378
379 \section{I socket \textit{Unix domain}}
380 \label{sec:unix_socket}
381
382 Benché i socket Unix domain non siano strattamente attinenti alla rete, in
383 quanto definiscono una interfaccia di comunicazione locale alla singola
384 macchina, li tratteremo comunque in questa sezione in quanto la loro
385 interfaccia è comunque basata sulla più generale interfaccia dei socket.
386
387
388
389
390
391 %%% Local Variables: 
392 %%% mode: latex
393 %%% TeX-master: "gapil"
394 %%% End: