Nuove figure e revisione completa dei primi due capitoli sulle reti.
[gapil.git] / socket.tex
index 2dc56748093a9512a8094634c3f235faca61585c..37bc64204ebca686d04ef98cd0be2a6b990ac4a2 100644 (file)
@@ -34,10 +34,10 @@ con essi.
 \label{sec:sock_socket_def}
 
 I \textit{socket}\footnote{una traduzione letterale potrebbe essere
-  \textsl{presa}, ma essendo universalmente noti come 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
+  \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
@@ -55,7 +55,7 @@ di quella dei socket (n
 
 La flessibilità e la genericità dell'interfaccia inoltre consente di
 utilizzare i socket con i più disparati meccanismi di comunicazione, e non
-solo con la suite dei protocolli TCP/IP, anche se questa sarà comunque quella
+solo con l'insieme dei protocolli TCP/IP, anche se questa sarà comunque quella
 di cui tratteremo in maniera più estesa.
 
 
@@ -78,8 +78,10 @@ funzioni utilizzate.
 
 La scelta di uno stile dipende sia dai meccanismi disponibili, sia dal tipo di
 comunicazione che si vuole effettuare. Ad esempio alcuni stili di
-comunicazione considerano i dati come una sequenza continua di byte, altri
-invece li raggruppano in blocchi (i pacchetti).
+comunicazione considerano i dati come una sequenza continua di byte, in quello
+che viene chiamato un \textsl{flusso} (in inglese \textit{stream}), mentre
+altri invece li raggruppano in \textsl{pacchetti} (in inglese
+\textit{datagram}) che vengono inviati in blocchi separati.
 
 Un'altro esempio di stile concerne la possibilità che la comunicazione possa o
 meno perdere dati, possa o meno non rispettare l'ordine in cui essi non sono
@@ -95,7 +97,8 @@ chiunque si collega possa riceverli.
 
 É chiaro che ciascuno di questi stili comporta una modalità diversa di gestire
 la comunicazione, ad esempio se è inaffidabile occorrerà essere in grado di
-gestire la perdita o il rimescolamento dei dati.
+gestire la perdita o il rimescolamento dei dati, se è a pacchetti questi
+dovranno essere opportunamente trattati, ecc.
 
 
 \section{La creazione di un \textit{socket}}
@@ -110,7 +113,7 @@ il tipo di comunicazione che esso deve utilizzare.
 \label{sec:sock_socket}
 
 La creazione di un socket avviene attraverso l'uso della funzione
-\funcd{socket}; questa restituisce un \textit{file descriptor}\footnote{del
+\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 è:
@@ -132,16 +135,18 @@ suo prototipo 
   \item[\errcode{EINVAL}] Protocollo sconosciuto o dominio non disponibile.
   \item[\errcode{ENOBUFS}] Non c'è sufficiente memoria per creare il socket
     (può essere anche \errval{ENOMEM}).
-  \end{errlist}}
+  \end{errlist}
+  inoltre, a seconda del protocollo usato, potranno essere generati altri
+  errori, che sono riportati nelle relative pagine di manuale.}
 \end{prototype}
 
 La funzione ha tre argomenti, \param{domain} specifica il dominio del socket
-(definisce cioè la famiglia di protocolli, come vedremo in
-\secref{sec:sock_domain}), \param{type} specifica il tipo di socket (definisce
-cioè lo stile di comunicazione, come vedremo in \secref{sec:sock_type}) e
+(definisce cioè, come vedremo in \secref{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
 \param{protocol} il protocollo; in genere quest'ultimo è indicato
-implicitamente dal tipo di socket, per cui viene messo a zero (con l'eccezione
-dei \textit{raw socket}).
+implicitamente dal tipo di socket, per cui di norma questo valore viene messo
+a zero (con l'eccezione dei \textit{raw socket}).
 
 Si noti che la creazione del socket si limita ad allocare le opportune
 strutture nel kernel (sostanzialmente una voce nella \textit{file table}) e
@@ -218,7 +223,7 @@ quanto specificato anche dallo standard POSIX.1g, ma non esistono a tuttora
 famiglie di protocolli che supportino diverse strutture di indirizzi, per cui
 nella pratica questi due nomi sono equivalenti e corrispondono agli stessi
 valori numerici.\footnote{in Linux, come si può verificare andando a guardare
-  il contenuto di \file{bits/socket.h} le costanti sono esattamente le stesse
+  il contenuto di \file{bits/socket.h}, le costanti sono esattamente le stesse
   e ciascuna \texttt{AF\_} è definita alla corrispondente \texttt{PF\_} e con
   lo stesso nome.}
 
@@ -229,7 +234,7 @@ famiglie di protocolli disponibili in Linux 
   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
-  massimo associabile ad un dominio (nel caso 32).}
+  massimo associabile ad un dominio (nel caso il suo valore 32).}
 
 Si tenga presente che non tutte le famiglie di protocolli sono utilizzabili
 dall'utente generico, ad esempio in generale tutti i socket di tipo
@@ -255,18 +260,20 @@ seguenti costanti:
   bidirezionale, sequenziale e affidabile. Opera su una connessione con un
   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 mandare pacchetti di lunghezza
-  massima fissata (\textit{datagram}) indirizzati singolarmente, senza
-  connessione e in maniera non affidabile. È l'opposto del precedente. 
+\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.
 \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 solo essere trasmessi e letti per pacchetti (di
-  dimensione massima fissata).
+  altro socket. I dati possono vengono trasmessi per pacchetti di dimensione
+  massima fissata, ed devono essere letti integralmente da ciascuna
+  chiamata a \func{read}.
 \item[\const{SOCK\_RAW}] Provvede l'accesso a basso livello ai protocolli di
   rete e alle varie interfacce. I normali programmi di comunicazione non
-  devono usarlo.
-\item[\const{SOCK\_RDM}] Provvede un canale di trasmissione di pacchetti
-  affidabile ma in cui non è garantito l'ordine di arrivo dei pacchetti.
+  devono usarlo, è riservato all'uso di sistema.
+\item[\const{SOCK\_RDM}] Provvede un canale di trasmissione di dati
+  affidabile, ma in cui non è garantito l'ordine di arrivo dei pacchetti.
 \item[\const{SOCK\_PACKET}] Obsoleto, non deve essere usato.
 \end{basedescript}
 
@@ -333,8 +340,8 @@ Gli indirizzi infatti vengono specificati attraverso apposite strutture che
 vengono utilizzate dalle altre funzioni della interfaccia dei socket, quando
 la comunicazione viene effettivamente realizzata.  Ogni famiglia di protocolli
 ha ovviamente una sua forma di indirizzamento e in corrispondenza a questa una
-sua peculiare struttura degli indirizzi; i nomi di tutte queste strutture
-iniziano per \var{sockaddr\_}, quelli propri di ciascuna famiglia vengono
+sua peculiare struttura degli indirizzi. I nomi di tutte queste strutture
+iniziano per \var{sockaddr\_}; quelli propri di ciascuna famiglia vengono
 identificati dal suffisso finale, aggiunto al nome precedente.
 
 
@@ -369,8 +376,7 @@ struct sockaddr {
 Tutte le funzioni dei socket che usano gli indirizzi sono definite usando nel
 prototipo un puntatore a questa struttura; per questo motivo quando si
 invocano dette funzioni passando l'indirizzo di un protocollo specifico
-occorrerà eseguire una coversione (il \textit{casting}) del relativo
-puntatore.
+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
@@ -418,10 +424,10 @@ campo \type{sa\_family\_t} era storicamente un \ctyp{unsigned short}.
 Dal punto di vista del programmatore l'unico uso di questa struttura è quello
 di fare da riferimento per il casting, per il kernel le cose sono un po'
 diverse, in quanto esso usa il puntatore per recuperare il campo
-\var{sa\_family} con cui determinare il tipo di indirizzo; per questo
-motivo, anche se l'uso di un puntatore \ctyp{void *} sarebbe più immediato
-per l'utente (che non dovrebbe più eseguire il casting), è stato mantenuto
-l'uso di questa struttura.
+\var{sa\_family}, comune a tutte le famiglie, con cui determinare il tipo di
+indirizzo; per questo motivo, anche se l'uso di un puntatore \ctyp{void *}
+sarebbe più immediato per l'utente (che non dovrebbe più eseguire il casting),
+è stato mantenuto l'uso di questa struttura.
 
 
 \subsection{La struttura degli indirizzi IPv4}
@@ -454,18 +460,18 @@ struct in_addr {
 \end{figure}
 
 L'indirizzo di un socket internet (secondo IPv4) comprende l'indirizzo
-internet di un'interfaccia più un numero di porta. 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 qual caso il numero della
-porta viene impostato al numero di protocollo.
+internet di un'interfaccia più un \textsl{numero di porta} (affronteremo in
+dettaglio il significato di questi numeri in \secref{sec:TCPel_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
+qual caso il numero della porta viene impostato al numero di protocollo.
 
 Il membro \var{sin\_family} deve essere sempre impostato a \const{AF\_INET},
 altrimenti si avrà un errore di \errcode{EINVAL}; il membro \var{sin\_port}
-specifica il \textsl{numero di porta} (affronteremo in dettaglio in le
-\textsl{porte} in \secref{sec:TCPel_port_num}). 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
+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:TCPel_func_bind}) su
 queste porte.
@@ -505,7 +511,6 @@ struct sockaddr_in6 {
     struct in6_addr sin6_addr;     /* IPv6 address */
     uint32_t        sin6_scope_id; /* Scope id (new in 2.4) */
 };
-
 struct in6_addr {
     uint8_t       s6_addr[16];   /* IPv6 address */
 };
@@ -528,23 +533,24 @@ 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 è più grande della \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.
+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.
 
 
 \subsection{La struttura degli indirizzi locali}
 \label{sec:sock_sa_local}
 
 I socket di tipo \const{PF\_UNIX} o \const{PF\_LOCAL} vengono usati per una
-comunicazione fra processi che stanno sulla stessa macchina (per vengono
-chiamati \textit{local domain} o anche \textit{Unix domain}); essi rispetto ai
-precedenti possono essere anche creati in maniera anonima attraverso la
-funzione \func{socketpair} (vedi \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}.
+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}.
 
 \begin{figure}[!htb]
   \footnotesize \centering
@@ -563,12 +569,12 @@ struct sockaddr_un {
 \end{figure}
 
 In questo caso il campo \var{sun\_family} deve essere \const{AF\_UNIX}, mentre
-il campo \var{sun\_path} deve specificare un indirizzo. Questo ha due forme:
-un file (di tipo socket) nel filesystem o una stringa univoca (mantenuta in
-uno spazio di nomi astratto). Nel primo caso l'indirizzo viene specificato
-come una stringa (terminata da uno zero) corrispondente al pathname del file;
-nel secondo invece \var{sun\_path} inizia con uno zero e vengono usati i
-restanti byte come stringa, senza terminazione.
+il campo \var{sun\_path} deve specificare un indirizzo. Questo ha due forme;
+può essere un file (di tipo socket) nel filesystem o una stringa univoca
+(mantenuta in uno spazio di nomi astratto). Nel primo caso l'indirizzo viene
+specificato come una stringa (terminata da uno zero) corrispondente al
+pathname del file; nel secondo invece \var{sun\_path} inizia con uno zero e
+vengono usati come nome i restanti byte come stringa, senza terminazione.
 
 
 \subsection{La struttura degli indirizzi AppleTalk}
@@ -603,7 +609,6 @@ struct sockaddr_atalk {
     uint8_t         sat_port;   /* port */
     struct at_addr  sat_addr;   /* net/node */
 };
-
 struct at_addr {
     uint16_t        s_net;
     uint8_t         s_node;
@@ -620,13 +625,130 @@ campo \var{sat\_port} specifica la porta che identifica i vari servizi. Valori
 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}; 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 genrica e vale anche per
-indicare la rete su cui si è, il singolo nodo è indicato da \var{s\_node}, e
-può prendere il valore generico \const{AT\_ANYNODE} che indica anche il nodo
-corrente, ed il valore \const{ATADDR\_BCAST} che indica tutti i nodi della
-rete.
+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
+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
+\const{AT\_ANYNODE} che indica anche il nodo corrente, ed il valore
+\const{ATADDR\_BCAST} che indica tutti i nodi della rete.
+
+
+\subsection{La struttura degli indirizzi dei \textit{packet socket}}
+\label{sec:sock_sa_packet}
+
+I \textit{packet socket}, identificati dal dominio \const{PF\_PACKET}, sono
+un'interfaccia specifica di Linux per inviare e ricevere pacchetti
+direttamente su un'interfaccia di rete, senza passare per le routine di
+gestione dei protocolli di livello superiore. In questo modo è possibile
+implementare dei protocolli in user space, agendo direttamente sul livello
+fisico. In genere comunque si preferisce usare la libreria \file{pcap}, che
+assicura la portabilità su altre piattaforme, anche se con funzionalità
+ridotte.
+
+Questi socket possono essere di tipo \const{SOCK\_RAW} o \const{SOCK\_DGRAM}.
+Con socket di tipo \const{SOCK\_RAW} si può operare sul livello di
+collegamento, ed i pacchetti vengono passati direttamente dal socket al driver
+del dispositivo e viceversa.  In questo modo, in fase di trasmissione, il
+contenuto completo dei pacchetti, comprese le varie intestazioni, deve essere
+fornito dall'utente. In fase di ricezione invece tutto il contenuto del
+pacchetto viene passato inalterato sul socket, anche se il kernel analizza
+comunque il pacchetto, riempiendo gli opportuni campi della struttura
+\struct{sockaddr\_ll} ad esso associata.
+
+Si usano invece socket di tipo \const{SOCK\_DGRAM} quando si vuole operare a
+livello di rete. In questo caso in fase di ricezione l'intestazione del
+protocollo di collegamento viene rimossa prima di passare il resto del
+pacchetto all'utente, mentre in fase di trasmissione viene creata una
+opportuna intestazione per il protocollo a livello di collegamento
+utilizzato, usando le informazioni necessarie che devono essere specificate
+sempre con una struttura \struct{sockaddr\_ll}.
+
+Nella creazione di un \textit{packet socket} il valore dell'argomento
+\param{protocol} di \func{socket} serve a specificare, in \textit{network
+  order}, il numero identificativo del protocollo di collegamento si vuole
+utilizzare. I valori possibili sono definiti secondo lo standard IEEE 802.3, e
+quelli disponibili in Linux sono accessibili attraverso opportune costanti
+simboliche definite nel file \file{linux/if\_ether.h}. Se si usa il valore
+speciale \const{ETH\_P\_ALL} passeranno sul \textit{packet socket} tutti i
+pacchetti, qualunque sia il loro protocollo di collegamento. Ovviamente l'uso
+di questi socket è una operazione privilegiata e può essere effettuati solo da
+un processo con i privilegi di amministratore (user-ID effettivo nullo) o con
+la capability \const{CAP\_NET\_RAW}.
+
+Una volta aperto un \textit{packet socket}, tutti i pacchetti del protocollo
+specificato passeranno attraverso di esso, qualunque sia l'interfaccia da cui
+provengono; se si vuole limitare il passaggio ad una interfaccia specifica
+occorre usare la funzione \func{bind} per agganciare il socket a quest'ultima.
+
+\begin{figure}[!htb]
+  \footnotesize \centering
+  \begin{minipage}[c]{15cm}
+    \begin{lstlisting}[labelstep=0]{}%,frame=,indent=1cm]{}
+struct sockaddr_ll {
+    unsigned short  sll_family;    /* Always AF_PACKET */
+    unsigned short  sll_protocol;  /* Physical layer protocol */
+    int             sll_ifindex;   /* Interface number */
+    unsigned short  sll_hatype;    /* Header type */
+    unsigned char   sll_pkttype;   /* Packet type */
+    unsigned char   sll_halen;     /* Length of address */
+    unsigned char   sll_addr[8];   /* Physical layer address */
+};
+    \end{lstlisting}
+  \end{minipage} 
+  \caption{La struttura \structd{sockaddr\_ll} degli indirizzi dei
+    \textit{packet socket}.}
+  \label{fig:sock_sa_packet_struct}
+\end{figure}
+
+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
+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
+specificare gli indirizzi. Essa mantiene questo ruolo solo per i socket di
+tipo \const{SOCK\_DGRAM}, per i quali permette di specificare i dati necessari
+al protocollo di collegamento, mentre viene sempre utilizzata in lettura (per
+entrambi i tipi di socket), per la ricezione dei i dati relativi a ciascun
+pacchetto.
+
+Al solito il campo \var{sll\_family} deve essere sempre impostato al valore
+\const{AF\_PACKET}. Il campo \var{sll\_protocol} indica il protocollo scelto,
+e deve essere indicato in \textit{network order}, facendo uso delle costanti
+simboliche definite in \file{linux/if\_ether.h}. Il campo \var{sll\_ifindex} è
+l'indice dell'interfaccia, che, in caso di presenza di più interfacce dello
+stesso tipo (se ad esempio si hanno più schede ethernet), permette di
+selezionare quella con cui si vuole operare (un valore nullo indica qualunque
+interfaccia).  Questi sono i due soli campi che devono essere specificati
+quando si vuole selezionare una interfaccia specifica, usando questa struttura
+con la funzione \func{bind}.
+
+I campi \var{sll\_halen} e \var{sll\_addr} indicano rispettivamente
+l'indirizzo associato all'interfaccia sul protocollo di collegamento e la
+relativa lunghezza; ovviamente questi valori cambiano a seconda del tipo di
+collegamento che si usa, ad esempio, nel caso di ethernet, questi saranno il
+MAC address della scheda e la relativa lunghezza. Essi vengono usati, insieme
+ai campi \var{sll\_family} e \var{sll\_ifindex} quando si inviano dei
+pacchetti, in questo caso tutti gli altri campi devono essere nulli.
+
+Il campo \var{sll\_hatype} indica il tipo ARP, come definito in
+\file{linux/if\_arp.h}, mentre il campo \var{sll\_pkttype} indica il tipo di
+pacchetto; entrambi vengono impostati alla ricezione di un pacchetto ed han
+senso solo in questo caso. In particolare \var{sll\_pkttype} può assumere i
+seguenti valori: \var{PACKET\_HOST} per un pacchetto indirizzato alla macchina
+ricevente, \var{PACKET\_BROADCAST} per un pacchetto di broadcast,
+\var{PACKET\_MULTICAST} per un pacchetto inviato ad un indirizzo fisico di
+multicast, \var{PACKET\_OTHERHOST} per un pacchetto inviato ad un'altra
+stazione (e ricevuto su un'interfaccia in modo promiscuo),
+\var{PACKET\_OUTGOING} per un pacchetto originato dalla propria macchina che
+torna indietro sul socket.
+
+Si tenga presente infine che in fase di ricezione, anche se si richiede il
+troncamento del pacchetto, le funzioni \func{recvmsg}, \func{recv} e
+\func{recvfrom} restituiranno comunque la lunghezza effettiva del pacchetto
+così come arrivato sulla linea.
+
 
 %% \subsection{La struttura degli indirizzi DECnet}
 %% \label{sec:sock_sa_decnet}
@@ -736,8 +858,8 @@ rispettivi prototipi sono:
   Converte l'intero a 16 bit \param{netshort} dal formato della rete a quello
   della macchina.
   
-  \bodydesc{Tutte le funzioni restituiscono il valore convertito, e non hanno
-    errori.}
+  \bodydesc{Tutte le funzioni restituiscono il valore convertito, e non
+    prevedono errori.}
 \end{functions}
 
 I nomi sono assegnati usando la lettera \texttt{n} come mnemonico per indicare
@@ -829,9 +951,9 @@ e \textit{numeric}.
 % \end{figure}
 
 Entrambe le funzioni accettano l'argomento \param{af} che indica il tipo di
-indirizzo e può essere soltanto \const{AF\_INET} o \const{AF\_INET6}. La prima
-funzione è \funcd{inet\_pton}, che serve a convertire una stringa in un
-indirizzo, il suo prototipo è:
+indirizzo, e che può essere soltanto \const{AF\_INET} o \const{AF\_INET6}. La
+prima funzione, \funcd{inet\_pton}, serve a convertire una stringa in un
+indirizzo; il suo prototipo è:
 \begin{prototype}{sys/socket.h}
 {int inet\_pton(int af, const char *src, void *addr\_ptr)} 
 
@@ -845,13 +967,13 @@ indirizzo, il suo prototipo 
 
 La funzione converte la stringa indicata tramite \param{src} nel valore
 numerico dell'indirizzo IP del tipo specificato da \param{af} che viene
-memorizzato all'indirizzo puntato da \param{addr\_ptr}, la funzione restituisce
-un valore positivo in caso di successo, e zero se la stringa non rappresenta
-un indirizzo valido, e negativo se \param{af} specifica una famiglia di
-indirizzi non valida.
+memorizzato all'indirizzo puntato da \param{addr\_ptr}, la funzione
+restituisce un valore positivo in caso di successo, nullo se la stringa non
+rappresenta un indirizzo valido, e negativo se \param{af} specifica una
+famiglia di indirizzi non valida.
 
-La seconda funzione è \funcd{inet\_ntop} che converte un indirizzo in una
-stringa; il suo prototipo è:
+La seconda funzione di conversione è \funcd{inet\_ntop} che converte un
+indirizzo in una stringa; il suo prototipo è:
 \begin{prototype}{sys/socket.h}
   {char *inet\_ntop(int af, const void *addr\_ptr, char *dest, size\_t len)}
   Converte l'indirizzo dalla relativa struttura in una stringa simbolica.
@@ -893,30 +1015,32 @@ Il formato usato per gli indirizzi in formato di presentazione 
 Per evitare di rendere questa introduzione ai socket puramente teorica
 iniziamo con il mostrare un esempio di un client TCP elementare.  Prima di
 passare agli esempi del client e del server, ritorniamo con maggiori dettagli
-su una caratteristica delle funzioni di I/O che nel caso dei socket è
+su una caratteristica delle funzioni di I/O, già accennata in
+\secref{sec:file_read} e \secref{sec:file_write}, che nel caso dei socket è
 particolarmente rilevante, e che ci tornerà utile anche in seguito.
 
 
 \subsection{Il comportamento delle funzioni di I/O}
 \label{sec:sock_io_behav}
 
-Una cosa di cui non sempre si è consapevoli quando si ha a che fare con i
-socket è che le funzioni di input/output non sempre hanno lo stesso
-comportamento che avrebbero con i normali files (in particolare questo accade
-per i socket di tipo stream). 
+Una cosa che si tende a dimenticare quando si ha a che fare con i socket è che
+le funzioni di input/output non sempre hanno lo stesso comportamento che
+avrebbero con i normali file di dati (in particolare questo accade per i
+socket di tipo stream).
 
 Infatti con i socket è comune che funzioni come \func{read} o \func{write}
 possano restituire in input o scrivere in output un numero di byte minore di
 quello richiesto. Come già accennato in \secref{sec:file_read} questo è un
-comportamento normale per l'I/O su file; con i normali file di dati il
-problema si avverte solo quando si incontra la fine del file, ma in generale
-non è così.
+comportamento normale per l'I/O su file, ma con i normali file di dati il
+problema si avverte solo quando si incontra la fine del file, in generale non
+è così, e con i socket questo è particolarmente evidente.
 
-In questo caso tutto quello che il programma chiamante deve fare è di ripetere
-la lettura (o scrittura) per la quantità di byte rimanenti (e le funzioni si
-possono bloccare se i dati non sono disponibili): è lo stesso comportamento
-che si può avere scrivendo più di \const{PIPE\_BUF} byte in una pipe (si
-riveda quanto detto in \secref{sec:ipc_pipes}).
+Quando ci si trova ad affrontare questo comportamento tutto quello che si deve
+fare è semplicemente ripetere la lettura (o la scrittura) per la quantità di
+byte restanti, tenendo conto che le funzioni si possono bloccare se i dati non
+sono disponibili: è lo stesso comportamento che si può avere scrivendo più di
+\const{PIPE\_BUF} byte in una pipe (si riveda quanto detto in
+\secref{sec:ipc_pipes}).
 
 \begin{figure}[htb]
   \centering
@@ -946,17 +1070,19 @@ ssize_t FullRead(int fd, void *buf, size_t count)
     return (count - nleft);
 }  
   \end{lstlisting}
-  \caption{Funzione \func{FullRead}, legge \var{count} byte da un socket }
+  \caption{Funzione \func{FullRead}, legge esattamente \var{count} byte da un
+    file descriptor, iterando opportunamente le letture.}
   \label{fig:sock_FullRead_code}
 \end{figure}
 
 Per questo motivo, seguendo l'esempio di W. R. Stevens in \cite{UNP1}, si sono
-definite due funzioni \func{FullRead} e \func{FullWrite} che eseguono la
-lettura da un socket tenendo conto di questa caratteristica, ed in grado di
+definite due funzioni, \func{FullRead} e \func{FullWrite}, che eseguono
+lettura e scrittura tenendo conto di questa caratteristica, ed in grado di
 ritornare dopo avere letto o scritto esattamente il numero di byte
-specificato; il sorgente è riportato in \figref{fig:sock_FullRead_code} e
-\figref{fig:sock_FullWrite_code} ed è disponibile fra i sorgenti allegati alla
-guida nei files \file{FullRead.c} e \file{FullWrite.c}.
+specificato; il sorgente è riportato rispettivamente in
+\figref{fig:sock_FullRead_code} e \figref{fig:sock_FullWrite_code} ed è
+disponibile fra i sorgenti allegati alla guida nei file \file{FullRead.c} e
+\file{FullWrite.c}.
 
 \begin{figure}[htb]
   \centering