Aggiornamenti del copyright all'anno nuovo, e risistemazione delle
[gapil.git] / othersock.tex
index 9af54ba66d3c073b214a3e731ce86d9f96f1435e..9ffb653055bd8489538494dc8e588405d0ca2ff8 100644 (file)
@@ -1,20 +1,21 @@
 %% othersock.tex
 %%
 %% othersock.tex
 %%
-%% Copyright (C) 2004 Simone Piccardi.  Permission is granted to
+%% Copyright (C) 2004-2007 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
 %% 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",
+%% Free Software Foundation; with the Invariant Sections being "Un preambolo",
 %% with no Front-Cover Texts, and with no Back-Cover Texts.  A copy of the
 %% license is included in the section entitled "GNU Free Documentation
 %% License".
 %%
 %% with no Front-Cover Texts, and with no Back-Cover Texts.  A copy of the
 %% license is included in the section entitled "GNU Free Documentation
 %% License".
 %%
+
 \chapter{Gli altri tipi di socket}
 \label{cha:other_socket}
 
 \chapter{Gli altri tipi di socket}
 \label{cha:other_socket}
 
-Dopo aver trattato in cap.~\ref{cha:TCP_socket} i socket TCP, che costituiscono
-l'esempio più comune dell'interfaccia dei socket, esamineremo in questo
-capitolo gli altri tipi di socket, a partire dai socket UDP, e i socket
-\textit{Unix domain} già incontrati in \secref{sec:ipc_socketpair}.
+Dopo aver trattato in cap.~\ref{cha:TCP_socket} i socket TCP, che
+costituiscono l'esempio più comune dell'interfaccia dei socket, esamineremo in
+questo capitolo gli altri tipi di socket, a partire dai socket UDP, e i socket
+\textit{Unix domain} già incontrati in sez.~\ref{sec:ipc_socketpair}.
 
 
 \section{I socket UDP}
 
 
 \section{I socket UDP}
@@ -54,10 +55,11 @@ utilizzando per il tipo di socket il valore \const{SOCK\_DGRAM}.
 Questa differenza comporta ovviamente che anche le modalità con cui si usano i
 socket UDP sono completamente diverse rispetto ai socket TCP, ed in
 particolare non esistendo il concetto di connessione non esiste il meccanismo
 Questa differenza comporta ovviamente che anche le modalità con cui si usano i
 socket UDP sono completamente diverse rispetto ai socket TCP, ed in
 particolare non esistendo il concetto di connessione non esiste il meccanismo
-del \textit{three way handshake} né quello degli stati del protocollo. In
-realtà tutto quello che avviene nella comunicazione attraverso dei socket UDP
-è la trasmissione di un pacchetto da un client ad un server o viceversa,
-secondo lo schema illustrato in fig.~\ref{fig:UDP_packet-exchange}.
+del \itindex{three~way~handshake} \textit{three way handshake} né quello degli
+stati del protocollo. In realtà tutto quello che avviene nella comunicazione
+attraverso dei socket UDP è la trasmissione di un pacchetto da un client ad un
+server o viceversa, secondo lo schema illustrato in
+fig.~\ref{fig:UDP_packet-exchange}.
 
 \begin{figure}[htb]
   \centering
 
 \begin{figure}[htb]
   \centering
@@ -130,11 +132,11 @@ la destinazione dei dati trasmessi o ottenere l'origine dei dati ricevuti. La
 prima di queste funzioni è \funcd{sendto} ed il suo prototipo\footnote{il
   prototipo illustrato è quello utilizzato dalle \acr{glibc}, che seguono le
   \textit{Single Unix Specification}, l'argomento \param{flags} era di tipo
 prima di queste funzioni è \funcd{sendto} ed il suo prototipo\footnote{il
   prototipo illustrato è quello utilizzato dalle \acr{glibc}, che seguono le
   \textit{Single Unix Specification}, l'argomento \param{flags} era di tipo
-  \type{int} nei vari BSD4.*, mentre nelle \acr{libc4} e \acr{libc5} veniva
-  usato un \type{unsigned int}; l'argomento \param{len} era \type{int} nei
+  \texttt{int} nei vari BSD4.*, mentre nelle \acr{libc4} e \acr{libc5} veniva
+  usato un \texttt{unsigned int}; l'argomento \param{len} era \texttt{int} nei
   vari BSD4.* e nelle \acr{libc4}, ma \type{size\_t} nelle \acr{libc5}; infine
   vari BSD4.* e nelle \acr{libc4}, ma \type{size\_t} nelle \acr{libc5}; infine
-  l'argomento \param{tolen} era \type{int} nei vari BSD4.* nelle \acr{libc4} e
-  nelle \acr{libc5}.} è:
+  l'argomento \param{tolen} era \texttt{int} nei vari BSD4.* nelle \acr{libc4}
+  nelle \acr{libc5}.} è:
 \begin{functions}
   \headdecl{sys/types.h}
   \headdecl{sys/socket.h}
 \begin{functions}
   \headdecl{sys/types.h}
   \headdecl{sys/socket.h}
@@ -211,7 +213,7 @@ come maschera binaria che permette di impostare una serie di modalit
 funzionamento della comunicazione attraverso il socket (come
 \const{MSG\_NOSIGNAL} che impedisce l'invio del segnale \const{SIGPIPE} quando
 si è già chiuso il capo locale della connessione). Torneremo con maggiori
 funzionamento della comunicazione attraverso il socket (come
 \const{MSG\_NOSIGNAL} che impedisce l'invio del segnale \const{SIGPIPE} quando
 si è già chiuso il capo locale della connessione). Torneremo con maggiori
-dettagli sul significato di questo argomento in sez.~\ref{sec:xxx_sendmsg},
+dettagli sul significato di questo argomento in sez.~\ref{sec:net_sendmsg},
 dove tratteremo le funzioni avanzate dei socket, per il momento ci si può
 limitare ad usare sempre un valore nullo.
 
 dove tratteremo le funzioni avanzate dei socket, per il momento ci si può
 limitare ad usare sempre un valore nullo.
 
@@ -219,9 +221,9 @@ La seconda funzione utilizzata nella comunicazione fra socket UDP 
 \funcd{recvfrom}, che serve a ricevere i dati inviati da un altro socket; il
 suo prototipo\footnote{il prototipo è quello delle \acr{glibc} che seguono le
   \textit{Single Unix Specification}, i vari BSD4.*, le \acr{libc4} e le
 \funcd{recvfrom}, che serve a ricevere i dati inviati da un altro socket; il
 suo prototipo\footnote{il prototipo è quello delle \acr{glibc} che seguono le
   \textit{Single Unix Specification}, i vari BSD4.*, le \acr{libc4} e le
-  \acr{libc5} usano un \type{int} come valore di ritorno; per gli argomenti
+  \acr{libc5} usano un \texttt{int} come valore di ritorno; per gli argomenti
   \param{flags} e \param{len} vale quanto detto a proposito di \func{sendto};
   \param{flags} e \param{len} vale quanto detto a proposito di \func{sendto};
-  infine l'argomento \param{fromlen} è \type{int} per i vari BSD4.*, le
+  infine l'argomento \param{fromlen} è \texttt{int} per i vari BSD4.*, le
   \acr{libc4} e le \acr{libc5}.} è:
 \begin{functions}
   \headdecl{sys/types.h}
   \acr{libc4} e le \acr{libc5}.} è:
 \begin{functions}
   \headdecl{sys/types.h}
@@ -264,9 +266,10 @@ I due argomenti \param{from} e \param{fromlen} sono utilizzati per ottenere
 l'indirizzo del mittente del pacchetto che è stato ricevuto, e devono essere
 opportunamente inizializzati con i puntatori alle variabili dove la struttura
 contenente quest'ultimo e la relativa lunghezza saranno scritti (si noti che
 l'indirizzo del mittente del pacchetto che è stato ricevuto, e devono essere
 opportunamente inizializzati con i puntatori alle variabili dove la struttura
 contenente quest'ultimo e la relativa lunghezza saranno scritti (si noti che
-\param{fromlen} è un valore intero ottenuto come \textit{value return
-  argument}).  Se non si è interessati a questa informazione, entrambi gli
-argomenti devono essere inizializzati al valore \const{NULL}.
+\param{fromlen} è un valore intero ottenuto come
+\itindex{value~result~argument} \textit{value result argument}).  Se non si è
+interessati a questa informazione, entrambi gli argomenti devono essere
+inizializzati al valore \const{NULL}.
 
 Una differenza fondamentale del comportamento di queste funzioni rispetto alle
 usuali \func{read} e \func{write} che abbiamo usato con i socket TCP è che in
 
 Una differenza fondamentale del comportamento di queste funzioni rispetto alle
 usuali \func{read} e \func{write} che abbiamo usato con i socket TCP è che in
@@ -321,9 +324,9 @@ Il passo successivo (\texttt{\small 13--21}) 
 struttura degli indirizzi; prima (\texttt{\small 14}) si cancella
 completamente la stessa con \func{memset}, (\texttt{\small 15}) poi si imposta
 la famiglia dell'indirizzo ed infine (\texttt{\small 16} la porta. Infine
 struttura degli indirizzi; prima (\texttt{\small 14}) si cancella
 completamente la stessa con \func{memset}, (\texttt{\small 15}) poi si imposta
 la famiglia dell'indirizzo ed infine (\texttt{\small 16} la porta. Infine
-(\texttt{\small 18--21}) si ricava l'indirizzo del server da contattare dal
-parametro passato a riga di comando, convertendolo con \func{inet\_pton}. Si
-noti come questa sezione sia identica a quella del client TCP di
+(\texttt{\small 18--21}) si ricava l'indirizzo del server da contattare
+dall'argomento passato a riga di comando, convertendolo con \func{inet\_pton}.
+Si noti come questa sezione sia identica a quella del client TCP di
 fig.~\ref{fig:TCP_daytime_client_code}, in quanto la determinazione dell'uso
 di UDP al posto di TCP è stata effettuata quando si è creato il socket.
 
 fig.~\ref{fig:TCP_daytime_client_code}, in quanto la determinazione dell'uso
 di UDP al posto di TCP è stata effettuata quando si è creato il socket.
 
@@ -656,8 +659,8 @@ asincroni.
 
 Quando si chiama \func{connect} su di un socket UDP tutto quello che succede è
 che l'indirizzo passato alla funzione viene registrato come indirizzo di
 
 Quando si chiama \func{connect} su di un socket UDP tutto quello che succede è
 che l'indirizzo passato alla funzione viene registrato come indirizzo di
-destinazione del socket, a differenza di quanto avviene con TCP non viene
-scambiato nessun pacchetto; tutto quello che succede è che da quel momento in
+destinazione del socket. A differenza di quanto avviene con TCP non viene
+scambiato nessun pacchetto, tutto quello che succede è che da quel momento in
 qualunque cosa si scriva sul socket sarà inviata a quell'indirizzo; non sarà
 più necessario usare l'argomento \param{to} di \func{sendto} per specificare
 la destinazione dei pacchetti, che potranno essere inviati e ricevuti usando
 qualunque cosa si scriva sul socket sarà inviata a quell'indirizzo; non sarà
 più necessario usare l'argomento \param{to} di \func{sendto} per specificare
 la destinazione dei pacchetti, che potranno essere inviati e ricevuti usando
@@ -666,12 +669,12 @@ le normali funzioni \func{read} e \func{write}.\footnote{in realt
   l'argomento \param{to} deve essere inizializzato a \const{NULL}, e
   \param{tolen} deve essere inizializzato a zero, pena un errore.}
 
   l'argomento \param{to} deve essere inizializzato a \const{NULL}, e
   \param{tolen} deve essere inizializzato a zero, pena un errore.}
 
-Una volta che il socket è connesso però cambia anche il comportamento in
+Una volta che il socket è connesso cambia però anche il comportamento in
 ricezione; prima infatti il kernel avrebbe restituito al socket qualunque
 pacchetto ricevuto con un indirizzo di destinazione corrispondente a quello
 del socket, senza nessun controllo sulla sorgente; una volta che il socket
 viene connesso saranno riportati su di esso solo i pacchetti con un indirizzo
 ricezione; prima infatti il kernel avrebbe restituito al socket qualunque
 pacchetto ricevuto con un indirizzo di destinazione corrispondente a quello
 del socket, senza nessun controllo sulla sorgente; una volta che il socket
 viene connesso saranno riportati su di esso solo i pacchetti con un indirizzo
-sorgente corrispondente a quello a cui ci si è connessi. 
+sorgente corrispondente a quello a cui ci si è connessi.
 
 Infine quando si usa un socket connesso, venendo meno l'ambiguità segnalata
 alla fine di sez.~\ref{sec:UDP_problems}, tutti gli eventuali errori asincroni
 
 Infine quando si usa un socket connesso, venendo meno l'ambiguità segnalata
 alla fine di sez.~\ref{sec:UDP_problems}, tutti gli eventuali errori asincroni
@@ -693,7 +696,7 @@ illustrate in fig.~\ref{fig:UDP_echo_conn_cli}.
 Ed in questo caso rispetto alla precedente versione, il solo cambiamento è
 l'utilizzo (\texttt{\small 17}) della funzione \func{connect} prima della
 chiamata alla funzione di gestione del protocollo, che a sua volta è stata
 Ed in questo caso rispetto alla precedente versione, il solo cambiamento è
 l'utilizzo (\texttt{\small 17}) della funzione \func{connect} prima della
 chiamata alla funzione di gestione del protocollo, che a sua volta è stata
-modificata eliminando l'indirizzo passato come parametro e sostituendo le
+modificata eliminando l'indirizzo passato come argomento e sostituendo le
 chiamata a \func{sendto} e \func{recvfrom} con chiamate a \func{read} e
 \func{write} come illustrato dal nuovo codice riportato in
 fig.~\ref{fig:UDP_echo_conn_echo_client}.
 chiamata a \func{sendto} e \func{recvfrom} con chiamate a \func{read} e
 \func{write} come illustrato dal nuovo codice riportato in
 fig.~\ref{fig:UDP_echo_conn_echo_client}.
@@ -708,28 +711,79 @@ fig.~\ref{fig:UDP_echo_conn_echo_client}.
   \label{fig:UDP_echo_conn_echo_client}
 \end{figure}
 
   \label{fig:UDP_echo_conn_echo_client}
 \end{figure}
 
+Utilizzando questa nuova versione del client si può verificare che quando ci
+si rivolge verso un indirizzo inesistente o su cui non è in ascolto un server
+si è in grado rilevare l'errore, se infatti eseguiamo il nuovo programma
+otterremo un qualcosa del tipo:
+\begin{verbatim}
+[piccardi@gont sources]$ ./echo 192.168.1.1
+prova
+Errore in lettura: Connection refused
+\end{verbatim}%$
+
+Ma si noti che a differenza di quanto avveniva con il client TCP qui l'errore
+viene rilevato soltanto dopo che si è tentato di inviare qualcosa, ed in
+corrispondenza al tentativo di lettura della risposta. Questo avviene perché
+con UDP non esiste una connessione, e fintanto che non si invia un pacchetto
+non c'è traffico sulla rete. In questo caso l'errore sarà rilevato alla
+ricezione del pacchetto ICMP \textit{destination unreachable} emesso dalla
+macchina cui ci si è rivolti, e questa volta, essendo il socket UDP connesso,
+il kernel potrà riportare detto errore in user space in maniera non ambigua,
+ed esso apparirà alla successiva lettura sul socket.
+
+Si tenga presente infine che l'uso dei socket connessi non risolve l'altro
+problema del client, e cioè il fatto che in caso di perdita di un pacchetto
+questo resterà bloccato permanentemente in attesa di una risposta. Per
+risolvere questo problema l'unico modo sarebbe quello di impostare un
+\textit{timeout} o riscrivere il client in modo da usare l'I/O non bloccante.
 
 
 
 
 
 
+\index{socket!locali|(}
+
 
 \section{I socket \textit{Unix domain}}
 \label{sec:unix_socket}
 
 
 \section{I socket \textit{Unix domain}}
 \label{sec:unix_socket}
 
-Benché i socket Unix domain non siano strettamente attinenti alla rete, in
-quanto definiscono una interfaccia di comunicazione locale alla singola
-macchina, li tratteremo comunque in questa sezione in quanto la loro
-interfaccia è comunque basata sulla più generale interfaccia dei socket.
+Benché i socket Unix domain, come meccanismo di comunicazione fra processi che
+girano sulla stessa macchina, non siano strettamente attinenti alla rete, li
+tratteremo comunque in questa sezione. Nonostante le loro peculiarità infatti,
+l'interfaccia di programmazione che serve ad utilizzarli resta sempre quella
+dei socket.
+
+
+
+\subsection{Il passaggio di file descriptor}
+\label{sec:sock_fd_passing}
+
+
+
+\index{socket!locali|)}
 
 
 \section{Altri socket}
 \label{sec:socket_other}
 
 
 
 \section{Altri socket}
 \label{sec:socket_other}
 
-
 Tratteremo in questa sezione gli altri tipi particolari di socket supportati
 Tratteremo in questa sezione gli altri tipi particolari di socket supportati
-da Linux, come i \textit{raw socket}, con i quali si possono \textsl{forgiare}
-direttamente i pacchetti a tutti i livelli dello stack dei protocolli, o i
+da Linux, come quelli relativi a particolare protocolli di trasmissione, i
 socket \textit{netlink} che definiscono una interfaccia di comunicazione con
 socket \textit{netlink} che definiscono una interfaccia di comunicazione con
-il kernel.
+il kernel, ed i \textit{packet socket} che consentono di inviare pacchetti
+direttamente a livello delle interfacce di rete. 
+
+\subsection{I socket \textit{raw}}
+\label{sec:socket_raw}
+
+Tratteremo in questa sezione i cosiddetti \textit{raw socket}, con i quali si
+possono \textsl{forgiare} direttamente i pacchetti a tutti i livelli dello
+stack dei protocolli. 
+
+\subsection{I socket \textit{netlink}}
+\label{sec:socket_netlink}
+
+
+\subsection{I \textit{packet socket}}
+\label{sec:packet_socket}
+
 
 
 
 
 
 
@@ -738,3 +792,16 @@ il kernel.
 %%% mode: latex
 %%% TeX-master: "gapil"
 %%% End: 
 %%% mode: latex
 %%% TeX-master: "gapil"
 %%% End: 
+
+% LocalWords:  socket cap TCP UDP domain sez NFS DNS stream datagram PF INET to
+% LocalWords:  IPv tab SOCK DGRAM three way handshake client fig bind listen AF
+% LocalWords:  accept recvfrom sendto connect netstat named DHCP kernel ICMP CR
+% LocalWords:  port unreachable read write glibc Specification flags int BSD LF
+% LocalWords:  libc unsigned len size tolen sys ssize sockfd const void buf MSG
+% LocalWords:  struct sockaddr socklen errno EAGAIN ECONNRESET EDESTADDRREQ RFC
+% LocalWords:  EISCONN EMSGSIZE ENOBUFS ENOTCONN EOPNOTSUPP EPIPE SIGPIPE EBADF
+% LocalWords:  NOSIGNAL EFAULT EINVAL EINTR ENOMEM ENOTSOCK NULL fromlen from
+% LocalWords:  ECONNREFUSED value result argument close shutdown daytime nell'
+% LocalWords:  memset inet pton nread NUL superdemone inetd sniffer daytimed
+% LocalWords:  INADDR ANY addr echo ClientEcho sendbuff serv VPN tcpdump l'I
+% LocalWords:  Stevens destination descriptor raw stack netlink