%% socket.tex
%%
-%% Copyright (C) 2000-2004 Simone Piccardi. Permission is granted to
+%% Copyright (C) 2000-2006 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 "Un preambolo",
\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 sez.~\ref{sec:ipc_socketpair}, fra i vari meccanismi di intercominazione
+in sez.~\ref{sec:ipc_socketpair}, fra i vari meccanismi di intercomunicazione
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
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
+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
inviati, o inviare dei pacchetti più volte (come nel caso di TCP e UDP).
avviene, in certi casi essa può essere condotta con una connessione diretta
con un solo corrispondente, come per una telefonata; altri casi possono
prevedere una comunicazione come per lettera, in cui si scrive l'indirizzo su
-ogni pacchetto, altri ancora una comunicazione \textit{broadcast} come per la
-radio, in cui i pacchetti vengono emessi su appositi ``\textsl{canali}'' dove
-chiunque si collega possa riceverli.
+ogni pacchetto, altri ancora una comunicazione \itindex{broadcast}
+\textit{broadcast} come per la radio, in cui i pacchetti vengono emessi su
+appositi ``\textsl{canali}'' dove 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
\const{PF\_ECONET} &19& Acorn Econet & \\
\const{PF\_ATMSVC} &20& ATM SVCs & \\
\const{PF\_SNA} &22& Linux SNA Project & \\
- \const{PF\_IRDA} &23& IRDA sockets & \\
- \const{PF\_PPPOX} &24& PPPoX sockets & \\
- \const{PF\_WANPIPE} &25& Wanpipe API sockets & \\
- \const{PF\_BLUETOOTH}&31& Bluetooth sockets & \\
+ \const{PF\_IRDA} &23& IRDA socket & \\
+ \const{PF\_PPPOX} &24& PPPoX socket & \\
+ \const{PF\_WANPIPE} &25& Wanpipe API socket & \\
+ \const{PF\_BLUETOOTH}&31& Bluetooth socket & \\
\hline
\end{tabular}
\caption{Famiglie di protocolli definiti in Linux.}
dall'utente generico, ad esempio in generale tutti i socket di tipo
\const{SOCK\_RAW} possono essere creati solo da processi che hanno i privilegi
di amministratore (cioè con user-ID effettivo uguale a zero) o dotati della
-capability \texttt{CAP\_NET\_RAW}.
+\itindex{capabilities}\textit{capability} \const{CAP\_NET\_RAW}.
\subsection{Il tipo, o stile}
\item[\const{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}).
+ byte (da cui il nome \textit{stream}) e possono essere letti in blocchi di
+ dimensioni qualunque. Può supportare la trasmissione dei cosiddetti dati
+ \itindex{out-of-band} \textit{out-of-band} (vedi
+ sez.~\ref{sec:TCP_urgent_data}).
\item[\const{SOCK\_DGRAM}] Viene usato per trasmettere pacchetti di dati
(\textit{datagram}) di lunghezza massima prefissata, indirizzati
singolarmente. Non esiste una connessione e la trasmissione è effettuata in
\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
- massima fissata, ed devono essere letti integralmente da ciascuna
- chiamata a \func{read}.
+ massima fissata, e 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, è riservato all'uso di sistema.
\begin{minipage}[c]{15cm}
\includestruct{listati/sockaddr_in.h}
\end{minipage}
- \caption{La struttura degli indirizzi dei socket internet (IPv4)
- \structd{sockaddr\_in}.}
+ \caption{La struttura \structd{sockaddr\_in} degli indirizzi dei socket
+ internet (IPv4) e la struttura \structd{in\_addr} degli indirizzi IPv4.}
\label{fig:sock_sa_ipv4_struct}
\end{figure}
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 sez.~\ref{sec:TCP_func_bind}) su
-queste porte.
+uguale a zero) o con la \itindex{capabilities}\textit{capability}
+\const{CAP\_NET\_BIND\_SERVICE} possono 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
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
-tab.~\ref{tab:TCP_ipv4_addr}, che reincontreremo più avanti.
+tab.~\ref{tab:TCP_ipv4_addr}, che rincontreremo 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è
\begin{minipage}[c]{15cm}
\includestruct{listati/sockaddr_in6.h}
\end{minipage}
- \caption{La struttura degli indirizzi dei socket IPv6
- \structd{sockaddr\_in6}.}
+ \caption{La struttura \structd{sockaddr\_in6} degli indirizzi dei socket
+ IPv6 e la struttura \structd{in6\_addr} degli indirizzi IPv6.}
\label{fig:sock_sa_ipv6_struct}
\end{figure}
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.
+riguardanti il \itindex{multicast} \textit{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}
\begin{minipage}[c]{15cm}
\includestruct{listati/sockaddr_un.h}
\end{minipage}
- \caption{La struttura degli indirizzi dei socket locali (detti anche
- \textit{unix domain}) \structd{sockaddr\_un} definita in \file{sys/un.h}.}
+ \caption{La struttura \structd{sockaddr\_un} degli indirizzi dei socket
+ locali (detti anche \textit{unix domain}) definita in \file{sys/un.h}.}
\label{fig:sock_sa_local_struct}
\end{figure}
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
-\index{\textit{pathname}}\textit{pathname} del file; nel secondo invece
+\itindex{pathname}\textit{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.
a pacchetto, di tipo \const{SOCK\_DGRAM}; l'argomento \param{protocol} di
\func{socket} deve essere nullo. È altresì possibile usare i socket raw
specificando un tipo \const{SOCK\_RAW}, nel qual caso l'unico valore valido
-per \param{protocol} è \func{ATPROTO\_DDP}.
+per \param{protocol} è \const{ATPROTO\_DDP}.
Gli indirizzi AppleTalk devono essere specificati tramite una struttura
\struct{sockaddr\_atalk}, la cui definizione è riportata in
\begin{minipage}[c]{15cm}
\includestruct{listati/sockaddr_atalk.h}
\end{minipage}
- \caption{La struttura degli indirizzi dei socket AppleTalk
- \structd{sockaddr\_atalk}.}
+ \caption{La struttura \structd{sockaddr\_atalk} degli indirizzi dei socket
+ AppleTalk, e la struttura \structd{at\_addr} degli indirizzi AppleTalk.}
\label{fig:sock_sa_atalk_struct}
\end{figure}
Il campo \var{sat\_family} deve essere sempre \const{AF\_APPLETALK}, mentre il
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} (vedi
-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
-\const{AT\_ANYNODE} che indica anche il nodo corrente, ed il valore
-\const{ATADDR\_BCAST} che indica tutti i nodi della rete.
+usati solo da processi con i privilegi di amministratore o con la
+\itindex{capabilities}\textit{capability} \const{CAP\_NET\_BIND\_SERVICE}.
+L'indirizzo remoto è specificato nella struttura \var{sat\_addr}, e deve
+essere in \textit{network order} (vedi 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 \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}}
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
+direttamente su un'interfaccia di rete, senza passare per le funzioni 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
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}.
+la \itindex{capabilities}\textit{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
\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
+seguenti valori: \const{PACKET\_HOST} per un pacchetto indirizzato alla
+macchina ricevente, \const{PACKET\_BROADCAST} per un pacchetto di
+\itindex{broadcast} \textit{broadcast}, \const{PACKET\_MULTICAST} per un
+pacchetto inviato ad un indirizzo fisico di \itindex{multicast}
+\textit{multicast}, \const{PACKET\_OTHERHOST} per un pacchetto inviato ad
+un'altra stazione (e ricevuto su un'interfaccia in modo promiscuo),
+\const{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.
+Si tenga presente infine che in fase di ricezione, anche se si richiede il
+troncamento del pacchetto, le funzioni \func{recv}, \func{recvfrom} e
+\func{recvmsg} (vedi sez.~\ref{sec:net_sendmsg}) restituiranno comunque la
+lunghezza effettiva del pacchetto così come arrivato sulla linea.
%% \subsection{La struttura degli indirizzi DECnet}
%% \label{sec:sock_sa_decnet}
% 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
+% In particolare le tre funzioni \func{bind}, \func{connect} e
+% \func{sendto} passano la struttura al kernel, in questo caso è passata
% \textsl{per valore} anche la dimensione della medesima
-% Le funzioni \texttt{accept}, \texttt{recvfrom}, \texttt{getsockname} e
-% \texttt{getpeername} invece ricevono i valori del kernel
+% Le funzioni \func{accept}, \func{recvfrom}, \func{getsockname} e
+% \func{getpeername} invece ricevono i valori del kernel
\subsection{La \textit{endianess}}
\label{sec:sock_endianess}
-\index{\textit{endianess}|(}
+\itindbeg{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 (ed in genere in diretta corrispondenza a come sono poi in
realtà cablati sui bus interni del computer).
+\begin{figure}[htb]
+ \centering
+ \includegraphics[height=3cm]{img/endianess}
+ \caption{Schema della disposizione dei dati in memoria a seconda della
+ \textit{endianess}.}
+ \label{fig:sock_endianess}
+\end{figure}
+
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
fig.~\ref{fig:sock_endianess} i singoli bit possono essere disposti un memoria
parte dal bit meno significativo è detto per lo stesso motivo \textit{little
endian}.
-\begin{figure}[htb]
- \centering
- \includegraphics[height=3cm]{img/endianess}
- \caption{Schema della disposizione dei dati in memoria a seconda della
- \textit{endianess}.}
- \label{fig:sock_endianess}
-\end{figure}
-
Si può allora verificare quale tipo di \textit{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.
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}
\label{fig:sock_endian_code}
\end{figure}
+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}.
+
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.
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.
-
-\index{\textit{endianess}|)}
+il valore del confronto delle due variabili.
+\itindend{endianess}
\subsection{Le funzioni per il riordinamento}
\label{sec:sock_func_ord}
-Il problema connesso all'endianess\index{\textit{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 byte in cui è suddiviso scambiati di posto. Per questo
-motivo si usano delle 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 \funcd{htonl}, \funcd{htons}, \funcd{ntohl} e \funcd{ntohs} ed i
-rispettivi prototipi sono:
+Il problema connesso all'endianess\itindex{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 byte in cui è suddiviso scambiati di posto. Per questo motivo si
+usano delle 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 \funcd{htonl},
+\funcd{htons}, \funcd{ntohl} e \funcd{ntohs} ed i rispettivi prototipi sono:
\begin{functions}
\headdecl{netinet/in.h}
\funcdecl{unsigned long int htonl(unsigned long int hostlong)}
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 \param{af} che indica il tipo di
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
%%% mode: latex
%%% TeX-master: "gapil"
%%% End:
+
+% LocalWords: socket sez cap BSD SVr XTI Transport Interface TCP stream UDP PF
+% LocalWords: datagram broadcast descriptor sys int domain type protocol errno
+% LocalWords: EPROTONOSUPPORT ENFILE kernel EMFILE EACCES EINVAL ENOBUFS raw
+% LocalWords: ENOMEM table family AF address name glibc UNSPEC LOCAL Local IPv
+% LocalWords: communication INET protocols ip AX Amateur IPX Novell APPLETALK
+% LocalWords: Appletalk ddp NETROM NetROM Multiprotocol ATMPVC Access to ATM
+% LocalWords: PVCs ITU ipv PLP DECnet Reserved for project NETBEUI LLC KEY key
+% LocalWords: SECURITY Security callback NETLINK interface device netlink Low
+% LocalWords: PACKET level packet ASH Ash ECONET Acorn Econet ATMSVC SVCs SNA
+% LocalWords: IRDA PPPOX PPPoX WANPIPE Wanpipe BLUETOOTH Bluetooth POSIX bits
+% LocalWords: dall'header tab SOCK capabilities capability styles DGRAM read
+% LocalWords: SEQPACKET RDM sockaddr reference void fig Header uint socklen at
+% LocalWords: addr netinet port len Stevens unsigned short casting nell'header
+% LocalWords: BIND SERVICE bind union order big endian flowinfo dell'header ll
+% LocalWords: multicast multicasting local socketpair sun path filesystem AARP
+% LocalWords: pathname AppleTalk netatalk personal Apple ATPROTO atalk sat if
+% LocalWords: ANYNET node ANYNODE ATADDR BCAST pcap IEEE linux ether ETH ALL
+% LocalWords: sll ifindex ethernet halen MAC hatype ARP arp pkttype HOST recv
+% LocalWords: OTHERHOST OUTGOING recvfrom recvmsg endianess little endtest Mac
+% LocalWords: Intel Digital Motorola IBM VME PowerPC l'Intel xABCD ptr htonl
+% LocalWords: all'endianess htons ntohl ntohs long hostlong hostshort netlong
+% LocalWords: sort netshort host inet aton ntoa dotted decimal const char src
+% LocalWords: strptr struct dest addrptr INADDR NULL pton ntop presentation af
+% LocalWords: numeric EAFNOSUPPORT size ENOSPC ENOAFSUPPORT ADDRSTRLEN