ALcune correzioni sparse, risistemati i commenti interni delle varie
[gapil.git] / socket.tex
index 331535298fa9dcd4bf5057ffc229de2dac39e481..9d86a3ef0d7732645ef58403581e50f49670c1ed 100644 (file)
@@ -1,6 +1,6 @@
 %% socket.tex
 %%
-%% Copyright (C) 2000-2002 Simone Piccardi.  Permission is granted to
+%% Copyright (C) 2000-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",
@@ -13,8 +13,8 @@
 
 In questo capitolo inizieremo a spiegare le caratteristiche salienti della
 principale interfaccia per la programmazione di rete, quella dei
-\textit{socket}, che, pur essendo nata in ambiente Unix è usata ormai da tutti
-i sistemi operativi.
+\textit{socket}, che, pur essendo nata in ambiente Unix, è usata ormai da
+tutti i sistemi operativi.
 
 Dopo una breve panoramica sulle caratteristiche di questa interfaccia vedremo
 come creare un socket e come collegarlo allo specifico protocollo di rete che
@@ -37,13 +37,13 @@ I \textit{socket}\footnote{una traduzione letterale potrebbe essere
   \textsl{presa}, ma essendo universalmente noti come \textit{socket}
   utilizzeremo sempre la parola inglese.} sono uno dei principali meccanismi
 di comunicazione utilizzato in ambito Unix, e li abbiamo brevemente incontrati
-in \secref{sec:ipc_socketpair}, fra i vari meccanismi di intercominazione fra
-processi. Un socket costituisce in sostanza un canale di comunicazione fra due
-processi su cui si possono leggere e scrivere dati analogo a quello di una
-pipe (vedi \secref{sec:ipc_pipes}) ma, a differenza di questa e degli altri
-meccanismi esaminati nel capitolo \capref{cha:IPC}, i socket non sono limitati
-alla comunicazione fra processi che girano sulla stessa macchina, ma possono
-realizzare la comunicazione anche attraverso la rete.
+in sez.~\ref{sec:ipc_socketpair}, fra i vari meccanismi di intercominazione
+fra processi. Un socket costituisce in sostanza un canale di comunicazione fra
+due processi su cui si possono leggere e scrivere dati analogo a quello di una
+pipe (vedi sez.~\ref{sec:ipc_pipes}) ma, a differenza di questa e degli altri
+meccanismi esaminati nel capitolo cap.~\ref{cha:IPC}, i socket non sono
+limitati alla comunicazione fra processi che girano sulla stessa macchina, ma
+possono realizzare la comunicazione anche attraverso la rete.
 
 Quella dei socket costituisce infatti la principale interfaccia usata nella
 programmazione di rete.  La loro origine risale al 1983, quando furono
@@ -63,7 +63,7 @@ di cui tratteremo in maniera pi
 \label{sec:sock_gen}
 
 Per capire il funzionamento dei socket occorre avere presente il funzionamento
-dei protocolli di rete (vedi \capref{cha:network}), ma l'interfaccia è del
+dei protocolli di rete (vedi cap.~\ref{cha:network}), ma l'interfaccia è del
 tutto generale e benché le problematiche (e quindi le modalità di risolvere i
 problemi) siano diverse a seconda del tipo di protocollo di comunicazione
 usato, le funzioni da usare restano le stesse.
@@ -115,8 +115,8 @@ il tipo di comunicazione che esso deve utilizzare.
 La creazione di un socket avviene attraverso l'uso della funzione
 \funcd{socket}; essa restituisce un \textit{file descriptor}\footnote{del
   tutto analogo a quelli che si ottengono per i file di dati e le pipe,
-  descritti in \secref{sec:file_fd}.} che serve come riferimento al socket; il
-suo prototipo è:
+  descritti in sez.~\ref{sec:file_fd}.} che serve come riferimento al socket;
+il suo prototipo è:
 \begin{prototype}{sys/socket.h}{int socket(int domain, int type, int protocol)}
 
   Apre un socket.
@@ -141,9 +141,9 @@ suo prototipo 
 \end{prototype}
 
 La funzione ha tre argomenti, \param{domain} specifica il dominio del socket
-(definisce cioè, come vedremo in \secref{sec:sock_domain}, la famiglia di
+(definisce cioè, come vedremo in sez.~\ref{sec:sock_domain}, la famiglia di
 protocolli usata), \param{type} specifica il tipo di socket (definisce cioè,
-come vedremo in \secref{sec:sock_type}, lo stile di comunicazione) e
+come vedremo in sez.~\ref{sec:sock_type}, lo stile di comunicazione) e
 \param{protocol} il protocollo; in genere quest'ultimo è indicato
 implicitamente dal tipo di socket, per cui di norma questo valore viene messo
 a zero (con l'eccezione dei \textit{raw socket}).
@@ -228,9 +228,9 @@ valori numerici.\footnote{in Linux, come si pu
   lo stesso nome.}
 
 I domini (e i relativi nomi simbolici), così come i nomi delle famiglie di
-indirizzi, sono definiti dall'header \textit{socket.h}. Un elenco delle
+indirizzi, sono definiti dall'header \texttt{socket.h}. Un elenco delle
 famiglie di protocolli disponibili in Linux è riportato in
-\tabref{tab:net_pf_names}.\footnote{l'elenco indica tutti i protocolli
+tab.~\ref{tab:net_pf_names}.\footnote{l'elenco indica tutti i protocolli
   definiti; fra questi però saranno utilizzabili solo quelli per i quali si è
   compilato il supporto nel kernel (o si sono caricati gli opportuni moduli),
   viene definita anche una costante \const{PF\_MAX} che indica il valore
@@ -261,9 +261,9 @@ seguenti costanti:
   altro socket. I dati vengono ricevuti e trasmessi come un flusso continuo di
   byte (da cui il nome \textit{stream}).
 \item[\const{SOCK\_DGRAM}] Viene usato per trasmettere pacchetti di dati
-  (\textit{datagram}) di lunghezza massima fissata indirizzati singolarmente,
-  Non esiste una connessione e la trasmissione è effettuata in maniera non
-  affidabile.
+  (\textit{datagram}) di lunghezza massima prefissata, indirizzati
+  singolarmente. Non esiste una connessione e la trasmissione è effettuata in
+  maniera non affidabile.
 \item[\const{SOCK\_SEQPACKET}] Provvede un canale di trasmissione di dati
   bidirezionale, sequenziale e affidabile. Opera su una connessione con un
   altro socket. I dati possono vengono trasmessi per pacchetti di dimensione
@@ -320,7 +320,7 @@ elencati.
   \label{tab:sock_sock_valid_combinations}
 \end{table}
 
-In \secref{tab:sock_sock_valid_combinations} sono mostrate le combinazioni
+In tab.~\ref{tab:sock_sock_valid_combinations} sono mostrate le combinazioni
 valide possibili per le principali famiglie di protocolli. Per ogni
 combinazione valida si è indicato il tipo di protocollo, o la parola
 \textsl{si} qualora non il protocollo non abbia un nome definito, mentre si
@@ -356,7 +356,7 @@ questi puntatori, il C moderno risolve questo problema coi i puntatori
 generici (i \ctyp{void *}), ma l'interfaccia dei socket è antecedente alla
 definizione dello standard ANSI C, e per questo nel 1982 fu scelto di definire
 una struttura generica per gli indirizzi dei socket, \struct{sockaddr}, che si
-è riportata in \figref{fig:sock_sa_gen_struct}.
+è riportata in fig.~\ref{fig:sock_sa_gen_struct}.
 
 \begin{figure}[!htb]
   \footnotesize \centering
@@ -374,7 +374,7 @@ invocano dette funzioni passando l'indirizzo di un protocollo specifico
 occorrerà eseguire una conversione del relativo puntatore.
 
 I tipi di dati che compongono la struttura sono stabiliti dallo standard
-POSIX.1g e li abbiamo riassunti in \tabref{tab:sock_data_types} con i
+POSIX.1g e li abbiamo riassunti in tab.~\ref{tab:sock_data_types} con i
 rispettivi file di include in cui sono definiti; la struttura è invece
 definita nell'include file \file{sys/socket.h}.
 
@@ -432,7 +432,7 @@ I socket di tipo \const{PF\_INET} vengono usati per la comunicazione
 attraverso internet; la struttura per gli indirizzi per un socket internet (se
 si usa IPv4) è definita come \struct{sockaddr\_in} nell'header file
 \file{netinet/in.h} ed ha la forma mostrata in
-\figref{fig:sock_sa_ipv4_struct}, conforme allo standard POSIX.1g.
+fig.~\ref{fig:sock_sa_ipv4_struct}, conforme allo standard POSIX.1g.
 
 \begin{figure}[!htb]
   \footnotesize\centering
@@ -446,7 +446,7 @@ si usa IPv4) 
 
 L'indirizzo di un socket internet (secondo IPv4) comprende l'indirizzo
 internet di un'interfaccia più un \textsl{numero di porta} (affronteremo in
-dettaglio il significato di questi numeri in \secref{sec:TCP_port_num}).  Il
+dettaglio il significato di questi numeri in sez.~\ref{sec:TCP_port_num}).  Il
 protocollo IP non prevede numeri di porta, che sono utilizzati solo dai
 protocolli di livello superiore come TCP e UDP. Questa struttura però viene
 usata anche per i socket RAW che accedono direttamente al livello di IP, nel
@@ -458,7 +458,7 @@ specifica il \textsl{numero di porta}. I numeri di porta sotto il 1024 sono
 chiamati \textsl{riservati} in quanto utilizzati da servizi standard e
 soltanto processi con i privilegi di amministratore (con user-ID effettivo
 uguale a zero) o con la capability \texttt{CAP\_NET\_BIND\_SERVICE} possono
-usare la funzione \func{bind} (che vedremo in \secref{sec:TCP_func_bind}) su
+usare la funzione \func{bind} (che vedremo in sez.~\ref{sec:TCP_func_bind}) su
 queste porte.
 
 Il membro \var{sin\_addr} contiene un indirizzo internet, e viene acceduto sia
@@ -466,13 +466,13 @@ come struttura (un resto di una implementazione precedente in cui questa era
 una \direct{union} usata per accedere alle diverse classi di indirizzi) che
 direttamente come intero. In \file{netinet/in.h} vengono definite anche alcune
 costanti che identificano alcuni indirizzi speciali, riportati in
-\tabref{tab:TCP_ipv4_addr}.
+tab.~\ref{tab:TCP_ipv4_addr}, che reincontreremo più avanti.
 
 Infine occorre sottolineare che sia gli indirizzi che i numeri di porta devono
 essere specificati in quello che viene chiamato \textit{network order}, cioè
 con i bit ordinati in formato \textit{big endian}, questo comporta la
 necessità di usare apposite funzioni di conversione per mantenere la
-portabilità del codice (vedi \secref{sec:sock_addr_func} per i dettagli del
+portabilità del codice (vedi sez.~\ref{sec:sock_addr_func} per i dettagli del
 problema e le relative soluzioni).
 
 
@@ -483,7 +483,7 @@ Essendo IPv6 un'estensione di IPv4, i socket di tipo \const{PF\_INET6} sono
 sostanzialmente identici ai precedenti; la parte in cui si trovano
 praticamente tutte le differenze fra i due socket è quella della struttura
 degli indirizzi; la sua definizione, presa da \file{netinet/in.h}, è riportata
-in \figref{fig:sock_sa_ipv6_struct}.
+in fig.~\ref{fig:sock_sa_ipv6_struct}.
 
 \begin{figure}[!htb]
   \footnotesize \centering
@@ -500,17 +500,17 @@ il campo \var{sin6\_port} 
 il campo \var{sin6\_flowinfo} è a sua volta diviso in tre parti di cui i 24
 bit inferiori indicano l'etichetta di flusso, i successivi 4 bit la priorità e
 gli ultimi 4 sono riservati. Questi valori fanno riferimento ad alcuni campi
-specifici dell'header dei pacchetti IPv6 (vedi \secref{sec:IP_ipv6head}) ed il
-loro uso è sperimentale.
+specifici dell'header dei pacchetti IPv6 (vedi sez.~\ref{sec:IP_ipv6head}) ed
+il loro uso è sperimentale.
 
-Il campo \var{sin6\_addr} contiene l'indirizzo a 128 bit usato da IPv6, infine
-il campo \var{sin6\_scope\_id} è un campo introdotto in Linux con il kernel
-2.4, per gestire alcune operazioni riguardanti il multicasting.
-Si noti che questa struttura ha una dimensione maggiore della struttura
-\struct{sockaddr} generica vista in \figref{fig:sock_sa_gen_struct}, quindi
-occorre stare attenti a non avere fatto assunzioni riguardo alla possibilità
-di contenere i dati nelle dimensioni di quest'ultima.
+Il campo \var{sin6\_addr} contiene l'indirizzo a 128 bit usato da IPv6,
+espresso da un vettore di 16 byte. Infine il campo \var{sin6\_scope\_id} è un
+campo introdotto in Linux con il kernel 2.4, per gestire alcune operazioni
+riguardanti il multicasting.  Si noti infine che \struct{sockaddr\_in6} ha una
+dimensione maggiore della struttura \struct{sockaddr} generica di
+fig.~\ref{fig:sock_sa_gen_struct}, quindi occorre stare attenti a non avere
+fatto assunzioni riguardo alla possibilità di contenere i dati nelle
+dimensioni di quest'ultima.
 
 
 \subsection{La struttura degli indirizzi locali}
@@ -521,10 +521,10 @@ comunicazione fra processi che stanno sulla stessa macchina (per questo
 vengono chiamati \textit{local domain} o anche \textit{Unix domain}); essi
 hanno la caratteristica ulteriore di poter essere creati anche in maniera
 anonima attraverso la funzione \func{socketpair} (che abbiamo trattato in
-\secref{sec:ipc_socketpair}).  Quando però si vuole fare riferimento esplicito
-ad uno di questi socket si deve usare una struttura degli indirizzi di tipo
-\struct{sockaddr\_un}, la cui definizione si è riportata in
-\secref{fig:sock_sa_local_struct}.
+sez.~\ref{sec:ipc_socketpair}).  Quando però si vuole fare riferimento
+esplicito ad uno di questi socket si deve usare una struttura degli indirizzi
+di tipo \struct{sockaddr\_un}, la cui definizione si è riportata in
+fig.~\ref{fig:sock_sa_local_struct}.
 
 \begin{figure}[!htb]
   \footnotesize \centering
@@ -565,8 +565,8 @@ per \param{protocol} 
 
 Gli indirizzi AppleTalk devono essere specificati tramite una struttura
 \struct{sockaddr\_atalk}, la cui definizione è riportata in
-\figref{fig:sock_sa_atalk_struct}; la struttura viene dichiarata includendo il
-file \file{netatalk/at.h}.
+fig.~\ref{fig:sock_sa_atalk_struct}; la struttura viene dichiarata includendo
+il file \file{netatalk/at.h}.
 
 \begin{figure}[!htb]
   \footnotesize \centering
@@ -584,7 +584,7 @@ inferiori a 129 sono usati per le \textsl{porte riservate}, e possono essere
 usati solo da processi con i privilegi di amministratore o con la capability
 \const{CAP\_NET\_BIND\_SERVICE}. L'indirizzo remoto è specificato nella
 struttura \var{sat\_addr}, e deve essere in \textit{network order} (vedi
-\secref{sec:sock_endianess}); esso è composto da un parte di rete data dal
+sez.~\ref{sec:sock_endianess}); esso è composto da un parte di rete data dal
 campo \var{s\_net}, che può assumere il valore \const{AT\_ANYNET}, che indica
 una rete generica e vale anche per indicare la rete su cui si è, il singolo
 nodo è indicato da \var{s\_node}, e può prendere il valore generico
@@ -651,7 +651,7 @@ occorre usare la funzione \func{bind} per agganciare il socket a quest'ultima.
 
 Nel caso dei \textit{packet socket} la struttura degli indirizzi è di tipo
 \struct{sockaddr\_ll}, e la sua definizione è riportata in
-\figref{fig:sock_sa_packet_struct}; essa però viene ad assumere un ruolo
+fig.~\ref{fig:sock_sa_packet_struct}; essa però viene ad assumere un ruolo
 leggermente diverso rispetto a quanto visto finora per gli altri tipi di
 socket.  Infatti se il socket è di tipo \const{SOCK\_RAW} si deve comunque
 scrivere tutto direttamente nel pacchetto, quindi la struttura non serve più a
@@ -750,7 +750,7 @@ realt
 
 Per capire meglio il problema si consideri un intero a 32 bit scritto in una
 locazione di memoria posta ad un certo indirizzo. Come illustrato in
-\figref{fig:sock_endianess} i singoli bit possono essere disposti un memoria
+fig.~\ref{fig:sock_endianess} i singoli bit possono essere disposti un memoria
 in due modi: a partire dal più significativo o a partire dal meno
 significativo.  Così nel primo caso si troverà il byte che contiene i bit più
 significativi all'indirizzo menzionato e il byte con i bit meno significativi
@@ -767,12 +767,37 @@ parte dal bit meno significativo 
   \label{fig:sock_endianess}
 \end{figure}
 
+Si può allora verificare quale tipo di endianess usa il proprio computer con
+un programma elementare che si limita ad assegnare un valore ad una variabile
+per poi ristamparne il contenuto leggendolo un byte alla volta. Il codice di
+detto programma, \file{endtest.c}, è nei sorgenti allegati, allora se lo
+eseguiamo su un PC otterremo:
+\begin{verbatim}
+[piccardi@gont sources]$ ./endtest
+Using value ABCDEF01
+val[0]= 1
+val[1]=EF
+val[2]=CD
+val[3]=AB
+\end{verbatim}%$
+mentre su di un Mac avremo:
+\begin{verbatim}
+piccardi@anarres:~/gapil/sources$ ./endtest
+Using value ABCDEF01
+val[0]=AB
+val[1]=CD
+val[2]=EF
+val[3]= 1
+\end{verbatim}%$
+
+
 La \textit{endianess}\index{endianess} di un computer dipende essenzialmente
 dalla architettura hardware usata; Intel e Digital usano il \textit{little
   endian}, Motorola, IBM, Sun (sostanzialmente tutti gli altri) usano il
-\textit{big endian}. Il formato della rete è anch'esso \textit{big endian},
-altri esempi di uso di questi formati sono quello del bus PCI, che è
-\textit{little endian}, o quello del bus VME che è \textit{big endian}.
+\textit{big endian}. Il formato dei dati contenuti nelle intestazioni dei
+protocolli di rete è anch'esso \textit{big endian}; altri esempi di uso di
+questi due diversi formati sono quello del bus PCI, che è \textit{little
+  endian}, o quello del bus VME che è \textit{big endian}.
 
 Esistono poi anche dei processori che possono scegliere il tipo di formato
 all'avvio e alcuni che, come il PowerPC o l'Intel i860, possono pure passare
@@ -781,6 +806,36 @@ in Linux l'ordinamento 
 resta sempre lo stesso, anche quando il processore permetterebbe di eseguire
 questi cambiamenti.
 
+Per controllare quale tipo di ordinamento si ha sul proprio computer si è
+scritta una piccola funzione di controllo, il cui codice è riportato
+fig.~\ref{fig:sock_endian_code}, che restituisce un valore nullo (falso) se
+l'architettura è \textit{big endian} ed uno non nullo (vero) se l'architettura
+è \textit{little endian}.
+
+\begin{figure}[htb]
+  \footnotesize \centering
+  \begin{minipage}[c]{15cm}
+    \includecodesample{listati/endian.c}
+  \end{minipage} 
+  \normalsize
+  \caption{La funzione \func{endian}, usata per controllare il tipo di
+    architettura della macchina.}
+  \label{fig:sock_endian_code}
+\end{figure}
+
+Come si vede la funzione è molto semplice, e si limita, una volta assegnato
+(\texttt{\small 9}) un valore di test pari a \texttt{0xABCD} ad una variabile
+di tipo \ctyp{short} (cioè a 16 bit), a ricostruirne una copia byte a byte.
+Per questo prima (\texttt{\small 10}) si definisce il puntatore \var{ptr} per
+accedere al contenuto della prima variabile, ed infine calcola (\texttt{\small
+  11}) il valore della seconda assumendo che il primo byte sia quello meno
+significativo (cioè, per quanto visto in fig.~\ref{fig:sock_endianess}, che sia
+\textit{little endian}). Infine la funzione restituisce (\texttt{\small 12})
+il valore del confonto delle due variabili. 
+
+
+
+
 \subsection{Le funzioni per il riordinamento}
 \label{sec:sock_func_ord}
 
@@ -869,7 +924,7 @@ di \func{inet\_aton}.
 
 La funzione \func{inet\_aton} converte la stringa puntata da \param{src}
 nell'indirizzo binario che viene memorizzato nell'opportuna struttura
-\struct{in\_addr} (si veda \secref{fig:sock_sa_ipv4_struct}) situata
+\struct{in\_addr} (si veda fig.~\ref{fig:sock_sa_ipv4_struct}) situata
 all'indirizzo dato dall'argomento \param{dest} (è espressa in questa forma in
 modo da poterla usare direttamente con il puntatore usato per passare la
 struttura degli indirizzi). La funzione restituisce 0 in caso di successo e 1
@@ -956,7 +1011,7 @@ pu
 
 Il formato usato per gli indirizzi in formato di presentazione è la notazione
 \textit{dotted decimal} per IPv4 e quello descritto in
-\secref{sec:IP_ipv6_notation} per IPv6.
+sez.~\ref{sec:IP_ipv6_notation} per IPv6.
 
 \index{socket|)}