Rinominati app_a e app_b
[gapil.git] / socket.tex
index 7e1f6bd7db68ba847089f35ac99dbbd04ce1cea8..e20c38800ce3e087de70946678e1a2854d80be31 100644 (file)
@@ -6,8 +6,8 @@ principali meccanismi di comunicazione fra programmi utilizzato in ambito unix
 (e non solo). Il 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 ma a differenza di questa e degli altri meccanismi esaminati nel capitolo
-\ref{cha:IPC} i socket non sono limitati alla comunicazione fra processi che
-girano sulla stessa macchina ma possono effettuare la comunicazione anche
+\capref{cha:IPC} i socket non sono limitati alla comunicazione fra processi
+che girano sulla stessa macchina ma possono effettuare la comunicazione anche
 attraverso la rete.
 
 Quella dei socket costituisce infatti la principale API (\textit{Application
@@ -29,8 +29,8 @@ tratteremo in maniera pi
 \label{sec:sock_gen}
 
 Per capire il funzionamento dei socket occorre avere presente il funzionamento
-dei protocolli di rete (vedi \ref{cha:network}), ma l'interfaccia è del tutto
-generale e benché le problematiche (e quindi le modalità di risolvere i
+dei protocolli di rete (vedi \capref{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.
 
@@ -75,21 +75,19 @@ dei file che contiene i puntatori alle opportune strutture usate dal kernel ed
 allocate per ogni processo, (la stessa usata per i files e le pipes [NdA
 verificare!]).
 
-Il prototipo della funzione è definito nell'header \texttt{sys/socket.h}, la
-funzione prende tre parametri, il dominio del socket (che definisce la
-famiglia di protocolli, vedi \ref{sec:sock_domain}), il tipo di socket (che
-definisce lo stile di comunicazione vedi \ref{sec:sock_type}) e 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}).
+La funzione prende tre parametri, il dominio del socket (che definisce la
+famiglia di protocolli, vedi \secref{sec:sock_domain}), il tipo di socket (che
+definisce lo stile di comunicazione vedi \secref{sec:sock_type}) e 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}).
 
-\begin{itemize}
-\item \texttt{int socket(int domain, int type, int protocol)}
+\begin{prototype}{sys/socket.h}{int socket(int domain, int type, int protocol)}
   
   La funzione restituisce un intero positivo se riesce, e -1 se fallisce, in
   quest'ultimo caso la variabile \texttt{errno} è settata con i seguenti
   codici di errore:
 
-  \begin{itemize}
+  \begin{errlist}
   \item \texttt{EPROTONOSUPPORT} Il tipo di socket o il protocollo scelto non
     sono supportati nel dominio.
   \item \texttt{ENFILE} Il kernel non ha memoria sufficiente a creare una
@@ -100,8 +98,8 @@ viene messo a zero (con l'eccezione dei \textit{raw socket}).
   \item \texttt{EINVAL} Protocollo sconosciuto o dominio non disponibile.
   \item \texttt{ENOBUFS} o \texttt{ENOMEM} Non c'è sufficiente memoria per
     creare il socket.
-  \end{itemize}
-\end{itemize}
+  \end{errlist}
+\end{prototype}
 
 Si noti che la creazione del socket non comporta nulla riguardo
 all'indicazione degli indirizzi remoti o locali attraverso i quali si vuole
@@ -112,14 +110,14 @@ effettuare la comunicazione.
 
 Dati i tanti e diversi protocolli di comunicazione disponibili, esistono vari
 tipi di socket, che vengono classificati raggruppandoli in quelli che si
-chiamano \textsl{domini} (\textit{domains}).  La scelta di un dominio equivale
-in sostanza alla scelta di una famiglia di protocolli. Ciascun dominio ha un
-suo nome simbolico che convenzionalmente inizia con \texttt{PF\_} (da
-\textit{Protocol Family}, altro nome con cui si indicano i domini). 
+chiamano \textsl{domini}.  La scelta di un dominio equivale in sostanza alla
+scelta di una famiglia di protocolli. Ciascun dominio ha un suo nome simbolico
+che convenzionalmente inizia con \texttt{PF\_} da \textit{protocol family},
+altro nome con cui si indicano i domini.
 
 A ciascun tipo di dominio corrisponde un analogo nome simbolico che inizia per
-\texttt{AF\_} da \textit{Address Family}, e che identifica il formato degli
-indirizzi usati in quel dominio; le man pages di linux si riferiscono a questi
+\texttt{AF\_} da \textit{address family}, e che identifica il formato degli
+indirizzi usati in quel dominio; le man pages di Linux si riferiscono a questi
 anche come \textit{name space}, (nome che però il manuale della glibc riserva
 ai domini) e che identifica il formato degli indirizzi usati in quel dominio.
 
@@ -132,7 +130,7 @@ supportino diverse strutture di indirizzi, per cui nella pratica questi due
 nomi sono equivalenti e corrispondono agli stessi valori.
 
 I domini (e i relativi nomi simbolici), così come i nomi delle famiglie di
-indirizzi sono definiti dall'header \textit{socket.h}. In linux le famiglie di
+indirizzi sono definiti dall'header \textit{socket.h}. In Linux le famiglie di
 protocolli disponibili sono riportate in \ntab.
 
 \begin{table}[htb]
@@ -140,6 +138,7 @@ protocolli disponibili sono riportate in \ntab.
   \centering
   \begin{tabular}[c]{lll}
        Nome               & Utilizzo                       & Man page   \\
+       \hline
        PF\_UNIX,PF\_LOCAL & Local communication            & unix(7)    \\
        PF\_INET           & IPv4 Internet protocols        & ip(7)      \\
        PF\_INET6          & IPv6 Internet protocols        &            \\
@@ -151,13 +150,13 @@ protocolli disponibili sono riportate in \ntab.
        PF\_APPLETALK      & Appletalk                      & ddp(7)     \\
        PF\_PACKET         & Low level packet interface     & packet(7)  \\    
   \end{tabular}
-  \caption{Famiglie di protocolli definiti in linux}
+  \caption{Famiglie di protocolli definiti in Linux}
   \label{tab:net_pf_names}
 \end{table}
 
 Non tutte le famiglie di protocolli sono accessibili dall'utente generico, ad
 esempio in generale tutti i socket di tipo \texttt{SOCK\_RAW} possono essere
-creati solo da processi che hanno i provilegi di root (cioè effective uid
+creati solo da processi che hanno i privilegi di root (cioè effective uid
 uguale a zero) o la capability \texttt{CAP\_NET\_RAW}.
 
 
@@ -167,7 +166,7 @@ uguale a zero) o la capability \texttt{CAP\_NET\_RAW}.
 La scelta di un dominio non comporta però la scelta dello stile di
 comunicazione, questo infatti viene a dipendere dal protocollo che si andrà ad
 utilizzare fra quelli disponibili nella famiglia scelta. Le API permettono di
-scegliere lo stile di comunicazione indicando il tipo di socket; linux e le
+scegliere lo stile di comunicazione indicando il tipo di socket; Linux e le
 glibc mettono a disposizione i seguenti tipi di socket (che il manuale della
 glibc chiama \textit{styles}) definiti come \texttt{int} in \texttt{socket.h}:
 
@@ -175,11 +174,10 @@ glibc chiama \textit{styles}) definiti come \texttt{int} in \texttt{socket.h}:
 \item \texttt{SOCK\_STREAM} Provvede un canale di trasmissione dati
   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}). Vedi \ref{sec:sock_stream}.
+  byte (da cui il nome \textit{stream}). 
 \item \texttt{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. Vedi
-  \ref{sec:sock_dgram}.
+  connessione e in maniera non affidabile. È l'opposto del precedente. 
 \item \texttt{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
@@ -270,14 +268,14 @@ in \nfig:
 
 \begin{figure}[!htbp]
   \footnotesize
-  \begin{lstlisting}{}
+  \begin{lstlisting}[labelstep=0,frame=,indent=1cm]{}
 struct sockaddr {
     sa_family_t  sa_family;     /* address family: AF_xxx */
     char         sa_data[14];   /* address (protocol-specific) */
 };
   \end{lstlisting}
   \caption{La struttura generica degli indirizzi dei socket \texttt{sockaddr}}
-  \label{fig:sock_sa_struct}
+  \label{fig:sock_sa_gen_struct}
 \end{figure}
 
 Tutte le funzioni dei socket che usano gli indirizzi sono definite usando nel
@@ -286,7 +284,7 @@ invocano dette funzioni passando l'indirizzo di un protocollo specifico
 occorrerà eseguire un casting del relativo puntatore.
 
 I tipi di dati che compongono la struttura sono stabiliti dallo standard
-Posix.1g, riassunti in \ntab\ con i rispettivi file di include in cui sono
+POSIX.1g, riassunti in \ntab\ con i rispettivi file di include in cui sono
 definiti; la struttura è invece definita nell'include file
 \texttt{sys/socket.h}
 
@@ -316,16 +314,15 @@ definiti; la struttura 
     \hline
   \end{tabular}
   \caption{Tipi di dati usati nelle strutture degli indirizzi, secondo quanto 
-    stabilito dallo standard Posix.1g}
+    stabilito dallo standard POSIX.1g}
   \label{tab:sock_data_types}
 \end{table}
 
-In alcuni sistemi (per BSD a partire da 4.3BSD-reno) la struttura è
-leggermente diversa e prevede un primo membro aggiuntivo \texttt{uint8\_t
-  sin\_len} (come riportato da R. Stevens nei suoi libri). Questo campo non
-verrebbe usato direttamente dal programmatore e non è richiesto dallo standard
-Posix.1g, in Linux pertanto non sussiste. Il campo \texttt{sa\_family\_t} era
-storicamente un \texttt{unsigned short}.
+In alcuni sistemi la struttura è leggermente diversa e prevede un primo membro
+aggiuntivo \texttt{uint8\_t sin\_len} (come riportato da R. Stevens nei suoi
+libri). Questo campo non verrebbe usato direttamente dal programmatore e non è
+richiesto dallo standard POSIX.1g, in Linux pertanto non sussiste. Il campo
+\texttt{sa\_family\_t} era storicamente un \texttt{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'
@@ -343,12 +340,12 @@ I socket di tipo \texttt{PF\_INET} vengono usati per la comunicazione
 attraverso internet; la struttura per gli indirizzi per un socket internet
 (IPv4) è definita come \texttt{sockaddr\_in} nell'header file
 \texttt{netinet/in.h} e secondo le man page ha la forma mostrata in \nfig,
-conforme allo standard Posix.1g.
+conforme allo standard POSIX.1g.
 
 
 \begin{figure}[!htbp]
   \footnotesize
-  \begin{lstlisting}{}
+  \begin{lstlisting}[labelstep=0,frame=,indent=1cm]{}
 struct sockaddr_in {
     sa_family_t     sin_family; /* address family: AF_INET */
     u_int16_t       sin_port;   /* port in network byte order */
@@ -361,7 +358,7 @@ struct in_addr {
   \end{lstlisting}
   \caption{La struttura degli indirizzi dei socket internet (IPv4)
     \texttt{sockaddr\_in}.}
-  \label{fig:sock_sa_struct}
+  \label{fig:sock_sa_ipv4_struct}
 \end{figure}
 
 L'indirizzo di un socket internet (secondo IPv4) comprende l'indirizzo
@@ -372,35 +369,35 @@ RAW che accedono direttamente al livello di IP, nel qual caso il numero della
 porta viene settato al numero di protocollo.
 
 Il membro \texttt{sin\_family} deve essere sempre settato; \texttt{sin\_port}
-specifica il numero di porta; i numeri di porta sotto il 1024 sono chiamati
-\textsl{riservati} in quanto utilizzati da servizi standard. Soltanto processi
-con i privilegi di root (effective uid uguale a zero) o con la capability
-\texttt{CAP\_NET\_BIND\_SERVICE} possono usare la funzione \texttt{bind} su
-queste porte.
+specifica il numero di porta (vedi \secref{sec:TCPel_port_num}; i numeri di
+porta sotto il 1024 sono chiamati \textsl{riservati} in quanto utilizzati da
+servizi standard. Soltanto processi con i privilegi di root (effective uid
+uguale a zero) o con la capability \texttt{CAP\_NET\_BIND\_SERVICE} possono
+usare la funzione \texttt{bind} su queste porte.
 
 Il membro \texttt{sin\_addr} contiene l'indirizzo internet dell'altro capo
 della comunicazione, e viene acceduto sia come struttura (un resto di una
-implementazione precedente in cui questa era una union usata per accedere alle
+implementazione precedente in cui questa era una \texttt{union} usata per accedere alle
 diverse classi di indirizzi) che come intero. 
 
 Infine è da 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 \ref{sec:sock_addr_func} per i dettagli del
+portabilità del codice (vedi \secref{sec:sock_addr_func} per i dettagli del
 problema e le relative soluzioni).
 
 \subsection{La struttura degli indirizzi IPv6}
 \label{sec:sock_sa_ipv6}
 
-Essendo IPv6 una estenzione di IPv4 i socket di tipo \texttt{PF\_INET6} sono
+Essendo IPv6 una estensione di IPv4 i socket di tipo \texttt{PF\_INET6} sono
 sostanzialmente identici ai precedenti; la parte in cui si trovano
 praticamente tutte le differenze è quella della struttura degli indirizzi. La
 struttura degli indirizzi è definita ancora in \texttt{netinet/in.h}.
 
 \begin{figure}[!htbp]
   \footnotesize
-  \begin{lstlisting}{}
+  \begin{lstlisting}[labelstep=0,frame=,indent=1cm]{}
 struct sockaddr_in6 {
     u_int16_t       sin6_family;   /* AF_INET6 */
     u_int16_t       sin6_port;     /* port number */
@@ -415,16 +412,16 @@ struct in6_addr {
   \end{lstlisting}
   \caption{La struttura degli indirizzi dei socket IPv6 
     \texttt{sockaddr\_in6}.}
-  \label{fig:sock_sa_struct}
+  \label{fig:sock_sa_ipv6_struct}
 \end{figure}
 
 Il campo \texttt{sin6\_family} deve essere sempre settato ad
 \texttt{AF\_INET6}, il campo \texttt{sin6\_port} è analogo a quello di IPv4 e
-segue le stesse regole; il campo \texttt{sin6\_flowinfo} è a dua volta diviso
+segue le stesse regole; il campo \texttt{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 \ref{sec:appA_ipv6}) ed il loro uso è sperimentale. 
+(vedi \secref{sec:IP_ipv6head}) ed il loro uso è sperimentale.
 
 Il campo \texttt{sin6\_addr} contiene l'indirizzo a 128 bit usato da IPv6,
 infine il campo \texttt{sin6\_scope\_id} è un campo introdotto con il kernel
@@ -434,20 +431,20 @@ Si noti che questa struttura 
 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 \texttt{PF\_UNIX} vengono usati per una comunicazione
 efficiente fra processi che stanno sulla stessa macchina; essi rispetto ai
 precedenti possono essere anche creati in maniera anonima attraverso la
-funzione \texttt{socketpair}. Quando però si vuole fare riferiemento ad uno di
-questi socket si deve usare la seguente struttura di indirizzi definita nel
-file di header \texttt{sys/un.h}.
+funzione \texttt{socketpair}. Quando però si vuole fare riferimento esplicito
+ad uno di questi socket si deve usare la seguente struttura di indirizzi
+definita nel file di header \texttt{sys/un.h}.
 
 \begin{figure}[!htbp]
   \footnotesize
-  \begin{lstlisting}{}
+  \begin{lstlisting}[labelstep=0,frame=,indent=1cm]{}
 #define UNIX_PATH_MAX    108
 struct sockaddr_un {
     sa_family_t  sun_family;              /* AF_UNIX */
@@ -456,7 +453,7 @@ struct sockaddr_un {
   \end{lstlisting}
   \caption{La struttura degli indirizzi dei socket locali 
     \texttt{sockaddr\_un}.}
-  \label{fig:sock_sa_struct}
+  \label{fig:sock_sa_local_struct}
 \end{figure}
 
 In questo caso il campo \texttt{sun\_family} deve essere \texttt{AF\_UNIX},
@@ -464,18 +461,18 @@ mentre il campo \texttt{sun\_path} deve specificare un indirizzo; questo ha
 due forme un file (di tipo socket) nel filesystem o una stringa univoca
 (tenuta 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 qinvece \texttt{sun\_path} inizia con uno zero
-vegono usati i restanti bytes come stringa (senza terminazione).
+pathname del file; nel secondo invece \texttt{sun\_path} inizia con uno zero
+vengono usati i restanti bytes come stringa (senza terminazione).
 
 
-\subsection{Il passaggio delle strutture}
-\label{sec:sock_addr_pass}
+\subsection{Il passaggio delle strutture}
+\label{sec:sock_addr_pass}
 
-Come detto nelle funzioni della API dei socket le strutture degli indirizzi
-vengono sempre passate per riferimento usando un puntatore; anche la lunghezza
-della struttura è passata come argomento, ma in questo caso la modalità del
-passaggio dipende dalla direzione del medesimo, dal processo al kernel o
-viceversa.
+Come detto nelle funzioni della API dei socket le strutture degli indirizzi
+vengono sempre passate per riferimento usando un puntatore; anche la lunghezza
+della struttura è passata come argomento, ma in questo caso la modalità del
+passaggio dipende dalla direzione del medesimo, dal processo al kernel o
+viceversa.
 
 % In particolare le tre funzioni \texttt{bind}, \texttt{connect} e
 % \texttt{sendto} passano la struttura al kernel, in questo caso è passata
@@ -489,149 +486,284 @@ viceversa.
 \section{Le funzioni di conversione degli indirizzi}
 \label{sec:sock_addr_func}
 
-Come accennato gli indirizzi internet e i numero di porta espressi in formato
-big endian. In genere la rappresentazione di un numbero binario in un computer
-può essere fatta in due modi, chiamati rispettivamente \textit{big endian} e
-\textit{little endian} a seconda di come i bit sono aggregati per formare le
-unità più grandi.
-
-Si consideri ad esempio un intero a 16 bit scritto in una locazione di memoria
-posta ad un certo indirizzo. 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
-nell'indirizzo successivo; questo ordinamento è detto little endian dato che
-il dato finale è la parte ``piccola'' del numero. Il caso opposto, in cui si
-parte dal bit meno significativo è detto big endian.
+In questa sezione tratteremo delle varie funzioni usate per manipolare gli
+indirizzi, limitandoci però agli indirizzi internet.
+
+Come accennato gli indirizzi e i numeri di porta usati nella rete devono
+essere forniti in formato opportuno (il \textit{network order}). Per capire
+cosa significa tutto ciò occorre introdurre un concetto generale che tornerà
+utile anche in seguito.
+
+
+\subsection{La \textit{endianess}}
+\label{sec:sock_endianess}
+
+La rappresentazione di un numero binario in un computer può essere fatta in
+due modi, chiamati rispettivamente \textit{big endian} e \textit{little
+  endian} a seconda di come i singoli bit vengono aggregati per formare le
+variabili intere (in diretta corrispondenza a come sono poi in realtà cablati
+sui bus interni del computer).
+
+Per capire meglio il problema si consideri un intero a 16 bit scritto in una
+locazione di memoria posta ad un certo indirizzo. 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 nell'indirizzo successivo; questo ordinamento è detto
+\textit{little endian} dato che il dato finale è la parte ``piccola'' del
+numero. Il caso opposto, in cui si parte dal bit meno significativo è detto
+per lo stesso motivo \textit{big endian}.
 
 La \textit{endianess} di un computer dipende essenzialmente dalla architettura
-usata; intel e digital usano il little endian, motorola, ibm, sun
+hardware usata; Intel e Digital usano il little endian, Motorola, IBM, Sun
 (sostanzialmente tutti gli altri) usano il big endian. Il formato della rete è
-anch'esso big endian. Esistono poi anche dei sistemi che possono scegliere il
-tipo di formato e alcuni, come il PowerPC o l'intel i860, possono pure passare
-da un tipo all'altro; ma in generale un sistema ha un suo specifico
-comportamento a questo riguardo.
-
-Il problema si pone quando si passano dei dati da un tipo di archiettura
-all'altra dato che, con l'eccezione dei tipi numerici ad otto bit, tutti gli
-altri si ritrovano rovesciati. 
-
-Per questo motivo si usano le seguenti funzioni di conversione che tengano
-conto della differenza delle architetture:
-\begin{itemize}
-\item \texttt{unsigned long int htonl(unsigned long int hostlong)} 
-  
+anch'esso big endian, quello del bus PCI è little endian, quello del bus VME è
+big endian. 
+
+Esistono poi anche dei processori che possono scegliere il tipo di formato
+all'avvio e alcuni, come il PowerPC o l'Intel i860, possono pure passare da un
+tipo di ordinamento all'altro con una specifica istruzione; in ogni caso in
+Linux l'ordinamento è definito dall'architettura e anche se questi cambiamenti
+sono possibili anche dopo che il sistema è avviato, non vengono mai eseguiti.
+
+\subsection{Le funzioni per il riordinamento}
+\label{sec:sock_func_ord}
+
+Il problema connesso all'endianess è che quando si passano dei dati da un tipo
+di architettura all'altra i dati vengono interpretati in maniera diversa, e ad
+esempio nel caso dell'intero a 16 bit ci si ritroverà con i due bytes in cui è
+suddiviso scambiati di posto, e ne sarà quindi invertito l'ordine di lettura
+per cui, per riavere il valore originale dovranno essere rovesciati.
+
+Per questo motivo si usano le seguenti funzioni di conversione che servono a
+tener conto automaticamente della possibile differenza fra l'ordinamento usato
+sul computer e quello che viene usato nelle trasmissione sulla rete; queste
+funzioni sono:
+\begin{prototype}{netinet/in.h}
+{unsigned long int htonl(unsigned long int hostlong)} 
   Converte l'intero a 32 bit \texttt{hostlong} dal formato della macchina a
   quello della rete.
-
-\item \texttt{unsigned sort int htons(unsigned short int hostshort)}
-
+\end{prototype}
+\begin{prototype}{netinet/in.h}
+{unsigned short int htons(unsigned short int hostshort)}
   Converte l'intero a 16 bit \texttt{hostshort} dal formato della macchina a
   quello della rete.
-  
-\item \texttt{unsigned long int ntonl(unsigned long int netlong)}
-  
+\end{prototype}
+\begin{prototype}{netinet/in.h}
+{unsigned long int ntonl(unsigned long int netlong)}
   Converte l'intero a 32 bit \texttt{netlong} dal formato della rete a quello
   della macchina.
-
-\item \texttt{unsigned sort int ntons(unsigned short int netshort)}
-  
+\end{prototype}
+\begin{prototype}{netinet/in.h}
+{unsigned sort int ntons(unsigned short int netshort)}
   Converte l'intero a 16 bit \texttt{netshort} dal formato della rete a quello
   della macchina.
-\end{itemize}
-in cui la lettera $n$ è uno mnemonico per indicare l'ordinamento usato sulla
-rete (da \textit{network order}) e la lettere $h$ uno mnemonico per
-l'ordinamento usato sulla macchina locale (da \textit{host order}), mentre le
-lettere $s$ e $l$ stanno ad indicare i tipi di dato (riportati anche dai
-prototipi).
-
-Usando queste funzioni si ha la conversione automatica in caso di necessità
-(nel caso pure la macchina sia in big endian queste funzioni sono definite
-come macro che non fanno nulla).
-
-A parte i problemi connessi con l'ordinamento dei bit esistono poi altre
-funzioni connesse alla manipolazione degli indirizzi internet, in particolare
-per convertire indirizzi espressi in forma di stringa (di più immediata
-manipolazione ``umana'') nella forma binaria usata nelle strutture degli
-indirizzi.
-
-Le prime tre funzioni riguardano la conversione degli indirizzi IPv4 fra
-l'espressione come stringhe \textit{dotted-decimal}, cioè del tipo
-\texttt{192.160.0.1} al formato binario ordinato secondo la rete:
-\begin{itemize}
-\item \texttt{int inet\_aton(const char *strptr, struct in\_addr *addrptr)} 
-  
-  Converte la stringa puntata da \texttt{strptr} nell'indirizzo binario da
-  memorizzare all'indirizzo puntato da \texttt{addrptr}, restituendo 0 in caso
-  di successo e 1 in caso di fallimento (è espressa in questa forma in modo da
-  poterla usare direttamente con il puntatore usato per passare la struttura
-  degli indirizzi). Se usata con \texttt{addrptr} inizializzato a
-  \texttt{NULL} effettua la validazione dell'indirizzo.
-  
-\item \texttt{in\_addr\_t inet\_addr(const char *strptr)} 
-  
+\end{prototype}
+I nomi sono assegnati usando la lettera $n$ come mnemonico per indicare
+l'ordinamento usato sulla rete (da \textit{network order}) e la lettera $h$
+come mnemonico per l'ordinamento usato sulla macchina locale (da \textit{host
+  order}), mentre le lettere $s$ e $l$ stanno ad indicare i tipi di dato
+(\texttt{long} o \texttt{short}, riportati anche dai prototipi).
+
+Usando queste funzioni si ha la conversione automatica (nel caso pure la
+macchina sia in big endian queste funzioni sono definite come macro che non
+fanno nulla); esse vanno sempre utilizzate per assicurare la portabilità del
+codice su tutte le architetture.
+
+
+\subsection{Le funzioni \texttt{inet\_aton}, \texttt{inet\_addr} e 
+  \texttt{inet\_ntoa}}
+\label{sec:sock_func_ipv4}
+
+Un secondo insieme di funzioni di manipolazione serve per passare dal formato
+binario usato nelle strutture degli indirizzi alla rappresentazione dei numeri
+IP che si usa normalmente.
+
+Le prime tre funzioni di manipolazione riguardano la conversione degli
+indirizzi IPv4 da una stringa in cui il numero di IP è espresso secondo la
+cosiddetta notazione \textit{dotted-decimal}, (cioè nella forma
+\texttt{192.160.0.1}) al formato binario (direttamente in \textit{network
+  order}) e viceversa; in questo caso si usa la lettera $a$ come mnemonico per
+indicare la stringa. Dette funzioni sono:
+\begin{prototype}{arpa/inet.h}
+  {int inet\_aton(const char *src, struct in\_addr *dest)} Converte la stringa
+  puntata da \texttt{src} nell'indirizzo binario da memorizzare all'indirizzo
+  puntato da \texttt{dest}, restituendo 0 in caso di successo e 1 in caso di
+  fallimento (è espressa in questa forma in modo da poterla usare direttamente
+  con il puntatore usato per passare la struttura degli indirizzi). Se usata
+  con \texttt{dest} inizializzato a \texttt{NULL} effettua la validazione
+  dell'indirizzo.
+\end{prototype}
+\begin{prototype}{arpa/inet.h}{in\_addr\_t inet\_addr(const char *strptr)}
   Restituisce l'indirizzo a 32 bit in network order a partire dalla stringa
   passata come parametro, in caso di errore restituisce il valore
-  \texttt{INADDR\_NONE} (che tipicamente sono trentadue bit a uno, il che
-  significa che la stringa \texttt{255.255.255.255} non può essere un
-  indirizzo valido). Questa funzione è generalmente deprecata in favore della
-  precedente. 
-
-\item \texttt{char *inet\_ntop(struct in\_addr addrptr)}
-  
-  Questa funzione converte il valore a 32 bit in network order dell'indirizzo
-  in una stringa. La stringe risiede in memoria statica, per cui questa
-  funzione non è rientrante, inoltre, in maniera abbastanza atipica, prende in
-  ingresso una struttura e non un puntarore.
-\end{itemize}
-
-Queste funzioni sono limitate solo ad IPv4, per questo motivo è preferibile
-usare le due nuove funzioni \texttt{inet\_pton} e \texttt{inet\_ntop} che
-funzionano anche per indirizzi IPv6. In questo caso le lettere $n$ e $p$ sono
-gli mnemonici per ricordare il tipo di conversione effettuato e stanno per
-\textit{presentation} e \textit{numeric}.
-
-\begin{itemize}
-\item \texttt{int inet\_pton(int family, const char *strptr, void *addrptr)} 
-  
-  Converte la stringa puntata da \texttt{strptr} nell'indirizzo binario da
-  memorizzare all'indirizzo puntato da \texttt{addrptr}, restituendo 0 in caso
-  di successo e 1 in caso di fallimento (è espressa in questa forma in modo da
-  poterla usare direttamente con il puntatore usato per passare la struttura
-  degli indirizzi). Se usata con \texttt{addrptr} inizializzato a
-  \texttt{NULL} effettua la validazione dell'indirizzo.
-  
-  
-\item \texttt{char *inet\_ntop(int family, const void *addrptr, char *strptr,
-    size\_t len)}
-  
-  Questa funzione converte il valore a 32 bit in network order dell'indirizzo
-  in una stringa. La stringe risiede in memoria statica, per cui questa
-  funzione non è rientrante, inoltre, in maniera abbastanza atipica, prende in
-  ingresso una struttura e non un puntatore.
-
-\end{itemize}
-
-
-
-
-\chapter{Socket TCP elementari}
-\label{cha:elem_TCP_sock}
-
-Esamineremo in questo capitolo quanto necessario per capire come scrivere un
-client e un server TCP, riprendendo quanto visto in \ref{sec:net_cli_sample} e
-\ref{sec:net_cli_server}. 
-
+  \texttt{INADDR\_NONE} che tipicamente sono trentadue bit a uno; questo
+  comporta che la stringa \texttt{255.255.255.255}, che pure è un indirizzo
+  valido, non può essere usata con questa funzione; per questo motivo essa è
+  generalmente deprecata in favore della precedente.
+\end{prototype}  
+\begin{prototype}{arpa/inet.h}{char *inet\_ntoa(struct in\_addr addrptr)}
+  Converte il valore a 32 bit dell'indirizzo (espresso in network order)
+  restituendo il puntatore alla stringa che contiene l'espressione in formato
+  dotted decimal. Si deve tenere presente che la stringa risiede in memoria
+  statica, per cui questa funzione non è rientrante.
+\end{prototype}
+
+
+\subsection{Le funzioni \texttt{inet\_pton} e \texttt{inet\_ntop}}
+\label{sec:sock_conv_func_gen}
+
+Le tre funzioni precedenti sono limitate solo ad indirizzi IPv4, per questo
+motivo è preferibile usare le due nuove funzioni \texttt{inet\_pton} e
+\texttt{inet\_ntop} che possono convertire anche gli indirizzi IPv6. Anche in
+questo caso le lettere $n$ e $p$ sono degli mnemonici per ricordare il tipo di
+conversione effettuata e stanno per \textit{presentation} e \textit{numeric}.
+
+% \begin{figure}[htb]
+%   \centering  
+
+%   \caption{Schema della rappresentazioni utilizzate dalle funzioni di 
+%     conversione \texttt{inet\_pton} e \texttt{inet\_ntop} }
+%   \label{fig:sock_inet_conv_func}
+
+% \end{figure}
+
+Entrambe le funzioni accettano l'argomento \texttt{af} che indica il tipo di
+indirizzo e può essere \texttt{AF\_INET} o \texttt{AF\_INET6}. Se la famiglia
+indicata non è valida entrambe le funzioni settano la variabile \texttt{errno}
+al valore \texttt{EAFNOSUPPORT}. I prototipi delle suddette funzioni sono i
+seguenti:
+\begin{prototype}{sys/socket.h}
+  {int inet\_pton(int af, const char *src, void *addr\_ptr)} Converte la
+  stringa puntata da \texttt{src} nell'indirizzo IP da memorizzare
+  all'indirizzo puntato da \texttt{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 \var{af} specifica una famiglia di indirizzi
+  non valida.
+\end{prototype}
+
+\begin{prototype}{sys/socket.h}
+  {char *inet\_ntop(int af, const void *addr\_ptr, char *dest, size\_t len)}
+  Converte la struttura dell'indirizzo puntata da \texttt{addr\_ptr} in una
+  stringa che viene copiata nel buffer puntato dall'indirizzo \texttt{dest};
+  questo deve essere preallocato dall'utente e la lunghezza deve essere almeno
+  \texttt{INET\_ADDRSTRLEN} in caso di indirizzi IPv4 e
+  \texttt{INET6\_ADDRSTRLEN} per indirizzi IPv6; la lunghezza del buffer deve
+  comunque venire specificata attraverso il parametro \texttt{len}.
+  La funzione restituisce un puntatore non nullo a \texttt{dest} in caso di
+  successo e un puntatore nullo in caso di fallimento, in quest'ultimo caso
+  viene settata la variabile \texttt{errno} con il valore \texttt{ENOSPC} in
+  caso le dimensioni dell'indirizzo eccedano la lunghezza specificata da
+  \texttt{len} o \macro{ENOAFSUPPORT} in caso \var{af} non sia una famiglia di
+  indirizzi valida.
+\end{prototype}
+
+Gli indirizzi vengono cnovertiti da/alle rispettive strutture di indirizzo
+(\var{struct  in\_addr} per IPv4, e \var{struct  in6\_addr} per IPv6), che
+devono essere precedentemente allocate e passate attraverso il puntatore
+\var{addr\_ptr}; il parametro \var{dest} di \func{inet\_ntop} non può essere
+nullo e deve essere allocato precedentemente.
+
+Il formato usato per gli indirizzi in formato di presentazione è la notazione
+\textit{dotted decimal} per IPv4 e quella descritta in
+\secref{sec:IP_ipv6_notation} per IPv6.
+
+\section{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). 
+
+Infatti con i socket può accadere che funzioni come \texttt{read} o
+\texttt{write} possano restituire in input o scrivere in output un numero di
+bytes minore di quello richiesto. Questo è un comportamento normale e non un
+errore, e succede perché si eccede in lettura o scrittura il limite di buffer
+del kernel. 
+
+In questo caso tutto quello che il programma chiamante deve fare è di ripetere
+la lettura (o scrittura) per la quantità di bytes rimanenti (lo stesso può
+avvenire scrivendo più di 4096 bytes in una pipe, dato che quello è il limite
+di solito adottato per il buffer di trasmissione del kernel).
+
+\begin{figure}[htb]
+  \centering
+  \footnotesize
+  \begin{lstlisting}{}
+#include <unistd.h>
 
+ssize_t SockRead(int fd, void *buf, size_t count) 
+{
+    size_t nleft;
+    ssize_t nread;
+    nleft = count;
+    while (nleft > 0) {             /* repeat until no left */
+        if ( (nread = read(fd, buf, nleft)) < 0) {
+            if (errno == EINTR) {   /* if interrupted by system call */
+                continue;           /* repeat the loop */
+            } else {
+                return(nread);      /* otherwise exit */
+            }
+        } else if (nread == 0) {    /* EOF */
+            break;                  /* break loop here */ 
+        }
+        nleft -= nread;             /* set left to read */
+        buf +=nread;                /* set pointer */
+    }
+    return (count - nleft);
+}  
+  \end{lstlisting}
+  \caption{Funzione \texttt{SockRead}, legge $n$ bytes da un socket }
+  \label{fig:sock_SockRead_code}
+\end{figure}
 
-\subsection{Creazione e terminazione della connessione TCP}
+Per questo motivo seguendo l'esempio di W. R. Stevens si sono definite due
+funzioni \texttt{SockRead} e \texttt{SockWrite} che eseguono la lettura da un
+socket tenendo conto di questa caratteristica, ed in grado di ritornare dopo
+avere letto o scritto esattamente il numero di bytes specificato; il sorgente
+è riportato in \curfig\ e \nfig\ ed è disponibile fra i sorgenti allegati alla
+guida nei files \texttt{SockRead.c} e \texttt{SockWrite.c}.
 
-Per capire il funzionamento delle funzioni della interfaccia dei socket che
-operano con TCP (le varie \texttt{connect}, \texttt{accept}, \texttt{close}
-che abbiamo visto negli esempi iniziali e su cui torneremo più avanti) è
-fodamentale capire come funziona la creazione e la conclusione di una
-connessione TCP.
+\begin{figure}[htb]
+  \centering
+  \footnotesize
+  \begin{lstlisting}{}
+#include <unistd.h>
+
+ssize_t SockWrite(int fd, const void *buf, size_t count) 
+{
+    size_t nleft;
+    ssize_t nwritten;
+
+    nleft = count;
+    while (nleft > 0) {             /* repeat until no left */
+        if ( (nwritten = write(fd, buf, nleft)) < 0) {
+            if (errno == EINTR) {   /* if interrupted by system call */
+                continue;           /* repeat the loop */
+            } else {
+                return(nwritten);   /* otherwise exit with error */
+            }
+        }
+        nleft -= nwritten;          /* set left to write */
+        buf +=nwritten;             /* set pointer */
+    }
+    return (count);
+}  
+  \end{lstlisting}
+  \caption{Funzione \texttt{SockWrite}, scrive $n$ bytes su un socket }
+  \label{fig:sock_SockWrite_code}
+\end{figure}
 
-\subsection{Le porte}
+Come si può notare le funzioni ripetono la lettura/scrittura in un loop fino
+all'esaurimento del numero di bytes richiesti, in caso di errore viene
+controllato se questo è \texttt{EINTR} (cioè un'interruzione della system call
+dovuta ad un segnale), nel qual caso l'accesso viene ripetuto, altrimenti
+l'errore viene ritornato interrompendo il loop. 
 
+Nel caso della lettura se il numero di bytes letti è zero significa che è
+arrivati alla fine del file e pertanto si ritorna senza aver concluso la
+lettura di tutti i bytes richiesti.